361 lines
5.8 KiB
Markdown
361 lines
5.8 KiB
Markdown
---
|
||
name: "Lang Framewok Missing Pieces"
|
||
description: "Language/framework recommendations and missing subsystems"
|
||
depth: 1
|
||
links: ["../index.md", "./spec-v0.1.md"]
|
||
---
|
||
|
||
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:
|
||
* [Ktor](https://ktor.io?utm_source=chatgpt.com)
|
||
|
||
reasons:
|
||
* coroutine-native
|
||
* lightweight
|
||
* excellent websocket support
|
||
* no spring complexity
|
||
* easy embedding
|
||
* modular
|
||
|
||
do NOT use:
|
||
* [Spring Boot](https://spring.io/projects/spring-boot?utm_source=chatgpt.com)
|
||
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](https://github.com/JetBrains/Exposed?utm_source=chatgpt.com) OR plain SQL
|
||
* [SQLite](https://www.sqlite.org/index.html?utm_source=chatgpt.com) initially
|
||
* migrate later to [PostgreSQL](https://www.postgresql.org/?utm_source=chatgpt.com)
|
||
|
||
serialization:
|
||
* [kotlinx.serialization](https://github.com/Kotlin/kotlinx.serialization?utm_source=chatgpt.com)
|
||
|
||
config:
|
||
* [Hoplite](https://github.com/sksamuel/hoplite?utm_source=chatgpt.com)
|
||
or
|
||
* [Typesafe Config](https://github.com/lightbend/config?utm_source=chatgpt.com)
|
||
|
||
logging:
|
||
* structured logging ONLY
|
||
* json logs
|
||
* correlation ids everywhere
|
||
|
||
CLI:
|
||
* [Clikt](https://ajalt.github.io/clikt/?utm_source=chatgpt.com)
|
||
|
||
TUI:
|
||
* honestly optional initially.
|
||
* if needed later:
|
||
|
||
* [Mordant](https://github.com/ajalt/mordant?utm_source=chatgpt.com)
|
||
* or web dashboard instead
|
||
|
||
web UI:
|
||
frontend:
|
||
* [SvelteKit](https://svelte.dev/docs/kit/introduction?utm_source=chatgpt.com)
|
||
|
||
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
|
||
|
||
1. scheduler subsystem
|
||
|
||
* queueing
|
||
* prioritization
|
||
* cancellation
|
||
* starvation prevention
|
||
* concurrency caps
|
||
* backpressure
|
||
|
||
eventually:
|
||
```text id="on4q1p"
|
||
StageScheduled
|
||
StageDeferred
|
||
StageBlocked
|
||
StagePreempted
|
||
```
|
||
|
||
2. capability negotiation
|
||
currently:
|
||
stage requests capabilities.
|
||
|
||
but models/tools/providers should advertise:
|
||
|
||
* hard capabilities
|
||
* soft capabilities
|
||
* confidence
|
||
* limits
|
||
|
||
example:
|
||
|
||
```yaml id="w4h8b4"
|
||
coding:
|
||
score: 0.92
|
||
reasoning:
|
||
score: 0.61
|
||
tool_calling:
|
||
score: 0.74
|
||
```
|
||
|
||
otherwise routing becomes binary and crude.
|
||
|
||
3. deterministic tool contracts
|
||
|
||
VERY important.
|
||
|
||
tools should never return freeform text internally.
|
||
|
||
tool outputs must be typed.
|
||
|
||
bad:
|
||
|
||
```json id="v4g2pr"
|
||
"pytest failed due to auth issue"
|
||
```
|
||
|
||
good:
|
||
|
||
```json id="i08vuj"
|
||
{
|
||
"failed_tests": [
|
||
{
|
||
"file": "auth_test.py",
|
||
"reason": "timeout"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
models can consume summaries.
|
||
harness consumes structure.
|
||
|
||
4. model sandboxing
|
||
|
||
define explicitly:
|
||
|
||
* max execution time
|
||
* max tokens
|
||
* max context
|
||
* max retries
|
||
* cancellation semantics
|
||
* kill signals
|
||
* watchdogs
|
||
|
||
otherwise local models WILL hang eventually.
|
||
|
||
5. config versioning/migrations
|
||
|
||
absolutely need:
|
||
|
||
```yaml id="v0i3qf"
|
||
config_version: 1
|
||
```
|
||
|
||
plus migration system.
|
||
|
||
6. projection snapshots
|
||
|
||
replaying 100k events eventually becomes painful.
|
||
|
||
need:
|
||
|
||
* periodic snapshots
|
||
* projection checkpoints
|
||
* replay cursors
|
||
|
||
classic event sourcing problem.
|
||
|
||
7. 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
|
||
|
||
8. state machine formalization
|
||
|
||
session lifecycle should become an explicit finite state machine.
|
||
|
||
not enums.
|
||
|
||
otherwise invalid transitions creep in later.
|
||
|
||
9. 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
|
||
|
||
10. trust boundaries
|
||
|
||
* model boundary
|
||
* tool boundary
|
||
* plugin boundary
|
||
* provider boundary
|
||
* ui boundary
|
||
|
||
especially if third-party plugins become possible later.
|
||
|
||
big recommendation
|
||
```text
|
||
everything important is append-only
|
||
```
|
||
|
||
events:
|
||
append-only
|
||
|
||
artifacts:
|
||
immutable
|
||
|
||
receipts:
|
||
immutable
|
||
|
||
approvals:
|
||
immutable
|
||
|
||
summaries:
|
||
versioned
|
||
|
||
projections:
|
||
rebuildable |