Gateway Module — `cross-references/`
1. Purpose
The cross-references/ module (AK-347) tracks weighted, decaying links between mission namespaces — e.g. "CS.AK.LISA depends_on CS.AK.Missions". Each link carries a link_type, human-readable evidence, and a strength (0–1) that is reinforced on re-observation and exponentially decayed over time. It is an internal repository surfaced via position 11 of createContextLayer, where related-namespace signals enrich RAG context assembly. Like knowledge-graph/, its Express router exists in the tree but is not mounted in production. It shares its Zod schemas and types with the knowledge-graph/ module (both import from knowledge-graph/types.ts).
2. File Inventory
| File | Lines | Responsibility |
|---|---|---|
repository.ts | 223 | createCrossRefRepository — upsert/reinforce, query (directional + typed), related-namespace aggregation, time-decay + prune |
routes.ts | 103 | Express router — defined but NOT mounted in production (see §3/§9) |
| Total | 326 | (No types.ts/index.ts — types live in knowledge-graph/types.ts; repo constructed inline in server/index.ts line 479.) |
3. Public API Surface
REST Endpoints
No live HTTP surface in production. routes.ts defines a createCrossRefRouter with five handlers (POST /write, DELETE /:id, POST /query, POST /related, POST /decay) — but createCrossRefRouter is never imported or mounted in server/index.ts. Only createCrossRefRepository is imported (line 45) and passed as position 11 of createContextLayer (line 498). The router is exercised only by test/cross-references-routes.test.ts on a standalone test app. These routes do not answer on the live gateway.
MCP Tools
None. Unlike the knowledge graph, cross-references have no MCP tool surface — the only live consumer is context assembly (related-namespace enrichment). There is no client-facing write path in production.
4. Internal API
createCrossRefRepository(db): CrossRefRepository — the live surface:
addReference(input)— upsert viaON CONFLICT(source_namespace, target_namespace, link_type, evidence) DO UPDATEbumpinglast_seenandMAX(strength, excluded.strength).removeReference(id)— returns boolean.query(input)— directional (outbound/inbound/both) × optionallink_type, filtered bymin_strength, ordered by strength.getRelatedNamespaces(input)— aggregatesMAX(strength)per related namespace (default min 0.3, limit 3). This is whatcreateContextLayerposition 11 calls.decay(input)— exponentialstrength * EXP(-lambda * days_since_last_seen); prunes below a threshold;dry_runreturns the would-prune count.
5. Background Services
None wired. decay exists but no scheduler drives it in-module.
6. Data Contracts
Schemas live in knowledge-graph/types.ts (imported): AddCrossRefInputSchema (source/target namespace, link_type ∈ LinkType, evidence, strength default 0.5), QueryCrossRefInputSchema (namespace, direction default both, optional link_type, min_strength default 0), RelatedNamespacesInputSchema (min_strength default 0.3, limit default 3, ≤20), DecayCrossRefInputSchema (lambda default 0.01, prune_below default 0.05, dry_run default false). LinkType enum: mentions, depends_on, shares_entity, dispatched_from, decision_impacts, derived_from. Row shape: CrossReference (id, source/target namespace, link_type, evidence, strength, created_at, last_seen). Table: cross_references with a 4-column UNIQUE key.
7. Dependencies
- Gateway modules consumed:
knowledge-graph/(all types/schemas),shared/(formatZodError, used only by the unmounted router). Consumed bycontext/(position 11). - External libraries:
better-sqlite3,express(router only),zod. Uses SQLite'sEXP()+julianday()for decay maths. - Environment variables: none.
8. Test Coverage
| Layer | File | Cases |
|---|---|---|
| Router (isolated) | test/cross-references-routes.test.ts (277 L) | 19 it blocks |
Repository behaviour (upsert/reinforce, directional query, related aggregation, decay + prune, dry-run) is covered through the router test. The live enrichment path is also exercised in test/context-kg-enrichment.test.ts (shared with knowledge-graph).
9. Known Limitations
- Unmounted router (HIGH-adjacent):
createCrossRefRouteris not mounted; the 5 endpoints + their 19-case test are dead relative to production. Unlike the KG, there is also no MCP tool surface — so cross-references have no production write path at all; the table is only readable via context enrichment. Whatever populatescross_referencesin production must do so outside this module (or the table stays empty). Flag for triage. - No scheduled decay —
strengthnever decays in production unlessdecayis invoked, which nothing does. Reinforcement-without-decay means strengths only ratchet up. - Types coupled to
knowledge-graph/types.ts— the two AK-347 modules are not independently versionable.
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 — cross-ref repo passed as createContextLayer position 11 |
| — | (AK-347 Phase 1) | Schema substrate + repository + router landed |