# Dependency Map — citation-evidence This document describes the **allowed dependency edges** between the subsystems of the citation-evidence ecosystem. It is the cycle-prevention contract. It complements `SharedContracts.md` (which says *what* is shared) by saying *who is allowed to depend on whom*. --- ## 1. The rule > Types flow downward from `citation-engine`. Behavior flows upward into > specialised repos. No subsystem may import another subsystem's behavior > unless this map shows an edge. The umbrella repo `citation-evidence` is allowed to depend on every subsystem; nothing depends on the umbrella. --- ## 2. Allowed edges ``` ┌───────────────────────┐ │ citation-evidence │ (umbrella) └───────────┬───────────┘ │ depends on ┌──────────────────────────┼────────────────────────────┐ ▼ ▼ ▼ ┌───────────────┐ ┌────────────────┐ ┌────────────────┐ │ citation- │ │ evidence- │ │ citation- │ │ work │ │ binder │ │ engine │ └──────┬────────┘ └────────┬───────┘ └────────┬───────┘ │ │ │ │ depends on │ depends on │ depends on │ │ │ (nothing — ▼ ▼ │ leaf node) ┌────────────────┐ ┌────────────────┐ │ │ evidence- │ │ evidence- │ │ │ anchor │ │ anchor │ │ └──────┬─────────┘ └────────┬───────┘ │ │ │ │ │ depends on │ depends on │ ▼ ▼ ▼ ┌────────────────┐ ┌────────────────┐ (citation-engine) │ evidence- │ │ citation- │ │ source │ │ engine │ └────────┬───────┘ └────────────────┘ │ │ depends on ▼ ┌────────────────┐ │ citation- │ │ engine │ └────────────────┘ ``` In tabular form: | Repo | May depend on | Must not depend on | |--------------------|--------------------------------------------------------|-----------------------------------------| | `citation-engine` | (nothing — it is the leaf) | every other subsystem | | `evidence-anchor` | `citation-engine` | `evidence-source`, `citation-work`, `evidence-binder`, `citation-evidence` | | `evidence-source` | `citation-engine` | `evidence-anchor`, `citation-work`, `evidence-binder`, `citation-evidence` | | `evidence-binder` | `citation-engine`, `evidence-anchor` | `evidence-source`, `citation-work`, `citation-evidence` | | `citation-work` | `citation-engine`, `evidence-anchor`, `evidence-source`| `evidence-binder`, `citation-evidence` | | `citation-evidence`| all five subsystems | (nothing else in the ecosystem) | Notes: - `evidence-source` does NOT depend on `evidence-anchor`. When an ingestion pipeline needs to know "could a selector resolve here?", the answer comes through events, not direct calls. - `citation-work` does NOT depend on `evidence-binder`. Linking evidence to form fields is a separate workflow; the review workspace should function without it. A separate "evidence-backed form" application composes work + binder + engine. - `evidence-binder` does NOT depend on `evidence-source`. When a binder needs source context, it asks `evidence-anchor` to resolve the annotation, which in turn knows nothing about how the document was ingested. --- ## 3. Communication channels Direct imports are allowed only along the edges above. Where two subsystems need to coordinate without being allowed to import each other, they use one of these indirect channels: | Channel | Owner | Notes | |---------------------------------|------------------|---------------------------------------------------------| | Shared event bus | `citation-engine`| Vocabulary frozen in `SharedContracts.md` §4 | | Shared types package | `citation-engine`| Re-exported through `@citation-evidence/engine` (post-extraction) | | Rect registry | `evidence-binder`| Used by form UI, evidence sidebar, viewer adapter | | Persistence interfaces | `citation-engine`| Concrete adapters in subsystems but interfaces in engine| --- ## 4. During umbrella-first MVP While all code lives in `citation-evidence/src/`, the rule is enforced by **folder structure** and **lint rules**: ``` citation-evidence/src/ shared/ ← what will become citation-engine (types + contracts) engine/ ← what will become citation-engine (services) anchor/ ← what will become evidence-anchor source/ ← what will become evidence-source work/ ← what will become citation-work (UI) binder/ ← what will become evidence-binder app/ ← the umbrella reference app ``` Lint rule (to be added in WP-0001): - `engine/` may import only from `shared/`. - `anchor/` may import only from `shared/`, `engine/`. - `source/` may import only from `shared/`, `engine/`. - `binder/` may import only from `shared/`, `engine/`, `anchor/`. - `work/` may import only from `shared/`, `engine/`, `anchor/`, `source/`. - `app/` may import from any. Violating these rules in MVP is a lint error, not a runtime error. When subsystems extract into their own repos, the lint rule disappears and the package boundary enforces the same constraint. --- ## 5. Why these rules 1. **`citation-engine` as the leaf** prevents the most common monorepo pathology: the "core" repo accumulating UI/IO dependencies because it was easier than inverting a dependency. 2. **`citation-work` ⊄ `evidence-binder`** keeps the review workspace usable even when there is no form context (e.g. just collecting evidence for a report). 3. **`evidence-binder` ⊄ `evidence-source`** keeps binding logic from accidentally caring about ingestion details. 4. **No subsystem depends on `citation-evidence`** — the umbrella is a composition point, not a library. --- ## 6. Change process Adding an edge to this map is a change to the contract. - New edges require a short ADR in `docs/decisions/`. - Removing an edge requires a refactoring plan (where do consumers go?). - The MVP itself is an exception: edges that turn out to be wrong during umbrella-first development are recorded as "deferred reshape" items in the relevant workplan, not as ADRs.