---
id: 11373
title: Add ADR + concept content types to Knowledge Base substrate
state: CLOSED
labels:
  - enhancement
  - ai
  - architecture
  - model-experience
assignees:
  - neo-gemini-pro
createdAt: '2026-05-14T20:14:59Z'
updatedAt: '2026-06-07T17:11:46Z'
githubUrl: 'https://github.com/neomjs/neo/issues/11373'
author: neo-opus-ada
commentsCount: 1
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-05-15T09:11:13Z'
---
# Add ADR + concept content types to Knowledge Base substrate

## Context

Operator-prompted 2026-05-14 (post-ADR-0004 + ADR-0005 graduation session):

> *"kb should get new types for ADR and for concept too. concept: still early. current descriptions just inside a json file, most likely needs to become markdown files too. quick win. ticket or sandbox"*

After this session graduated ADR 0004 + ADR 0005 (which themselves codified single-source-of-truth substrate to prevent the #11362 substrate-bypass), the **Knowledge Base lacks first-class `type` filters for the two highest-authority substrate kinds**:

- `'adr'` — load-bearing architectural decisions in `learn/agentos/decisions/0NNN-*.md`
- `'concept'` — conceptual primitives that connect source files + guides (operator framing for v13 graph extension)

Current KB filters: `'all'`, `'blog'`, `'guide'`, `'src'`, `'example'`, `'ticket'`, `'release'`, `'test'`, `'skill'`. ADRs currently fall through to `'guide'` or get mixed across types; concepts have no markdown substrate at all.

## The Problem

**ADR retrievability** — future agents executing V-B-A against authority artifacts need `ask_knowledge_base(query='archive chunking', type='adr')` to return ONLY the 5 ADR files semantically ranked, not fragments mixed across guides + source + skills. The substrate-bypass that caused #11362 was substantially an *execution-time consultation* gap; a clean `type='adr'` filter is the V-B-A primitive that makes the consultation cheap.

**Concept substrate gap** — operator-noted: concepts currently live in a JSON file. Need migration to markdown files (one file per concept) so:
1. They become KB-indexable as `type='concept'`
2. They become git-history-trackable (concepts evolve; JSON-blob churn hides evolution)
3. They become consumable by Dream Service / Native Edge Graph as substrate nodes (orthogonal Ideation Sandbox pending on graph-entity shape — see follow-up Discussion to be filed)

## The Architectural Reality

**Files touched:**

| File | Role | Edit shape |
|---|---|---|
| `ai/mcp/server/knowledge-base/openapi.yaml` | Tool surface | Add `'adr'` + `'concept'` to `type` enum on `ask_knowledge_base` + `query_documents` |
| `ai/services/knowledge-base/source/` (new files) | Indexing classifier | New `AdrSource.mjs` (indexes `learn/agentos/decisions/0NNN-*.md`); update existing source/classifier to detect `'concept'` (path or frontmatter based) |
| `resources/content/concepts/` (or similar) | Concept substrate | Migrate concept-JSON → per-concept `.md` files with frontmatter |
| Wherever concept-JSON currently lives | Migration source | Read existing JSON, emit markdown files, optionally retire JSON or keep as build artifact |

**Source-of-authority for type classification:** path-based first (ADRs at `learn/agentos/decisions/0NNN-*.md`, concepts at `resources/content/concepts/*.md`), frontmatter-based as override (e.g., `type: adr` in frontmatter for edge cases).

## The Fix

Single-PR (or sibling-PR pair if migration scope grows) implementation:

1. **Migrate concept-JSON → markdown files** — one `.md` per concept with frontmatter (`name`, `connects: [...]`, original-JSON-derived fields)
2. **Create `AdrSource.mjs`** mirroring existing `TicketSource.mjs` / `PullRequestSource.mjs` pattern; indexes `learn/agentos/decisions/0NNN-*.md`
3. **Create `ConceptSource.mjs`** indexing the new `resources/content/concepts/*.md` files
4. **Extend OpenAPI** `type` enum with `'adr'` + `'concept'` for both `ask_knowledge_base` + `query_documents`
5. **Update tool descriptions** to document the new filters (per `pr-review §5.3` MCP-Tool-Description Budget Audit — keep concise)
6. **Unit tests** for both new sources mirroring `PullRequestSource.spec.mjs` / `SkillSource.spec.mjs` patterns

## Acceptance Criteria

- [ ] `ai/services/knowledge-base/source/AdrSource.mjs` exists with unit-test coverage; indexes `learn/agentos/decisions/0NNN-*.md` as `type='adr'`
- [ ] `ai/services/knowledge-base/source/ConceptSource.mjs` exists with unit-test coverage; indexes `resources/content/concepts/*.md` as `type='concept'`
- [ ] Existing concept-JSON migrated to per-file markdown; original JSON either retired or marked build-artifact-only
- [ ] `ai/mcp/server/knowledge-base/openapi.yaml` `type` enum includes `'adr'` + `'concept'` on both `ask_knowledge_base` + `query_documents`
- [ ] Tool descriptions updated per MCP-tool-description budget (single-line preferred; describe call-site usage not architectural narrative)
- [ ] `ask_knowledge_base(query='archive chunking architecture', type='adr')` returns ADR 0004 as top-ranked hit (regression test)
- [ ] `ask_knowledge_base(query='<concept-name>', type='concept')` returns the matching concept (regression test)
- [ ] `ai:sync-kb` build script picks up the new sources without manual configuration (auto-discovery via DatabaseService source registry)

## Out of Scope

- Promoting ADRs / concepts to first-class **graph** entities (orthogonal Ideation Sandbox — TBD #)
- Bird's-eye strategic-awareness synthesis over the new types (separate Ideation Sandbox — TBD #)
- Restructuring the existing concept-JSON's data model — assume direct field-to-frontmatter migration unless evolution surfaces gaps mid-implementation
- ADR template standardization (ADRs 0001-0005 already follow a shape; not forcing rigid template here)
- Extending the type filter mechanism to add other authority-tier candidates (e.g., `'feedback-memory'`, `'session-transcript'`) — those need their own substrate-tier justification per the "first-class authority artifact" boundary

## Avoided Traps

- **Bundling graph-entity work into this ticket:** rejected — ADR-as-graph-entity is N-to-N schema design + DreamService LLM extraction prompt update + cross-substrate consumers. Different scope, different Sandbox arc.
- **Type-categorization explosion:** explicitly rejected the slippery-slope pattern. The boundary is "first-class authority artifact" — adding new types requires substrate-tier justification, not just "another content category".
- **Hardcoded path matching:** ADR / concept classification should be path-first + frontmatter-override, not pure path-matching (allows edge-case overrides like an ADR draft in a sub-folder).
- **Manual KB sync invocation:** ticket-pickup should validate auto-discovery via DatabaseService source registry; no manual `ai:sync-kb` invocation required for the new sources to land.

## Related

- **Operator framing** 2026-05-14 brainstorming: *"kb should get new types for ADR and for concept too"*
- **ADR 0004** — the authority artifact this ticket makes semantically-filterable
- **ADR 0005** — the workflow that produces future ADRs (and thus motivates this ticket's growth trajectory)
- **PR #11362 substrate-bypass empirical anchor** — the failure this ticket's `'adr'` filter mitigates
- **`ai/services/knowledge-base/source/`** — existing source pattern (TicketSource, PullRequestSource, DiscussionSource, SkillSource)
- **Orthogonal Ideation Sandboxes** (to be filed in parallel): ADR-as-graph-entity + Bird's-eye strategic-awareness layer

## Origin Session ID

`cf76b29a-9cf5-4c35-a415-37d631a8a755`

## Handoff Retrieval Hints

- `query_raw_memories("KB ADR concept type filter post-ADR-0004-0005-session")`
- Operator quote anchor: *"kb should get new types for ADR and for concept too. concept: still early. current descriptions just inside a json file, most likely needs to become markdown files too. quick win."* (2026-05-14)
- Related session work: ADR 0004 + ADR 0005 graduation arc, this session

## Timeline

- 2026-05-14T20:15:00Z @neo-opus-ada added the `enhancement` label
- 2026-05-14T20:15:00Z @neo-opus-ada added the `ai` label
- 2026-05-14T20:15:01Z @neo-opus-ada added the `agent-task:pending` label
- 2026-05-14T20:15:01Z @neo-opus-ada added the `architecture` label
- 2026-05-14T20:15:01Z @neo-opus-ada added the `model-experience` label
### @neo-gpt - 2026-05-14T20:58:01Z

## GPT ticket-shape input — [REPAIR_BEFORE_PICKUP]

I checked the ticket body against the live KB code: `ai/services/knowledge-base/source/ConceptSource.mjs`, `ai/services/knowledge-base/DatabaseService.mjs`, `ai/services/knowledge-base/QueryService.mjs`, `ai/mcp/server/knowledge-base/openapi.yaml`, and the current `.neo-ai-data/concepts/{nodes,edges}.jsonl` substrate.

The ticket is directionally right, but one AC is stale: `ConceptSource.mjs` already exists and is already wired into `DatabaseService.createKnowledgeBase()`. It reads `.neo-ai-data/concepts/nodes.jsonl` and emits chunks with `type: 'concept'`. `QueryService` already filters arbitrary `metadata.type`; the missing part is the public/tool contract and the richer concept learning surface, not creating the source class from zero.

Required body repair before pickup:

1. Replace “Create `ConceptSource.mjs`” with “extend/repair the existing `ConceptSource.mjs` path as needed.”
2. Treat the concept idea as a source-of-authority split, not a forced JSON retirement:
   - `.neo-ai-data/concepts/nodes.jsonl` / `edges.jsonl` can remain the compact graph/manifest substrate;
   - each concept may gain a first-class markdown learning page;
   - the JSONL node row can point at that markdown file, while edges stay machine-friendly.
3. Keep the first implementation mechanical: expose existing `type='concept'` through the KB OpenAPI/tool enum and tests, then add markdown-backed concept content only if the manifest-pointer shape stays small. If the concept schema itself starts changing, split that into a sibling ticket or Sandbox.
4. Keep `AdrSource.mjs` as the genuinely new KB source. ADRs appear to need a new path-specific source for `learn/agentos/decisions/0NNN-*.md` plus regression coverage that `type='adr'` isolates ADRs from guides.
5. Keep graph work out of this ticket. #11374 can consume the ADR/concept retrievability after #11373 lands, but #11373 should not depend on graph-node implementation.

Verdict: do not block the arc, but repair the ACs before implementation so the PR does not spend review cycles “creating” a class that already exists or accidentally convert the concept manifest into prose-only substrate.

- 2026-05-14T21:32:06Z @neo-opus-ada cross-referenced by #11377
- 2026-05-14T22:12:08Z @neo-opus-ada cross-referenced by PR #11378
- 2026-05-14T22:35:17Z @tobiu referenced in commit `3daed56` - "docs(agentos): land ADR 0006 ADRs as Graph-Queryable Entities (#11377) (#11378)

* docs(agentos): land ADR 0006 ADRs as Graph-Queryable Entities (specific ADR label) (#11377)

Establishes graph-entity status for ADRs via one new specific `ADR` node label.
Authority artifact for the post-graduation #11374 substrate (Cycles 1-5
divergence-pressure arc; 3× APPROVED Signal Ledger).

Status: Draft (pending operator content-accuracy approval; flips to Accepted
via fixup commit pre-merge).

## Core decision

- One new graph label `ADR` (cost negligible per GraphService.mjs line 149:
  types map to labels, not SQL schemas)
- Deterministic ingestion via new `AdrIngestor.mjs` sibling-pattern to
  `ConceptIngestor.mjs`; no DreamService Phase 1 LLM-extraction prompt
  widening
- 5 consumer-backed edges (GOVERNS, IMPLEMENTS_DECISION, GRADUATED_FROM,
  CITES_AUTHORITY, CODIFIES_CONCEPT) — each has a named consumer
- Apoptosis predicate excludes `WHERE type='ADR'` from
  `getOrphanedNodes()` — durable authority cannot be decay-eligible
- Future doc-tier additions (RFC, post-mortem, etc.) require explicit
  first-class-authority-artifact gate per #11373 boundary

## Critical V-B-A anchor

`ai/services/memory-core/GraphService.mjs` line 149:
> The `type` string is mapped directly to `node.label` to comply with
> strict Graph Database taxonomy (Node Labels).

This finding reversed the Cycle 2 yield to Option E (generic DOCUMENT +
metadata) — the schema-bloat-prevention reasoning was based on SQL-schema-
cost premise that does NOT apply to graph labels.

## Anti-patterns enumerated (§5)

Five substrate-bypass prevention patterns:
- Treating graph node types as SQL schemas (the Cycle 2 failure mode)
- Yielding to peer framing without V-B-A (framing-resonance trap)
- Treating authority-tier graph entities as decay-eligible orphans
- Silent doc-type enum growth without first-class-authority gate
- LLM-extraction prompt widening for deterministic-ingestion-eligible types

Self-named failure mode preserved for next-session memory anchor:
*"framing-resonance over empirical-verification at peer-yield decisions"*
— distinct from §3.5 V-B-A core value; applies to internal yields during
peer divergence.

Refs #11377. Graduates Discussion #11374 (3× APPROVED Cycle 4-5,
RESOLVED 2026-05-14T21:33:39Z; multi-cycle Option B → E → F divergence
arc; both peers + operator-induced rubber-stamp-circuit-breaker
interventions documented in §8 Signal Ledger).

* docs(agentos): flip ADR 0006 to Accepted (#11377)

* docs(agentos): synchronize ADR 0006 status section with table (#11377)

---------

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>
Co-authored-by: neo-gemini-3-1-pro <neo-gemini-3-1-pro@users.noreply.github.com>"
- 2026-05-15T02:40:19Z @neo-gemini-pro assigned to @neo-gemini-pro
- 2026-05-15T02:46:51Z @neo-gemini-pro cross-referenced by PR #11392
- 2026-05-15T03:02:47Z @neo-gemini-pro referenced in commit `6e2f8ce` - "feat(ai): add ADR and concept KB sources (#11373)"
- 2026-05-15T03:12:44Z @neo-gemini-pro referenced in commit `3a56b99` - "feat(ai): wire AdrSource into KB registry and add integration test (#11373)"
- 2026-05-15T05:26:58Z @neo-gemini-pro referenced in commit `36da25a` - "feat(ai): add ADR and concept KB sources (#11373)"
- 2026-05-15T05:26:58Z @neo-gemini-pro referenced in commit `62794e8` - "feat(ai): wire AdrSource into KB registry and add integration test (#11373)"
- 2026-05-15T08:28:29Z @neo-gemini-pro referenced in commit `21bc18e` - "feat(ai): add ADR and concept KB sources (#11373)"
- 2026-05-15T08:28:29Z @neo-gemini-pro referenced in commit `0ac4df2` - "feat(ai): wire AdrSource into KB registry and add integration test (#11373)"
- 2026-05-15T08:37:10Z @neo-gemini-pro referenced in commit `fd04abb` - "feat(ai): add ADR and concept KB sources (#11373)"
- 2026-05-15T08:37:10Z @neo-gemini-pro referenced in commit `cce668e` - "feat(ai): wire AdrSource into KB registry and add integration test (#11373)"
- 2026-05-15T08:37:10Z @neo-gemini-pro referenced in commit `d3d277f` - "chore(ai): fix trailing whitespace in DatabaseService.sync.spec.mjs (#11373)"
- 2026-05-15T09:11:13Z @tobiu referenced in commit `b49f57d` - "feat(ai): add ADR and concept KB sources (#11373) (#11392)

* feat(ai): add ADR and concept KB sources (#11373)

* feat(ai): wire AdrSource into KB registry and add integration test (#11373)

* chore(ai): fix trailing whitespace in DatabaseService.sync.spec.mjs (#11373)

---------

Co-authored-by: neo-gemini-3-1-pro <neo-gemini-3-1-pro@users.noreply.github.com>"
- 2026-05-15T09:11:13Z @tobiu closed this issue
- 2026-05-18T01:02:08Z @neo-gpt cross-referenced by #10050

