CivicRecords AI

Unified Operations Manual
Version 1.4.1
Staff User Guide & IT Administration Reference
April 2026
AI-Powered Open Records Support for American Cities

v1.2.0 — what changed since this manual was authored

This unified manual was first written against v1.1.0. Five operator-facing capabilities landed in the v1.2.0 release (2026-04-23) and are not individually documented in every section below. Where this manual and the current CHANGELOG disagree, the CHANGELOG wins.

Canonical narrative: the v1.2.0 release page · CHANGELOG §[1.2.0] · UNIFIED-SPEC.

Table of Contents

Part I — User Guide (Records Staff)
  1. Welcome
  2. Signing In
  3. Dashboard Overview
  4. Searching for Records
  5. Managing Records Requests
  6. Reviewing Exemption Flags
  7. Response Letters
  8. Timeline & Messaging
  9. Fee Tracking
  10. Department Access
  11. Quick Reference
Part II — IT Administration Guide
  1. System Architecture
  2. Hardware Requirements
  3. Installation
  4. Configuration Reference
  5. User & Department Administration
  6. Data Source Management
  7. Model Management
  8. Exemption Rules Administration
  9. Compliance & Audit
  10. Security
  11. Backup & Recovery
  12. Monitoring & Troubleshooting
  13. Upgrading
Appendices

Part I: User Guide

For City Clerks, Records Officers, Department Liaisons, and City Managers

1. Welcome

What CivicRecords AI Does

CivicRecords AI is a tool that helps your city respond to public records requests faster, more consistently, and with greater confidence. When a resident submits a records request, the system searches across your city's record sources — meeting minutes, resolutions, ordinances, permits, and more — and presents the most relevant results in seconds. It also suggests which exemptions might apply, drafts response letters, and tracks every request from receipt to fulfillment.

What CivicRecords AI Is Not

CivicRecords AI is an assistant, not a decision-maker. Everything it does is a recommendation for you to review. The system suggests and drafts; you review and approve. Every exemption flag, every response letter, and every release decision requires a human sign-off.

It is not a public portal. Residents do not interact with CivicRecords AI directly. You use it internally to process their requests.

Privacy by Design

CivicRecords AI runs entirely on your city's local network or on-premises servers. No records or request data leave your infrastructure. The AI models run locally — no cloud AI services are used.

Note
This manual is written for city staff members who use CivicRecords AI day to day: city clerks who process records requests, records officers who manage compliance, department liaisons who search for and provide departmental records, and city managers who oversee the process. You do not need any technical background to use the system.

Who This Manual Is For

RolePrimary Tasks
City ClerkReceive and process incoming records requests, search for responsive documents, draft and send response letters
Records OfficerManage compliance, review exemption flags, approve response letters, oversee request workflows
Department LiaisonSearch for records within your department, attach documents to requests, provide context for department-specific records
City ManagerMonitor dashboard for workload and compliance, review reports, oversee department performance

2. Signing In

How to Access CivicRecords AI

Open your web browser (Chrome, Edge, or Firefox are recommended) and navigate to the address provided by your IT department. In most installations, this is:

http://localhost:8080

