Roadmap
On this page
- Live Tracking
- Phase 1 — Foundation
- Phase 2 — Rules and Policy Engine
- Phase 3 — Case Management Service
- Phase 4 — Placement and Foster Care Service
- Testing Infrastructure
- Performance Testing
- Object Storage
- Phase 5 — Data Exchange Service
- Hardening — Seed Data, Tests & Documentation
- Phase 6 — Financial and Claims Service
- Phase 7 — Reporting and Data Quality Service
- Phase 8 — Security and Compliance Service
- Phase 9 — CLI Client (
craig) - Phase 10 — Caseworker Web UI
- Phase 11 — Constituent and Provider Portal
- Phase 12 — Public Intake Service
- Phase 13 — Mobile & Offline-Capable Client
- Known Issues & Tech Debt
- Rules Engine — Cache Invalidation Race Condition ✓ RESOLVED
- Reference Data — Remaining Steps
- Multi-Jurisdictional Authorization ✓ COMPLETE
- Service Identity + On-Behalf-Of (Plan E)
- API Idempotency Audit
- Pre-1.0 API Contract Stability — Prioritization Guidance
- Deployment Work Is Owned by a Separate Team
The roadmap is organized into phases that reflect the modular OpenStack-style architecture. Each phase delivers independently deployable services that collectively satisfy the CCWIS federal requirements under 45 CFR Part 1355.
| For detailed technical specifications — database schemas, API endpoints, event flows, and verification steps — see the Implementation Guide. |
Live Tracking
The phase checklists below are the high-level long-arc roadmap. For day-to-day triage and what’s actively in flight, use the live GitLab views — they update as issues, MRs, and epics change without requiring a roadmap doc edit:
Kanban view with columns by priority (P0-critical / P1-high / P2-medium / P3-low). Add |
|
Production blockers + compliance-critical work |
|
High-value, actively schedulable |
|
Quality / hygiene / nice-to-have |
|
Awaiting external dependency or ADR resolution; excluded from the active triage queue |
|
Multi-issue initiatives at the group level |
|
Historical record of completed multi-issue initiatives |
Every issue carries a P-label. New issues without one will not show up on the board until a priority is assigned — backfill via glab issue update <N> --label P2-medium (or whatever fits).
|
Phase 1 — Foundation
Goal: Establish the core platform infrastructure on which all services are built.
-
Monorepo workspace structure (Cargo workspace with per-service crates)
-
Shared authentication and authorization service (OAuth2 / OpenID Connect via Keycloak)
-
RabbitMQ integration layer — shared message bus client library (
craig-mq) -
Core REST API framework (Axum-based) with shared middleware (logging, tracing, auth, error handling) (
craig-api) -
Database migration framework (SQLx) (
craig-db) -
CI/CD pipeline (GitLab CI) with SAST, dependency auditing, and lint checks
-
Plain-language automated function documentation framework (§ 1355.53(a)(2)) — cargo xtask api-docs
-
Developer environment setup (Docker Compose: Postgres, RabbitMQ, Keycloak)
Phase 2 — Rules and Policy Engine
Goal: Establish the jurisdiction-configurable rules engine that all other services rely on for policy evaluation — directly satisfying the § 1355.53(a)(1) requirement to separate business rules from core programming.
-
Integrate zen-engine (GoRules Zen Engine Rust crate)
-
REST API for rule evaluation (synchronous) and rule management (CRUD for JDM rule sets)
-
RabbitMQ event subscription — rule evaluation triggered by case and eligibility events
-
Jurisdiction rule set loader — load JDM rule sets from database or file system at startup and on update
-
Rule set versioning and audit trail — every rule evaluation records the rule set version used
-
Jurisdiction-configurable rule set activation (
CRAIG_RULES__JURISDICTION) -
Title IV-E eligibility JDM rule set — Georgia DFCS (
rulesets/georgia/georgia-ive-eligibility.json) -
Safety and risk assessment JDM rule set — Georgia DFCS (
rulesets/georgia/georgia-safety-assessment.json) -
Timeliness monitoring JDM rule set — Georgia DFCS with ASFA deadlines (
rulesets/georgia/georgia-timeliness.json) -
Intake screening JDM rule set — Georgia DFCS (
rulesets/georgia/georgia-intake-screening.json) -
Placement matching JDM rule set — Georgia DFCS (
rulesets/georgia/georgia-placement-matching.json) -
Rule set import/export tooling for jurisdiction onboarding
-
Title IV-E eligibility JDM rule set — Texas DFPS (
rulesets/texas/texas-ive-eligibility.json) -
Safety assessment JDM rule set — Texas DFPS, three-outcome model (
rulesets/texas/texas-safety-assessment.json) -
Timeliness monitoring JDM rule set — Texas DFPS with TFC 262/263 deadlines (
rulesets/texas/texas-timeliness.json) -
Intake screening JDM rule set — Texas DFPS Statewide Intake with P1/P2 priorities (
rulesets/texas/texas-intake-screening.json) -
Placement matching JDM rule set — Texas DFPS with four-tier LOC and ICWA preferences (
rulesets/texas/texas-placement-matching.json) -
Case routing and complexity classification JDM rule set — Georgia + Texas, 12 evaluation tests
-
Plain-language rule documentation generation from JDM rule sets (§ 1355.53(a)(2))
Phase 3 — Case Management Service
Goal: Core child welfare case lifecycle management.
-
Intake and referral management
-
Investigation and assessment tracking
-
Case plan creation and management
-
Family and household composition management
-
Worker assignment and caseload management
-
Court order and legal status tracking (supports court data exchange)
-
ICWA compliance tracking and documentation (§ 1355.52(b))
-
Case notes and narrative documentation —
contactstable withnarrativefield, 6 endpoints, UI tab, attachments via object storage -
Automated data quality monitoring and staff alerting (§ 1355.52(d)(1)) —
data_quality_issuestable, dashboard endpoint, Rules Engine continuous monitoring
Phase 4 — Placement and Foster Care Service
Goal: Foster care, kinship, and residential placement management.
-
Foster home and provider licensing and capacity management
-
Placement matching and history
-
Title IV-E eligibility determination — calls Rules Engine (Phase 2) for identical automated functions for all users (§ 1355.52(g)) — JDM rule sets (GA + TX),
POST /v1/rules/evaluatewith eligibility context, financial service tracks IV-E fields -
Placement stability and sibling group tracking
-
Reunification and permanency planning — case plan permanency goals, timeliness monitoring (permanency hearing 365d, TPR 455d per ASFA)
-
Educational enrollment tracking (supports education data exchange) —
education_recordstable, 5 endpoints, CLI, web UI -
Health and developmental records (supports health agency data exchange) —
health_recordstable, 6 endpoints (incl. overdue), CLI, web UI -
Major changes monitoring —
major_changestable on craig-security, 5 admin endpoints, CLI, web UI
Testing Infrastructure
Goal: Comprehensive integration test harness inspired by OpenStack Tempest — typed service clients, credential isolation, event verification, and API-only black-box testing.
-
craig-test-libshared crate — test configuration, Keycloak token provider, generic HTTP client -
Typed service clients —
RulesClient,CasesClient,PlacementClient,ExchangeClient,FinancialClient,ReportingClient,SecurityClient,IntakeClient(one method per endpoint) -
Test harness with cleanup stack — resource creation, UUID-suffixed naming, LIFO teardown
-
Event collector — RabbitMQ temporary queue for verifying published events
-
Test data builders — fluent builders with valid defaults for all request types
-
Unit test additions —
craig-commonerror/pagination/settings,craig-authclaims/middleware,craig-mqenvelope (~33 tests) -
craig-rulesintegration tests — CRUD, evaluation, auth, import/export, events (~123 tests) -
craig-casesintegration tests — persons, referrals, investigations, cases, plans, contacts, court orders, events, cross-service workflow (~84 tests) -
craig-placementintegration tests — foster homes, placements, kinship, matching, events (~62 tests) -
craig-exchangeintegration tests — partners, agreements, ICPC, transactions, home studies (~39 tests) -
craig-cliintegration tests — library-level tests for all 22 command modules viacmd::*::run()(~86 tests) -
CI pipeline integration test job (manual trigger with docker-compose)
Performance Testing
Goal: Establish automated performance baselines and regression detection for all CRAIG services using industry-standard load testing tools, ensuring the platform meets production throughput and latency requirements without building a custom testing framework.
Tooling
-
k6 test runner — Grafana k6 as the primary load testing tool, invoked via
cargo xtask perf(Dockergrafana/k6image) -
k6 test scripts directory structure —
tests/k6/(services/one script per service,scenarios/per profile,helpers/,baselines/) -
Shared k6 utility module —
tests/k6/helpers/auth.js(Keycloak ROPC token acquisition) +config.js+thresholds.js -
Docker Compose performance profile (
docker-compose.perf.yml) — resource limits mimicking production sizing
Test Scenarios per Service
-
Per-service k6 scripts —
tests/k6/services/{rules,cases,placement,exchange,financial,reporting,security,intake,web}.js(coverage depth varies by service; the named scenarioperson-suggestions-bench.jscovers the matching hot path) -
Deep per-service scenario coverage as originally scoped (cache hit-vs-miss, concurrent same-key contention profiles)
-
Cross-service workflow tests — full intake-to-placement lifecycle (cases → rules engine safety assessment → placement matching), measuring end-to-end latency
-
Authentication overhead tests — token acquisition latency, JWT validation throughput, comparison of cold vs. warm JWKS cache
-
Database contention tests as k6 scenarios — the contested-environment program (epic &83, ADR-067) covers contention at the Rust test layer instead
Test Types
-
Smoke tests — 1 VU across all 9 services, ~5 s; the pre-push gate (
cargo xtask perf --profile smoke; request counts live intests/k6/baselines/) -
Load tests — sustained realistic concurrency ~5 minutes with SLO thresholds (
--profile load; the CIperf-loadjob) -
Stress tests — ramp beyond expected load, 10-30 minutes (
--profile stress; manual/scheduled) -
Soak tests — moderate sustained load 30+ minutes for leak/drift detection (
--profile soak; manual)
Performance Thresholds
-
p95 latency thresholds defined —
tests/k6/helpers/thresholds.js(#1134 class budgets: Read<50 / List<100 / Write<200 / Cross<500 / BFF<300 ms, validated against the dated baseline intests/k6/baselines/) -
Error-rate threshold — <1% in
thresholds.js(the original <0.1% aspiration lives in the implementation guide) -
Throughput baselines —
tests/k6/baselines/dated recordings; re-record via--save-baseline -
k6 threshold assertions — k6 exits non-zero on breach, failing the pre-push smoke and the CI
perf-loadjob
Profiling and Optimization Infrastructure
-
tokio-consoleintegration — conditional compilation flag for async runtime introspection (task polling latency, waker counts, resource utilization) -
Criterion micro-benchmarks — targeted benchmarks for hot paths (rule evaluation, JWT validation, pagination query construction)
-
Connection pool tuning guide — documented methodology for sizing PostgreSQL and HTTP client pools based on load test results
-
Performance baseline documentation — recorded results for each service at known hardware specs, updated with each phase
CI/CD Integration
-
Pre-push k6 smoke gate —
cargo xtask perf --profile smokeruns on every push (1 VU, 29 requests, ~5s); not a CI job by design (the per-push gate model keeps smoke out of CI) -
GitLab CI
perf-loadjob (#258, !187) — runscargo xtask perf --profile load --save-baselineagainst a devstack ondhs-aws-autoscaler-docker.medium. Threshold breaches fail the job. main + schedule triggers;allow_failure: truewhile baselining noise (flip after a clean week) -
GitLab CI
perf-stressjob (#258, !187) —cargo xtask perf --profile stress --save-baseline, manual + scheduled invocation only -
Performance trend tracking —
test-results/k6/JSON retained as CI artifacts for 30 days -
Alerting on regression — currently k6 threshold breach fails the job; no pager hook yet (P3 follow-up after
allow_failureflips to blocking)
Object Storage
Goal: Store non-machine-readable documents (PDFs, images, scanned forms, generated report files) in an S3-compatible object store instead of PostgreSQL.
Services store only metadata and an object_key in the database; actual file bytes live in the object store.
-
craig-storeshared crate — wraps Apacheobject_storecrate; unifiedput/get/delete/listAPI -
Garage devstack container — local S3-compatible backend for development
-
craig-exchangeadoption — ICPC attachments (100A forms, medical records, birth certificates) -
craig-casesadoption — court order documents, contact attachments -
craig-placementadoption — foster home documents (home_documentsstore + the BFF upload route; DB-anchoring hardening tracked as #990) -
Upload validation — max file size, MIME type allowlist, content-type verification, filename sanitization
-
craig-webfile upload/download UI (multipart forms, streaming downloads) -
craig-cliattachment upload/download commands (ICPC attachments) -
craig-reportingadoption — generated AFCARS/NCANDS export files (craig-storebacked, ADR-062 §U deterministic export attempts) -
craig-securityadoption — security review evidence artifacts -
craig-portalsadoption — family document upload (when Phase 11 is built)
Phase 5 — Data Exchange Service
Goal: Satisfy all 11 mandatory bi-directional data exchange requirements (§ 1355.52(e-f)).
-
Unified data exchange standard implementation (ExchangeAdapter trait + NoopAdapter)
-
CWCA exchange adapter — format transformer with case_data, service_record, placement_notification exchange types
-
Financial payments and claims exchange adapter — payment_submission, claim_submission, rate_update
-
Medicaid eligibility exchange adapter — eligibility_request, enrollment_notification
-
Child abuse and neglect system exchange adapter — report_submission, disposition_notification (NCANDS codes)
-
TANF / Title IV-A exchange adapter — family_referral, benefit_status
-
Child support / Title IV-D exchange adapter — case_referral, support_order
-
External data collection system adapter — generic data_submission pass-through
-
Court system exchange adapter — case_notice, order_submission, hearing_schedule
-
Education system exchange adapter — enrollment_notification, records_request
-
Health agency exchange adapter — health_notification, immunization_record
-
Tribal entity exchange adapter (§ 1355.54) — icwa_notice, placement_notification, kinship_verification
-
Data sharing agreement management (per ACF Technical Bulletin #8)
-
Exchange audit trail and error logging
-
RabbitMQ event publication for all inbound and outbound exchange events
-
ICPC interstate compact — full workflow (draft → home study → decision → completion)
-
ICPC home studies with structured evaluation criteria
-
ICPC attachments (upload, download, list via object storage)
Hardening — Seed Data, Tests & Documentation
Goal: Strengthen the foundation before adding new feature services — improve seed data realism, close test coverage gaps, and produce developer/operator documentation.
Seed Data Overhaul
-
craig-seedgenerator — replaced static SQL with scalable Rust binary (tools/craig-seed/), deterministic via--seed N, arbitrary scale via--families N, 21 tests -
Deterministic UUIDv7s — custom generator using monotonic counter + seeded RNG for reproducible, time-ordered IDs
-
Cross-service FK integrity — all foreign key references validated across craig_cases, craig_placement, craig_exchange
-
Seed attachments — the seed uploads attachment fixtures on first start (gated on the in-graph
garage-initone-shot since the C4 gate, #1012) -
E2E manifest integration — generate
seed.tswith--manifestflag, pinnedCRAIG_SEED=42andCRAIG_FAMILIES=12for deterministic E2E runs
Test Audit
-
E2E assertion hardening — strengthened flash text assertions, added waitForLoadState/waitForURL patterns
-
Negative and error path e2e tests — 404 pages, invalid UUIDs, form validation, RBAC boundary tests
-
Cross-service integration tests —
services/craig-cases/tests/api/workflow.rscovers the referral → investigation → case arc; the placement/exchange legs ride their services' own suites -
API contract tests — response schema validation for all endpoints
-
Pagination tests — verified pagination controls with per_page override
Documentation
-
Data model documentation — ER diagrams (Mermaid) per service (the
data-model-*.adocfamily) + the 16-machine state-machine inventory (craig-test-lib::state_machine_matrix; exhaustive matrix pinning first adopted in craig-financial, sibling matrices tracked per D4.5) -
Domain glossary — 30 CCWIS domain terms across 5 categories
-
Developer onboarding guide — project structure, initialization pattern, how-to guides, testing reference
-
Architecture Decision Records (ADRs) — the practice is established; the ADR index under
adrs/is the source of truth (60+ records at 2026-08-25, from the Rust-monorepo foundation through the contested-environment program) -
Deployment and operations guide — env var reference, container deployment, infrastructure config, scaling
Phase 6 — Financial and Claims Service
Goal: Title IV-B and IV-E financial management.
-
Foster care maintenance payment calculation and issuance
-
Adoption assistance payment management — enum + seed-rate scaffolding only; no live writer generates adoption-assistance payments (#1080 corrected the overstatement; the real capability rides the DFCS-confirmed program set, #1073)
-
Guardianship assistance payment management — delivered by epic &70 (ADR-056 SG/NRSG agreement lifecycle + the ADR-053/055 monthly generator); state-funded per GA 22.8 (structurally never IV-E; per-code UAS/TANF reportability recorded by #1072) — federal IV-E GAP claiming is NOT implemented, funding confirmations ride #1073
-
Title IV-E eligibility and claiming
-
Title IV-B claiming and reporting
-
Federal financial participation (FFP) cost allocation tracking (§ 1355.57)
-
APD budget tracking and reporting integration
Phase 7 — Reporting and Data Quality Service
Goal: Federal reporting, NCANDS, and ongoing data quality assurance (§ 1355.52(d)).
-
NCANDS data collection and submission
-
AFCARS (Adoption and Foster Care Analysis and Reporting System) reporting
-
Biennial data quality review workflow and tooling (§ 1355.52(d)(2))
-
Automated data quality monitoring dashboard
-
Data quality plan management and APD submission support (OMB Form 0970-0463)
-
CCWIS automated function checklist reporting (OMB Form 0970-0463)
-
ACF review and assessment support artifacts (§ 1355.55)
Phase 8 — Security and Compliance Service
Goal: Satisfy all security, privacy, and compliance requirements.
-
Biennial security review workflow (45 CFR § 95.621(f))
-
Data archiving and purging automation (2 CFR § 200.334)
-
Role-based access control with audit logging for all data access and modifications
-
Confidentiality controls enforcing Section 471(a)(8), 45 CFR § 205.50, and CAPTA § 106
-
Data breach detection and notification workflows — detection_rules + security_alerts tables, 8 endpoints, 6 rule types, audit log anomaly detection, webhook notification, CLI + web UI, periodic background scheduler (#266 / !186, configurable via
CRAIG_SECURITY__DETECTION_INTERVAL_SECS, default 60s) -
NIST SP 800-53 control mapping documentation
-
Penetration testing and vulnerability management integration
-
ATO pathway and continuous compliance documentation
Phase 9 — CLI Client (craig)
Goal: A first-class command-line interface providing complete access to all CRAIG API functionality, modeled after the openstack CLI.
-
Unified
craigbinary (Rust, single statically-linked executable) -
Authentication and session management (
craig login,craig token) -
Case management commands (
craig case,craig person,craig referral,craig investigation,craig plan) -
Placement commands (
craig placement,craig home,craig kinship) -
Financial and claims commands (
craig financial,craig adjustment,craig claim) -
Data exchange commands (
craig exchange,craig agreement,craig icpc) -
Reporting commands (generate and export reports)
-
Rules management commands (
craig rules list,craig rules evaluate,craig rules import) -
Security and compliance CLI commands (audit log, security reviews, archive, NIST controls)
-
Output formatting (table, JSON) for scripting and human use
-
Shell completion (bash, zsh, fish)
-
Configurable profiles for multi-jurisdiction deployments
-
Integration tests — ~86 library-level tests across 22 modules (rules, person, referral, investigation, case, plan, home, placement, exchange, agreement, ICPC, auth, workflow, financial, adjustment, claim, reporting, security, archive, nist, intake, kinship)
Phase 10 — Caseworker Web UI
Goal: A browser-based interface for caseworkers built entirely on the public REST APIs — no privileged backend access.
Implemented as craig-web BFF (Axum + Askama + htmx + Alpine.js) instead of the originally planned Dioxus WASM SPA.
|
-
Case dashboard with live stats — parallel API calls for total cases, open investigations, active placements, pending reviews
-
Case detail view and editing (cases, contacts, household, court orders, plans, tasks)
-
Intake module (referrals, investigations, safety assessments)
-
Placement management interface (foster homes, placements, training, matching)
-
Title IV-E eligibility determination workflow (financial module — payments, rates, claims)
-
Data exchange module (partners, agreements, ICPC with home studies and attachments)
-
Rules management interface (rule sets CRUD, import/export)
-
Reporting and data quality dashboard — quality metrics, issues list, AFCARS/NCANDS workflow pages, 14 handlers
-
OIDC authentication via Keycloak (Authorization Code + PKCE)
-
Georgia Orchard theming with CSS custom properties
-
Accessible design (Section 508 / WCAG 2.1 AA compliance) — the enumerated page set audited by axe-core with zero violations as a blocking pre-push gate; VPAT 2.5 published (page counts and dates live there)
-
Multi-language support
Phase 11 — Constituent and Provider Portal
Goal: Self-service interfaces for constituents, foster parents, and contracted providers, also built entirely on the public REST APIs.
The Multi-Jurisdiction Foundation program (Plan S, complete 2026-06-19 — Plan S: Multi-Jurisdiction Foundation) made the platform state-neutral and is the foundation this portal builds on: bundle-contributed partners / transport / theme / terminology / plugins / composition, plus the surface-agnostic field-permission authz (craig-authz::resolve_field_permission).
|
-
Constituent application and case status portal
-
Foster parent and kinship caregiver portal
-
CWCA provider portal for bi-directional data submission (supports Phase 5 exchange) — also the home of the surface-bound per-field ownership application (ADR-037 §4–§7: the
field_ownershipbundle axis, per-surface ownership tables, thepending_edits_<surface>propose/accept/reject queue, BFF lock-icon + Studio), building on Plan Y’s evaluation capability. Tracked by #634 under the still-open epic &50. -
Accessible design (Section 508 / WCAG 2.1 AA compliance)
-
Multi-language support
Phase 12 — Public Intake Service
Goal: Public-facing child abuse reporting system with web form and API/SDK for third-party integration. See Public Child Abuse Reporting plan for full design.
-
craig-intakeservice (port 8008; stateless edge — no database, ADR-017) -
Public web form for anonymous and identified reporters (
/report) -
Public status check via confirmation code (
/report/status) -
Confirmation code generation (RPT-YYYYMMDD-XXXX format)
-
Honeypot anti-bot field (silently accepts, does not persist)
-
IP-based rate limiting (governor crate, configurable per-hour)
-
CAPTCHA integration (Cloudflare Turnstile, disabled in devstack)
-
Partner API with API key authentication (
/partner/v1/) -
API key management — create, list, revoke (admin only)
-
Authenticated report review — list, detail, claim, convert, screen out
-
Report-to-referral conversion (cross-service call to craig-cases)
-
State machine: pending → screening → converted / screened_out
-
RabbitMQ events (6 event types, captured by craig-security audit)
-
craig-intake-sdkcrate (AGPL-3.0, typed client with builder API) -
craig-web public report pages (standalone templates, no auth)
-
craig-web authenticated review pages (caseworker intake module)
-
CLI
craig intakecommand group (8 subcommands) -
Integration tests (~101 tests) + unit tests (68 + 27 SDK tests)
-
OpenAPI/Swagger documentation
-
E2E tests — Playwright browser tests:
intake.spec.ts,intake-review.spec.ts,intake-embedded-ui.spec.ts(the edge public form — the craig-webpublic-report*.spec.tswere removed with craig-web’s/reportin Phase 5, #736) -
Phase 2a — Reference enums, typed JSONB structs, expanded data model (7 enums, 15+ columns)
-
Phase 2b — Typed validation, file upload endpoint, SDK expansion,
craig-storeintegration -
Phase 2c — Multi-step wizard form (6-step Alpine.js wizard with expanded fields, file upload on confirmation page)
-
Phase 2d — Full test coverage and documentation for field expansion
-
Phase 2e — JWS integrity verification: signer key registry, detached ES256 signing, verification audit endpoint
-
Phase 2f — Multi-language SDKs: TypeScript (
@craig/intake-sdk), Python (craig-intake-sdk), browser signing library (craig-sign.js), Rust SDK signing support -
CAPTCHA integration testing (Turnstile end-to-end with real token)
Phase 13 — Mobile & Offline-Capable Client
Goal: Field-ready client application for caseworkers operating in rural areas and other low-connectivity environments. Works on phones (iOS, Android), laptops (Windows, macOS, Linux), and tablets. Offline-first with encrypted local storage and bidirectional sync. See Mobile & Offline Client plan and ADR-009 for architecture decision.
-
ADR-009 decision accepted (Tauri 2.0 recommended)
-
craig-clientTauri workspace crate (desktop: Windows, macOS, Linux) -
craig-syncshared crate (sync engine, conflict resolution) -
SQLCipher encrypted local database (AES-256 at rest)
-
Keycloak OIDC authentication with offline token caching
-
Pull sync — assigned cases, persons, contacts, placements, reference data
-
Offline write — contact notes, safety assessments, case plan tasks
-
Push sync with field-level conflict detection and resolution UI
-
Mobile builds (iOS, Android) via Tauri 2.0 mobile
-
Biometric unlock and device security
-
Camera integration for document capture
-
Attachment caching for offline document viewing
-
Admin dashboard for device management and remote wipe
-
Sync health monitoring and alerting
Known Issues & Tech Debt
Bugs and technical debt discovered during development and testing. These are tracked here rather than in a separate issue tracker until the project moves to a public GitLab issue board.
Rules Engine — Cache Invalidation Race Condition ✓ RESOLVED
Status: Fixed — replaced reload_all() in API mutation handlers with incremental insert_decision() / remove_decision() cache operations.
See Rules Cache Race Fix plan for details.
Reference Data — Remaining Steps
Steps 3-4 from the Reference Data Management plan are complete. Worker identity architecture uses claims.sub (UUID) for API handlers and preferred_username for web display per standard OIDC practice.
-
Admin registry —
admin_unit_registrytable on craig-security, 5 CRUD + config endpoints, 159 Georgia counties seeded -
Texas counties — 254 rows seeded via
default_admin_units/texas.csv+cargo xtask seed-admin-units(Plan A § Step 13a; closes #225) -
Worker identity —
claims.sub(UUID) for API,preferred_usernamefor display; lazy-populated intoworker_identitiesfrom JWT claims (Plan A § Step 3) — IdP-neutral, no admin-API dependency -
Worker display names on detail pages — denormalized
_namecolumns populated fromclaims.preferred_usernameat write time, templates render display names with UUID fallback (!43, !44)
Multi-Jurisdictional Authorization ✓ COMPLETE
Plan A — archived May 2026. 14 step MRs (!230–!246) land record-level authorization across all 7 stateful services.
-
Record-level authz engine on zen-engine/JDM — ~140 handler sites enforce per-row access decisions via
authz.check(…)(single row) andauthz.auto_scope_list(…)(LIST). -
Cross-service
assigned_worker_sub UUIDdenormalization across 11 tables. Identity normalized toclaims.subUUID. -
Default JDM rulesets for Georgia + Texas under
rulesets/{jurisdiction}-authz-{resource}.json. -
IdP-neutral
worker_identitiespopulated lazily from JWT claims. -
Georgia hardcoded defaults removed —
CRAIG_<SVC>JURISDICTION+CRAIG_<SVC>ADMIN_UNIT_LABELare now required env vars (Plan A § Step 12). -
Admin units externalized to per-jurisdiction CSVs (georgia 159 + texas 254) with idempotent
cargo xtask seed-admin-unitsupsert (Plan A § Step 13a). -
BFF/intake i18n hardcodes generic; ICPC deadline + payment-period config externalized (Plan A § Step 13b).
-
5 ADRs accepted: ADR-023 (architecture), ADR-024 (zen-engine + RMQ cache invalidation), ADR-025 (identity normalization), ADR-026 (IdP-neutral identity), ADR-027 (architectural principles).
Non-Georgia adopters now onboard via rulesets + CSVs + env vars — no code changes.
Service Identity + On-Behalf-Of (Plan E)
Plan E — complete (15 step MRs across 2026-05-09 → 2026-05-11). Service-to-service auth runs on per-service client_credentials against any OIDC issuer, with on-behalf-of worker attribution via the signed X-Craig-Actor header.
-
Steps 1–2/2b — Plan filing + ADR-028 + OIDC discovery convergence + destructive
keycloak_*→oidc_*rename (!235, !248) -
Steps 3–7 —
Claims::{is_service, service_id, acting_worker, actor}+OidcServiceToken+ActorTokenIssuer+ per-service JWKS registry +CraigClientExtoutbound helpers (!250–!254) -
Step 8 — bootstrap wiring;
BootstrapResultgainsservice_token+actor_issuer; 6 standard services migrated (!255) -
Steps 9–10 — devstack actor-key provisioning + craig-web BFF flip (P0 fix routing JDM input through
claims.acting_worker()) + craig-intake outbound flip (!256–!259) -
Step 11 — audit-log enrichment with
actor_service+actor_user_subcolumns + filter API (!261) -
Step 12 —
cargo xtask identity verifyOIDC conformance gate; soft-check wired into the pre-pushvalidatebattery (!262) -
Step 13 —
cargo xtask identity render --backend keycloak\|authentik\|dexreference IaC generator (!263) -
Step 14a —
cargo xtask gen-actor-keys+ file-path env loaders (CRAIG_<SVC>__SIGNING_JWK_FILE/CRAIG_PEER_JWKS_JSON_FILE) + 6-step rotation procedure (!264). Step 14b (xtask dev identity provisionKeycloak admin-API automation) deferred — devstack works via committed config; per ADR-026 IdP-neutrality the admin-API client isn’t justified. -
Step 15 — archive (this MR)
Operators of any compliant OIDC backend (Keycloak, authentik, dex, Okta, Azure AD/Entra, ForgeRock, PingFederate, custom) can now deploy CRAIG without backend-specific code in the codebase. ADR-028 Accepted.
API Idempotency Audit
All API endpoints must be safe to retry without unintended side effects. GET, PUT, and DELETE are naturally idempotent; POST create endpoints need idempotency keys or de-duplication to prevent duplicate records on retry. This audit covers all existing services (rules, cases, placement, exchange, financial, reporting, security) and must be applied to all future services.
-
Audit all POST create endpoints across all services for retry safety — 51 POST endpoints classified (11 naturally idempotent, 35 need key, 5 stateless)
-
Add idempotency-key header support where needed — shared
IdempotencyLayermiddleware incraig-apiwithDashMapcache, applied to all 8 services -
Document idempotency guarantees in OpenAPI specs
Pre-1.0 API Contract Stability — Prioritization Guidance
CRAIG is pre-1.0 and its REST API surface is still being redesigned (see the ADR series around intake and identity). While the contracts are still moving, deprioritize work whose value depends on those contracts being frozen — it either gets rewritten every time an API shape changes (negative ROI) or it locks in an immature contract and fights legitimate redesigns.
Defer (revisit at 1.0 / API stabilization):
-
API contract tests (response-schema validation as a stability gate).
-
Heavy external-integration work that bakes in current API shapes — third-party orgs, federal data-exchange partners, and downstream automation that would have to migrate when a response shape evolves.
Prefer instead (uses the APIs as-is without freezing them externally):
-
Internal
craig-web/ BFF / UX work — consumes the APIs but does not expose a frozen external contract. -
Compliance-driven features that use the APIs as readers and may surface gaps to fix.
-
Domain features inside CRAIG’s own service boundaries, plus refactor / cleanup / docs / observability work.
A quick prioritization test: "would this work need to be redone if we changed an API response shape next month?" If yes, defer it.
Scope: the caution is for external integrators only
The contract-locking concern applies narrowly to external API integrators who cannot migrate on demand. It does NOT gate first-party or human-facing work, which is in fact more valuable pre-launch because it surfaces gaps before real users have frozen expectations. Do not over-apply a "wait for API stability" gate to:
-
Internal UIs — even those aimed at external user populations (constituents, foster parents, providers). Until users exist in production the UI can be rebuilt freely.
-
Internal tooling and admin surfaces.
-
First-party clients — the mobile/offline app, the web BFF, and the CLI.
-
Compliance-driven reporting that consumes the APIs as a reader.
Default disposition pre-launch: build it, evaluate it, iterate. Lock-in is the exception, not the rule — the deciding question is whether a real production integrator could exist today that would break when the shape changes.
Deployment Work Is Owned by a Separate Team
AWS deployment and standalone-application deployment are owned by a separate team and are out of scope for this repository’s active work. Do not propose plans, MRs, or implementation for them, and skip them when surfacing backlog — mention them for awareness only if a draft or issue references one.
The recognizable artifacts in this family:
-
Draft MR !71 — Craig Deployment to AWS
-
Draft MR !124 — Standalone Craig App Deployment (using container-registry images)
-
Issues #163, #172, #199 — the deployment issues those drafts correspond to
The reason for the carve-out is ownership, not deprioritization: another team is delivering this work, so duplicating or volunteering to take it on here would collide with theirs.