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

## 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:

```
CONCEPT --IMPLEMENTED_BY--> CLASS (e.g., "Config System" → Neo.core.Config)
CONCEPT --EXPLAINED_BY-->  GUIDE (e.g., "Config System" → ConfigSystem.md)  
CONCEPT --PARENT_CONCEPT--> CONCEPT (e.g., "Reactivity" → "Push-Based Reactivity")
CONCEPT --EXEMPLIFIED_BY--> FILE (e.g., "Config System" → examples/...)
CONCEPT --REQUIRES--> CONCEPT (e.g., "Effects" → "Reactive Configs")
```

Gap detection becomes deterministic graph traversal: a concept missing an `EXPLAINED_BY` edge = 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
- Define JSONL schema, seed from `tree.json` + human curation
- Build `ConceptService` in `ai/services.mjs` SDK
- Playwright unit tests for graph queries and traversal

### Phase 2: Visualization & Validation
- Neo.mjs app or example to visualize the concept graph
- Interactive: click concept → see implementing classes, explaining guides, and gaps
- Serialized concept tree doubles as LLM context primer (~50 lines for full Tier 1-2 map)

### Phase 3: Graph Integration
- Ingest concept JSONL into the real Native Edge Graph via DreamService
- Refactor GapInferenceEngine to use concept traversal instead of regex matching
- Connect to Memory Core for concept discovery from session summaries and tickets

## 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
- **The Teaching Test**: A concept exists if a developer needs to understand it to USE Neo.mjs, AND it can't be learned from one API doc page alone
- **No JSDoc hashtags**: The graph is the source of truth, not distributed annotations in source
- **Glossary is downstream**: Benefits from the concept graph but is not a source for it
- **SDK-first, not MCP**: `ConceptService` lives in `ai/services.mjs`, no new MCP tools (77/100 cap)
- **Decoupled from #9999**: Runs in parallel with Multi-Tenant Memory Core

Origin Session ID: 496c0120-29aa-4b02-a804-d5a32ff6b5eb

## Timeline

- 2026-04-15T21:55:24Z @tobiu added the `epic` label
- 2026-04-15T21:55:24Z @tobiu added the `ai` label
- 2026-04-15T21:55:25Z @tobiu added the `architecture` label
- 2026-04-15T21:56:35Z @tobiu cross-referenced by #10031
- 2026-04-15T21:56:55Z @tobiu cross-referenced by #10032
- 2026-04-15T21:57:09Z @tobiu cross-referenced by #10033
- 2026-04-15T21:57:28Z @tobiu cross-referenced by #10034
- 2026-04-15T21:57:46Z @tobiu cross-referenced by #10035
- 2026-04-15T21:58:06Z @tobiu cross-referenced by #10036
- 2026-04-15T21:58:13Z @tobiu added sub-issue #10031
- 2026-04-15T21:58:15Z @tobiu added sub-issue #10032
- 2026-04-15T21:58:17Z @tobiu added sub-issue #10033
- 2026-04-15T21:58:19Z @tobiu added sub-issue #10034
- 2026-04-15T21:58:21Z @tobiu added sub-issue #10035
- 2026-04-15T21:58:23Z @tobiu added sub-issue #10036
### @tobiu - 2026-04-15T22:02:25Z

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

> ❋ **Note on Origin Session ID**: The `496c0120-29aa-4b02-a804-d5a32ff6b5eb` is 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.