If your city has deployed CivicRecords AI on a shared network server, your IT administrator will provide the correct address (for example, http://records.yourcity.local:8080).

Logging In

  1. Enter your email address in the Email field.
  2. Enter your password in the Password field.
  3. Select Sign In.

Your account is created by your IT administrator. If you do not have an account, contact your IT department.

Tip
If you see a "connection refused" or "page cannot be displayed" error, the CivicRecords AI server may not be running. Contact your IT administrator.

Logging Out

Select your name or initials in the upper-right corner of any page, then select Sign Out. Your session expires automatically after a period of inactivity (configured by your IT administrator, typically 30 minutes).

Password Changes

Password management is handled by your IT administrator. If you need to change your password, contact them directly. Self-service password reset is not available in the current version.

3. Dashboard Overview

The Main Dashboard

After signing in, you land on the Dashboard. This is your home screen and provides an at-a-glance view of your workload and the overall status of records requests in the system.

Dashboard Components

ComponentDescription
Open Requests CounterThe total number of records requests currently in progress (not yet closed or fulfilled).
Approaching DeadlinesRequests with statutory deadlines within the next 3 business days, highlighted in amber or red depending on urgency.
Status DistributionA breakdown of all active requests by their current status (received, searching, in review, etc.).
Recent ActivityA timeline of the most recent actions across all requests: status changes, documents attached, letters sent.
My Assigned RequestsRequests specifically assigned to you. This is your personal work queue.
Tip
Check the dashboard at the start of each workday to identify urgent deadlines and new assignments.

Navigation Sidebar

The left sidebar provides links to the main areas of the application:

4. Searching for Records

How Search Works

CivicRecords AI uses hybrid search that combines two techniques: keyword search (traditional full-text matching) and semantic search (AI-powered meaning-based retrieval). This means you can search using natural language questions, not just exact keywords.

Performing a Search

  1. Select Search from the sidebar or use the search bar at the top of any page.
  2. Type your search query. You can use natural language (e.g., "building permits issued in 2024 for Main Street") or keywords (e.g., "permit Main Street 2024").
  3. Press Enter or select the search button.
  4. Results appear ranked by relevance, with the most relevant documents at the top.

Understanding Search Results

Each result shows:

Refining Your Search

If your initial search returns too many or too few results:

Note
Search results are limited to documents within your department unless you have Reviewer or Admin access, which provides cross-department visibility.

Attaching Search Results to a Request

When you find a document that is responsive to a records request:

  1. Select the Attach to Request button on the search result.
  2. Choose the request from the dropdown list or enter the request ID.
  3. Optionally add a relevance note explaining why this document is responsive.
  4. Select Attach. The document now appears in the request's document list.

5. Managing Records Requests

Creating a New Request

When a public records request arrives (by email, in person, or through your city's intake process):

  1. Select Requests from the sidebar, then select New Request.
  2. Fill in the required fields:
    • Requester Name — The name of the person or organization making the request.
    • Requester Email — Contact email address.
    • Description — The full text of the records request as received.
    • Statutory Deadline — The date by which your state's open records law requires a response. The system pre-fills this based on your state's default timeline, but you can adjust it.
  3. Select Create Request. The request is created with a status of Received.

Request Status Workflow

Every request moves through a defined workflow. The following table shows each status and what it means:

StatusMeaningWho Acts
ReceivedThe request has been logged but not yet assigned or acted upon.Clerk
Clarification NeededThe request is unclear or incomplete; the requester has been asked for more information.Clerk
AssignedThe request has been assigned to a specific staff member.Clerk / Manager
SearchingStaff is actively searching for responsive documents.Staff
In ReviewDocuments have been gathered and are being reviewed for exemptions and completeness.Staff / Reviewer
Ready for ReleaseDocuments have been reviewed and are ready for supervisor approval.Reviewer
DraftedA response letter has been drafted and is awaiting review.Staff
ApprovedThe response letter and documents have been approved by a reviewer.Reviewer
Fulfilled / SentThe response has been sent to the requester.Clerk
RejectedThe request was denied (with documented reasons and legal basis).Reviewer
ClosedThe request is complete and archived.Clerk

Moving a Request Through the Workflow

To advance a request to its next status:

  1. Open the request from the Requests list.
  2. The available workflow actions appear as buttons in the sidebar (e.g., "Start Searching," "Submit for Review," "Approve").
  3. Select the appropriate action. The system validates the transition and updates the status.
  4. A timeline entry is automatically created recording the status change, your identity, and a timestamp.
Warning
You cannot skip statuses. The system enforces the defined workflow transitions. For example, you cannot move a request directly from "Received" to "Approved" — it must pass through the intermediate steps.

Assigning Requests

Clerks and managers can assign requests to specific staff members:

  1. Open the request.
  2. Select Assign and choose the staff member from the dropdown.
  3. The assignee is notified and the request appears in their "My Assigned Requests" dashboard list.

6. Reviewing Exemption Flags

What Exemption Flags Are

When documents are attached to a request, CivicRecords AI automatically scans them for content that may be exempt from disclosure under your state's open records law. These are presented as exemption flags — recommendations for your review, not automatic decisions.

Viewing Exemption Flags

Open a request and select the Exemptions tab. For each flag, you will see:

Exemption Categories

CategoryDescriptionExamples
PII (Personal Information)Personally identifiable information that may need to be redacted for privacy.Social Security numbers, driver's license numbers, personal phone numbers, dates of birth, home addresses, medical information
StatutoryContent that may be exempt by specific state statute.Attorney-client privileged communications, law enforcement investigation records, trade secrets, sealed court records
Deliberative ProcessInternal deliberations, draft documents, and policy discussions that may be exempt.Pre-decisional memoranda, internal policy drafts, staff recommendations before a vote
SecurityInformation that could pose a security risk if disclosed.Building security plans, IT infrastructure details, emergency response protocols, access codes
PersonnelEmployee records that may be partially or fully exempt.Performance evaluations, disciplinary records, medical leave records, personal contact information of employees

Understanding Confidence Scores

Acting on Exemption Flags

For each flag, you have three options:

  1. Accept — You agree this content is exempt. It will be noted for redaction in the response documents.
  2. Reject — You disagree with the flag. The content will be included in the response as-is.
  3. Escalate — You are unsure and want a reviewer or city attorney to weigh in.
Security
Never release documents with unreviewed exemption flags. Every flag must be accepted or rejected by a staff member before a response letter can be finalized. The system enforces this requirement.

7. Response Letters

Generating a Response Letter

Once you have gathered all responsive documents and reviewed all exemption flags, you can generate a response letter:

  1. Open the request and select the Response Letter tab.
  2. Select Generate Draft. The system creates a draft letter using your city's response template, automatically populated with:
    • Requester name and contact information.
    • A description of the records requested.
    • A list of responsive documents being provided.
    • Citations for any exemptions applied, with the corresponding state statutes.
    • Fee information, if applicable.
  3. Review the draft carefully. You can edit any part of the letter directly in the editor.
  4. Select Save Draft when you are satisfied with the letter.

Submitting for Review

After saving a draft:

  1. Select Submit for Review. The request status changes to In Review.
  2. A reviewer (Records Officer or authorized supervisor) is notified.
  3. The reviewer can:
    • Approve — The letter is approved for release. The status changes to Approved.
    • Request Changes — The reviewer adds comments and returns the letter to the staff member for revision.
    • Reject — The draft is rejected entirely. The staff member must create a new draft.

Sending the Response

After a letter is approved:

  1. Open the approved request.
  2. Select Mark as Sent after you have delivered the response through your city's normal channels (email, postal mail, in-person pickup).
  3. The request status changes to Fulfilled / Sent.
Note
CivicRecords AI does not send response letters directly to requesters. You use your city's existing communication channels. The system tracks that the response was sent and records the date and method.

8. Timeline & Messaging

Viewing the Request Timeline

Every request has a Timeline tab that shows a chronological log of everything that has happened:

The timeline is read-only — you cannot edit or delete entries. This ensures a complete, tamper-proof record of every action taken on the request.

Adding Notes to the Timeline

  1. Open the request and go to the Timeline tab.
  2. Select Add Note.
  3. Type your note in the text field. You can document research findings, record phone conversations with the requester, or leave instructions for colleagues.
  4. Select Save Note. The note appears in the timeline with your name and a timestamp.

Sending Messages to Requesters

You can send messages to the requester directly from within a request:

  1. Open the request and go to the Messages tab.
  2. Select New Message.
  3. Type your message. Common uses include asking for clarification, providing status updates, or notifying the requester about fees.
  4. Select Send. The message is logged in the timeline and the request's message history.
Note
Messages sent through CivicRecords AI are recorded for compliance purposes. Use them for official communications related to the request. The system stores the message content, timestamp, and sender for the audit trail.

9. Fee Tracking

Adding Fees

If your city charges fees for records requests (copying fees, research time, etc.):

  1. Open the request and select the Fees tab.
  2. Select Add Fee.
  3. Enter the fee type (e.g., "Copying — Standard," "Research Time"), quantity, unit price, and any notes.
  4. Select Save. The fee appears in the fee table with a running total.

Fee Summary

The Fees tab shows:

Fee information is automatically included in generated response letters when applicable.

Tip
If your city's policy allows fee waivers for certain requesters (media, indigent requesters, etc.), you can mark individual fees as "Waived" with a reason. This is recorded in the audit trail.

10. Department Access

How Department Scoping Works

CivicRecords AI uses department-based access control to ensure staff members see only the records relevant to their work:

Note
If you cannot find a document you expect to see, it may belong to a different department's data source. Contact your Records Officer or a user with cross-department access for assistance.

Department Assignment

Your department assignment is configured by your IT administrator. If you need access to a different department's records, contact your administrator to request a department change or role upgrade.

11. Quick Reference

Glossary

TermDefinition
FOIA / Open Records RequestA formal request from a member of the public for government records. Name varies by state (FOIA, CORA, Public Records Act, etc.).
Responsive DocumentA document that contains information relevant to a records request.
ExemptionA legal basis for withholding all or part of a record from public disclosure.
RedactionThe removal or obscuring of exempt information from a document before release.
Statutory DeadlineThe legal timeframe within which your city must respond to a records request.
Hybrid SearchA search method that combines keyword matching with AI-powered semantic understanding.
RAG (Retrieval-Augmented Generation)The AI technique used to find relevant documents and generate contextual responses.
IngestionThe process of importing documents into CivicRecords AI for indexing and search.
Confidence ScoreA percentage indicating how certain the AI is about an exemption flag or search result relevance.
Audit TrailA tamper-proof log of every action taken in the system, used for compliance verification.

Keyboard Shortcuts

ShortcutAction
/ or Ctrl+KFocus the search bar
Ctrl+EnterSubmit the current form
EscClose the current modal or dialog
?Show keyboard shortcuts help

Status Reference

StatusColorPhase
Received■ BlueIntake
Clarification Needed■ BlueIntake
Assigned■ BlueIntake
Searching■ AmberProcessing
In Review■ PurpleReview
Ready for Release■ PurpleReview
Drafted■ AmberProcessing
Approved■ GreenCompletion
Fulfilled / Sent■ GreenCompletion
Rejected■ RedTerminal
Closed■ GrayTerminal

Part II: IT Administration Guide

For System Administrators, IT Directors, and DevOps Staff

12. System Architecture

CivicRecords AI is a self-contained, Docker-based application stack designed to run entirely on-premises. The architecture follows a three-tier design: a browser-based client layer, a Python application layer, and a data and AI layer. All components communicate over internal Docker networking with no external cloud dependencies.

12.1 Architecture Overview

The system comprises seven Docker services orchestrated by Docker Compose. The following diagram shows all components, their ports, internal modules, and data flow paths.

CLIENT LAYER APPLICATION LAYER DATA & AI LAYER Staff Users Browser (React 18 + shadcn/ui + Tailwind CSS) Single-Page Application — Port 8080 nginx Reverse Proxy — Port 8080 FastAPI Application Server Port 8000 Auth Module (JWT, RBAC) Search API (Hybrid RAG) Workflow API (11 Statuses) Exemption Engine (180 Rules) Dept Scoping Compliance (Audit Logger) LLM Abstraction Federation API Document Ingestion Pipeline Embedding Service Chunking Engine Celery Worker Async Ingestion / Embedding Celery Beat Scheduled Tasks PostgreSQL 17 + pgvector Port 5432 — 29 Tables Redis 7.2 Task Queue / Cache Port 6379 Ollama Local LLM Runtime — Port 11434 Gemma 4 nomic-embed -text HTTP :8080 Proxy :8000 SQL / pgvector :5432 Task Dispatch Task Consume :6379 LLM / Embed :11434 LLM Calls Embedding Storage
Figure 12-1. CivicRecords AI System Architecture — Docker Compose Stack

12.2 Component Details

ServiceTechnologyPortPurpose
FrontendReact 18, shadcn/ui, Tailwind CSS8080Single-page application served through nginx
nginxnginx (latest)8080Reverse proxy, static file serving, TLS termination
APIPython 3.12, FastAPI, Uvicorn8000Application server with all business logic modules
WorkerCelery 5.xAsynchronous document ingestion, embedding generation, LLM processing
BeatCelery BeatScheduled tasks (deadline monitoring, periodic re-indexing)
PostgreSQLPostgreSQL 17 + pgvector5432Primary database (29 tables), vector storage for embeddings
RedisRedis 7.26379Celery task broker, session cache, rate limiting
OllamaOllama (latest)11434Local LLM runtime hosting Gemma 4 and nomic-embed-text

12.3 Application Modules

The FastAPI application server contains the following internal modules:

ModuleResponsibility
Auth ModuleUser authentication via JWT tokens, role-based access control (RBAC) with 4 roles: Admin, Staff, Reviewer, Read-Only. Service account management for machine-to-machine API access.
Search APIHybrid retrieval-augmented generation (RAG) combining semantic vector search (pgvector) with keyword full-text search. Source attribution, session context for iterative refinement.
Workflow APIRecords request CRUD operations, status transitions through 11 defined statuses with validation, document association, deadline management.
Exemption EngineRules engine with 180 pre-loaded rules (regex patterns, keyword matching, statutory phrase detection) plus LLM-powered suggestion layer. Each exemption category is a separate detector.
Department ScopingRow-level access control tying users, data sources, documents, and requests to departments. Enforces department boundaries for Staff and Read-Only roles.
Compliance ModuleMiddleware-based audit logger recording every API call. Hash-chained, append-only audit trail. Exportable as CSV/JSON for external review.
LLM AbstractionModel-agnostic interface wrapping Ollama. Supports chat completion and embedding endpoints. Swap models without application code changes.
Federation APIREST endpoints for inter-instance communication. Allows one CivicRecords AI installation to query another with scoped, authenticated access via service account API keys.

12.4 Ingestion Pipeline

The document ingestion pipeline processes files from configured data sources through a two-track architecture. Files are routed based on type detection: standard document formats follow a fast track through native parsers, while scanned documents and images are routed through the LLM-powered track for multimodal text extraction.

Document Ingestion Pipeline Data Sources File Shares Uploads Email Archives Network Drives File Type Detection FAST TRACK Native Parsers PDF / DOCX / XLSX CSV / HTML / Email / Text (python-docx, openpyxl, etc.) Text Extraction LLM TRACK Gemma 4 Multimodal Scanned Docs / Images Handwritten Text / Photos Tesseract OCR Fallback (if LLM unavailable) Text Extraction Sentence-Aware Chunking nomic-embed-text Embedding Generation pgvector PostgreSQL Storage Supported Formats Fast Track: PDF (text-based), DOCX, XLSX, CSV, HTML, EML/MSG (email), TXT, RTF, JSON, XML LLM Track: Scanned PDF (image-only), TIFF, PNG, JPEG, BMP, GIF (document images) OCR Fallback: Tesseract 5 activates automatically when Ollama/Gemma 4 is unavailable or returns low-confidence results
Figure 12-2. Two-Track Document Ingestion Pipeline

12.5 Request Lifecycle Workflow

Records requests move through 11 defined statuses. Status transitions are validated by the workflow engine — invalid transitions are rejected. The following diagram shows all valid transitions, color-coded by processing phase.

Request Lifecycle — 11-Status Workflow Intake Processing Review Completion Terminal Received Clarification Needed Assigned Searching In Review Ready for Release Drafted Approved Rejected Revise Fulfilled Closed assign begin search submit review pass review draft letter approve mark sent close ask reply
Figure 12-3. Records Request Lifecycle — 11-Status Workflow with Phase Color Coding

12.6 Network Architecture

All services communicate over a single Docker bridge network (civicrecords-net). Only the nginx service exposes a port to the host. External access topology:

ServiceHost BindingInternal Only
nginx0.0.0.0:8080No (externally accessible)
FastAPIYes (nginx proxies to :8000)
PostgreSQLYes (:5432 internal)
RedisYes (:6379 internal)
OllamaYes (:11434 internal)
Celery WorkerYes (no port)
Celery BeatYes (no port)
Security
The system binds to localhost or a city-designated internal IP only. It must never be exposed to the public internet. HTTPS with self-signed or city-provided TLS certificates is recommended for all web interfaces.

13. Hardware Requirements

Server Specifications

ComponentMinimum SpecRecommended Spec
CPUAMD Ryzen 7 (8-core)AMD Ryzen 9 (12-16 core)
RAM32 GB DDR4/DDR564 GB DDR5
Storage1 TB NVMe SSD2 TB NVMe SSD
GPUIntegrated (CPU inference)Discrete AMD or NVIDIA with 8+ GB VRAM
NetworkGigabit EthernetGigabit Ethernet
OSUbuntu 24.04 LTSUbuntu 24.04 LTS
Estimated Cost~$800~$1,200
Note
The system must deliver usable response times (under 30 seconds for a typical query-and-retrieve cycle) on the minimum spec without a discrete GPU. GPU acceleration is a performance bonus, not a requirement.

Docker Resource Allocation

When running on Windows or macOS with Docker Desktop, allocate at least:

GPU Acceleration

GPU acceleration is optional but significantly improves LLM inference speed:

GPU TypeDriver RequirementDocker Compose Overlay
NVIDIACUDA drivers + NVIDIA Container Toolkitdocker-compose.nvidia.yml
AMDROCm driversdocker-compose.amd.yml
Intel / DirectMLDirectML runtime (Windows)docker-compose.directml.yml
NoneDefault (CPU inference)

Physical Deployment

14. Installation

Prerequisites

14.1 Windows Installation

Open PowerShell as Administrator in the project directory and run:

.\install.ps1

The script performs the following steps:

  1. Verifies Docker Desktop is installed and the daemon is running
  2. Verifies Docker Compose v2 is available
  3. Creates .env from .env.example and generates a cryptographically random JWT secret
  4. Pauses for you to configure admin credentials in .env
  5. Runs hardware detection (scripts/detect_hardware.ps1) and writes .env.hardware
  6. Selects the appropriate Docker Compose overlay (GPU or host Ollama if applicable)
  7. Pulls base Docker images and builds application images
  8. Starts PostgreSQL and Redis; waits for database readiness (up to 60 seconds)
  9. Runs Alembic database migrations
  10. Starts all seven services
  11. Waits for the API health endpoint to respond
  12. Pulls the embedding model (nomic-embed-text)
  13. Prints the recommended language model command and access URLs

14.2 Linux Installation (Ubuntu/Debian)

Run from the project directory:

chmod +x install.sh
./install.sh

The Linux installer follows the same steps as the Windows installer but uses scripts/detect_hardware.sh for hardware detection and operates natively without Docker Desktop.

14.3 macOS Installation

Run from the project directory:

chmod +x install.sh
./install.sh

The macOS installer uses Docker Desktop and follows the same workflow. GPU acceleration is not available on macOS; the system uses CPU inference only.

Warning
Do not skip the hardware detection step. The installer uses this information to select the correct Docker Compose overlay for your hardware. Running with the wrong overlay may cause the Ollama container to fail to start.

14.4 Post-Installation Verification

After installation completes, verify all services are healthy:

# Check all containers are running
docker compose ps

# Verify API health
curl http://localhost:8000/health

# Verify frontend is accessible
curl -I http://localhost:8080

# Check Ollama models
docker compose exec ollama ollama list

14.5 Pulling the Language Model

The embedding model (nomic-embed-text) is pulled automatically during installation. The language model must be pulled separately:

docker compose exec ollama ollama pull gemma3:4b
Tip
For systems with limited resources, the 4-billion parameter model (gemma3:4b) provides the best balance of quality and speed. Systems with 16+ GB VRAM can use larger variants.

15. Configuration Reference

Environment Variables

All configuration is managed through the .env file in the project root. The following table documents all available variables:

VariableDefaultDescription
DATABASE_URLpostgresql+asyncpg://civicrecords:...@postgres:5432/civicrecordsPostgreSQL connection string
REDIS_URLredis://redis:6379/0Redis connection string
JWT_SECRET(auto-generated)Secret key for JWT token signing. Must be a cryptographically random string.
JWT_LIFETIME_SECONDS3600JWT token expiration in seconds (default: 1 hour)
ADMIN_EMAILEmail address for the initial admin account
ADMIN_PASSWORDPassword for the initial admin account. Change after first login.
OLLAMA_BASE_URLhttp://ollama:11434Ollama API endpoint
LLM_MODELgemma3:4bDefault language model for chat completions
EMBEDDING_MODELnomic-embed-textModel used for document embedding
CHUNK_SIZE512Target chunk size in tokens for document splitting
CHUNK_OVERLAP50Overlap in tokens between adjacent chunks
MAX_SEARCH_RESULTS20Maximum number of search results to return per query
SIMILARITY_THRESHOLD0.3Minimum cosine similarity score for vector search results
LOG_LEVELINFOApplication log level (DEBUG, INFO, WARNING, ERROR)
CORS_ORIGINShttp://localhost:8080Allowed CORS origins (comma-separated)
Security
Never commit the .env file to version control. The .gitignore file excludes it by default. Store a backup of your production .env in a secure location (e.g., password manager, encrypted volume).

16. User & Department Administration

Role Hierarchy

RoleLevelPermissions
Admin4Full access: manage users, departments, data sources, models, exemption rules, system settings. Cross-department visibility.
Reviewer3Approve/reject response letters, review exemption flags, cross-department visibility.
Staff2Create/manage requests, search, attach documents, draft letters. Limited to assigned department.
Read-Only1View requests and documents within assigned department. Cannot create or modify.

Creating Users

curl -X POST http://localhost:8000/auth/register \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jsmith@yourcity.gov",
    "password": "temporary-password-123",
    "role": "staff",
    "department_id": "dept-uuid-here"
  }'
Tip
Instruct new users to change their password after first login. Self-service password reset is planned for a future release.

Department Scoping Behavior

Service Accounts for Federation

Service accounts enable machine-to-machine API access for integrations with other municipal systems (e.g., a records management system pushing documents). Service accounts authenticate with API keys rather than JWT tokens.

curl -X POST http://localhost:8000/service-accounts/ \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "RMS Integration", "description": "Automated document feed from Records Management System"}'
Security
The API key is returned only once at creation time. It is stored as a bcrypt hash in the database and cannot be retrieved. Record it securely immediately. If lost, create a new service account.

17. Data Source Management

Adding File Directory Sources

A directory data source points to a file system path accessible to the API container. This path must be mounted as a Docker volume.

curl -X POST http://localhost:8000/datasources/ \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "City Council Minutes",
    "source_type": "directory",
    "connection_config": {"path": "/data/council-minutes"},
    "department_id": "dept-uuid-here"
  }'

