0%

Pillar A — typed cross_plan_relations[] + derived reverse

Goal

The v7 schema carries a typed cross_plan_relations[] authored in ONE direction; the reverse edge is DERIVED by export_json, never hand-authored, so it cannot drift.

Implementation Sketch

Augment cross_plan_needs[] into cross_plan_relations[] {plan, id, kind: dependency|non_contradiction|mission_enforces, rationale, surface}. Synthesize the reverse edge in export_json._emit_plan_edges (mirrors existing DEPENDS_ON/BLOCKED_BY derivation). Forward-only migration backfills []; consumer version pin bumps.

Spec References

scripts/plan_corpus/schemas/v7/plan-routing.schema.json (Section.cross_plan_needs lines 485-497); scripts/plan_corpus/export_json.py:_emit_plan_edges (335-400). routing.md §5 ordering primitives.

Work Items

  • Add cross_plan_relations[] to the v7 schema ($defs Section + WorkItem) with kind/rationale/surface fields; keep cross_plan_needs as the dependency subset alias
  • Derive the reverse edge in export_json._emit_plan_edges — reverse is computed, never stored (kills bidirectional drift)
  • Forward-only migration backfilling cross_plan_relations: [] + bump the consumer plan-corpus-version pin
  • Schema validator (reject malformed kind/surface) + pytest