- 2026-04-15T22:12:31Z @tobiu cross-referenced by #10037
- 2026-04-15T22:12:38Z @tobiu added sub-issue #10037
- 2026-04-16T18:44:35Z @tobiu cross-referenced by #10014
- 2026-04-16T18:44:37Z @tobiu cross-referenced by #10002
- 2026-04-16T18:44:39Z @tobiu cross-referenced by #10004
- 2026-04-16T18:44:41Z @tobiu cross-referenced by #10006
- 2026-04-16T18:44:43Z @tobiu cross-referenced by #10012
- 2026-04-16T18:44:50Z @tobiu cross-referenced by #10003
- 2026-04-16T18:44:51Z @tobiu cross-referenced by #9999
- 2026-04-16T18:44:53Z @tobiu added parent issue #9999
- 2026-04-17T07:38:14Z @tobiu cross-referenced by PR #10047
- 2026-04-17T08:22:29Z @tobiu assigned to @tobiu
- 2026-04-17T13:39:53Z @tobiu added sub-issue #10049
- 2026-04-17T13:44:43Z @tobiu added sub-issue #10050
- 2026-04-17T14:30:24Z @tobiu cross-referenced by PR #10052
- 2026-04-18T14:22:18Z @tobiu cross-referenced by #10061
- 2026-04-18T14:38:10Z @tobiu cross-referenced by PR #10062
- 2026-04-18T14:57:24Z @tobiu cross-referenced by #10063
- 2026-04-18T18:11:52Z @tobiu cross-referenced by #10057
- 2026-04-18T18:15:34Z @tobiu cross-referenced by PR #10066
- 2026-04-18T23:01:05Z @tobiu cross-referenced by #10074
- 2026-04-19T08:12:18Z @tobiu cross-referenced by #10077
- 2026-04-19T08:28:02Z @tobiu cross-referenced by PR #10078
- 2026-04-19T08:43:44Z @tobiu cross-referenced by #10079
- 2026-04-19T09:16:31Z @tobiu cross-referenced by #10080
- 2026-04-19T09:16:43Z @tobiu cross-referenced by #10081
- 2026-04-19T09:17:24Z @tobiu added sub-issue #10080
- 2026-04-19T09:17:25Z @tobiu added sub-issue #10081
- 2026-04-19T10:20:30Z @tobiu cross-referenced by PR #10084
- 2026-04-19T10:31:22Z @tobiu cross-referenced by #10085
- 2026-04-19T10:31:35Z @tobiu cross-referenced by #10086
- 2026-04-19T10:31:51Z @tobiu cross-referenced by #10087
- 2026-04-19T10:32:07Z @tobiu cross-referenced by #10088
- 2026-04-19T10:32:31Z @tobiu added sub-issue #10085
- 2026-04-19T10:32:32Z @tobiu added sub-issue #10086
- 2026-04-19T10:32:35Z @tobiu added sub-issue #10087
### @tobiu - 2026-04-19T10:33:35Z

**Input from Claude Opus 4.7 (Claude Code):**

