5.8 KiB
name, description, depth, links
| name | description | depth | links | ||
|---|---|---|---|---|---|
| Lang Framewok Missing Pieces | Language/framework recommendations and missing subsystems | 1 |
|
language: use Kotlin.
not because it’s trendy, but because architecture is inherently:
- state-heavy
- concurrency-heavy
- schema-heavy
- event-heavy
- validation-heavy
that maps extremely well to:
- sealed hierarchies
- coroutines
- structured concurrency
- immutable data classes
- serialization
- type-safe DSLs
avoid:
- Python as primary runtime
- TypeScript as orchestration core
they’re excellent glue languages, but this system is closer to:
- a workflow engine
- an orchestration runtime
- a distributed state machine than an app backend.
kotlin gives:
- better long-term maintainability
- safer concurrency
- better event typing
- cleaner DSLs
- stronger replay guarantees
framework stack core runtime:
- plain kotlin first
- minimal framework dependence
web/api:
reasons:
- coroutine-native
- lightweight
- excellent websocket support
- no spring complexity
- easy embedding
- modular
do NOT use:
- Spring Boot spring will slowly eat the architecture:
- hidden lifecycle
- implicit DI magic
- reflection-heavy
- runtime complexity
- startup overhead
- difficult deterministic control system wants explicit orchestration.
persistence:
- Exposed OR plain SQL
- SQLite initially
- migrate later to PostgreSQL
serialization:
config:
logging:
- structured logging ONLY
- json logs
- correlation ids everywhere
CLI:
TUI:
-
honestly optional initially.
-
if needed later:
- Mordant
- or web dashboard instead
web UI: frontend:
not react.
reasons:
- simpler state model
- less boilerplate
- lower memory
- faster iteration
- easier websocket/event-stream integration
ui should behave like:
- workflow inspector
- event debugger
- replay console
- orchestration monitor
NOT “chatgpt clone ui”.
transport:
- websocket first
- event-stream oriented
REST only for:
- management
- configs
- health
- exports
real-time state should be event-driven.
architecture split important: core MUST NOT depend on infrastructure. only interfaces/ports. hexagonal architecture fits this system very well.
recommended internal layering domain layer pure logic:
- events
- transitions
- policies
- approvals
- artifacts
- projections
- session state
NO IO.
application/service layer orchestration:
- stage execution
- replay coordination
- context synthesis
- validation pipeline
- routing
infrastructure layer actual implementations:
- sqlite
- llama.cpp
- shell execution
- websocket
- filesystem
interface layer external access:
- cli
- api
- ui
- websocket
plugin layer dynamic extensibility. missing pieces in the spec
- scheduler subsystem
- queueing
- prioritization
- cancellation
- starvation prevention
- concurrency caps
- backpressure
eventually:
StageScheduled
StageDeferred
StageBlocked
StagePreempted
- capability negotiation currently: stage requests capabilities.
but models/tools/providers should advertise:
- hard capabilities
- soft capabilities
- confidence
- limits
example:
coding:
score: 0.92
reasoning:
score: 0.61
tool_calling:
score: 0.74
otherwise routing becomes binary and crude.
- deterministic tool contracts
VERY important.
tools should never return freeform text internally.
tool outputs must be typed.
bad:
"pytest failed due to auth issue"
good:
{
"failed_tests": [
{
"file": "auth_test.py",
"reason": "timeout"
}
]
}
models can consume summaries. harness consumes structure.
- model sandboxing
define explicitly:
- max execution time
- max tokens
- max context
- max retries
- cancellation semantics
- kill signals
- watchdogs
otherwise local models WILL hang eventually.
- config versioning/migrations
absolutely need:
config_version: 1
plus migration system.
- projection snapshots
replaying 100k events eventually becomes painful.
need:
- periodic snapshots
- projection checkpoints
- replay cursors
classic event sourcing problem.
- artifact lineage graph
this one is important and often missed.
artifacts should track:
- parent artifacts
- originating events
- tool receipts
- approvals
- validator passes
this enables:
- blame tracing
- replay diffing
- synthetic training extraction
- state machine formalization
session lifecycle should become an explicit finite state machine.
not enums.
otherwise invalid transitions creep in later.
- policy engine
currently mixed into approvals/validation.
should probably become its own subsystem.
because eventually policies will govern:
- tools
- providers
- models
- routing
- retries
- approvals
- networking
- secrets
- filesystem access
- trust boundaries
- model boundary
- tool boundary
- plugin boundary
- provider boundary
- ui boundary
especially if third-party plugins become possible later.
big recommendation
everything important is append-only
events: append-only
artifacts: immutable
receipts: immutable
approvals: immutable
summaries: versioned
projections: rebuildable