You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor TMI from a monolith-with-deployment-variability into a Kubernetes-native system of cooperating components. The server binary has accreted significant complexity (most recently content providers with their authorization, fetching, chunking, and embedding logic). This roadmap establishes a generic component model so functionality can be moved out of the monolith over time, and standardizes deployment on container + Kubernetes — removing today's deployment-shape variability (local Docker, Heroku, multiple cloud registries).
This is a tracking/roadmap issue. Individual components ship as their own issues. The first tenant is #347.
Thesis
The monolith becomes the stateful coordinator — sole DB writer, fetch/egress owner, job-state authority, result-consumer. It does not dissolve; it becomes a coordinator.
Components are stateless workers — declared as TMIComponent custom resources.
Architecture
NATS JetStream — the spine for asynchronous job work (durable subjects, fan-out, autoscaling signal).
TMIComponent CRD — the durable, runtime-editable contract for a component type. kubectl apply registers a new type; no monolith redeploy. CRD OpenAPI schema validates declarations before any pod runs. Key fields: jobSubjects, inputMode, egress, spec.config, secretRefs, resources, timeouts, scratchVolume, scaling.
Custom controller — reconciles each TMIComponent CR into a Deployment + KEDA ScaledObject + NetworkPolicy + NATS stream/consumer wiring.
KEDA — autoscales workers on JetStream queue depth, scale-to-zero capable. Neither the monolith nor the worker decides scaling.
Worker heartbeat — workers heartbeat on the bus; the monolith distinguishes "type declared, no healthy instance yet" from "instances present."
Cross-cutting contracts (derived while designing the first tenant, #347)
Egress is a first-class CRD field with three postures: none / fetch-controlled / allowlist. The controller renders the NetworkPolicy from it, and always renders a cluster-layer NetworkPolicy backstop regardless of in-code guarding. fetch-controlled is backed by one shared egress-guard library (owned by the T3 issue) — components never reimplement SSRF defense.
Filesystem: read-only root is a hard, universal invariant. Writable space is only ever a size-capped ephemeral emptyDir — never writable root, hostPath, or a PV.
Job input: two modes (content-ref / source-locator), one stable job-envelope schema with optional fields, mode declared per-CR. Large payloads travel by reference via a JetStream Object Store, never as large NATS messages.
Config has three categories: bootstrap (local, chicken-and-egg) / operational-monolith-local (DB settings service) / shared-cross-component (platform-owned, controller-projected). Components consume a minimal local bootstrap + projected shared config — never the monolith's config cascade. See the config-system issue.
Dev/test — three tiers
Tier
Where
Frequency
Unit/integration
Process-mode; workers as processes against NATS as a CI services: container
Every PR
E2E/cluster
kind with Calico/Cilium (kindnet does not enforce NetworkPolicy); CRD + controller + KEDA
Gated merge check
Local dev
kind / k3d, prod-shaped manifests
Developer-driven
make start-dev is reworked to bring up a local cluster; the standalone-Docker dev path is retired.
"Core" webhook extensions — first-party extension functionality as components.
Open questions / deferred decisions
Synchronous component interaction pattern — async bus jobs do not fit latency-sensitive request work (OAuth, webhook dispatch). Deferred until the first such tenant. Stated direction: reuse TMI's existing REST/HTTP API style rather than introduce a second protocol (gRPC, etc.). The TMIComponent CRD is designed to accept an interactionType field later without a breaking change.
Controller build vs. Helm templating — preference is a custom controller; a Helm-templated interim is the documented fallback if controller delivery is too large for a milestone.
Design reference
docs/superpowers/specs/2026-05-16-extractor-component-isolation-design.md — full design of the first tenant (#347), which derived these platform contracts.
Summary
Refactor TMI from a monolith-with-deployment-variability into a Kubernetes-native system of cooperating components. The server binary has accreted significant complexity (most recently content providers with their authorization, fetching, chunking, and embedding logic). This roadmap establishes a generic component model so functionality can be moved out of the monolith over time, and standardizes deployment on container + Kubernetes — removing today's deployment-shape variability (local Docker, Heroku, multiple cloud registries).
This is a tracking/roadmap issue. Individual components ship as their own issues. The first tenant is #347.
Thesis
TMIComponentcustom resources.Architecture
TMIComponentCRD — the durable, runtime-editable contract for a component type.kubectl applyregisters a new type; no monolith redeploy. CRD OpenAPI schema validates declarations before any pod runs. Key fields:jobSubjects,inputMode,egress,spec.config,secretRefs,resources,timeouts,scratchVolume,scaling.TMIComponentCR into a Deployment + KEDAScaledObject+ NetworkPolicy + NATS stream/consumer wiring.Cross-cutting contracts (derived while designing the first tenant, #347)
none/fetch-controlled/allowlist. The controller renders the NetworkPolicy from it, and always renders a cluster-layer NetworkPolicy backstop regardless of in-code guarding.fetch-controlledis backed by one shared egress-guard library (owned by the T3 issue) — components never reimplement SSRF defense.emptyDir— never writable root,hostPath, or a PV.content-ref/source-locator), one stable job-envelope schema with optional fields, mode declared per-CR. Large payloads travel by reference via a JetStream Object Store, never as large NATS messages.Dev/test — three tiers
services:containerkindwith Calico/Cilium (kindnet does not enforce NetworkPolicy); CRD + controller + KEDAkind/k3d, prod-shaped manifestsmake start-devis reworked to bring up a local cluster; the standalone-Docker dev path is retired.Roadmap (component extraction order)
tmi-extractor+tmi-chunk-embedworkers. Proves the platform contracts.source-locator/fetch-controlledtenant (depends on the T3 shared egress-guard library).Open questions / deferred decisions
TMIComponentCRD is designed to accept aninteractionTypefield later without a breaking change.Design reference
docs/superpowers/specs/2026-05-16-extractor-component-isolation-design.md— full design of the first tenant (#347), which derived these platform contracts.Related issues
config-*.ymltoward bootstrap-only.fetch-controlleddepends on.