Context
Consumer-enabling leaf of epic #14472 (Golden Path v2), filed in the operator-directed full-fledging pass (2026-07-02: every sub executable, no scrap-hunting). Live latest-open sweep at 2026-07-02T19:37:34Z: no equivalent ticket; epic sub-graph carries only #14454 (closed) + #14474 (probe, in progress).
Empirical origin: the #14474 pre-implementation scan (on-ticket, 14:46Z) found the concept spine FRAGMENTED — one semantic query surfaced four distinct node-ids for the Golden Path concept (CONCEPT:GoldenPath · golden-path · CONCEPT:Golden Path Synthesis · a fourth variant) and three for Dream Pipeline (CLASS:DreamPipeline / dream-pipeline / CONCEPT:DreamPipeline) — duplicates minted under at least three id-conventions (CONCEPT:PascalCase, bare kebab-case, CONCEPT:Title Case).
The Problem
Every graduated consumer of #14472 anchors to concept ids. Over a fragmented spine, anchoring silently splits neighborhoods: retrieval walks reach a fraction of the real neighborhood, gap detection double-counts, measurement (consumer 4) attributes touches to different nodes for the same concept, and the sandman slice renders partial pictures. Fragmentation is plausibly the single largest reachability-gap class the epic will measure — and no defragmentation mechanism exists.
The Architectural Reality
- Mint sites:
ai/services/graph/SemanticGraphExtractor.mjs (session anchoring, TAGGED_CONCEPT @ 1.0 curated / 0.8 auto) and ai/services/memory-core/MailboxService.mjs (message-side tagging). Neither canonicalizes ids at mint time.
- Edge decay:
ai/services/memory-core/GraphService.mjs:73 — PROTECTED_EDGE_TYPES excludes concept edges (IMPLEMENTED_BY/PARENT_CONCEPT decay by design, ADR 0024); any merge must preserve decaying-scent semantics, not inflate weights.
- The #14474 probe artifact (measurements file, in progress) quantifies alias-cluster size and neighborhood disjointness per sampled concept — this leaf's detection pass generalizes that measurement to the full 20,526-concept spine.
The Fix
One PR delivering four pieces:
- Detection pass — normalize ids (strip
CONCEPT: prefix, case-fold, kebab-ize) → cluster report artifact under learn/agentos/measurements/ (cluster count, size distribution, top-N worst clusters, per-cluster neighborhood overlap/disjointness).
- Canonical-id policy — one convention wins (candidate: bare kebab-case, matching the curated
delta-updates/golden-path precedent); decided IN the PR from the report data and stated in the module docblock.
- Merge executor — re-point all edges from alias nodes to the canonical node (weight on collision: MAX, never SUM — sum would inflate scent against ADR-0024 decay semantics); write an alias→canonical map node property (or sidecar) so historical references resolve; alias nodes tombstoned, never hard-deleted in the same pass.
- Mint-time guard — both mint sites canonicalize through one shared helper before writing; spec pins that a Pascal/Title-form input lands on the kebab canonical id.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
| Concept node ids (graph) |
ADR 0024 taxonomy + curated-id precedent |
One canonical id per concept; aliases resolve via map |
Unresolvable/ambiguous cluster → left split + listed in the report (no forced merges) |
Module docblock states the policy |
Report artifact + probe re-run showing unified neighborhoods |
SemanticGraphExtractor / MailboxService mint paths |
This leaf |
Canonicalize-before-write via shared helper |
Helper failure → write proceeds with raw id + warn (never block the write path) |
JSDoc on the helper |
Unit spec per mint site |
Decision Record impact
aligned-with ADR 0024 (taxonomy + decay semantics respected; no new edge classes, no protection changes — those belong to the OQ1 anchoring leaf).
Acceptance Criteria
Out of Scope
- Anchoring architecture / edge protection (OQ1 leaf).
- Retrieval consumption of the unified spine (consumer-1 leaf).
- Re-triggering extraction over historical sessions (the merge operates on the existing graph).
Avoided Traps
- SUM-merging weights — inflates scent; MAX preserves the strongest real signal under decay semantics.
- Hard-deleting aliases — breaks historical references and session provenance; tombstone + map.
- Blocking mint on canonicalization failure — the write path's never-fail contract outranks id hygiene (#12972 arc).
- Forced merges of ambiguous clusters — a wrong merge is worse than a split; ambiguity stays split and visible in the report.
Sequencing
Consumes the #14474 measurements artifact for validation (soft gate: detection can build in parallel; the merge PR lands after the probe artifact exists).
Related: #14472 (parent epic), #14474 (probe — validation instrument), Discussion #14422 (graduation source; measured-reality items 2/4)
Origin Session ID: 8cf234b7-e698-47ca-99e2-bf865196b6aa
Retrieval Hint: concept spine defrag alias cluster canonical id merge TAGGED_CONCEPT mint-time guard
Context
Consumer-enabling leaf of epic #14472 (Golden Path v2), filed in the operator-directed full-fledging pass (2026-07-02: every sub executable, no scrap-hunting). Live latest-open sweep at 2026-07-02T19:37:34Z: no equivalent ticket; epic sub-graph carries only #14454 (closed) + #14474 (probe, in progress).
Empirical origin: the #14474 pre-implementation scan (on-ticket, 14:46Z) found the concept spine FRAGMENTED — one semantic query surfaced four distinct node-ids for the Golden Path concept (
CONCEPT:GoldenPath·golden-path·CONCEPT:Golden Path Synthesis· a fourth variant) and three for Dream Pipeline (CLASS:DreamPipeline/dream-pipeline/CONCEPT:DreamPipeline) — duplicates minted under at least three id-conventions (CONCEPT:PascalCase, barekebab-case,CONCEPT:Title Case).The Problem
Every graduated consumer of #14472 anchors to concept ids. Over a fragmented spine, anchoring silently splits neighborhoods: retrieval walks reach a fraction of the real neighborhood, gap detection double-counts, measurement (consumer 4) attributes touches to different nodes for the same concept, and the sandman slice renders partial pictures. Fragmentation is plausibly the single largest reachability-gap class the epic will measure — and no defragmentation mechanism exists.
The Architectural Reality
ai/services/graph/SemanticGraphExtractor.mjs(session anchoring,TAGGED_CONCEPT@ 1.0 curated / 0.8 auto) andai/services/memory-core/MailboxService.mjs(message-side tagging). Neither canonicalizes ids at mint time.ai/services/memory-core/GraphService.mjs:73—PROTECTED_EDGE_TYPESexcludes concept edges (IMPLEMENTED_BY/PARENT_CONCEPTdecay by design, ADR 0024); any merge must preserve decaying-scent semantics, not inflate weights.The Fix
One PR delivering four pieces:
CONCEPT:prefix, case-fold, kebab-ize) → cluster report artifact underlearn/agentos/measurements/(cluster count, size distribution, top-N worst clusters, per-cluster neighborhood overlap/disjointness).delta-updates/golden-pathprecedent); decided IN the PR from the report data and stated in the module docblock.Contract Ledger Matrix
SemanticGraphExtractor/MailboxServicemint pathsDecision Record impact
aligned-with ADR 0024 (taxonomy + decay semantics respected; no new edge classes, no protection changes — those belong to the OQ1 anchoring leaf).
Acceptance Criteria
Resolvesthis leaf,Refs#14472Out of Scope
Avoided Traps
Sequencing
Consumes the #14474 measurements artifact for validation (soft gate: detection can build in parallel; the merge PR lands after the probe artifact exists).
Related: #14472 (parent epic), #14474 (probe — validation instrument), Discussion #14422 (graduation source; measured-reality items 2/4)
Origin Session ID: 8cf234b7-e698-47ca-99e2-bf865196b6aa
Retrieval Hint:
concept spine defrag alias cluster canonical id merge TAGGED_CONCEPT mint-time guard