---
number: 10048
title: >-
  feat: implement ConceptService for deterministic ontology graph traversal
  (#10032)
author: tobiu
state: MERGED
createdAt: '2026-04-17T13:08:55Z'
updatedAt: '2026-04-17T13:14:41Z'
closedAt: '2026-04-17T13:14:35Z'
mergedAt: '2026-04-17T13:14:35Z'
head: agent/10032-concept-service
base: dev
url: 'https://github.com/neomjs/neo/pull/10048'
---
## Summary

Implements the **ConceptService** — the runtime SDK interface for the Concept Ontology graph. This service loads the version-controlled JSONL concept graph from `.neo-ai-data/concepts/` and exposes deterministic query APIs for gap detection, coverage analysis, and LLM context priming.

This is the foundational service layer for replacing the GapInferenceEngine's fragile regex-based token matching with graph-traversal-based gap detection.

## Architectural Context

The ConceptService is placed in `ai/services/ConceptService.mjs` (not `ai/graph/` or `ai/daemons/services/`) to align with the emerging Services-Based OS architecture (Discussion #10040). The `ai/graph/` directory contains the custom graph DB internals (Database, Store, NodeModel); this service is a consumer of the ontology data, not a graph DB implementation.

### Design Decision: Decoupled from Native Edge Graph
The concept graph is stored as standalone JSONL files and loaded into a pure in-memory Map structure. This intentionally avoids coupling to the SQLite-backed Native Edge Graph, which is undergoing the Multi-Tenant Memory Core refactor (#9999).

## Changes

### `ai/services/ConceptService.mjs` [NEW]
Singleton service extending `Neo.core.Base` with 7 public APIs:
- **`loadGraph()`** — Parses `nodes.jsonl` + `edges.jsonl`, builds bidirectional edge indexes
- **`getConceptTree(maxTier)`** — Builds nested hierarchy from the tier-0 anchor
- **`getConceptCoverage(conceptId)`** — Returns EXPLAINED_BY, IMPLEMENTED_BY, EXEMPLIFIED_BY edges
- **`findGuideGaps(minWeight)`** — Deterministic gap detection sorted by weighted priority
- **`classifyConcept(classPath)`** — Reverse lookup: file path → concepts it implements
- **`serializeForLLM(maxTier)`** — Compact tree with Unicode connectors for context priming
- **`getSummary()`** — Diagnostics: coverage %, gap counts, severity breakdown

**Weight formula:** `tier_score + uniqueness_score + coverage_deficit`
- Tier: 0.8 (T1), 0.5 (T2), 0.3 (T3)
- Uniqueness: +0.2 if architecturally unique to Neo.mjs
- Coverage deficit: +0.3 if no EXPLAINED_BY edges

### `ai/services.mjs` [MODIFIED]
Registered ConceptService import and export in the SDK.

### `test/playwright/unit/ai/services/ConceptService.spec.mjs` [NEW]
16 Playwright unit tests covering:
- JSONL parsing (valid, malformed, duplicates)
- Guard clause (ensureLoaded throws before loadGraph)
- Coverage analysis (EXPLAINED_BY/IMPLEMENTED_BY counts)
- Gap detection (identification, weight sorting, threshold filtering)
- Weight calculation (tier + uniqueness + deficit formula)
- Reverse classification (file → concept lookup)
- Tree building (hierarchy, maxTier filtering)
- Tree serialization (connector chars, coverage markers)
- Summary statistics (coverage %, gap counts)
- Production graph validation (59 nodes, 169 edges, 0 errors)

## Validation
```
npm run test-unit -- test/playwright/unit/ai/services/ConceptService.spec.mjs
16 passed (586ms)
```

## Production Ontology Status
- **59 concepts**, **169 edges**, **0 parse errors**
- **71% documentation coverage** (17 guide gaps, 18 dead concepts)
- 5 CRITICAL gaps (tier 1 + unique + no guide): SharedWorker, VDOM IPC, Delta Updates, Pull-Based Reactivity, Zero-Build

Origin Session ID: c9bf0d61-a58d-42ba-a030-6426dc5fe270

Resolves #10032

## Comments

### `@tobiu` commented on 2026-04-17T13:09:18Z

**Input from Claude Opus 4.6 (Antigravity):**

> ✦ ## PR Review: ConceptService Implementation (#10032)
> 
> ### Evaluation Metrics
> 
> | Dimension | Score | Notes |
> |-----------|-------|-------|
> | **Architectural Alignment** | ✅ 9/10 | Service placed in `ai/services/` per #10040 vision. Decoupled from SQLite graph. |
> | **Content Completeness** | ✅ 9/10 | All 7 APIs implemented. Comprehensive JSDoc with @summary tags. |
> | **Test Coverage** | ✅ 10/10 | 16 specs covering happy paths, error cases, and production graph validation. |
> | **Semantic Anchoring** | ✅ 9/10 | @class, @summary, @param, @returns on all public methods. |
> 
> ### Architecture Notes
> 
> **Service Placement Decision:** The initial implementation was placed in `ai/graph/` (graph DB internals), then `ai/daemons/services/` (DreamPipeline phases). Final location `ai/services/` was chosen because ConceptService is a standalone SDK service, not a graph DB component or a daemon-specific phase. This aligns with the Hybrid Swarm Broker blueprint (Discussion #10040).
> 
> **Decoupled Storage:** The JSONL-backed in-memory Map approach intentionally avoids coupling to the Native Edge Graph's SQLite backend, which is undergoing the Multi-Tenant refactor (#9999). This makes the concept ontology portable and version-controllable via git.
> 
> **Weight Formula:** `tier_score + uniqueness_score + coverage_deficit` provides deterministic prioritization without LLM inference. The formula correctly identifies tier-1, unique-to-Neo concepts without guides as the highest priority gaps (weight 1.3).
> 
> ### Graph Ingestion Tags
> 
> - [KB_GAP] The `serializeForLLM` output should be indexed by the Knowledge Base to provide agents with instant ontology context priming.
> - [RETROSPECTIVE] The migration path (ai/graph → ai/daemons/services → ai/services) demonstrates the importance of the `ai/services/*` convention established in #10040. Future services should be placed here directly.
> - [TOOLING_GAP] The ConceptService currently loads JSONL synchronously via `fs.readFileSync`. For the Swarm Broker architecture (#10040), this should be migrated to async I/O when the service runs inside a Worker Thread.

---

