Canonical Project Record (CPR)
The Canonical Project Record (CPR) is a source-agnostic project-data schema that decouples internal project-data representation from source products (such as Jira, Asana, and MS Project).
Architecture Overview
The pipeline is implemented by a single CanonicalWriter (api/src/cpr/canonical-writer.ts) that owns all project_memory writes, drift capture via captureTransitions, and RAG upsert via RagService. Connectors (ADO/Asana) call it with CanonicalProjectRecord[] produced by SourceAdapter implementations.
Structured sources use declarative TransformerMapping objects (ADO_MAPPING, JIRA_MAPPING, ASANA_MAPPING in api/src/cpr/structured-mappings.ts) fed to structuredTransformer (api/src/cpr/structured-transformer.ts). Unstructured resolvers (e.g. ConfluenceResolver sketch in api/src/cpr/resolver-sketch.confluence.ts) satisfy the same SourceAdapter contract but emit ProgramAssociationProposal[] routed to the sign-off gate; the sketch is foundation only — not yet wired.
Core Schema Categories
The CPR schema is structured around 6 core categories:
- Identity: Core identifiers.
- Hope: Target states and baselines.
- Reality: Actual progress and lifecycle state.
- Gap: Schedule health and deviations.
- Narrative: Embedded status updates and summaries.
- Provenance: Multi-source trust, audit trails, and status fidelity.
Status and Lifecycle (Two Axes)
Rather than a single status field, CPR separates status into two distinct axes:
- Lifecycle (Reality): Core states (
not_started,active,done) mapped from language-agnostic keys, plus enriched states (blocked,on_hold,in_review,cancelled). - Schedule-health (Gap): Health indicators (
on_track,at_risk,late,unknown).
Baseline and Trustworthiness
- Baseline Source: Tracks how the baseline was established (
native_baseline,recovered_from_history,first_ingest_snapshot, orunknown). - Honesty Principle: A late project must never look on-track via snapshot baseline (no slippage-laundering).
Granularity and Hierarchy
- Granularity: One CPR per node at any level. Hierarchy is maintained via
parent_idand type links (altitude, not structure). - Trajectory: Lightweight gap-history time-series (
cpr_id,observed_at,gap_days,schedule_health) are recorded for trajectory tracking and risk modeling.