Skip to content

Extension Playbooks

These playbooks are decision-complete checklists for common repository extensions.

Playbook A: Add a New Law Source Adapter

Goal

Add a new source adapter that can download/ingest data while preserving canonical identity contracts.

Required contracts

  • Source identity key tuple must be stable and explicit:
  • source
  • owner_alias_kind
  • owner_alias_value
  • Source artifacts must be traceable to manifest rows and source refs.
  • Runner-facing APIs should remain at store/pipeline boundaries, not direct SQL.

Files to edit

  • backend/src/law_graph/pipelines/<source>/... (new adapter pipeline)
  • backend/src/law_graph/pipelines/__init__.py and/or origin registration
  • backend/src/law_graph/cli.py (new source command wiring)
  • Source-specific ingest projection adapter (if ingest shape differs)
  • Tests:
  • backend/tests/unit/... for adapter behavior
  • backend/tests/integration/pipelines/... for end-to-end flow

Storage touchpoints

  • Download persistence should flow through download manifest store/repository.
  • Ingest persistence should flow through IngestManifestDbStore intent APIs.
  • Identity resolution must use source alias keys consistently.

Runner registration points

  • Origin pipeline registry (get_origin_pipeline and related origin config)
  • CLI subcommands for download/ingest/backfill (if supported)

Do not edit

  • Do not add SQL primitives in runner/pipeline modules.
  • Do not bypass store APIs to call ingest/download repositories directly.
  • Do not add fallback identity keys outside the canonical tuple.

Acceptance checklist

  • New source commands run from CLI and Makefile workflow.
  • Identity key tuple is used consistently end-to-end.
  • Download and ingest manifests capture source rows correctly.
  • Unit + integration tests cover happy path and key failures.

Playbook B: Add a New Ingest Persisted Field or Table

Goal

Add ingest persistence without violating SQLModel-first contracts.

Required flow

  1. Contract first: define/update SQLModel contract in backend/src/law_graph/storage/contracts/ingest/....
  2. Repository primitive: add/update IngestRepository table primitive.
  3. Store intent API: expose policy-level method in IngestManifestDbStore.
  4. Runner path: call store method from ingest runner, not repository.
  5. Migration policy: schema/data migration in external scripts only.
  6. Roundtrip tests: write -> read -> validate contract behavior.

Files to edit

  • backend/src/law_graph/storage/contracts/ingest/...
  • backend/src/law_graph/storage/repositories/ingest_repository.py
  • backend/src/law_graph/storage/ingest_manifest_db.py
  • backend/src/law_graph/pipelines/normattiva/ingest/__init__.py (call path)
  • backend/scripts/migrations/... (if schema migration needed)
  • backend/tests/... contract/store/runner tests

Do not edit

  • Do not run migrations from runtime downloader/ingest code paths.
  • Do not duplicate schema literals/enums across multiple modules.
  • Do not add one-to-one pass-through store aliases with no policy value.

Acceptance checklist

  • SQLModel contract is canonical and imported where needed.
  • Repository change is table-oriented primitive only.
  • Store API encapsulates orchestration/policy concerns.
  • Runner uses store API, not repository directly.
  • Migration script exists (when required) and runtime code stays migration-free.
  • Roundtrip contract tests pass.

Playbook C: Add or Modify Ingestion Transformation Logic

Goal

Place new transformation logic at the correct layer (delta, etl, or store) without leaking concerns.

Placement checklist

  • Put logic in delta/* when it changes canonical record semantics, reconstruction semantics, or timeline/event modeling.
  • Put logic in etl/* (or source snapshot adapters) when it maps raw payloads into normalized snapshots/variant inputs.
  • Keep the steady-state ingest worker on the direct RawAct -> DeltaProjection -> VariantEvent path; avoid rebuilding full schema Act trees unless the workflow explicitly needs snapshots.
  • Put logic in IngestManifestDbStore only when it is orchestration policy (batch dedupe, lock scope, transaction grouping).

Files to edit

  • backend/src/law_graph/delta/builder.py and related delta modules (if canonical semantics change)
  • Source ingest/snapshot adapter modules under backend/src/law_graph/pipelines/...
  • backend/src/law_graph/pipelines/normattiva/ingest/__init__.py (pipeline wiring)
  • Tests adjacent to changed layer (unit + integration)

Do not edit

  • Do not encode transformation-specific business rules in repository SQL methods.
  • Do not add downloader-specific behavior in delta resolver/builder modules.
  • Do not mutate contracts as an incidental side effect of transformation changes.

Acceptance checklist

  • Logic lives in the correct layer by ownership.
  • Existing contracts and boundaries remain explicit.
  • Tests cover transformation behavior and regression scenarios.
  • Ingest output remains reconstructable via resolve_state.