Volume Mounting

Add the source directory as a volume mount in docker-compose.override.yml:

services:
  api:
    volumes:
      - /path/on/host/council-minutes:/data/council-minutes:ro
  worker:
    volumes:
      - /path/on/host/council-minutes:/data/council-minutes:ro
Note
Both the API and Worker containers need access to the data source path. Mount as read-only (:ro) when possible.

Triggering Ingestion

# Trigger ingestion for a specific data source
curl -X POST http://localhost:8000/datasources/{source_id}/ingest \
  -H "Authorization: Bearer <admin-jwt-token>"

# Check ingestion status
curl http://localhost:8000/datasources/{source_id}/status \
  -H "Authorization: Bearer <admin-jwt-token>"

Incremental Ingestion

CivicRecords AI tracks file modification timestamps. Subsequent ingestion runs only process new or modified files. Deleted files are marked as inactive but remain in the database for audit purposes.

Supported File Formats

TrackFormats
Fast Track (native parsers)PDF (text-based), DOCX, XLSX, CSV, HTML, EML, MSG, TXT, RTF, JSON, XML
LLM Track (Gemma 4 multimodal)Scanned PDF, TIFF, PNG, JPEG, BMP, GIF

18. Model Management

Listing Available Models

docker compose exec ollama ollama list