> ❋ # Session Handoff — 2026-04-19 / Session `62d6f155-e57f-4279-9b59-36c9e4ecbc5e`
> 
> A2A 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](https://github.com/neomjs/neo/pull/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](https://github.com/neomjs/neo/pull/10084). **Architectural Pillar shipped.** Replaces regex + per-match gemma4-31b LLM Boolean verification with deterministic concept-graph edge traversal. New `ConceptIngestor` daemon service wires the JSONL ontology into the Native Edge Graph as DreamService Phase 0. Adds `[EXAMPLE_GAP]` signal + display section in `sandman_handoff.md`. 30 tests pass.
> 
> ### Meta-infrastructure (not #10030-scoped but session-generated)
> 
> - **#10075** (memory-mining skill) → merged via PR [#10076](https://github.com/neomjs/neo/pull/10076). Promoted the memory-first reflex from rule-in-AGENTS.md to Progressive Disclosure skill. Also corrected `ask_knowledge_base` vs `query_documents` official tool descriptions in `openapi.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 `guideGapWeightThreshold` | Tiny | Tiny scope (`config.template.mjs` + one import path). Any-session pickup. |
> | **6** | **#10087** — ORPHAN_CONCEPT distinct display channel | Small | Promote from `logger.warn` to 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_labels` MCP 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_base` query telemetry → Agent FAQ → Gap signal
> - **#10082** — Strengthen `tech-debt-radar` for 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#addEdge` JSDoc
> 
> ## Durable 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 verified `ask_knowledge_base` returns synthesized answer PLUS the same top-5 refs `query_documents` returns. 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
> 
> 1. **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.
> 2. **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.
> 3. **The concept graph is the authoritative source for "does concept X have a guide?"** — via `EXPLAINED_BY` edges. Do not re-introduce regex-based or LLM-based guide matching. Gap detection is now deterministic.
> 4. **Stub-node seeding is a requirement for any SQLite edge insertion** — the FK constraint is enforced at storage layer. Use `ConceptIngestor.ensureEdgeTargetsExist` as the pattern.
> 5. **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`
> 

- 2026-04-19T11:09:50Z @tobiu cross-referenced by #10090
- 2026-04-19T11:34:22Z @tobiu referenced in commit `a32c0af` - "fix(github-workflow): paginate timelineItems to prevent silent content drop (#10090)

The IssueSyncer rendered comment bodies through the unified timelineItems
GraphQL channel, which was page-capped at maxTimelineItemsPerIssue (50) with
no continuation logic. Once an issue's timeline grew past the cap, tail
events including newly-authored comments were silently dropped from the
local markdown while scalar frontmatter metadata (commentsCount, updatedAt)
stayed correct — a divergence between metadata tracking and content
rendering that gave a false appearance of successful sync.

Changes:
- issueQueries: add pageInfo on timelineItems in both FETCH queries and
  introduce FETCH_ISSUE_TIMELINE_PAGE for continuation fetches.
- IssueSyncer: add #exhaustTimelineItems pagination primitive with a warn
  log on continuation; extract the related-issues force-update loop into
  a reusable refetchIssuesByNumber(numbers, metadata) method that both
  pullFromGitHub and external tooling share.
- SyncService: expose refetchIssuesByNumber({numbers}) as the SDK entry
  for surgical recovery bypassing delta-sync updatedAt gating.
- ai/scripts/detectTruncatedTimelines.mjs: diagnostic that flags files
  whose rendered comment blocks fall short of frontmatter commentsCount
  or whose timeline sits exactly at the cap.
- ai/scripts/refetchTruncatedIssues.mjs: thin recovery wrapper that
  consumes the detector output (list or --stdin JSON) and delegates to
  the SyncService endpoint.
- IssueSyncer.spec: Playwright regression covering a 75-event mocked
  issue that forces one continuation page and asserts every comment and
  structural event lands in the rendered markdown.

Recovery artifacts in this commit: issues #10030, #9486, #9999, #9535 —
the four issues flagged as drifted by the detector baseline run — were
healed via the new refetch endpoint and now reflect live GitHub state."
- 2026-04-19T11:35:15Z @tobiu cross-referenced by PR #10091
- 2026-04-19T11:41:29Z @tobiu referenced in commit `3ec8167` - "fix(github-workflow): paginate timelineItems to prevent silent content drop (#10090) (#10091)

The IssueSyncer rendered comment bodies through the unified timelineItems
GraphQL channel, which was page-capped at maxTimelineItemsPerIssue (50) with
no continuation logic. Once an issue's timeline grew past the cap, tail
events including newly-authored comments were silently dropped from the
local markdown while scalar frontmatter metadata (commentsCount, updatedAt)
stayed correct — a divergence between metadata tracking and content
rendering that gave a false appearance of successful sync.

Changes:
- issueQueries: add pageInfo on timelineItems in both FETCH queries and
  introduce FETCH_ISSUE_TIMELINE_PAGE for continuation fetches.
- IssueSyncer: add #exhaustTimelineItems pagination primitive with a warn
  log on continuation; extract the related-issues force-update loop into
  a reusable refetchIssuesByNumber(numbers, metadata) method that both
  pullFromGitHub and external tooling share.
- SyncService: expose refetchIssuesByNumber({numbers}) as the SDK entry
  for surgical recovery bypassing delta-sync updatedAt gating.
- ai/scripts/detectTruncatedTimelines.mjs: diagnostic that flags files
  whose rendered comment blocks fall short of frontmatter commentsCount
  or whose timeline sits exactly at the cap.
- ai/scripts/refetchTruncatedIssues.mjs: thin recovery wrapper that
  consumes the detector output (list or --stdin JSON) and delegates to
  the SyncService endpoint.
- IssueSyncer.spec: Playwright regression covering a 75-event mocked
  issue that forces one continuation page and asserts every comment and
  structural event lands in the rendered markdown.

Recovery artifacts in this commit: issues #10030, #9486, #9999, #9535 —
the four issues flagged as drifted by the detector baseline run — were
healed via the new refetch endpoint and now reflect live GitHub state."
- 2026-04-19T12:01:12Z @tobiu cross-referenced by PR #10093
- 2026-04-19T13:10:27Z @tobiu cross-referenced by PR #10099
- 2026-04-19T14:17:12Z @tobiu cross-referenced by PR #10100
- 2026-04-19T14:59:29Z @tobiu cross-referenced by PR #10101
- 2026-04-19T15:19:01Z @tobiu referenced in commit `db5bdae` - "feat(ai): config-lift guideGapWeightThreshold to aiConfig.data (#10086)

Promotes the previously file-local `GUIDE_GAP_WEIGHT_THRESHOLD = 0.8` constant
in `GapInferenceEngine` to `aiConfig.data.guideGapWeightThreshold`, making the
weight gate curator-tunable without a code change. Default value preserved
(`0.8`); the derivation comment moves from the const JSDoc to the config
template next to the value itself, where tuners will see it.

## Scope

- `ai/mcp/server/memory-core/config.template.mjs`: adds `guideGapWeightThreshold:
  Number(process.env.NEO_GUIDE_GAP_WEIGHT_THRESHOLD) || 0.8` after `decayFactor`
  (both graph-pipeline behavior floats — semantic grouping). JSDoc carries the
  full derivation from ConceptService.calculateWeight plus the post-#10087
  context (threshold now gates three signals, not just GUIDE_GAP — historical
  prefix retained per ticket AC).
- `ai/daemons/services/GapInferenceEngine.mjs`: removes the file-local const,
  imports `Memory_Config as aiConfig` via the services SDK, caches the
  threshold once per cycle at the top of `inferConceptGraphGaps` so the live
  config value is consulted (tests can mutate it; module-load capture would
  miss runtime overrides). Class + method JSDoc updated to reference the
  config path and explain the historical `guideGap*` prefix (introduced in
  #10035 for GUIDE_GAP alone; widened in #10087 to gate all three concept-
  graph signals — rename considered but scoped out to keep this PR tight).

**Parity note:** the gitignored local `config.mjs` must mirror the template
addition for tests to pick up the key. Updated locally in this worktree but
not committed (by design — the template is the source of truth for the
shipped repo; each checkout's `config.mjs` is derived manually or via
`bootstrapWorktree.mjs` on worktree creation).

## Tests (41/41 stable × 5 runs)

New test `threshold override via aiConfig.data.guideGapWeightThreshold
changes emission behavior (#10086)`:
- Plants a tier-2 concept with weight 0.5 (below default 0.8 threshold).
- Overrides `aiConfig.data.guideGapWeightThreshold = 0.3` inside try/finally.
- Asserts the concept now emits both `[GUIDE_GAP]` and `[ORPHAN_CONCEPT]`,
  proving the config is read at gate time (not captured at module load).
- Restores the original value in `finally`.

The existing "skip low-weight concepts" test (weight 0.3 with default 0.8)
remains and now acts as the counterpart — default config path.

## AC checklist

- [x] `aiConfig.data.guideGapWeightThreshold` exists in `config.template.mjs`
      with default 0.8 + derivation comment (moved from GapInferenceEngine)
- [x] `GapInferenceEngine` reads the value from config, not from a file-local
      constant — verified via runtime-override test
- [x] Existing tests pass (40 → 41 total, all green × 5 consecutive runs)
- [x] New test proves threshold override via config produces different
      gap-emission behavior

## Related

- Parent epic: #10030
- Origin PR: #10084 (introduced the const)
- Preceded by: #10100 (scope hoist), #10101 (ORPHAN_CONCEPT — now also gated
  by this threshold, so config-lift value compounded)
- Weight formula precedent: `ConceptService.calculateWeight` (tier + uniqueness + coverage_deficit)

Resolves #10086

Origin Session ID: 1db25bbe-f39d-4dcd-bb0e-bc125ce91326"
- 2026-04-19T15:20:04Z @tobiu cross-referenced by PR #10102
- 2026-04-19T15:31:57Z @tobiu cross-referenced by #10103
- 2026-04-19T15:33:22Z @tobiu referenced in commit `45b6f63` - "feat(ai): config-lift guideGapWeightThreshold to aiConfig.data (#10086) (#10102)

Promotes the previously file-local `GUIDE_GAP_WEIGHT_THRESHOLD = 0.8` constant
in `GapInferenceEngine` to `aiConfig.data.guideGapWeightThreshold`, making the
weight gate curator-tunable without a code change. Default value preserved
(`0.8`); the derivation comment moves from the const JSDoc to the config
template next to the value itself, where tuners will see it.

## Scope

- `ai/mcp/server/memory-core/config.template.mjs`: adds `guideGapWeightThreshold:
  Number(process.env.NEO_GUIDE_GAP_WEIGHT_THRESHOLD) || 0.8` after `decayFactor`
  (both graph-pipeline behavior floats — semantic grouping). JSDoc carries the
  full derivation from ConceptService.calculateWeight plus the post-#10087
  context (threshold now gates three signals, not just GUIDE_GAP — historical
  prefix retained per ticket AC).
- `ai/daemons/services/GapInferenceEngine.mjs`: removes the file-local const,
  imports `Memory_Config as aiConfig` via the services SDK, caches the
  threshold once per cycle at the top of `inferConceptGraphGaps` so the live
  config value is consulted (tests can mutate it; module-load capture would
  miss runtime overrides). Class + method JSDoc updated to reference the
  config path and explain the historical `guideGap*` prefix (introduced in
  #10035 for GUIDE_GAP alone; widened in #10087 to gate all three concept-
  graph signals — rename considered but scoped out to keep this PR tight).

**Parity note:** the gitignored local `config.mjs` must mirror the template
addition for tests to pick up the key. Updated locally in this worktree but
not committed (by design — the template is the source of truth for the
shipped repo; each checkout's `config.mjs` is derived manually or via
`bootstrapWorktree.mjs` on worktree creation).

## Tests (41/41 stable × 5 runs)

New test `threshold override via aiConfig.data.guideGapWeightThreshold
changes emission behavior (#10086)`:
- Plants a tier-2 concept with weight 0.5 (below default 0.8 threshold).
- Overrides `aiConfig.data.guideGapWeightThreshold = 0.3` inside try/finally.
- Asserts the concept now emits both `[GUIDE_GAP]` and `[ORPHAN_CONCEPT]`,
  proving the config is read at gate time (not captured at module load).
- Restores the original value in `finally`.

The existing "skip low-weight concepts" test (weight 0.3 with default 0.8)
remains and now acts as the counterpart — default config path.

## AC checklist

- [x] `aiConfig.data.guideGapWeightThreshold` exists in `config.template.mjs`
      with default 0.8 + derivation comment (moved from GapInferenceEngine)
- [x] `GapInferenceEngine` reads the value from config, not from a file-local
      constant — verified via runtime-override test
- [x] Existing tests pass (40 → 41 total, all green × 5 consecutive runs)
- [x] New test proves threshold override via config produces different
      gap-emission behavior

## Related

- Parent epic: #10030
- Origin PR: #10084 (introduced the const)
- Preceded by: #10100 (scope hoist), #10101 (ORPHAN_CONCEPT — now also gated
  by this threshold, so config-lift value compounded)
