ADR-0179: Navin Enterprise Policy Administration and Renewals Agent (insurance), product layer mirroring the policy system on top of the Control Plane
- Status: proposed on 2026-11-04, awaiting the user's validation (see "Points to validate")
- Date: 2026-11-04
- Scope: new project
navin-enterprise-assurance-contrats-renouvellements/(FastAPI backendnavin_contrats, workers, Navin integration, product manifest of the shared frontend shell; no frontend of its own), additive OpenFGA types (deploy/policies/openfga/model.fga), OPA packageeai.assurance_contrats(deploy/policies/opa/assurance_contrats.rego), contractscontracts/v1/assurance-contrats-renouvellements-action-requestandassurance-contrats-renouvellements-copilot-event, Navin Manager agent template prepared but not published - Related documents: ADR-0101 (licences), ADR-0103 (LiteLLM), ADR-0108 (Opik), ADR-0166 (ClamAV and YARA-X), ADR-0174
(Mem0 and Cognee), ADR-0175 (RAG, product layer pattern), ADR-0176 (Banking Back-Office, generic modules reused),
decisions of 2026-11-04 (
.navin/continuity/DECISIONS.md: five agents in parallel, product manifest, one frontend), auditnavin-enterprise-assurance-contrats-renouvellements/docs/en/NAVIN_INTEGRATION_AUDIT.md, briefagent_uses_cases/04_Assurance_Contrats_Renouvellements.md
Context
The UC-04 brief asks for an agent that analyses contractual deadlines and versions, prepares endorsements and renewals, identifies termination risks and organises the work of the policy managers with validation of commitments. It requires the policy administration system to stay the source of truth, no invented legal deadline, Decimal amounts per currency, an authorised procedure for every change of cover, premium or termination, and an LLM that proposes without ever deciding.
The audit of 2026-11-04 shows that the banking back-office (ADR-0176) already provides, tested, the generic modules this product needs: typed configuration, bilingual errors, i18n, fail-closed authorisation (OpenFGA and OPA through the Control Plane), append-only audit, durable jobs and outbox, RLS, Action Gateway with maker-checker and source confirmation, document pipeline with quarantine, copilot runtime (events, SSE, figures governance), observability and operations. No insurance business exists: no policy projection, notice rule, prorata, renewal campaign or termination request.
Decision
1. Copy the generic modules, write only the business
The navin_contrats backend takes the generic modules of the banking backend with no change other than the package
name, the SQL schema (contrats), the environment prefix (NAVIN_CONTRATS_), the API prefix and the OPA action names,
so that a later extraction into a shared library stays mechanical. Only the modules of section 7 and the entities of
section 18.1 are written: contract_register, deadlines, endorsements, premium_adjustments,
renewal_campaigns, retention_reviews, termination_requests, contract_reconciliation.
2. The policy system is the master; PostgreSQL is a dated mirror
contract_projections and contract_versions are timestamped projections of the policy system (source_status,
source_connector, refreshed_at). Two overlapping active versions open a contract_reconciliation_items row with
outcome conflict; the application never picks the most recent one. No table creates a parallel cover; the active
state shown is the one confirmed by the source.
3. Nothing applies without a human and without the source
Endorsements, renewals, terminations and reinstatements are requests. Their state machine (section 6) is a transition
registry as data (navin_contrats/workflows/machine.py): source state, target state, event, authorised actor, source
or clock binding; a forbidden transition answers 409 transition_not_allowed, a missing expected version 428, a stale
version 412. Every transition with an external effect goes through the Action Gateway: contract
assurance-contrats-renouvellements-action-request, OPA decision contrats.action.prepare / approve / execute,
maker-checker when the matrix of section 15 requires it, submission to the source with an idempotency key and status
unknown_pending_confirmation until re-read. An approval is bound to the object version: any change after approval
voids it (approval_void) and forbids sending.
4. Deterministic, versioned, Decimal computations
Notice dates are computed from the event named by a versioned notice rule (notice_rules: event_basis,
days_before, calendar_id, source_uri, effective_from), never from a coded legal threshold. Financial impacts
are Decimal proposals per currency from a dated tariff version (tariff_versions) with an explicit prorata convention
(day_count_basis 365, 360 or actual, documented bounds) and engine_version, ruleset_version, input_snapshot,
as_of, explanation. Retention scores are explained priority indicators without a displayed probability and never
slow down a termination request.
5. Communications and documents as reviewed drafts
Customer communications are generated as draft and reviewed by a human; a reminder never creates a second active
offer. Document generation requests are versioned and handed to the document service of the Control Plane; ingestion
follows quarantine, ClamAV and YARA-X, Docling, human review when the extraction is ambiguous.
6. Observability, reports, licences
Same choices as ADR-0176: Prometheus, Alertmanager, OpenSearch, Jaeger, Opik (Grafana, Loki and Tempo refused by
ADR-0101); contrats_* metrics per currency without identifier; csv and json reports only, other formats announced
unavailable; no Python dependency added.
7. One frontend, one product manifest, one unpublished template
The product carries no frontend code: product.manifest.json (contract agent-product-manifest) describes name, logo,
colours, prefix, ports 3476 / 8475 / 6396, roles, menus, entities and copilot prompts for the shared shell. The template
navin-assurance-contrats-renouvellements-agent is prepared (published: false, status prepared); nothing is
written under navin-manager/catalog.
Consequences
- The invariants of section 7 live in the product and in the OPA package; the Control Plane is not modified.
- Real integration with a policy system, rating engine, billing, CRM or e-signature is not demonstrated: connectors declared by capabilities, deterministic sandbox flagged as such.
- The temporary duplication of the generic modules is accepted; the extraction into a shared library follows the closure of UC-00.
Points to validate
- Notice rules and calendars stay data entered by the organisation with their source: no jurisdictional default is shipped.
- Accepted prorata conventions:
365,360,actual, start inclusive and end exclusive. csvandjsonreports only until a Navin engine exists.- Pre-publication only: the template stays
prepareduntil the user's explicit agreement.
Rejected alternatives
- An own policy repository: a second master, contrary to the brief.
- A generic prorata or a live tariff: not reproducible, not dated.
- A displayed termination probability without a validated model: forbidden by section 8.
- A shared Python library extracted now: unstable while five products consume it.