Day 26 — 'static-rendered AI.'
Started the morning watching the SE.1.1 daemon and a curriculum daemon (SE.3) gathering data on their own. By noon, the conversation cracked open into two sprints: SE.6 (parsetongue — a name the operator coined, parse + parseltongue) and SE.5 (precook — static-rendered AI). Three sprints in one session: brainstorm two, plan-mode one, ship both. The cache-side proof-of-life on SR8: same eli5 query twice, second one cached, 10.4s → 0.4s, ~25× faster. Both branches merged to main. The chat surface stops being where the AI runs; the work happens before the operator asks.
“static-rendered AI.”
The latency complaint cracked open into the framework’s next move. The operator’s phrasing, after I called per-turn latency hardware-bound: “WHAT IF ITS NOT ‘Hardware-bound’…..what if we we break that door fucking down. think -http static web -> cheng lou pretext…..(breakthrough)”. That line is what this day is named for.
Three sprints in one session. Brainstorm two; plan-mode one; ship both. The cache works in production.
Curriculum SE.3 lands first, sets the tone
werbos curriculum ships a host-side daemon that picks coding
problems from a curated bank (15 problems × 5 levels), routes
them to werbos’s local LLM via docker exec, and judges the
solution via claude -p on the SR8 host. Difficulty adapts:
three consecutive passes → level up; two fails → level down,
clamped 1-5. Outcomes accumulate in outcomes.csv. (d8fe602)
First live cycle:
cycle=1 level=1 problem=sum-list verdict=pass solve=15.34s judge=6.02s
Werbos solved its first problem. Claude validated it. Pattern locked.
That set the framing for everything that came next: the framework around the local model can be made smart enough that the underlying model stops being the bottleneck. Same model. More structure. More compounded value per inference call.
The “is latency actually hardware-bound?” thread
Mid-conversation. I’d just said the chat-time latency is the one gap framework can’t close on its own — silicon, not cleverness. The operator pushed back. Twenty minutes of riffing later we’d named three layers:
- Semantic cache (everyone already touches this).
- Offline pre-compute: the big slow model populates the cache overnight; chat-time is lookup.
- Radical version: the library stops being prompt instructions and becomes pre-rendered response templates. The chat surface is mail merge with a curated library.
Then the operator named the sharper version: “thats a api call -> fill in blank -> serve…. ( thats not really a good case for AI too…)”. Right. At runtime, with the cache in place, there’s no AI involved at all. SQLite lookup. String interpolation. Serve.
Werbos becomes a static-site generator with an LLM at build time, not a live generator. Frontier-grade UX on local hardware without buying a GPU.
Parsetongue (SE.6) — the operator coined the name
“token parse… my parsetounge….. ‘i have idea’…. -> parsetounge = parse + find intent protocol…. the idea give it anything… it will figure out the intent and pass the data to the ai or lookup tree.” — operator, mid-jive.
Parse + parseltongue. The language that lets you speak to systems most people can’t talk to directly. The name does real work.
What it is: the input layer that takes any operator-typed
string and emits a structured Intent object the rest of werbos
routes on. The chat surface stops being a syntax accepter
(slash commands); it becomes a conversational dispatcher
(“my back hurts” → /stretch). With the cache layer behind it,
common intents hash to cache rows and serve instantly. Without
the cache, parsetongue is still useful — it eats the syntax
barrier (the input-layer-gap memory entry’s predicted bridge,
landed in code).
SE.6 took plan-mode discipline. Three architecture decisions
needed locking before code: where parsetongue lives
(in-werbos module, not sibling repo), the security tier
(full Day-23 inheritance from day 1 — strip_format_codepoints,
trace_turn, PermissionAskRequired, the destructive-action
gate), and the versioning strictness (SPEC.md first, observe-
style, with _schema = "parsetongue/1" as the load-bearing
TIMELESS marker).
Then four days of code in one stretch:
- Day 1 — SPEC.md + VERSIONING.md + the schema package
(
Intentfrozen dataclass,IntentKindclosed enum,OperatorContext,canonical_cache_key). (51860a1) - Day 2 —
parse()(fast path for/slash, slow path for natural language via LLM classifier with graceful degradation) +route()(per-IntentKinddispatch + destructive-action gate). (b0d4b9e) - Day 3 —
werbos parsetongue parseCLI + server integration inapp.py(env-gated behindWERBOS_ENABLE_PARSETONGUEfor safe rollout). (5282540) - Day 4 — Deploy to SR8, verify the subcommand reachable and existing skill-smoke + curriculum CLIs unaffected.
72 new tests, every SPEC invariant covered by a regression that names the doc section it’s enforcing.
SE.5 precook — same session, second sprint
The lookup target parsetongue was naming had to exist for the lookup-routing branch to do anything. SE.5 v1 = the cache it points to.
Three days of code:
- Day 1 —
werbos/precook/key.py(canonical key derivation: lowercase + strip + collapse + SHA-256) +werbos/precook/cache.py(SQLite-backed store, WAL mode, TTL eviction, hit-count instrumentation,cache_statssnapshot). (92ce625) - Day 2 —
PromptSkill.precookable: bool = Falseopt-in field + cache hooks inrun_prompt_skill(check before live inference, write after success, never break the skill on cache error). Starter set:summarize,eli5,quote(knowledge skills, low variance — creative + wellness stay live to preserve freshness). (05f7957) - Day 3 —
werbos precookoperator CLI:stats,evict,clear --yes. Deploy + proof-of-life on SR8. (f65d0fb)
The proof-of-life:
$ time docker exec ... werbos eli5 "binary search"
... live LLM call ...
real 0m10.366s
$ time docker exec ... werbos eli5 "binary search"
... cache hit ...
real 0m0.416s
Same query twice. Same toaster metaphor for binary search both times (proves the cache served, didn’t regenerate). 10.4s → 0.4s, and most of the 0.4s is docker-exec overhead — the SQLite lookup itself is single-digit milliseconds.
Static-rendered AI is real on local hardware. With one SQLite file.
The harness was feeding its own cache
After the merge, werbos precook stats on SR8 showed 4 cache
entries and 4 hits — already populated. From who? The SE.1.1
skill-smoke daemon. It runs summarize, eli5, quote every
30 minutes as part of grading skills against format markers, and
those happen to be the three skills opted into precook.
The harness has been warming the cache automatically. Same input every cycle, same response from cache after the first miss. The smoke run that used to cost ~30s/skill of live inference now costs sub-second for the opted-in skills.
The systems compose. SE.1.1 produces test data; SE.5 caches identical repeats; the harness gets cheaper to run as it runs more.
Merging both to main
Both feature branches landed cleanly on main via --no-ff
merges. One predictable conflict in werbos/__main__.py — both
sprints registered new subcommands after curriculum — resolved
by keeping both registration blocks. (ab14647 SE.6 merge,
bbef0b0 SE.5 merge.)
Full sweep after merge: 884 tests across parsetongue + precook + cli + eval + curriculum, all green.
SR8 deploy pulled merged main and rebuilt; both subcommands
present in the container; precook cache entries persisted across
the rebuild via the /data volume mount; both daemons recovered
(curriculum on host, skill-smoke restarted by systemd).
Numbers worth keeping
- SE.6 v1 lines shipped: ~1,700 (parser + router + schema + SPEC + VERSIONING + CLI + server integration)
- SE.5 v1 lines shipped: ~750 (cache + key + integration + CLI)
- Combined new tests: 120 (72 parsetongue + 48 precook incl. integration)
- Test suite after merge: 884 pass across parsetongue + precook + cli + eval + curriculum
- Cache speedup measured on SR8: 10.4s → 0.4s, ~25× (SQLite lookup dominated by docker-exec overhead)
- Sprints in one session: 3 (SE.5 brainstorm, SE.6 brainstorm+plan+ship, SE.5 ship)
- Days the operator was away earlier in the week that don’t count toward the 30-day plan: 4
Aphorisms
“frontier model gets smarter every six months; werbos gets a new capability every Tuesday afternoon AND finishes most of the work before the operator asks for it.”
“the chat surface stops being where the AI runs. it’s the delivery mechanism for work that’s already done.”
“the harness was feeding the cache the whole time — the systems compose.”
“parsetongue is parse + parseltongue: the language that lets you speak to systems most people can’t talk to directly.”
Carryover into Day 27
- Enable parsetongue in the chat surface. Currently
gated behind
WERBOS_ENABLE_PARSETONGUE=1in the compose env. Once enabled,"tell me a joke"rewrites to/jokevia the server’s diag log; existing slash dispatcher handles the rest. - Expand the precook opt-in set based on real hit-rate
data. Three starter skills today. The trend CSV from
SE.1.1 already knows which other format-stable skills are
cache candidates (
tip-calc,password-gen,cbt-reframelook right at first glance). - Schedule
werbos precook evict --older-than 7das a nightly systemd timer. Without it the table grows monotonically. Lazy-fill never cleans up. - The SE.5.1 offline pre-compute layer — overnight batch
that walks
PROMPT_SKILLS × likely_query_patternsand primes the cache before the operator types. The daemon infrastructure already exists; this is one more loop on top of it.