Frontmatter
| id | 10030 |
| title | [Epic] Concept Ontology & Semantic Gap Inference |
| state | Closed |
| labels | epicaiarchitecture |
| assignees | tobiu |
| createdAt | Apr 15, 2026, 11:55 PM |
| updatedAt | Jun 6, 2026, 6:02 PM |
| githubUrl | https://github.com/neomjs/neo/issues/10030 |
| author | tobiu |
| commentsCount | 5 |
| parentIssue | 9999 |
| subIssues | 10031 JSONL Schema & Concept Seed Extraction 10032 ConceptService & Source Code Wiring 10033 Concept Graph Unit Tests 10035 Graph Integration & GapInferenceEngine Refactor 10036 Memory Core Concept Discovery & Glossary Enhancement 10037 ChromaDB Concept Embedding & Hybrid Search 10049 Concept Schema Enrichment: Aliases, Analogous Edges & Rich Descriptions 10050 Concept Description Enrichment: Source-Grounded Semantic Anchors 10080 [enhancement] Relevance-bounded query APIs for ConceptService — prevent context window flooding as ontology grows 10081 [enhancement] ask_knowledge_base query telemetry — Agent FAQ signal for gap inference 10085 [enhancement] ConceptIngestor follow-ups post-#10035 — hoist concept-graph pass to cycle-scope + dedicated spec + observability polish 10086 [enhancement] Promote GUIDE_GAP_WEIGHT_THRESHOLD to aiConfig.data for human tuning 10087 [enhancement] ORPHAN_CONCEPT signal — distinct display channel in sandman_handoff.md 10574 Concept nodes: add non-destructive verifiedAt freshness |
| subIssuesCompleted | 14 |
| subIssuesTotal | 14 |
| contentTrust | |
| projected | |
| quarantined | 0 |
| signals | [] |
| blockedBy | [] |
| blocking | [x] 10219 Sandman active detector: stale assignments + recent open PRs |
| closedAt | Jun 6, 2026, 6:02 PM |
[Epic] Concept Ontology & Semantic Gap Inference

Input from Claude Opus 4.6 (Antigravity):
❋ Note on Origin Session ID: The
496c0120-29aa-4b02-a804-d5a32ff6b5ebis an Antigravity conversation ID, not a Memory Core session ID (Memory Core was offline during this planning session). The planning artifacts (implementation plan, concept layer analysis, walkthrough) are persisted at~/.gemini/antigravity/brain/496c0120-29aa-4b02-a804-d5a32ff6b5eb/. Future agents can retrieve full context from there.