Pulling New Models

# Pull a language model
docker compose exec ollama ollama pull gemma3:4b

# Pull a larger model (requires more VRAM/RAM)
docker compose exec ollama ollama pull gemma3:12b

# Verify the model is available
docker compose exec ollama ollama list

Switching the Active Model

Update the LLM_MODEL variable in .env and restart the API service:

# Edit .env: LLM_MODEL=gemma3:12b
docker compose restart api worker

Model Recommendations by Hardware

Hardware TierRecommended ModelVRAM / RAM Needed
CPU-only, 32 GB RAMgemma3:4b~8 GB RAM
GPU with 8 GB VRAMgemma3:4b~4 GB VRAM
GPU with 12+ GB VRAMgemma3:12b~10 GB VRAM
GPU with 24+ GB VRAMgemma3:27b~20 GB VRAM
Warning
Do not remove the nomic-embed-text model. It is required for document embedding and search functionality. Removing it will break search until it is re-pulled.

19. Exemption Rules Administration

Rules Overview

CivicRecords AI ships with approximately 180 pre-loaded exemption rules covering common exemption categories from all 50 state open records statutes. Each rule uses one of two detection methods:

Managing Rules via API

# List all rules
curl http://localhost:8000/exemptions/rules/ \
  -H "Authorization: Bearer <admin-jwt-token>"

