ADR-0001: kaged sits in front of adjacent operator tooling, not within
- Status: Accepted
- Date: 2026-05-21
- Deciders: @karasu
- Supersedes: —
- Superseded by: —
Context
There is a category of adjacent operator-oriented tooling already in the world that kaged has to position itself relative to:
- oh-my-pi — opinionated self-hosted operator setup with CLI-first ergonomics
- opencode and similar agentic dev tools — agent harnesses with hidden system-prompt rules and forced agentic loops
- Agentic coding harnesses generally (pi-harness and adjacent products) — long-running agents driven by configurations the operator does not own
- Self-hosted "operator console" products — dashboards that market a futuristic surface and ship a tile of disk gauges
kaged needs a position relative to these. The options on the table were:
- Fork one of the dashboard/console products as a base and replace its frontend
- Build kaged as an extension/plugin layer of oh-my-pi
- Build kaged from scratch and reuse adjacent tooling as adapters/data sources
- Build kaged from scratch and ignore the prior ecosystem
The question is load-bearing because kaged's most differentiated features — long-lived sessions, sandbox supervision, project DSL, mobile-first web UI, debug checkpoints — assume kaged is the lifecycle root of the operator's agent fleet. Where kaged sits in the stack determines what it can promise about lifetime, security, and access.
Decision
kaged is a new project, built from scratch, that sits in front of existing adjacent operator tooling. It does not fork or extend oh-my-pi, opencode, or any of the dashboard-style products. Their value (opinionated presets, agent harnesses, install scripts) is exposed to kaged via the plugin SDK as adapters and data sources.
Concretely:
- kaged has no parent process other than the operator's init system (systemd / launchd / equivalent).
- kaged's web UI is the primary product surface. Terminal access is exposed as a capability of the web UI (PTY-over-WebSocket), not as a separate CLI.
- oh-my-pi becomes an importable preset source — operators who want an oh-my-pi-flavored base can install one through kaged's plugin host.
- opencode and adjacent harnesses become session bridges — kaged can drive them via a plugin adapter, but they do not host kaged.
- Dashboard-style products are not used as a base; their frontend conventions and IA do not transfer.
Consequences
What this commits us to
- Writing the daemon, session manager, PTY broker, DSL runtime, sandbox supervisor, plugin host, storage layer, and web UI ourselves. There is no shortcut via inheritance.
- Maintaining a plugin SDK that's stable enough for third-party adapters to depend on.
- Documenting and packaging kaged for direct install on a fresh OS — we cannot rely on the operator having already gone through an oh-my-pi flow.
What this forecloses
- We cannot inherit a pre-existing user base by forking. Adoption starts from zero.
- We cannot reuse inherited frontend conventions or UI patterns from adjacent dashboards. Different IA, different aesthetic, different audience.
- "kaged is an oh-my-pi plugin" is not a posture we can take later without restructuring.
What becomes easier
- The architecture has full freedom: lifecycle ownership, sandbox supervision, and mobile-first UI all assume kaged is at the top. We don't fight a parent process's assumptions.
- Brand and UX are unconstrained by an inherited project's existing identity.
- We can ship a tight, opinionated v0 without backwards-compat baggage.
What becomes harder
- More to build before v0 is testable. The doc-first phase is correspondingly longer.
- Plugins must do real work: exposing an existing tool's capabilities through our SDK requires a real adapter, not just a re-skin.
- We carry the support burden for installation, OS-level integration, and lifecycle on every supported host.
Alternatives considered
Alternative A — Fork an existing operator-console product
Why tempting: Some of these products ship a tile-based dashboard and an "operator console" frame; forking inherits a head start on the visible surface.
Why rejected: Across the category, marketed feature sets substantially exceed what's shipped. The architectures are frontend-heavy and not designed to host long-lived sessions or supervise sandboxed subagents. The IA is geared at "view your host's stats" rather than "orchestrate agents per project." Inheriting any of these brands would also conflict with the kaged voice and identity.
Alternative B — Fork oh-my-pi
Why tempting: Operator-coded CLI ergonomics, opinionated defaults, an existing community of self-hosters.
Why rejected: oh-my-pi is CLI-first by design. kaged is web-first by design (see ADR-0002). Forking would mean either fighting the inheritance forever or restructuring it to the point where the fork has near-zero shared code with the upstream. The CLI/terminal posture also conflicts with kaged's "operator's phone is first-class" principle.
Alternative C — Build as an oh-my-pi plugin/extension
Why tempting: Minimal install friction for existing oh-my-pi users; ride the host's lifecycle.
Why rejected: The lifecycle root problem. A long-lived daemon that supervises sandboxed subprocesses must be a top-level process. Living inside another tool's lifecycle means we inherit its crashes, its upgrades, its shutdown semantics. For the supervisor of agent sandboxes, that's not acceptable.
Alternative D — Ignore the prior ecosystem entirely
Why tempting: Cleanest architecture, no compat surface.
Why rejected: oh-my-pi in particular has accumulated real preset-curation work that would be wasteful to re-do. Exposing it as an adapter gives operators the presets without making kaged the preset-maintainer. Similar argument for any future adapters into other agentic harnesses — the plugin model gets us interop without inheritance.
References
docs/02-architecture.md— the resulting architecturedocs/01-vision.md— the product vision this enables- ADR-0008 — the plugin model that makes "in front of" mechanical
- Original discussion: design conversation with colleagues, 2026-05-21