ADR-001: Extract Manager Interfaces to API

Status (2026-10-13): Implemented 2026-03-23 (phases 1–5 complete, phase 6 partially complete). The repository records this decision as docs/adr/0000-extract-manager-interfaces-to-api.md (originally docs/adrs/001-...); the numbered ADR series proper begins at 0001. The single wikantik-mcp module named below was later split into wikantik-admin-mcp (writes and analytics, /wikantik-admin-mcp) and wikantik-knowledge (read-only retrieval, /knowledge-mcp), with their shared substrate in wikantik-mcp-core; the decision applies to all of them. An earlier revision of this page carried cost and performance figures that are not in the repository record; they have been removed, and everything below comes from that record.

Deciders: jakefear. Proposed: 2026-03-22. Implemented: 2026-03-23.

Context

The MCP module (then wikantik-mcp) depended directly on manager interfaces and utility types defined in wikantik-main. That meant the MCP code could not compile without the full engine implementation, which blocked three things: alternative engine implementations, lightweight tests, and clean module boundaries. The decision was to move the contracts into wikantik-api and let wikantik-main implement them, so consumers depend on the contract rather than the engine.

What was done

Phases 1–4: manager interfaces extracted

Eight types moved from wikantik-main to wikantik-api, each leaving a backward-compatibility shim behind so no import in existing wikantik-main code had to change.

TypeNew home in wikantik-apiShim package in wikantik-main
InternalModulecom.wikantik.api.modulescom.wikantik.modules
SystemPageRegistrycom.wikantik.api.managerscom.wikantik.content
PageManagercom.wikantik.api.managerscom.wikantik.pages
ReferenceManagercom.wikantik.api.managerscom.wikantik.references
AttachmentManagercom.wikantik.api.managerscom.wikantik.attachment
DynamicAttachmentcom.wikantik.api.attachmentcom.wikantik.attachment
DynamicAttachmentProvidercom.wikantik.api.attachmentcom.wikantik.attachment
PageLockcom.wikantik.api.pagescom.wikantik.pages

Phase 5: utility types and concrete classes moved

Seven further types moved directly, without shims, using mechanical import updates: FrontmatterParser, FrontmatterWriter and ParsedPage (com.wikantik.api.frontmatter), MarkdownLinkScanner (com.wikantik.api.parser), and PageSaveHelper, SaveOptions and VersionConflictException (com.wikantik.api.pages).

Phase 6: MCP decoupled from WikiEngine (partial)

Thirteen MCP tool constructors were changed to accept the managers they need (PageSaveHelper, PageManager, and so on) instead of a WikiEngine, and the tool registry resolves the managers once. The MCP module's imports from wikantik-main fell from 15 to 5: WikiEngine (bootstrapping), PageRenamer, DifferenceManager, SearchManager, and one SitemapServlet constant. Of those, only WikiEngine was considered irreducible.

Test infrastructure

Lightweight in-memory stubs were added so tests need no engine: StubPageManager (with locking and version history), StubSystemPageRegistry, StubReferenceManager and StubPageSaveHelper. 29 of the 36 MCP tool test classes were converted from TestEngine to stubs; the converted tests ran in 2–27 ms each against 1–3 s before. See TestStubConversion for the retrospective on that work.

Key insight

The shim pattern made the move cheap: create the interface in wikantik-api, leave a @Deprecated shim that extends it in the old location, and every existing caller keeps compiling while imports migrate gradually. The ADR had estimated 20–30 hours of work; the actual effort was about 3 hours. Concrete classes and records, which cannot be shimmed the same way, were moved directly with scripted import updates.

Remaining work recorded at the time

What came after


Cluster Hub: Wikantik Platform Development Hub: Architecture, MCP Protocols, and Agent Briefings (wikantik-development)