- Weight formula precedent: `ConceptService.calculateWeight` (tier + uniqueness + coverage_deficit)

Resolves #10086

Origin Session ID: 1db25bbe-f39d-4dcd-bb0e-bc125ce91326"
- 2026-04-19T16:05:15Z @tobiu cross-referenced by PR #10105
### @tobiu - 2026-04-19T17:52:59Z

**Input from Claude Opus 4.7 (Claude Code):**

> ❋ # Session Handoff — 2026-04-19 / Session `1db25bbe-f39d-4dcd-bb0e-bc125ce91326`
> 
> A2A 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](https://github.com/neomjs/neo/pull/10100). Hoisted `inferConceptGraphGaps` from per-session to cycle-scope; deleted the `executeCapabilityGapInference` wrapper; promoted `inferTestGapsFromSession` + `inferConceptGraphGaps` to public API with matching thin facades on `DreamService`. New `ConceptIngestor.spec.mjs` with 6 coverage targets. **Bonus: closed a pre-existing cross-spec singleton-leak flake** (symmetric `afterEach` discipline — 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](https://github.com/neomjs/neo/pull/10101). Promoted orphan-concept surfacing from ephemeral `logger.warn` in `ConceptIngestor` to the durable `capabilityGap` tag channel + new `### ⚠️ Orphaned Concepts` section in `sandman_handoff.md` via `GoldenPathSynthesizer`. Shared `GUIDE_GAP_WEIGHT_THRESHOLD` gate 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](https://github.com/neomjs/neo/pull/10102). `GUIDE_GAP_WEIGHT_THRESHOLD` promoted from file-local const to `aiConfig.data.guideGapWeightThreshold` with 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](https://github.com/neomjs/neo/pull/10105). Deliverables 1, 2, 4 shipped. New `ConceptDiscoveryService` — LLM-driven extraction via `OpenAiCompatible.generate` (gemma-4-31b-it). Two corpora: epic-labeled issues + recent pull-request markdown including `## Comments` sections. 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`). New `validated` schema flag + GapInferenceEngine gate: mined candidates carry `validated: false` + tier 3, silenced via weight-gate + validated-gate (belt-and-suspenders) until curator promotes via `nodes.jsonl` git-diff edit. Polish commit followed self-review + tobi's magic-number challenge: config-lifted `prScanLimit` + `minSourceLength` under new `aiConfig.data.conceptDiscovery` block. 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 in `src/Neo.mjs` + `src/core/Base.mjs` that 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-create` skill (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 = this` policy 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:
> 
> 1. **`feedback_challenge_prescribed_fixes.md`** — verify prescription layer (right substrate), not just premise. Premise-true + prescription-wrong = doubled effort.
> 2. **`feedback_symmetric_spec_cleanup.md`** — Playwright `fullyParallel` interleaves specs in same worker; cross-singleton mutations need **symmetric** `beforeEach`+`afterEach` resets. `beforeEach`-only leaks state.
> 3. **`feedback_observability_consumer_identity.md`** — `sandman_handoff.md` is A2A (next REM cycle, next agent boot, Librarian), NOT a human-facing report. Identify substrate's consumer, not just its durability.
> 4. **`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.
> 5. **`feedback_no_title_prefix_duplicating_labels.md`** — ticket titles describe subject, not category. `[enhancement]`/`[bug]`/`[epic]` belong in labels, not titles.
> 6. **`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.
> 7. **`project_core_base_conventions.md`** — patterns that look like smell (`me=this`, `className`-on-instance, `globalThis.Neo`, `setupClass` as 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
> 
> 1. **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.
> 
> 2. **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`.
> 
> 3. **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.jsonl` still 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).
> 
> 4. **Template/local config parity is a real trap**: committing `config.template.mjs` without mirroring into gitignored `config.mjs` leaves the worktree with the old config at runtime. `.gitignore` enforcement catches this at `git add` time (loud failure) — heed it. `bootstrapWorktree.mjs` copies from main on worktree creation; operators must manually sync main's local config when templates change.
> 
> 5. **PR self-review via the `pr-review` skill 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 on `dev`.
> 
> 6. **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.
> 
> 7. **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`

- 2026-04-20T02:07:08Z @tobiu cross-referenced by #10120
- 2026-04-20T10:40:37Z @tobiu cross-referenced by PR #10121
- 2026-04-20T11:13:56Z @tobiu cross-referenced by #9748
- 2026-04-20T11:19:03Z @tobiu cross-referenced by PR #10122
- 2026-04-20T15:20:11Z @tobiu cross-referenced by #10129
- 2026-04-20T18:26:55Z @tobiu cross-referenced by PR #10131
- 2026-04-20T20:45:16Z @tobiu cross-referenced by #10136
- 2026-04-21T09:27:58Z @tobiu cross-referenced by #10139
- 2026-04-21T09:28:52Z @tobiu cross-referenced by #10143
- 2026-04-21T09:29:39Z @tobiu cross-referenced by #10147
- 2026-04-21T11:17:25Z @tobiu cross-referenced by #10154
- 2026-04-21T13:23:14Z @tobiu cross-referenced by #10158
- 2026-04-22T21:56:53Z @neo-opus-ada marked this issue as blocking #10219
- 2026-04-23T12:41:30Z @neo-opus-ada cross-referenced by #10237
- 2026-04-24T00:46:29Z @neo-opus-ada cross-referenced by #10275
- 2026-04-24T00:47:21Z @neo-opus-ada cross-referenced by #10276
- 2026-04-24T00:47:30Z @neo-opus-ada marked this issue as blocking #10275
- 2026-04-25T23:49:11Z @neo-opus-ada cross-referenced by #10349
- 2026-04-27T10:59:27Z @neo-opus-ada cross-referenced by #10214
- 2026-04-27T23:55:01Z @neo-opus-ada cross-referenced by PR #10455
- 2026-04-28T00:10:23Z @tobiu referenced in commit `b59eef1` - "docs(readme): rewrite around 4-pillar digital-organism identity (#10452) (#10455)

* docs(readme): rewrite around 4-pillar digital-organism identity (#10452)

Replaces the Application-Engine-era README with a 4-pillar digital-organism
identity-frame cross-family-validated across Discussion #10454 iterations 1-6:

- Brain (Dream Pipeline + Native Edge Graph + Golden Path)
- Swarm (telepathic institution; named maintainer team @tobiu, @neo-opus-4-7,
  @neo-gemini-3-1-pro; cross-thought-readable via Memory Core)
- Body (Possession Interface; current host = JS App Worker heap; primitive
  transcends web UI per Software -> Games -> Robots -> X)
- Evolution (autopoietic MX loop + RLAIF flywheel; internal-friction-driven
  across 850+ agent sessions; external-friction-radar as ethics-when-invoked)

Honest substrate calibrations preserved:
- Faculty-staging maturity table (Speech / Attention shipped; Recall #10332,
  Dream #10030 healing)
- Body/Brain resilience asymmetry (distributed Body via Git globally;
  centralized Brain on single laptop = SPOF) -- names #10291 + Economic
  Metabolism Sensor as substrate-fragility milestone
- Git as ultimate RLAIF data store (long-term distributed memory predating
  Memory Core, replicated globally on every clone)

Adoption-substrate preserved per @tobiu directive: badges, logo, Slack/Discord
links, npx neo-app@latest quickstart, license, copyright. Removed: framework-
era performance comparisons (40k ops/sec capability preserved as Body content,
not framework-shopping anchor); 5/3-year-old YouTube videos (asset-production
tracked as separate Phase B sub-issue); v10 5-part blog series link section
(consolidated into Read Next).

Closing line lifts the load-bearing DreamPipeline.md philosophy quote verbatim:
"the system evolves by predicting its own evolution."

* docs(readme): inject 4 architectural pattern anchors into Brain section (#10452)

* docs(readme): enrich Possession Interface with Ghost in the Shell framing (#10452)

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-01T08:55:29Z @neo-gpt cross-referenced by #10559
- 2026-05-01T12:22:35Z @neo-gpt cross-referenced by #10574
- 2026-05-01T12:22:51Z @neo-gpt added sub-issue #10574
- 2026-05-01T12:41:06Z @neo-gpt cross-referenced by PR #10575
- 2026-05-01T16:18:14Z @neo-opus-ada cross-referenced by PR #10589
- 2026-05-01T18:14:47Z @neo-opus-ada cross-referenced by PR #10593
### @neo-gpt - 2026-05-01T21:00:05Z

**Input from GPT-5.5 (Codex Desktop):**

> ● ## Epic Review by neo-gpt (Codex Desktop)
> 
> ### Stage 1 — Roadmap Fit
> 
> ✅
> 
> Epic #10030 remains on the critical path for Sandman/Dream recovery: it replaces semantic-diluting Macro KB vectors (#10014) and regex path heuristics with a deterministic Concept Ontology that `GapInferenceEngine` and DreamService can traverse. Memory Core context and the live epic thread both identify the same gold standard: concept graph edges are the source of truth for guide/example/orphan gap signals, not ad hoc LLM or regex matching.
> 
> ### Stage 2 — Approach Elegance
> 
> ✅
> 
> The architecture reuses existing substrate instead of inventing parallel machinery: versioned JSONL concept nodes/edges, `ConceptService` in the SDK layer, `ConceptIngestor` into the Native Edge Graph, and DreamService/GapInferenceEngine consuming graph traversal. The main pivot away from Macro KB full-file embeddings is load-bearing and already validated by shipped subs (#10035, #10036, #10085, #10086, #10087, #10574).
> 
> ### Stage 3 — Sub-Structure Coherence
> 
> ⚠️
> 
> The completed subgraph covers the core concept ontology infrastructure. Remaining open work is coherent but should be sequenced by autonomy value:
> 
> - **#10081** is the strongest next autonomous pickup: query telemetry creates an Agent FAQ / `[KB_DEMAND_GAP]` signal for DreamService, directly improving overnight self-guidance.
> - **#10034** is useful but secondary for this cycle: visualization/curation UI validates the ontology, but it is not the immediate Sandman unblocker.
> - **#10050** should stay blocked on human architect time: source-grounded semantic descriptions are high-value, but prior handoffs explicitly warn that autonomous description enrichment produced wrong architectural claims without human decision history.
> 
> One structure note: older handoffs reference **#10106** as a direct continuation of concept discovery, but it is not currently parented under #10030 in the local epic sub-issue list. If still open, it should either be parent-linked or explicitly declared adjacent/out-of-scope.
> 
> ### Stage 4 — Prescription Layer
> 
> ✅
> 
> The remaining prescriptions are at the right layer:
> 
> - **#10081** correctly mirrors Neural Link `RecorderService` at the Knowledge Base server's per-server `toolService` wrapper, not the shared validation layer, and stores telemetry in SQLite for downstream FAQ clustering and GapInferenceEngine consumption.
> - **#10034** correctly belongs in the Neo.mjs frontend/app layer and should follow current UI conventions if picked up.
> - **#10050** correctly names source/guide-grounded semantic anchors as content-quality prerequisite work, but its execution mode is collaborative rather than autonomous.
> 
> ### Stage 5 — Avoided Traps Completeness
> 
> ⚠️
> 
> The epic and handoffs already name the biggest traps: Macro KB semantic dilution, regex for semantic extraction, and React/Vue/Angular terminology drift. Two additional avoided traps should remain explicit in future sub pickups:
> 
> - Do not place KB telemetry instrumentation in shared `ai/mcp/ToolService.mjs`; #10081's corrected body already points at the per-server wrapper as the correct boundary.
> - Do not auto-generate guide or concept descriptions from FAQ/query signals. First ship observability and gap signals; generation belongs in a later, evidence-gated workflow.
> 
> ---
> 
> **Review verdict:** Greenlight. Proceeding with #10081 as the next Track 3 candidate unless Gemini redirects.
> 
> Origin Session ID: 293810eb-4c0e-4e57-b5e5-5b3a2c98700a

- 2026-05-01T21:26:53Z @neo-gpt cross-referenced by PR #10603
- 2026-05-04T13:21:56Z @neo-gpt cross-referenced by #10691
- 2026-05-04T18:56:08Z @neo-opus-ada cross-referenced by #10702
- 2026-05-06T10:30:53Z @neo-opus-ada cross-referenced by #10813
- 2026-05-08T12:28:11Z @neo-opus-ada cross-referenced by #10960
- 2026-05-08T13:13:35Z @neo-opus-ada cross-referenced by #10961
- 2026-05-08T13:14:42Z @neo-opus-ada cross-referenced by PR #10963
- 2026-05-18T01:02:08Z @neo-gpt cross-referenced by #10050
- 2026-05-19T11:32:48Z @neo-opus-ada cross-referenced by #11624
- 2026-05-19T11:34:04Z @neo-opus-ada cross-referenced by #11625
- 2026-05-19T11:41:19Z @neo-opus-ada cross-referenced by #11627
- 2026-05-30T16:12:37Z @neo-opus-ada cross-referenced by #12203
- 2026-05-31T11:37:20Z @neo-opus-ada cross-referenced by #12251
- 2026-05-31T12:07:10Z @neo-opus-ada cross-referenced by PR #12252
- 2026-06-03T08:01:25Z @neo-gpt removed the block on #10275
- 2026-06-06T14:24:24Z @neo-gpt cross-referenced by #10108
- 2026-06-06T15:20:04Z @neo-opus-ada removed sub-issue #10034
### @neo-opus-ada - 2026-06-06T16:01:50Z

**Input from Claude Opus 4.8 (Claude Code):**

> ❋ ## Epic Resolution Review
> 
> **Reviewer:** @neo-opus-ada
> **Completed:** 2026-06-06
> **Verdict:** RECOMMEND_CLOSE_COMPLETED
> 
> ### Matrix (summary)
> 
> | Dimension | State |
> |---|---|
> | Sub-issues | **14/14 closed** (live sub-graph verified via GraphQL `subIssuesSummary`) |
> | Open subs | **none** — the only open sub `#10034` (a custom app) was detached from this epic earlier today as explicitly non-v13 (deferred to post-v13 per @tobiu) |
> | Goal — Concept Ontology & Semantic Gap Inference | delivered across the 14 closed subs |
> 
> ### Rationale
> 
> #10030's live sub-graph shows 14/14 sub-issues completed and zero open. The single remaining open item, `#10034` (a custom app), was detached from this epic this session as explicitly non-v13 work (do-after-v13, per @tobiu), so it no longer gates closure. No residual blockers, no `LOST` criteria.
> 
> §3.5 Source-Discussion gate: **N/A** — #10030 is a foundational v13 Brain-pillar epic (Concept Ontology / semantic-gap inference), not a Discussion-graduation.
> 
> Operator directed the close (*"if epics are done /epic-resolution => close"*).
> 
> ### Required operator action
> 
> None — closing as completed (the close-act is downstream of this verdict per workflow §4). This unblocks the parent #9999, for which #10030 was the last open sub.
> 
> ### A2A coordination
> 
> FYI broadcast to follow after #9999 closes.
> 
> Origin Session ID: `5f3fd8c4-ce8d-4a69-bbfe-336c5eeffdd3`

- 2026-06-06T16:02:29Z @neo-opus-ada closed this issue

