Roadmap Target Architecture: Incremental Evolution to RAG-as-a-Service

This page is the architectural spine for the RagServiceRoadmapHub capability briefs. It defines an end state that is reachable incrementally from the current architecture — every step ships value on its own, no big-bang rewrite — and shows which seam each roadmap capability plugs into. Read WikantikArchitecture first for the current state.

Design stance: evolve the modular monolith, do not replatform

Wikantik is a modular Java monolith — one WAR, a WikiEngine orchestrator, manager interfaces with default implementations, provider-pattern storage, a WikiEvent bus, PostgreSQL + pgvector as the single datastore, and in-process Lucene indexes. The roadmap does not require microservices, a message broker, a workflow engine, or a second database. Every capability lands as a new module, a new SPI seam in an existing pipeline, or new tables behind an existing chokepoint. The single deliberate exception is the fleet control plane (tenancy), which is outside the monolith by design because the monolith itself is the unit it manages.

Two standing pressures shape everything below: wikantik-main is already a god module (the critique page's first-listed debt), and the architecture is governed by freeze/ratchet gates (DecompositionArchTest, the PMD complexity gate). The rule that reconciles growth with that debt:

New capabilities land in new modules or existing satellite modules — never as new packages in wikantik-main. Contracts go in wikantik-api; wikantik-main may gain only thin wiring at its established seams, and growth of its existing packages (e.g. new stages beside the bundle pipeline) is tolerated where the code they extend already lives there.

Current-state anchors the evolution builds on

These existing mechanisms are load-bearing for the roadmap — extend them, do not duplicate them:

Target module map

Naming trap (verified against the repo): the wikantik-knowledge Maven module contains only the knowledge MCP server (com.wikantik.knowledge.mcp, com.wikantik.knowledge.retrieval). The bundle pipeline's com.wikantik.knowledge.bundle and com.wikantik.knowledge.chunking packages live physically inside the wikantik-main module. Do not scaffold retrieval-pipeline code in the wikantik-knowledge module because the package name suggests it.

New modules (all depending on wikantik-api, none on wikantik-main internals):

Existing modules that grow, bounded: wikantik-ingest gains OCR and image-caption extraction (keeping the heavy-deps isolation rationale it exists for); wikantik-rest gains admin resources for connector/eval/audit surfaces; wikantik-observability gains OTel span export; wikantik-main hosts the retrieval pipeline seams below in its existing com.wikantik.knowledge.bundle package (see the naming trap above). The already-proposed wikantik-renderer extraction stays on the debt list — the roadmap neither needs it nor excuses deferring it forever.

Retrieval pipeline seams: QueryPlanner in front, RerankChain behind

The bundle pipeline (package com.wikantik.knowledge.bundle, physically inside the wikantik-main module — see the naming trap above) gains two SPI seams, contracts in wikantik-api:

query → [QueryPlanner] → candidate sources (BM25 + dense) → RRF fusion → [RerankChain] → bundle + coverage

Every stage lands flag-gated and is accepted only on eval/bundle-corpus movement — the pipeline SPI makes experiments cheap; the harness decides what survives.

Authorization pushdown: extend the one chokepoint

External ACL inheritance does not add an authorization layer; it widens the existing one downward:

  1. New tables (numbered migrations): source_principals (external identity → wiki principal, keyed by what SCIM/SSO already provision) and per-derived-page ACL sidecars written at sync time.
  2. A single RetrievalAuthorizationPredicate component renders the caller's effective permission set into index-native filters: a SQL predicate joined into pgvector queries, a Lucene filter clause for BM25/HNSW. Pre-filtering in the index, never post-filtering in application code — the in-database pattern the market research recommends and Wikantik's PostgreSQL-first stack is uniquely placed to do.
  3. The predicate is consumed inside the existing candidate-retrieval path, so /api/bundle, MCP tools, and search all inherit it — no per-surface reimplementation, no drift between surfaces.
  4. Fail-closed semantics: an unresolvable external principal or stale sidecar denies, and permission-sync lag is surfaced by the same drift machinery that tracks citation staleness.

Data layer: PostgreSQL-first, no second datastore

All new state is tables in the one database, behind numbered idempotent migrations: connector sync state (cursors, content hashes, tombstones), principal mappings and ACL sidecars, eval-run results and retrieval-audit events, caption chunks (which are just chunks — the vision-captioning output re-enters the existing chunk→embed→index pipeline untouched). This keeps backup (3-2-1 NAS pull), migrations, and the silo-per-tenant story single-artifact. The only new persistent artifact class is per-connector credentials, which need encryption-at-rest — a deliberate design decision in the connector brief, not an afterthought (note: the existing CryptoUtil is one-way password hashing only; reversible credential encryption is greenfield).

Tenancy: the monolith is the tenant unit

The silo-per-tenant posture (RoadmapMultiTenancyPosture) is what makes this whole page incremental: no tenant_id columns, no row-level-security retrofit, no shared-store schema surgery anywhere. The application stays single-tenant; isolation is the deployment boundary (one compose stack per tenant); the fleet control plane and a shared Ollama inference pool live outside. If a future B2C-scale demand forces shared-store tenancy, that is a new roadmap, not a hidden assumption in this one.

API stability contract for SDKs

Publishing SDKs freezes surfaces. Before the first SDK release: bundle/briefing/changes response DTOs are declared stable in wikantik-api (com.wikantik.api.bundle already exists as the contract home), versioning policy stated (additive-only within a major), and an OpenAPI spec covering /api/bundle|briefing|changes is generated and CI-diffed so an accidental breaking change fails the build — the same ratchet philosophy as the complexity gate, applied to the wire.

Invariants that must not break

Any design that violates one of these is wrong for this codebase, whatever the market says:

  1. ADR-0001: the platform assembles cited evidence; it never synthesizes answers — the QueryPlanner decomposes queries, it does not generate content.
  2. Fail-closed retrieval: no LLM on the query path may make retrieval unavailable; every intelligent stage degrades to the deterministic pipeline.
  3. Async indexing: the save path stays fast; all enrichment (embedding, captioning, sync, projection) is queued background work.
  4. One authorization chokepoint: every retrieval surface flows through the same permission predicate; no surface-local ACL logic.
  5. PostgreSQL-first: new state means new tables and migrations, not new infrastructure.
  6. wikantik-main does not grow: contracts to wikantik-api, implementations to satellite modules or existing packages at established seams; no new packages in wikantik-main.
  7. Measure-first: retrieval-affecting changes ship flag-gated and live or die by the eval harness — the rejected-levers list (LLM rerank, HyDE, doc2query, page-level KG rerank) stays rejected.
  8. Apache 2.0 core stays complete: the open-core seam is a module boundary; the core must remain a fully functional product without the enterprise modules.

Capability-to-seam map

Capability briefArchitectural seamNew module(s)Schema impact
RoadmapConnectorFrameworkProvider-pattern SPI + derived pages + async queuewikantik-connectorssync state, credentials
RoadmapExternalAclInheritanceAuthorization predicate pushdown at the existing chokepointwikantik-authz-syncprincipal map, ACL sidecars
RoadmapMultiTenancyPostureDeployment boundary; control plane externalfleet repo (non-WAR)none
RoadmapMultimodalIngestionwikantik-ingest extraction + existing chunk pipeline— (grows wikantik-ingest)caption chunks reuse chunk tables
RoadmapComposableRerankingRerankChain SPI post-fusion— (in wikantik-main, existing com.wikantik.knowledge.bundle pkg)none
RoadmapAgenticRetrievalQueryPlanner SPI pre-retrieval, coverage-conditional— (in wikantik-main, existing com.wikantik.knowledge.bundle pkg)none
RoadmapRetrievalEvaluationObservabilityTelemetry in the stage SPI contract + OTel export— (grows wikantik-observability)eval results, audit events
RoadmapCompliancePostureExisting audit log widened to retrieval eventsretrieval audit table
RoadmapPackagingAndPricingModule boundary = license boundaryenterprise artifact splitnone
RoadmapClientSdkDeveloperExperienceFrozen DTO contracts + spec-diff CI gateSDK repos (out-of-reactor)none

See Also