# Create a new rule
curl -X POST http://localhost:8000/exemptions/rules/ \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "state_code": "CO",
    "category": "personnel",
    "rule_type": "keyword",
    "rule_definition": "performance evaluation"
  }'

# Disable a rule
curl -X PATCH http://localhost:8000/exemptions/rules/{rule_id} \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

Exemption Dashboard

The admin panel provides an Exemptions dashboard showing:

Use this dashboard to identify rules that are generating too many false positives (low acceptance rate) and consider disabling or refining them.

Tip
All changes to exemption rules are logged in the audit trail. This includes rule creation, modification, enabling, and disabling. The audit log records which admin made the change and when.

20. Compliance & Audit

Audit Trail Architecture

CivicRecords AI maintains a hash-chained, append-only audit log. Every API call is logged with:

Exporting Audit Logs

# Export audit logs as JSON
curl "http://localhost:8000/admin/audit-logs?format=json&start_date=2026-01-01&end_date=2026-03-31" \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -o audit-export.json

# Export as CSV
curl "http://localhost:8000/admin/audit-logs?format=csv&start_date=2026-01-01&end_date=2026-03-31" \
  -H "Authorization: Bearer <admin-jwt-token>" \
  -o audit-export.csv

Compliance Reporting

The system provides several built-in compliance reports:

