Gateway Module — `knowledge-graph/`
1. Purpose
The knowledge-graph/ module (AK-347) stores temporal subject–predicate–object triples about entities — location, employment, affiliation, role, family, temporal, financial facts — with validity intervals (valid_from/valid_to) so a fact can be soft-closed ("invalidated") rather than deleted, preserving history. It is an internal repository surfaced two ways: (1) as position 10 of createContextLayer, where it enriches RAG context assembly with entity facts; (2) via the MCP kg_* tools. Its own Express router exists in the source tree but is not mounted in the production app (see §3). It also ships a vault scanner that can derive triples from vault-note frontmatter + wikilinks.
2. File Inventory
| File | Lines | Responsibility |
|---|---|---|
repository.ts | 262 | createKGRepository — add/invalidate/query/timeline/stats over the triples table |
types.ts | 164 | Zod schemas + KGTriple/KGPredicate/CrossReference interfaces + both repository contracts (KG and cross-ref types live here) |
vault-scanner.ts | 508 | Frontmatter + wikilink parsing → triple generation (createVaultScanner, generateTriples, parseFrontmatter, extractWikilinks) |
routes.ts | 108 | Express router — defined but NOT mounted in production (see §3/§9) |
| Total | 1042 | (No index.ts — the repo is constructed inline in server/index.ts line 478.) |
3. Public API Surface
REST Endpoints
No live HTTP surface in production. routes.ts defines a createKGRouter with six handlers (POST /add, PUT /invalidate, POST /query, POST /timeline, GET /predicates, GET /stats) — but createKGRouter is never imported or mounted in server/index.ts. Only createKGRepository is imported (line 44) and passed as position 10 of createContextLayer (line 497). The router is exercised only by test/knowledge-graph-routes.test.ts, which mounts it on a standalone test app. These routes do not answer on the live gateway.
MCP Tools
The knowledge graph's write/read surface reaches clients through the MCP server (mcp/index.ts), which exposes eight tools (four semantic + four _raw twins), each with D4 admission constraints (.max(256) length cap, control-char strip, predicate regex):
| Tool | Raw twin | Gateway path it fetches |
|---|---|---|
kg_add_triple | kg_add_triple_raw | POST /api/knowledge-graph/add |
kg_query_entity | kg_query_entity_raw | POST /api/knowledge-graph/query |
kg_timeline | kg_timeline_raw | POST /api/knowledge-graph/timeline |
kg_invalidate | kg_invalidate_raw | PUT /api/knowledge-graph/invalidate |
DIVERGENCE (flagged, HIGH — see §9): the MCP tools gatewayFetch to /api/knowledge-graph/*, but that prefix has no router mounted in index.ts. As statically read, these MCP tools would 404 against the production gateway. Not runtime-verified in this audit — flagged for Phase 2 triage.
4. Internal API
createKGRepository(db): KGRepository—addTriple,invalidate,queryEntity,timeline,getPredicates,stats,deleteBySource,getSubjects. This is the live surface (consumed bycreateContextLayerposition 10 for entity enrichment during RAG assembly — seetest/context-kg-enrichment.test.ts).vault-scanner.ts:createVaultScanner,generateTriples,parseFrontmatter,extractWikilinks,VaultScanResult/VaultScannerinterfaces.
5. Background Services
None wired. The vault scanner is invocable but not scheduled or called from index.ts.
6. Data Contracts
- Enums:
PredicateCategory(location/employment/affiliation/role/family/temporal/financial/custom),Confidence(high/medium/low),ObjectType(entity/literal),LinkType(6 values — shared with cross-references). AddTripleInputSchema(subject/predicate/object/object_type + optional validity/confidence/source),InvalidateTripleInputSchema(by id OR by subject+predicate+object),QueryEntityInputSchema(entity,as_of, predicate, limit ≤200),TimelineInputSchema,RebuildInputSchema.KGTriple,KGPredicate(withbidirectional+inverse_predicate).
7. Dependencies
- Gateway modules consumed:
shared/(formatZodError, used only by the unmounted router); consumed bycontext/(position 10).types.tsis also imported by thecross-references/module. - External libraries:
better-sqlite3,express(router only),zod. - Environment variables:
VAULT_ROOT(vault scanner, when invoked).
8. Test Coverage
| Layer | File | Cases |
|---|---|---|
| Repository | test/knowledge-graph.test.ts (401 L) | (triples, validity intervals, invalidate, stats) |
| Router (isolated) | test/knowledge-graph-routes.test.ts (329 L) | 19 it blocks |
| Vault scanner | test/vault-scanner.test.ts (279 L) | (frontmatter, wikilinks, triple generation) |
| MCP envelope | test/mcp-kg-envelope.test.ts (475 L) | admission-constraint validation for the 8 tools |
| Context enrichment | test/context-kg-enrichment.test.ts (390 L) | the LIVE path (KG repo → context assembly) |
9. Known Limitations
- Unmounted router / MCP path mismatch (HIGH):
createKGRouteris not mounted inindex.ts, yet the MCPkg_*tools fetch/api/knowledge-graph/*. Either the router must be mounted or the tools re-pointed. The routes.ts + its 19-case test are effectively dead relative to production. Flag for triage. createVaultScanneris unwired dead code: coverage (lcov.info) showsFNDA:0— never invoked in tests orindex.ts; referenced only indepmap.yaml. The vault→triple ingest path exists but nothing drives it.- The live surface is read-only enrichment (context assembly); no production write path to the KG exists today unless the router is mounted.
10. Change History
| Date | Dispatch | Summary |
|---|---|---|
| 2026-07-04 | 2297 | Initial module spec (smoke-clone-3, LisaOS audit campaign Phase 4) |
| — | 1484 (AK-347) | Production consumer wiring — KG repo passed as createContextLayer position 10 |
| — | (AK-347 Phase 1) | Schema substrate + repository + router + vault scanner landed |