Orchestrata Ultimate › Plans › kg-project-scoped-identity
Project-scoped KG identity — migration plan (session 227)
Source: plans/kg-project-scoped-identity.md at 8a2cb42ad · last changed 2026-07-27 · first committed 2026-07-12 · 51 lines.
Prose pending.
Plan text
Project-scoped KG identity — migration plan (session 227)
User rulings 2026-07-12: (1) "the graph must take multiple projects, 100 even"; (2) "projects have specs, user stories, requirements, and ast unique to them". Every project-derived entity is unique PER PROJECT — bare natural ids (relative paths, qualified names, spec/req ids) must never be global MERGE identity. Memory: project-kg-multi-project-invariant.
Identity rule
Canonical id for project-derived labels = "{project}:{natural_id}".
Genuinely global registries keep their keys: Volk(alias), Tool(name),
Pattern(name), Portfolio(name). Session-scoped records key on their own ids.
Status by label (writer-verified)
| Label | Writer key today | Verdict | Wave |
|---|---|---|---|
| Package | {project}:{path} (sync.py) |
FIXED — canon key → id (7eee8a46) | done |
| Module | {project}:module:{path} (sync.py) |
already qualified | done |
| File / Directory | bare relative path (2 diverging writers) | builder in flight | W1 |
| Class / Function | bare qualified_name (sync.py:342/376) |
COLLIDES | W2 |
| Spec / Requirement / RequirementItem | bare "023" / "023::REQ-…" (_stage_specs_traces.py:129-153, sync.py:491) |
COLLIDES | W2 |
| UserStory / Specification / Requirement (kg_design.py:208-296) | bare story_id/spec_id/req_id + divergent key names | COLLIDES + key drift | W2 |
| Requirement (kernel/pipeline_kg.py:330) | req_id divergent key, bare |
COLLIDES + key drift | W2 |
| Test | {?} sync.py:805 — verify id shape |
verify in W2 | W2 |
| TestRun / TestResult | run_id (uuid — inherently unique) / bare name (test_results_store.py:171) |
TestResult.name COLLIDES | W2 |
| Scenario | harness scenario_id — verify uniqueness scope | verify in W2 | W2 |
| Component | name — unverified | watch item | W3 |
Waves
- W1 (in flight): File/Directory → qualified id; canonical_schema + schema.py legacy constraints; both writers + readers project-scoped.
- W2: Class/Function ids project-prefixed in sync.py; spec tier
(_stage_specs_traces, sync.py spec enrichment, kg_design, pipeline_kg)
→
{project}:prefix AND canonical key names (Requirement.id everywhere, retiring req_id/story_id/spec_id key drift per canonical_schema); Test/TestResult verification + fixes; readers (context_injector, check-traces graph consumers, semantic enrichment scripts) follow. - W3: live-schema reconciliation — drop stale bare-key UNIQUE constraints on all 4 Neo4j instances; re-derive graph state via bootstrap_graphs.py (never hand-migrate node ids — the graph is derived from source); Component.name verdict; kg_schema check contract update.
Constraint drops owed (after each wave's writers land)
- package_path: DONE on .11 + clones.
- file_path, directory_path: after W1 lands (all 4 instances).
- Any spec-tier bare-key constraints: after W2 (enumerate via SHOW CONSTRAINTS vs canon at that point).