ReportDescription
Response Time ReportAverage and median response times, broken down by department and time period. Identifies requests that exceeded statutory deadlines.
Exemption Accuracy ReportFlag acceptance/rejection rates by category, department, and time period. Helps assess whether AI flagging is systematically biased.
Workload DistributionRequest counts and processing times by staff member and department.
Disclosure ReportSummary of records released, withheld, and partially redacted for a given period.

Exemption Detection Auditability

The exemption engine is designed for transparency and external review:

21. Security

Authentication

Authorization

Data Security

Network Security

Security
CivicRecords AI processes potentially sensitive government records. Ensure that the server is physically secured, network access is restricted to authorized personnel, and all security patches for the host operating system are applied promptly.

22. Backup & Recovery

Database Backup

# Full database backup (compressed custom format)
docker compose exec -T postgres pg_dump -U civicrecords -Fc civicrecords > backup-$(date +%Y%m%d).dump

# Backup with timestamp
docker compose exec -T postgres pg_dump -U civicrecords -Fc civicrecords > civicrecords-backup-$(date +%Y%m%d-%H%M%S).dump

Restoring from Backup

# Stop the application (keep database running)
docker compose stop api worker beat

# Restore the database
docker compose exec -T postgres pg_restore -U civicrecords -d civicrecords --clean --if-exists < backup-20260401.dump

