AI end-to-end
for business operators
Describe it in plain language. The Cascade planner builds the plan, durable agents run it, eval grades it, the loop evolves it.
- the plan agents
- the steps agents
- the runtime engine
Every run can make the next one better.
You approve the proposal and the final change.
The playbooks, context and rules
that make this operator yours.
Candidate and incumbent replay the same frozen inputs under the same judge. A guard past its band vetoes before any score is read. A losing candidate closes its own pull request; an inconclusive result goes to a human.
The run at the top is what the loop improves. The nine stages under it are the loop. What is fixed below is fixed for every brain that runs on this engine — it is the part that makes a self-editing loop something you can leave running. What is left open is left open on purpose: the thresholds, the models and the deadlines belong to your operation, not to the framework that hosts it.
| Stage | Fixed for every brain | Your brain chooses |
|---|---|---|
| 01 · Run Run what the loop improves | The playbook in your repo executes against real tools and pauses for the approvals your operation declares. Every run leaves the record the next stage reads. | The playbook, the tools, and where it stops to ask. |
| 02 · Grade Evaluate | Every criterion comes back with a verdict, the evidence for it and the reasoning — never a bare number. The judge model and the method’s hash are recorded on the row that carries the score. | The method, the threshold, the judge model, and your own metrics with the job each one does: objective, guard, observe. |
| Trigger | Never opens on a single bad run: k of the last n graded runs have to have missed, and the newest must be one of them. A single execution samples an operation’s noise — the trigger reads the window, never the morning. | windowRuns and minFailures — the engine defaults to 2 of the last 5 — or your own shouldImprove(). |
| 03 · Propose Freeze | Before anything is written, the cycle pins what it will measure on: the entity’s last graded inputs, deduplicated, plus your golden cases, plus the commit the current version stands at — and the judge. Everything the cycle compares, it compares on these. | How many inputs, and which golden cases join them. |
| Analyse | The analyst is read-only and cannot open the rubric. Its evidence is the window — the runs that missed first, carrying the judge’s reasoning per criterion — and the earlier proposals for this entity with how each one turned out. | The model, the prompt, and how much evidence it reads. |
| Decide | Who decided is on the record. One live improvement per entity, so two proposals never race for the same file. | decide: human or auto, and how long the question stands. |
| 04 · Prove Apply | Always a pull request, written by an agent whose write access is an allow-list: the files the accepted proposal named, and nothing else. That one list is rendered three times — into the agent’s own permissions, into the sandbox around it, and over the diff afterwards — so a rule means the same thing before a write and after it. The engine’s floor is add-only: a brain can protect more, never less. | protectedPaths brain-wide, editablePaths per entity. |
| Check, before the merge | The candidate and the version it wants to replace run the same frozen inputs, under the same judge, in the same runtime — so the two sides differ in exactly one thing. The verdict is an ordered rule over the metrics rather than one score: a guard past its band vetoes mechanically, before any judge score is read. It publishes as a commit status, which is what lets the repository require it. | check: replay or none, attempts per input, the deadline, and your own verdict(). |
| 05 · Merge Merge | The engine publishes its own checks, so an automatic merge always has something to wait for — and the doctor warns when the base branch requires none, because a merge with nothing required is an unreviewed push. A revert is a pull request through the same gate. | merge: human or auto, and the merge method. |
| 06 · Watch Observe and settle | After the merge the entity’s own next runs are counted by the rule the trigger uses, asking one question: would this have triggered again? A change that would has regressed, and its revert opens. A lesson is filed whether the change won or lost. Regressions in a row pause autonomy until a person acknowledges them. | watch: observe or none, the window, and the deadline. |
One cycle’s actual diff, and the ordered rules its verdict settled in, are drawn further down this page — the loop ↗. The write surface it runs under, with the receipts behind it — self-evolution ↗.
You own the brain. The engine earns every change.
Bring me one operationSame relationship a Next.js app has to its platform: the brain — markdown prompts, capability declarations, planner methods, one omnislash.config.ts — is yours, diffable and self-hosted. Everything else you inherit, not build: every mechanism this page goes on to prove, plus the stack that’s normally a three-year project. No queue wiring, no Postgres schema, no Restate handler, no retry logic, no dashboard.
yours
--- name: Competitor Watch schedule: every day at 9am --- ## Steps 1. Collect — pricing, changelog, jobs … 2. Diff vs yesterday — what moved … 3. Classify — release / price / hiring … …
12 files · diffable · yours
inherited — you did not build this
infrastructure
the substrate it lives on, deploys as, and is watched through
intelligence
what it thinks with, reaches for, and learns from
control
who is allowed, who is watching, who owns the record
the stack that’s normally a three-year project — ships with the engine
≈1 week · you author the brain ≈3 years · the framework under it, already built 1 : 156
None of that is a roadmap. Here is the same engine running — a fleet mid-turn, a run being spent against its plan, the bill it ran up, and the checks it runs on itself — on the build this page was written against.
The brain is the part that’s yours. The engine is the part you’d hate to build — and it’s already built, and running.
receipt · file names are illustrative; every frontmatter key, path convention and API name is real — brain-example/ ships working files for nine of the eleven kinds on the card (Scenarios, Agents, Heartbeats, Hooks, skills/, tools/, *.pipeline.ts, omnislash.config.ts, memory/); the grading method and the ingest source are engine contracts that fixture does not use · docs/features.md · docs/replay.md
Refunds, pricing exceptions, incident response — the knowledge that today lives in fragments and in people. Omnislash keeps it as a living, versioned map the engine can read and act on, kept current without anyone curating it.
Unset, every agent shares one line; a role gets a private one the moment its file names it. And the line rides the run, not the prompt: the write tool has no argument for it, and one in the call is stripped rather than honoured.
Two agents will eventually write the same file. Because the brain is a real repo, that surfaces as a merge conflict — not as one edit quietly overwriting another.
The sync daemon stops touching the repo, hands the merge to an agent, and tells you once. It reopens only when a full sync runs clean again — the agent saying “fixed” doesn’t count. See the mechanisms →
You pick the altitudes. A year of the line is 365 logs; six files of it reach the turn with no search call, and never more than 25 000 chars however large the line grows. What the ceiling cuts off the top rung is what the bottom one hands back.
those four folders are not a metaphor for a UI — they are the UI
and in a pocket — a company’s knowledge is consulted where the question is asked
Set the permissions, choose who answers approval requests, and step in when a run needs guidance. Every action and decision stays on the record.
the record · the desk screens
the 3am path · on a phone
scenarios fire while you sleep. tonight: ten tool calls, 23:41 to 05:30, each named by the capability it needs.
every capability carries a risk tier and an hitl flag — the flag is the gate. seven of 56 ship flagged; tonight five calls hit one and raise a card to you.
your constitution flips any flag: one line in a file, reviewed like code, so no agent can. yours opens two locks, shuts one.
a flagged call does not fail. the run suspends at zero compute and waits for its answer — however long that takes.
one card per capability, however many callers — seven emails, one tap. the runs sit parked, waiting on you.
a standing grant — one scope, a TTL, a call ceiling — approved once on your phone, or declared in the scenario. email:send never raises a card again.
a boss run — time-boxed, started by hand — takes every flagged call and signs an answer sixty minutes later.
every flagged call still got an answer — your file, your grant, or your delegate — signed and replayable. the levers are yours: flip them.
telegram · 09:00 screenshot slot · 5 cards
Let a boss handle approval requests for a set time, within limits you choose. Or answer them yourself and guide a run when it needs help. Every decision stays on the record.
on /agents · one run at a time
expires one of
5m30m1h4ha date
past it, every wake-up is dropped unread
head start one of
0s30s1m5m
answer inside it and the boss finds nothing to do
kinds any of
questiongrant_request…
a kind left out never reaches it
initial holds
hitl:write
what the boss itself carries, for the run’s length
approvable may approve
email:sendmessaging:send
what it may hand to other agents
it ends with a summary: duration · turns · tools by count · decisions by kind and status
you · 02:07 Anything asking for a refund over $200 — park it for me. Answer the rest.
the agent Understood. Two tickets parked for you; resuming the other eleven under the same grants.
you · 02:09release
Released · continuation → the task’s resultomnislash/validation at the PR head, before the merge
AI end-to-end handles 80–90% of operations. The rest eventually need more predictability than autonomy gives — so the dial is per workflow: keep the easy 90% AI-managed, and pull the mission-critical ones down to a locked blueprint or hand-written code.
for business operators
Describe it in plain language. The Cascade planner builds the plan, durable agents run it, eval grades it, the loop evolves it.
for power users, analysts
Let AI draft the plan, then freeze it: export the blueprint, edit tasks and DoD, lock phases. Deterministic — no re-planning per run.
for software engineers
Write a typed Restate pipeline in TypeScript. Every step, branch and error handler is code; agents are called as typed steps, not autonomous actors.
describe & run → lock the blueprint → engineer it — per workflow, not per account
the same path, screen by screen
| platform | tier 1 | tier 2 | tier 3 |
|---|---|---|---|
| n8n · Zapier · Make | — | visual | — |
| LangGraph · CrewAI | yes | — | partial |
| Temporal · Restate | — | — | yes |
| Omnislash | yes | yes | yes |
Most platforms are built for exactly one of these tiers; Omnislash spans all three, with a path between them. A Tier-3 pipeline isn’t a separate product — it inherits the entire engine: the same agents, eval, memory, tools, HITL and scheduler the AI tiers use, called as typed steps.
all three tiers land in the same run list, graded the same way
Two of these didn’t start in the column they’re standing in — they were escalated a tier, one workflow at a time, on the same instance. The other 61 never moved, and nothing had to be migrated for them.
Machine-readable interfaces — catalogs, APIs, MCPs — are what let an agent work without a person driving. Omnislash ships that surface both ways: every tool declares what it does and what it risks, so an agent reads before it calls instead of scraping docs — and the same declaration makes your own product agent-ready, with no per-integration boilerplate.
It runs the other way too — an agent can work a channel as a person, answering in your own DMs with no bot chrome. The same gate applies from the inside: every tool call it makes there is pinned to that one conversation.
the same gate · from the phone it reaches
The surface
what an agent finds when it looks
Headless OAuth
the redirect becomes a consent card
The card above is drawn. The real one — the request, the partial approval, the grant it mints — is photographed in the three phone tiles this section opens with. The full machinery — HMAC state, replay guards, one-shot PKCE, per-issuer DCR locks — is one tab away: Headless OAuth →
Every trigger enters the same governed runtime: what is allowed to wake a run, what every path passes through on the way, and where the work goes when it leaves.
The webhook server, cron, event bus, and notifier ship with the engine.
ways in · what wakes it 16
a person says so
the clock
the world
the system itself
what every path passes
who is this?
surface · actor · subject. Nothing runs anonymous, on any door.
one durable owner
chat · heartbeat · hook · task · pipeline step · planner stage · eval — one object, per agent. Crash and it replays; park on a human and it holds the lock.
one gate
capability · risk · a grant with a TTL. No grant → a typed refusal naming how THIS caller can ask.
ways out · where it lands 7
Most automation is an open loop: it runs, and a human checks later. Here the loop closes on the record — every action lands in one searchable activity stream and a real control plane. Inside a run, a failed check branches a recovery agent that patches the plan and resumes. Between runs, the operation rewrites itself — as a pull request that has to beat the version it replaces on the same inputs, under the same judge, before it merges. You choose human review or autonomous approval. The lesson is a file in your repo; the change is a diff. Here is one.
The ring is a diagram of something already running. Here is one lap of it on the record: the run list, a run in flight, its tasks, what it cost, the grade it earned, the change it proposed about itself, and the backlog that change lands in.
the diff — PR #214, off the run at the top of this page
constitution/Scenarios/Finance/revenue-recovery.scenario.md
An analysis opens on a pattern, not a bad morning — two of the last five graded runs came in under the bar. Three challengers ran, and the engine reads them in this order. The first rule that answers decides.
03 above 05 is the design: a guard past its band outranks any score the judge produced, so “cost halved, quality through the floor” never reaches the objective. Stop at 01 and the verdict is unvalidated — nothing shipped, no lesson, and the PR stays open with the merge gate back in your hands. From 02 down it is regressed, and before the merge that closes the PR outright.
Deciding and merging are two gates, and both start as your button. Arm either, and two regressions in a row hand it straight back. The lesson is filed on a loss too: “this mutation made it worse — don’t retry it here.”
the fence — it may move the numbers, never the ruler
Every proposal that survives the fence queues up in one backlog . The rubric fence and its cited receipts are one tab away — Self-evolution →
Eleven mechanisms a skeptical staff engineer would want to see before trusting an agent with production. Each names the failure in your vocabulary, the exact primitive that fixes it, and a test you could re-run. Use the index to jump.
One of them no lab will ship: the labs each orchestrate their own agents. Omnislash runs all of them — claude, codex, opencode, API models — under one policy gate, with cross-harness fallover mid-task. Model fabric → What each one costs a turn →
Durability · the failure every framework ships
A HITL wait in most frameworks is a blocking thread or a from-scratch rehydrate, so a crash mid-wait loses the turn. Here the entire session is one Restate virtual-object invocation, keyed by agentId: it owns the prepare, the subprocess turns and a multi-day human pause, suspended at zero compute while still holding its exclusive per-key lock. It journals the resume handle via ctx.set before ringing the lifecycle bell, and a finally clears it on every exit — so single-writer ordering, callback identity and exactly-once settlement fall out of the live invocation for free, not rebuilt across a rehydrate.
receipt · agent-vo.ts:639-666 (ctx.set before the bell) · real-Restate test agent-vo.integration.ts:508-595 asserts exactly-once settlement across a kill.
Durability · the bug only production shows you
The agent row still reads idle — current_invocation_id is projected only after the virtual object grabs its per-key lock. So control here never trusts the read model: stop, liveness and the HITL barrier all query Restate’s sys_invocation over SQL, which is ground truth. Two details prove this was learned in production, not whiteboarded: Restate serves binary Arrow IPC unless you ask for JSON, and a finished invocation lingers ~24h as completed — so the orphan reconciler filters status != 'completed' and re-verifies each run individually. A stale batch read can never mass-false-resume.
receipt · restate-client.ts:481-495,:274-311 · AgentController.ts:489-522.
Governance · the rogue-agent fear, as a database problem
A framework without a shared HITL ledger — which is nearly all of them — raises N prompts for N callers needing sign-off, by construction. Omnislash collapses them with one Postgres upsert — ON CONFLICT (dedup_key) WHERE status='pending', first-writer detected via xmax=0 — keyed on [subject, scenario, sorted-caps] with the producer omitted, so a pipeline, an agent and a workflow converge on one card. One approval fans back out to an awakeable, a paused virtual object and a workflow FSM, each wake idempotent. The decision is CAS-committed to Postgres before the grant is issued; die in that gap and a 15s reconcile sweep replays it — the human is never re-asked.
receipt · grant-dedup.integration.ts:34-158 · validateApprovalActions.ts:111-124 (forged-button rejection).
Isolation · “cool demo” → “I’d run it on my prod”
The Claude and Codex SDKs spawn their CLI internally and expose exactly one knob — an executable-path override — so the engine points it at a bwrap shim that execs the real jail: --ro-bind / / --proc /proc --unshare-pid --unshare-ipc --die-with-parent. It binds the per-run git checkout over /app/brain so every absolute path still resolves, and binds the artifacts root RW at its own sibling absolute path — so the agent’s declared output reaches the validator while a write to /app/brain stays trapped in a throwaway clone. The boot gate probes the exact namespace combo and refuses to start if it can’t actually jail.
receipt · bwrap-claude.sh:41-58 (verbatim argv) · artifactsTopology.integration.ts:115-161 (real-bwrap containment test).
Model fabric · the outage every subscription team has lived
resilience4j and opossum are in-process and threshold-only — every worker re-discovers the same dead upstream and burns its own retry budget. Omnislash turns the provider’s own wall-clock-with-timezone recovery string into an absolute instant (regex + Intl.DateTimeFormat) and an atomic Redis-Lua breaker pins the harness open until exactly that moment — the first worker to hit the wall makes every other process fast-skip it. The runtime state itself is one string in one TEXT column. And when a chain falls over mid-task, the partial tool-use transcript is rebuilt from your own Postgres into vendor-neutral markdown that tells the successor: read this, do not redo committed work.
receipt · redisCircuitBreaker.integration.ts:210-214 · handoff.ts:92-102.
Model fabric · the bill nothing else in your stack itemises
A turn opens with a prefix — the tool array, the system prompt, the memory envelope — that is paid on every single turn and never shrinks. A context-window meter shows one total for the last turn and cannot attribute a byte of it. Omnislash itemises that prefix per role by assembling the real prompt rather than a description of one, then names the lever rather than the number: this role’s skills catalog is a sixth of its prefix, give it a focus list. Two figures are never conflated — what is actually on the wire on turn one, and what is priced but deferred behind tool search. And the difference between harnesses is the part only a multi-vendor engine can see at all: of the three the engine drives, exactly one hides tool schemas behind a search tool, so the same brain config that is a rounding error on one is tens of thousands of tokens a turn on another. Anything the report knows exists but could not price is counted unmeasured, never as zero — the total is an admitted lower bound, not a number that quietly omits the thing you opened it to check.
receipt · mcp-wire.ts:164 (the deferring-harness list is one entry long), :232 · thresholds.ts:14-42 (every judgement number, with the rationale beside it) · estimate.ts:28-31 (two chars-per-token buckets, ≈±15%, marked ≈ on every surface) · docs/context-budget.md.
Planning · the silent corruption one-shot planners ship
So one-shot planners ship a plausible, broken plan the moment the LLM silently drops task-3 while mapping capabilities. Omnislash plans in up to 11 independently schema-constrained hops, and every enrichment merge runs assertTaskCoverage — diffing the stage’s task IDs against the live set and throwing with the exact missing ID, one targeted re-prompt, then escalate. Each stage snapshots to Redis before the LLM call, so killing the worker at stage 7 resumes at stage 8 with zero re-spent tokens. The final-review stage critiques the real assembled blueprint, but its output schema has no add-task or delete-task field — the worst self-review failure mode is impossible by construction.
receipt · stageSchemas.ts:311-340 (the 5-field review whitelist) · buildPipeline.ts:71 (coverage assertion).
Isolation · live edit vs pull request, decided at the git layer
The brain stays live: on the default rung an agent writes straight into the running checkout and a sync daemon commits and pushes — the agent never pushes. What makes that safe is that the daemon commits exactly a declared push surface and nothing else, so a write outside it is not merely “not hot”, it is never persisted — the container is writable, the write succeeds, and it vanishes on the next recreate. That silent loss is now a boot-time failure. A path in the set must be a directory, because a sparse-checkout anchor never matches a blob and a file there would lose every write. Two classes are forbidden outright, for blast radius rather than boot order: docker/ — an agent that can commit a compose override can mount the docker socket into its own container — and .github, where an edit is arbitrary code on the runner. Everything else is cold, and a live agent that needs one delegates to a rung that commits and opens a PR.
receipt · brain-paths.ts:114-145 (the forbidden set, split structural vs blast radius) · project.ts:721-773 (the directory assertion, and the second door through contentRoots) · docs/agent-isolation.md (the ladder, and what each declaration site actually does).
Self-evolution · autonomous, because it’s fenced
The boundary is not an instruction in a prompt. One accepted proposal resolves to one list of paths, and the engine renders that same list three times — before the write, around it, and over the diff after it. The rubric sits on the unreadable side: the improver works from per-criterion feedback and never opens the thing scoring it. And the one rule no path can state — an entity's own evaluation: and improvement: blocks sit in the very file it is rewriting — is held by comparing them before and after: any move rejects the change.
receipt · protectedSurface.ts:70-97 (the three lists) · protected-paths.ts:74-77 (the rubric, closed to reading) · protectedSurface.ts:160-181 (the measurement blocks). Designed against DGM Appendix H + METR reward-hacking reports.
Depth · the protocol most frameworks skip
Most agent frameworks treat MCP servers as no-auth or static bearer tokens. Omnislash implements the MCP SDK’s OAuthClientProvider so the official auth() orchestrator runs the full RFC 9728 / 8414 / 7591 / 7636 / 8707 flow unchanged — except redirectToAuthorization() doesn’t redirect a browser, it mints a durable oauth_consent row a human approves later from Telegram. The protocol scars prove someone got bitten by the real spec: HMAC-signed stateless state, a SET-NX replay guard, a GETDEL one-shot PKCE, a per-issuer DCR lock, and an RFC 7009 revoke if the token-persist fails. That consent card is the same hitl_interactions row as every other human pause.
receipt · mcp-oauth-provider.ts:148,:419-477,:303-371 · oauth-state.ts:119-189.
Depth · the capability that needs a fence, not a disclaimer
Connect a bot to Telegram Business and the engine runs turns on messages from the private chats you chose, replying on your behalf with no bot chrome at all: no status cards, no keyboards, no typing indicator, no reactions — one plain message. A failed turn is silent for the other person: no error bubble, nothing appended to a half-streamed answer; you get one plain note in your own control DM, and approval cards reroute there too. The connection id is a credential, never identity — the platform rotates it whenever you edit the connection — so state is keyed on (chat, bot, owner) and survives a disconnect and a rotation. The agent reads the real history through MTProto, including messages from before the bot existed that the Bot API can never see, and that is exactly why the fence exists: under a business chat every MTProto call is pinned to that one conversation. An account-wide tool, another chat’s id, or an explicitly named account is refused permanently. A counterpart-facing agent must not become a window into your whole account.
receipt · helpers.ts:239-262 (the scope refusals, verbatim) · telegram-error.ts:35 (classified permanent, not retryable) · businessFailureNotice.ts (you get the failure, they don’t) · docs/secretary-mode.md.
Pick one operation that should run itself. Tell me what it is, who owns it today, and where it breaks. I'll map it to a brain and a scenario and walk you through how it runs — durable through a crash, gated at every permission, graded against a definition of done, and rewriting its own playbook between runs. On the engine every receipt above points at, not on a slide.
Prefer to dig in first? See the packages & image
Send me the one operation: what it is, who owns it today, and where it breaks. It comes straight to me — I read every one and reply myself.
Talk to me about your operation