ADR-008: Jurisdiction-Specific Form Configuration
On this page
Status
Partially resolved (mandated reporter categories shipped via craig-reference enum; remaining jurisdiction-varying form content still Pending).
Resolution Notes (2026-04-20)
The immediate trigger — Georgia’s mandated-reporter categories — was handled in Phase 12 Phase 2c by adding a MandatedReporterCategory enum to craig-reference and a dropdown in the public intake BFF form.
That subset of the problem is complete and in production.
The broader question of jurisdiction-specific form field labels, required/optional toggles, guidance text, and conditional field logic is still open. The YAML-per-jurisdiction approach (Option A in the analysis below) has not been implemented. For multi-state deployments beyond Georgia, a future MR will need to either:
-
Pick and implement one of the options below.
-
Accept per-deployment template overrides (craig-web + craig-intake templates mounted from a jurisdiction-specific volume) as a stopgap.
Revisit this ADR before onboarding the second state/tribe.
Context
CRAIG’s public intake form needs jurisdiction-specific content that varies by state statute. The immediate trigger is mandated reporter categories — Georgia’s O.C.G.A. §19-7-5 defines 15 categories, but other states have different lists. Beyond reporter categories, other form elements may vary by jurisdiction: required vs optional fields, guidance text, dropdown options, and conditional field logic.
Universal demographic enums (Gender, Race, Ethnicity) are federally standardized (AFCARS/NCANDS) and belong in craig-reference as Rust enums.
Jurisdiction-specific statutory content is a different category — it changes by state law, not by code logic.
Options
Option A: YAML jurisdiction config files loaded at startup
Jurisdiction-specific form definitions stored as YAML files under config/jurisdictions/{state}/intake-form.yaml.
craig-intake loads the file at startup based on CRAIG_INTAKE__JURISDICTION env var.
Served via a GET /public/v1/form-config endpoint.
The web form fetches config to populate dropdowns dynamically.
Pros:
-
Easy to add states without code changes — YAML editable by non-developers
-
Follows the existing pattern of
rulesets/{jurisdiction}/for jurisdiction-specific content -
Supports Epic &9 (Standalone Mode) — standalone deployments ship their own YAML
-
Version-controllable in git
Cons:
-
Need to define a YAML schema and validate at startup
-
Conditional logic in YAML can get complex if taken too far
-
No compile-time type safety on config values
Option B: Database-driven form config (admin UI)
Store form definitions in a form_configs table, editable via admin API endpoints.
Pros:
-
Runtime-changeable without redeploy
-
Admin users can update without git access
Cons:
-
Over-engineered for current stage
-
Requires admin UI for editing
-
Harder to version control and audit
-
Migration path unclear for multi-jurisdiction
Option C: Rust enums per jurisdiction (extend current pattern)
Add MandatedReporterCategory and other jurisdiction-specific enums to craig-reference with strum serialization, gated by jurisdiction feature flags or separate enum sets.
Pros:
-
Compile-time safety
-
Consistent with existing enum pattern
Cons:
-
Adding a state requires code change + redeploy
-
Enum explosion as jurisdictions multiply (50 states × N categories)
-
Mixes universal standards (AFCARS) with state-specific statutes in same crate
Consequences
The chosen approach affects:
-
How
craig-intakeloads and serves form metadata -
Whether the web form uses static
<option>elements or dynamically populates from an API -
How new jurisdictions are onboarded (code change vs config file vs admin UI)
-
Epic &9 (Standalone Mode) architecture — standalone deployments need form config
-
Whether mandated reporter categories need a
craig-referenceenum or live outside the crate
References
-
Georgia mandated reporters: O.C.G.A. §19-7-5
-
Georgia OCA training: Mandated Reporting
-
DFCS policy: PAMMS 3.24 — Mandated Reporters
-
Plan: Public Child Abuse Reporting — Phase 2c, mandated reporter categories section