# Restart services
docker compose up -d

Configuration Backup

Back up these files regularly:

FileContents
.envAll environment configuration, including JWT secret
.env.hardwareHardware detection results
docker-compose.override.ymlCustom volume mounts and service overrides

Backup Schedule Recommendations

FrequencyWhat to Back UpRetention
DailyPostgreSQL database dump30 days
WeeklyFull system backup (database + config + volumes)12 weeks
Before upgradesFull database dump + config filesUntil upgrade verified
Warning
Always back up the database before performing any upgrade. Database migrations are forward-only and cannot be easily reversed without a backup.

23. Monitoring & Troubleshooting

Health Checks

# API health endpoint
curl http://localhost:8000/health

# Individual service checks
docker compose exec postgres pg_isready -U civicrecords
docker compose exec redis redis-cli ping
docker compose exec ollama ollama list

Admin Status Dashboard

The admin panel (/admin) displays a system status page showing:

Viewing Logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f api
docker compose logs -f worker

# Last 100 lines
docker compose logs --tail=100 api

Common Issues

SymptomLikely CauseResolution
"Connection refused" on port 8080nginx or API not runningdocker compose up -d and check logs
Search returns no resultsNo documents ingested, or embedding model missingVerify data sources and run ollama list to check for nomic-embed-text
Slow LLM responses (>60s)Insufficient RAM or CPU for the selected modelSwitch to a smaller model or add GPU acceleration
Celery tasks stuck in "pending"Redis connection issue or worker not runningCheck Redis connectivity and restart worker: docker compose restart worker
Database migration errorsSchema conflict from skipped versionRestore from backup and upgrade sequentially through each version
Ollama "model not found"Model not pulledRun docker compose exec ollama ollama pull <model>
"Permission denied" on data sourceVolume mount permissionsVerify the container user has read access to the mounted directory

Performance Monitoring

# Container resource usage
docker stats

# Database size
docker compose exec postgres psql -U civicrecords -c "SELECT pg_size_pretty(pg_database_size('civicrecords'));"

# Vector index size
docker compose exec postgres psql -U civicrecords -c "SELECT pg_size_pretty(pg_total_relation_size('document_embeddings'));"

24. Upgrading

Upgrade Procedure

  1. Back up the database before any upgrade:
    docker compose exec -T postgres pg_dump -U civicrecords -Fc civicrecords > pre-upgrade-backup.dump
  2. Pull the latest code:
    git pull origin main
  3. Rebuild Docker images:
    docker compose build
  4. Run database migrations:
    docker compose run --rm api alembic upgrade head
  5. Restart all services:
    docker compose up -d
  6. Verify health:
    curl http://localhost:8000/health
Tip
The API service automatically runs Alembic migrations on startup. However, running migrations explicitly as a separate step (step 4) allows you to catch migration errors before bringing the full stack online.

Database Migrations

CivicRecords AI uses Alembic for database schema migrations. Migration files are stored in backend/alembic/versions/. Key commands:

# Apply all pending migrations
docker compose exec api alembic upgrade head

# Check current migration version
docker compose exec api alembic current

# View migration history
docker compose exec api alembic history

Version Compatibility

Always upgrade sequentially through minor versions. Skipping major versions may result in migration conflicts. Check the CHANGELOG.md for breaking changes between versions.

Rollback Procedure

  1. Stop all services: docker compose down
  2. Restore the database from backup:
    docker compose up -d postgres
    docker compose exec -T postgres pg_restore -U civicrecords -d civicrecords --clean --if-exists < pre-upgrade-backup.dump
  3. Check out the previous version: git checkout v1.0.0
  4. Rebuild and restart: docker compose build && docker compose up -d

Appendices

A. API Endpoint Reference

Authentication

