- INTENT.md: declare umbrella as the home for shared contracts; document umbrella-first MVP decision (code lives here until subsystems stabilize) - wiki/SharedContracts.md: vocabulary, state enums, relation types, selector taxonomy, event vocabulary, viewer adapter contract, canonical text normalization, rect-registry contract - wiki/DependencyMap.md: allowed dependency edges; folder layout + lint-rule strategy during umbrella-first phase - history/2026-05-24-initial-assessment.md: alignment review, technical risks, and the umbrella-first pivot rationale - workplans/CE-WP-0001..0004: four ralph-compatible workplans covering foundations, PDF review slice, form binding + visual guide, and citation card export — implementing PRD §20 end-to-end Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
7.9 KiB
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-sourcedoes NOT depend onevidence-anchor. When an ingestion pipeline needs to know "could a selector resolve here?", the answer comes through events, not direct calls.citation-workdoes NOT depend onevidence-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-binderdoes NOT depend onevidence-source. When a binder needs source context, it asksevidence-anchorto 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 fromshared/.anchor/may import only fromshared/,engine/.source/may import only fromshared/,engine/.binder/may import only fromshared/,engine/,anchor/.work/may import only fromshared/,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
citation-engineas the leaf prevents the most common monorepo pathology: the "core" repo accumulating UI/IO dependencies because it was easier than inverting a dependency.citation-work⊄evidence-binderkeeps the review workspace usable even when there is no form context (e.g. just collecting evidence for a report).evidence-binder⊄evidence-sourcekeeps binding logic from accidentally caring about ingestion details.- 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.