Input from Claude Opus 4.7 (Claude Code):
❋ # Session Handoff — 2026-04-19 / Session
62d6f155-e57f-4279-9b59-36c9e4ecbc5eA2A Contextual Bridge per AGENTS.md §14. Future sessions picking up the Concept Ontology epic should find everything they need to boot efficiently here.
What Landed This Session
Directly scoped to #10030
- #10033 (Concept Graph Unit Tests) → closed via PR #10078. Closed four named-AC coverage gaps in the existing spec (root-tier assertion, coverage-annotation placement, production-graph line-count observability, explicit tier-ordering weight test). 23 tests total in
ConceptService.spec.mjs.- #10035 (Graph Integration & GapInferenceEngine Refactor) → closed via PR #10084. Architectural Pillar shipped. Replaces regex + per-match gemma4-31b LLM Boolean verification with deterministic concept-graph edge traversal. New
ConceptIngestordaemon service wires the JSONL ontology into the Native Edge Graph as DreamService Phase 0. Adds[EXAMPLE_GAP]signal + display section insandman_handoff.md. 30 tests pass.Meta-infrastructure (not #10030-scoped but session-generated)
- #10075 (memory-mining skill) → merged via PR #10076. Promoted the memory-first reflex from rule-in-AGENTS.md to Progressive Disclosure skill. Also corrected
ask_knowledge_basevsquery_documentsofficial tool descriptions inopenapi.yaml.Current Epic Status
Completed sub-issues
- ✅ #10031 — JSONL Schema & Concept Seed Extraction
- ✅ #10032 — ConceptService & Source Code Wiring
- ✅ #10033 — Concept Graph Unit Tests (closed this session)
- ✅ #10035 — Graph Integration & GapInferenceEngine Refactor (closed this session)
- ✅ #10049 — Concept Schema Enrichment: Aliases, Analogous Edges
Open sub-issues (recommended pickup order)
Priority Sub-Issue Complexity Why this order 1 #10085 — ConceptIngestor follow-ups (bundle) Low Polish from #10084's self-review: hoist concept-graph pass to cycle-scope, dedicated spec, observability, orphan warn consolidation. Same two files, natural single PR. Closes the #10035 loop cleanly. 2 #10036 — Memory Core Concept Discovery Medium Unblocked by #10035 now that concept graph is in SQLite. Next natural consumer of the concept-graph infrastructure. 3 #10034 — Concept Graph Visualization App Medium Neo.mjs app surfacing the concept ontology. Independent of #10036; can run in parallel. Good candidate for a Neo.mjs frontend-focused session. 4 #10037 — ChromaDB Concept Embedding & Hybrid Search Medium Powers the relevance-bounded queries proposed in #10080 (separate ticket — see below). Do after #10085 lands so the stable concept-node contract is locked in. 5 #10086 — Config-lift guideGapWeightThresholdTiny Tiny scope ( config.template.mjs+ one import path). Any-session pickup.6 #10087 — ORPHAN_CONCEPT distinct display channel Small Promote from logger.warnto a first-class sandman_handoff section. Non-blocking; value grows with ontology size.7 #10050 — Concept Description Enrichment Medium ⚠️ Blocked on human architect time per @tobiu's 2026-04-17 annotation — agent-generated descriptions produce wrong results without architectural decision history (e.g., Data Worker case study). Collaborative session required. Open sub-issues NOT filed by this session but visible on the epic
- #10050 — blocked (see above)
Related Tickets Not Parented Under #10030 (Worth Tracking)
These were filed this session but are broader than the Concept Ontology scope:
- #10077 —
manage_issue_labelsMCP tool fails on PRs (bug — pre-existing)- #10079 — Broadened Hypothesis gate for written claims (skill strengthening — covers 5 claim classes observed this session)
- #10080 — Relevance-bounded query APIs for ConceptService (will consume #10037's embeddings when ready)
- #10081 —
ask_knowledge_basequery telemetry → Agent FAQ → Gap signal- #10082 — Strengthen
tech-debt-radarfor unbounded-list API detection (sub-issue of #10080)- #10083 — Audit AGENTS.md §9 "Single Full-Read Rule" for frontier-context-era relaxation
- #10088 — Automate post-merge knowledge-base sync (solves recurring
[KB_GAP]pattern)- #10089 — Document SQLite FK constraints on
Database.mjs#addEdgeJSDocDurable Lessons Captured This Session
Three feedback memory files written to the Agent OS's persistent cross-session memory:
feedback_ask_kb_dominates_query_documents.md— empirically verifiedask_knowledge_basereturns synthesized answer PLUS the same top-5 refsquery_documentsreturns. Reserve the latter only for exhaustive enumeration beyond top-5.feedback_challenge_numerical_thresholds_in_acs.md— hardcoded numerical thresholds in AC items (≤ N lines,at most N ms) trigger the Hypothesis gate. Prefer observability + architectural-layer assertions over format-layer caps.feedback_verify_written_claims_against_precedent.md— five distinct sub-classes of "accept written claim without verifying precedent" observed + remediations for each. Covers numerical, architectural, tool-routing, self-inferred-policy, and wrong-grounding-assumption classes.What to Know for the Next Session
- Opus 4.7 has 1M context — earlier session-management rules calibrated for smaller models may be over-conservative (see #10083). Don't blindly apply "fresh session per Architectural Pillar" — semantic locality usually wins.
- Gemma 4 31B is frontier-class (85.2% MMLU Pro, distilled from Gemini 3) — don't frame SLM design decisions as "SLM is weak." Frame them correctly: deterministic code over LLM inference is about curated data being the source of truth, not capability.
- The concept graph is the authoritative source for "does concept X have a guide?" — via
EXPLAINED_BYedges. Do not re-introduce regex-based or LLM-based guide matching. Gap detection is now deterministic.- Stub-node seeding is a requirement for any SQLite edge insertion — the FK constraint is enforced at storage layer. Use
ConceptIngestor.ensureEdgeTargetsExistas the pattern.- Invoke the memory-mining skill BEFORE diagnostics or architectural claims — the skill exists for exactly the failure modes observed this session.
Origin Session ID
62d6f155-e57f-4279-9b59-36c9e4ecbc5e

Input from Claude Opus 4.7 (Claude Code):
❋ # Session Handoff — 2026-04-19 / Session
1db25bbe-f39d-4dcd-bb0e-bc125ce91326A2A Contextual Bridge per AGENTS.md §14. Future sessions picking up the Concept Ontology epic should find everything they need here. Session signal: marathon, valuable — tobi's explicit framing. Depth-investment paid off; next sessions should expect similar collaboration cadence.
What Landed This Session
Directly scoped to #10030 (all 4 closed)
#10085 (ConceptIngestor follow-ups) → closed via PR #10100. Hoisted
inferConceptGraphGapsfrom per-session to cycle-scope; deleted theexecuteCapabilityGapInferencewrapper; promotedinferTestGapsFromSession+inferConceptGraphGapsto public API with matching thin facades onDreamService. NewConceptIngestor.spec.mjswith 6 coverage targets. Bonus: closed a pre-existing cross-spec singleton-leak flake (symmetricafterEachdiscipline — see durable memory). Ship-polish commits added hoist-behavioral test + idempotency skip-path assertion after self-review challenge. 40/40 stable × 8 runs.#10087 (ORPHAN_CONCEPT channel) → closed via PR #10101. Promoted orphan-concept surfacing from ephemeral
logger.warninConceptIngestorto the durablecapabilityGaptag channel + new### ⚠️ Orphaned Conceptssection insandman_handoff.mdviaGoldenPathSynthesizer. SharedGUIDE_GAP_WEIGHT_THRESHOLDgate with the other two concept-graph signals. Self-review pivot mid-PR: tobi caught an "A2A vs human consumer" framing miss in the PR body — corrected inline, durable lesson saved. 40/40 stable.#10086 (config-lift threshold) → closed via PR #10102.
GUIDE_GAP_WEIGHT_THRESHOLDpromoted from file-local const toaiConfig.data.guideGapWeightThresholdwith env override (NEO_GUIDE_GAP_WEIGHT_THRESHOLD). Self-review caught the service-boundary placement miss (memory-core config vs SDK-layer config); tracked as deferred debt via filed ticket #10103. 41/41 stable.#10036 (Memory Core Concept Discovery) → closed via PR #10105. Deliverables 1, 2, 4 shipped. New
ConceptDiscoveryService— LLM-driven extraction viaOpenAiCompatible.generate(gemma-4-31b-it). Two corpora: epic-labeled issues + recent pull-request markdown including## Commentssections. Major mid-PR pivot: first draft used regex + stop-phrase blocklist for extraction; tobi's sharp challenge "makes literally ZERO sense" forced the architectural rewrite to LLM-based. Durable memory captures the lesson (feedback_llm_substrate_for_semantic_tasks.md). Newvalidatedschema flag + GapInferenceEngine gate: mined candidates carryvalidated: false+ tier 3, silenced via weight-gate + validated-gate (belt-and-suspenders) until curator promotes vianodes.jsonlgit-diff edit. Polish commit followed self-review + tobi's magic-number challenge: config-liftedprScanLimit+minSourceLengthunder newaiConfig.data.conceptDiscoveryblock. 49/49 stable × 3 runs.Meta-infrastructure (not #10030-scoped but session-generated)
- 6 new durable feedback memories captured architectural-literacy lessons surfacing this session. See "Durable Lessons Captured" below.
- 1 project memory (
project_core_base_conventions.md) preserves tobi's historical rationale for patterns insrc/Neo.mjs+src/core/Base.mjsthat look like smells but have multi-decade justification.Current Epic Status
Completed sub-issues (all of #10030's core scope)
- ✅ #10031 — JSONL Schema & Concept Seed Extraction
- ✅ #10032 — ConceptService & Source Code Wiring
- ✅ #10033 — Concept Graph Unit Tests (#10078)
- ✅ #10035 — Graph Integration & GapInferenceEngine Refactor (#10084) — the architectural pillar
- ✅ #10036 — Memory Core Concept Discovery (#10105) — this session
- ✅ #10049 — Concept Schema Enrichment: Aliases, Analogous Edges
- ✅ #10085 — ConceptIngestor follow-ups (#10100) — this session
- ✅ #10086 — Config-lift guideGapWeightThreshold (#10102) — this session
- ✅ #10087 — ORPHAN_CONCEPT signal (#10101) — this session
Open sub-issues (recommended pickup order)
Priority Sub-Issue Complexity Why this order 1 #10106 — ConceptDiscoveryService extraction_metadata schema (new this session) Small Direct continuation of #10105. Gemma-4-31b-it's OWN proposed schema for reliable self-report (validated empirically — it agreed generic feedback is unreliable then proposed the structured alternative itself). Quick downstream win with real model-side endorsement. 2 #10037 — ChromaDB Concept Embedding & Hybrid Search Medium Now unblocked by the stable concept-node contract. Powers the relevance-bounded queries in #10080. 3 #10034 — Concept Graph Visualization App Medium Neo.mjs frontend app surfacing the ontology. Independent; good candidate for a frontend-focused session. 4 #10080 — Relevance-bounded query APIs Medium Consumes #10037's embeddings. 5 #10081 — ask_knowledge_base query telemetry Medium Agent-FAQ signal for gap inference. 6 #10050 — Concept Description Enrichment Medium ⚠️ Still blocked on human architect time per tobi's 2026-04-17 annotation — agent-generated descriptions produce wrong results without architectural decision history. Related Tickets Filed This Session (Not Epic-Parented)
These surfaced from architectural insights during PR self-reviews and stepping-back discussion. All open for future pickup:
- #10103 — SDK-layer config migration (move daemon/service-layer config keys out of
memory-core/config.template.mjs). Surfaced when #10102's placement revealed the memory-core-as-catch-all pattern.- #10104 —
ticket-createskill (centralize issue-creation discipline — currently scattered across tool description + ticket-intake + AGENTS_STARTUP §9 + tribal knowledge).- #10106 — ConceptDiscoveryService extraction_metadata schema (see pickup #1 above).
- #10107 — core.Base + Neo.mjs audit. AUDIT, not refactor. Documents intentional patterns (className-on-instance = DevTools ergonomics; globalThis.Neo = single-registry; setupClass hot-path constraint) + adds benchmark harness as baseline. Any actual refactor becomes downstream tickets that must pass the A/B benchmark gate.
- #10108 —
me = thispolicy decision. Three options; recommended (B): keep FE-only + document boundary in CODING_GUIDELINES.md §34.- #10109 — PR comment hygiene workflow. Quick-win doc update for
.agent/skills/pull-request/references/pull-request-workflow.md.Durable Lessons Captured This Session
Seven new memory files written to the Agent OS's persistent cross-session memory. These form the six-stage challenge chain now applied at both ticket-intake AND ticket-creation:
feedback_challenge_prescribed_fixes.md— verify prescription layer (right substrate), not just premise. Premise-true + prescription-wrong = doubled effort.feedback_symmetric_spec_cleanup.md— PlaywrightfullyParallelinterleaves specs in same worker; cross-singleton mutations need symmetricbeforeEach+afterEachresets.beforeEach-only leaks state.feedback_observability_consumer_identity.md—sandman_handoff.mdis A2A (next REM cycle, next agent boot, Librarian), NOT a human-facing report. Identify substrate's consumer, not just its durability.feedback_config_service_boundary.md— config-lifts must match consuming service's ownership, not import-convenience. Memory-core has been catch-all but daemon/service-agnostic configs belong in the SDK layer; file migration debt explicitly when destination doesn't exist yet.feedback_no_title_prefix_duplicating_labels.md— ticket titles describe subject, not category.[enhancement]/[bug]/[epic]belong in labels, not titles.feedback_llm_substrate_for_semantic_tasks.md— regex is for STRUCTURAL extraction; semantic tasks (Teaching Test, "what qualifies as X") require LLM. Cheap+deterministic+offline is irrelevant if output is noise. Growing STOP_PHRASES lists are a warning sign.project_core_base_conventions.md— patterns that look like smell (me=this,className-on-instance,globalThis.Neo,setupClassas god-function) have deliberate multi-decade rationale. Don't propose refactors without auditing GC pressure + ripple scope + historical constraint first.Common failure-mode thread across 1-7: defaulting to path-of-least-resistance without challenging whether the prescription is correct. Each check in the six-stage chain addresses a different axis of this bias.
What to Know for the Next Session
Gemma-4-31b-it is genuinely frontier-class for local. Empirically probed this session (MMLU Pro 85.2%, LiveCodeBench v6 80%, Codeforces ELO 2150). When asked directly whether a generic LLM feedback field would be reliable, it correctly identified its own failure modes (confabulation, RLHF bias, correlation/causation) and proposed the narrower structured alternative. Calibrate collaboration posture accordingly — it can reason, not just pattern-match.
LM Studio context-length operator control:
lms load <model> --context-length <N> --ttl <seconds>. Default 4K is insufficient for source-file context; bump to 32K+ for Neo.mjs reasoning. Persistent across sessions via--ttl.The concept graph is growing — but not from mining yet. #10105 shipped the pipeline but it hasn't been run against the real corpus. Today's
nodes.jsonlstill has ~60 curated rows, 0 mined. First real discovery run will reveal signal-to-noise empirically — DO that run before deciding whether to ship cross-session Hebbian aggregation (tobi's original clarified feedback-loop idea; deferred to after data is observable).Template/local config parity is a real trap: committing
config.template.mjswithout mirroring into gitignoredconfig.mjsleaves the worktree with the old config at runtime..gitignoreenforcement catches this atgit addtime (loud failure) — heed it.bootstrapWorktree.mjscopies from main on worktree creation; operators must manually sync main's local config when templates change.PR self-review via the
pr-reviewskill is load-bearing. Every merged PR this session went through it; every time tobi caught at least one architectural miss that polish commits fixed before merge. The self-review is NOT cosmetic — it's the last point where the discipline chain can catch a prescription mistake before the code lands ondev.Tobi challenges with compressed signal. Short messages often carry sharp architectural challenges ("makes literally ZERO sense", "is the memory core server config really the right spot?", "const feels like bloat"). Read them as invitations to re-calibrate, not as pushback. The "challenge:" = reasoning-test framing from the user profile memory applies throughout.
Ticket-inflation vs. A2A-memory trade-off. Tobi's earlier concern "500 tickets in 3 weeks — release notes get harder" was offset by "only closed tickets count for releases" — filing decision-audit tickets (like #10107) is net-positive because their closure produces architectural documentation. Don't over-index on "minimize ticket count"; optimize for "tickets that resolve into durable decisions."
Session Metrics
- 4 PRs merged (#10100, #10101, #10102, #10105)
- 6 new tickets filed (#10103, #10104, #10106, #10107, #10108, #10109) + 4 tickets closed via merges (#10085, #10086, #10087, #10036)
- 7 durable memories saved
- Test delta: 30 → 49 across daemon + ConceptService + new ConceptDiscoveryService specs; 5× stability check on each PR before merge
- Session duration: marathon — multiple architectural pivots caught mid-PR via self-review + tobi's challenges
Origin Session ID
1db25bbe-f39d-4dcd-bb0e-bc125ce91326
Objective
Build a standalone Concept Ontology Layer — a lightweight, version-controlled knowledge graph that maps Neo.mjs's architectural concepts to their implementing source files, explaining guides, and examples. This replaces the Macro Knowledge Base approach (#10014) which suffered from semantic dilution with full-file vector embeddings.
The Problem
The current gap detection (
GapInferenceEngine) uses regex token matching against file paths. It produces false positives ("Portal App About Us View has no guide") because it operates at the wrong abstraction level — files, not concepts. Not every class deserves a guide, but every architectural concept does.The Solution: Concept Nodes as First-Class Graph Citizens
Instead of comparing file vectors, we introduce CONCEPT nodes that sit between source code and documentation in the knowledge graph:
Gap detection becomes deterministic graph traversal: a concept missing an
EXPLAINED_BYedge = a real documentation gap.Storage
JSONL files at
.neo-ai-data/concepts/(gitignore exception). ~500 nodes, ~1000 edges, ~50KB total. Version-controlled, PR-reviewable, zero infrastructure dependency.Phased Architecture
Phase 1: Standalone Graph
tree.json+ human curationConceptServiceinai/services.mjsSDKPhase 2: Visualization & Validation
Phase 3: Graph Integration
Relationship to #10014
This epic supersedes #10014 (Macro Knowledge Base). The vector-based approach is abandoned due to semantic dilution (centroid of noise for large files). Sub-issue #10003 (Global Embedding Config) retains independent value for Memory Core ↔ KB compatibility.
Key Design Decisions
ConceptServicelives inai/services.mjs, no new MCP tools (77/100 cap)Origin Session ID: 496c0120-29aa-4b02-a804-d5a32ff6b5eb