MethodEndpointMin RoleDescription
POST/auth/loginAuthenticate and receive JWT token
POST/auth/registerAdminCreate a new user account
GET/users/meRead-OnlyGet current user profile

Records Requests

MethodEndpointMin RoleDescription
GET/requests/StaffList all requests (department-scoped)
POST/requests/StaffCreate a new request
GET/requests/{id}StaffGet request details
PATCH/requests/{id}StaffUpdate request fields or status
GET/requests/{id}/documentsStaffList documents attached to request
POST/requests/{id}/documentsStaffAttach a document to request
POST/requests/{id}/submit-reviewStaffSubmit request for review
POST/requests/{id}/approveReviewerApprove request for release
POST/requests/{id}/rejectReviewerReject request
GET/requests/{id}/timelineStaffGet request timeline events
POST/requests/{id}/timelineStaffAdd a timeline event / note
GET/requests/{id}/messagesStaffGet request messages
POST/requests/{id}/messagesStaffSend a message on request
GET/requests/{id}/feesStaffGet request fee items
POST/requests/{id}/feesStaffAdd a fee item
POST/requests/{id}/response-letterStaffGenerate a response letter draft
GET/requests/{id}/response-letterStaffGet current response letter
PATCH/requests/{id}/response-letter/{letter_id}StaffUpdate response letter (approve requires Reviewer)

Search

MethodEndpointMin RoleDescription
POST/search/StaffHybrid search across ingested documents
GET/search/historyStaffGet search history for current user

Documents & Data Sources

MethodEndpointMin RoleDescription
GET/documents/StaffList ingested documents
GET/documents/{id}StaffGet document details and metadata
GET/datasources/AdminList configured data sources
POST/datasources/AdminAdd a new data source
POST/datasources/{id}/ingestAdminTrigger ingestion for data source
GET/datasources/statsAdminGet ingestion statistics

Exemptions

MethodEndpointMin RoleDescription
GET/exemptions/rules/AdminList all exemption rules
POST/exemptions/rules/AdminCreate a new exemption rule
PATCH/exemptions/rules/{id}AdminUpdate/toggle an exemption rule
GET/exemptions/dashboardAdminGet exemption dashboard statistics

Administration

MethodEndpointMin RoleDescription
GET/admin/statusAdminSystem health and service status
GET/admin/audit-logsAdminQuery and export audit logs
GET/healthUnauthenticated health check endpoint
POST/service-accounts/AdminCreate a service account

B. Database Schema Overview

CivicRecords AI uses PostgreSQL 17 with the pgvector extension for vector storage. The schema consists of 29 tables organized into the following functional groups:

Authentication & Administration

TableDescription
usersUser accounts with role enum (admin, staff, reviewer, read_only), department assignment, and fastapi-users fields
service_accountsMachine-to-machine API key accounts with roles and bcrypt-hashed keys
departmentsDepartment definitions for access scoping

Documents & Ingestion

TableDescription
data_sourcesConfigured data source connections (directory paths, types, department ownership)
documentsIngested document metadata (filename, file type, size, ingestion status, error messages)
document_chunksText chunks extracted from documents (content, position, chunk index)
document_embeddingsVector embeddings for document chunks (pgvector column, model identifier)

Records Requests

TableDescription
records_requestsPublic records requests with status workflow, requester info, deadlines, and assignment
request_documentsMany-to-many associations between requests and documents with inclusion decisions and relevance notes
document_cacheCached document files per request for legal defensibility
request_timelineChronological event log for each request (status changes, notes, actions)
request_messagesMessages between staff and requesters
request_feesFee items associated with requests (type, amount, status)
response_lettersDraft and final response letters with approval status

Exemptions

TableDescription
exemption_rulesConfigurable rules (state code, category, rule type, definition, enabled flag)
exemption_flagsFlags generated by the exemption engine (document, chunk, category, confidence, status)

Search & Analytics

TableDescription
search_sessionsSearch session context for iterative refinement
search_queriesIndividual search queries with result counts and timing

Audit & Compliance

TableDescription
audit_logHash-chained, append-only audit trail of all system actions

C. Supported Platforms

Operating Systems

PlatformSupport LevelNotes
Ubuntu 24.04 LTSPrimary (recommended)Full support including GPU acceleration
Debian 12 (Bookworm)PrimaryFull support including GPU acceleration
Windows 11 Pro/EnterpriseSupportedRequires Docker Desktop. GPU via CUDA (NVIDIA) or DirectML.
Windows 10 (21H2+)SupportedRequires Docker Desktop with WSL 2 backend
macOS 13+ (Ventura)SupportedDocker Desktop required. CPU inference only (no GPU acceleration).
RHEL 9 / Rocky Linux 9CommunityShould work with Docker CE; not formally tested

Browsers

BrowserMinimum Version
Google Chrome120+
Microsoft Edge120+
Mozilla Firefox120+
Safari17+

Docker Requirements

ComponentMinimum Version
Docker Engine24.0
Docker Composev2.20
Docker Desktop (Windows/macOS)4.25

© 2026 CivicRecords AI Project — Unified Operations Manual v1.4.1

AI-Powered Open Records Support for American Cities

This document is confidential and intended for authorized municipal staff and IT personnel only.