Omnislash — the self-evolving operator for your company

  • Durable Kill the box mid-run. The same turn resumes and settles exactly once.
  • Governed Nine parallel runs hit one wall — you get one approval card, not nine.
  • Self-evolving It rewrites its own playbook — as a pull request graded against the version it replaces.
  • Yours Your repo, your keys, your box — and any vendor’s agents, not one lab’s.
what you can ask it for

You send one message. It builds the whole operation, and runs it.

Four businesses, four separate operations. Pick the one closest to yours.

You your part

Find a niche where short explainers can sell our $29 template; show me three, with evidence. Then run the channel: one original Short a day, each on one sourced point, labelled AI-voiced. Post to YouTube, Instagram, and TikTok through an approved scheduler. Turn viewers into signups and sell the template. Grade each video at 48 hours and 7 days, answer comments, keep improving. Keep AI spend under $250 a month. First Monday monthly, we replan together; otherwise ask only if a platform flags us.

to your chief, in Telegram sent ✓✓

Where you come in

  1. Once, to start Pick one niche of three, connect accounts, approve the upload code.
  2. First Monday monthly Read one page and decide together. Between reviews it only tunes parts.
  3. A platform flags you One card: what was flagged and what it suggests.

No file to edit, no prompt to write, no log to read.

Omnislash everything else 46 parts · 8 features

3 running now · grades itself on email signups per 1,000 engaged views

  • pipelines
  • scenarios
  • heartbeats
  • hooks
  • code modules
  • agents
  • asks you
  • self-evolving
  • Already handled
You your part

Every weekday, find 40 Texas dental clinics rated under 4.4 or with unanswered bad reviews. Name their top complaint and check their site. Email the owner a note quoting it with a free fix plan, and follow up twice. Book every yes into my calendar; keep the pipeline in a sheet. Each week, shift toward what books calls. I approve the first 20 emails and every new template.

to your chief, in Telegram sent ✓✓

Where you come in

  1. The first week Connect Gmail and Calendar on one card. Approve the first 20 emails.
  2. Every new template One card with the draft. Approve, edit or say no.
  3. Before a fix plan Approve the plan before it goes out under your name.

No file to edit, no prompt to write, no log to read.

Omnislash everything else 30 parts · 6 features

2 running now · grades itself on calls booked per 100 businesses contacted

  • pipelines
  • scenarios
  • heartbeats
  • hooks
  • code modules
  • agents
  • asks you
  • self-evolving
  • Already handled
You your part

Take over support email and site chat: order status, returns and sizing, in our tone. Refunds over $50 and upset customers come to me as drafts. Each night, group complaints by product; on Mondays, bring me the three biggest with a fix. After we ship one, show me whether complaints dropped. Warn me two weeks before a bestseller runs out.

to your chief, in Telegram sent ✓✓

Where you come in

  1. Once, to start Approve the store integration and connect the support inbox.
  2. Big refund, upset customer A card with the order and draft: approve, edit, take over.
  3. Mondays Pick which of the three fixes ships this week.

No file to edit, no prompt to write, no log to read.

Omnislash everything else 29 parts · 6 features

3 running now · grades itself on support tickets per 100 orders

  • pipelines
  • scenarios
  • heartbeats
  • hooks
  • code modules
  • agents
  • asks you
  • self-evolving
  • Already handled
You your part

Each morning, check my invoices sheet. Chase overdue ones politely at 3 days, firmly at 10; at 21, ask me. Fridays, draft each client a status update for me to approve. Flag anyone quiet for two weeks. Log emailed receipts as expenses.

to your chief, in Telegram sent ✓✓

Where you come in

  1. Day 21 overdue A card: the client, the history, what it suggests next.
  2. Fridays One tap for every update, or an edit where one is wrong.

No file to edit, no prompt to write, no log to read.

Omnislash everything else 14 parts · 3 features

2 running now · grades itself on days from invoice to paid

  • pipelines
  • scenarios
  • heartbeats
  • hooks
  • code modules
  • agents
  • asks you
  • self-evolving
  • Already handled

Example requests and builds. Part names are illustrative; the six kinds, the gates and the guarantees are the engine’s own.

The operation that rewrites itself. And it has to prove every line.

It runs your playbook, grades what happened, proposes a change to itself, proves it against the version it would replace, merges it through your gate, and watches it hold. Then it runs again. That’s the loop.

YOUR REPOSITORYgit

Your company brain.

The playbooks, context and rules
that make this operator yours.

proven changes return here↵
04 /Proof before merge

A replayable workflow’s candidate replays the inputs the cycle froze and is paired with the incumbent on each, under the same judge; a guard past its band vetoes before any score is read. A losing candidate closes its own pull request. A pipeline, a heartbeat or a chat role cannot be replayed, so it is judged after the merge, on its next graded runs.

held by
the engine
on the record
a verdict on the pull request, published as a commit status
Interactive demo · select a step ↗Screens from Sixty Seconds Studio, a fictional demo studio, on the real dashboard.
How it works what happens between two runs — every stage, what it leaves on the record, and where it stops

Every change the operation makes to itself lands on the record, so what it learned reads as a diff, not a promise. The Run card 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.

every change leaves
a pull request
Every change to the playbook, in your repo, with who decided it and who merged it on the record.
a verdict
A replayable workflow’s change is replayed on frozen inputs and paired with the version it replaces on each, before the merge; everything else is judged on its own graded runs after it. A change that regresses gets its own revert.
a lesson
Won or lost — kept, reverted, or closed before it shipped — filed where the next cycle’s analyst is shown it.
what it can never do, whoever holds the gates
  • Every self-edit is a pull request on your record; nothing reaches the playbook any other way.
  • It rewrites the playbook, never its own eval — a diff that moves the measurement is rejected.
  • No change moves more lines than its budget allows — past it, the apply fails at the gate and no pull request opens.
  • Before the merge, a replayable workflow’s candidate replays frozen inputs and is paired with the incumbent on each, under the same judge; everything else is judged on its next graded runs instead.
  • Loses that check: the PR closes, nothing shipped. Regresses after the merge: a revert PR at the same gate.

Two regressions in a row hand the gates back to a person until someone re-arms them. Each job’s policy reads as sentences, every value marked with the tier that set it — the engine’s default, your constitution, or the job itself .

  1. Where it can, proof happens before the merge, and it is paired. A new version scored on new inputs against an old version’s old score measures the inputs, not the change. So a workflow’s candidate replays inputs the old version already ran, and is paired with it on each one — its grade there, or a fresh re-run — and a candidate that loses closes its own pull request: nothing shipped, so nothing is reverted. A pipeline, a heartbeat or a chat role cannot be replayed — nor can a workflow whose plan a replay can’t run safely — so each is judged on its runs after the merge instead.
  2. The fence is enforced before the write, not audited after it. An accepted proposal buys write access to the files it named and nothing else. The rubric sits on the unreadable side of that line: an optimiser that can open its own grader will eventually edit the grader, because editing the test is the cheapest way to pass it.
  3. The judge is an instrument, not an oracle. One snapshot is pinned at the start of the cycle and never re-read, so a judge swapped underneath a comparison cannot look like a regression. A judge that fails leaves the run ungraded rather than quietly re-graded by a different model — and past a third of a batch ungraded, the cycle reports on the judge instead of on the change.
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. A grade can be taken hours after the run ends, because the outcome the loop is chasing may not exist when the last step finishes — a view count three days later, a reply rate over a week. The method, the threshold, the judge model, your own metrics with the job each one does — objective, guard, observe — and gradeAfterHours.
Trigger Under repair it 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. Under evolve nothing has to fail: a cycle opens on a cadence, once n new grades have landed since the last one looked. Four things open a window: a grade landing, a scheduled look, your own Analyze now, or an idea someone queued. preset: repair or evolve; windowRuns and minFailures — the engine defaults to 2 of the last 5 — or your own shouldImprove(); and trigger.every, a look on a schedule.
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 — under repair the runs that missed first, under evolve its best and its worst runs by the objective — with 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. One change may also move only so many lines, added plus removed; past that the apply fails at the gate, and no pull request opens. protectedPaths brain-wide, editablePaths per entity, and maxChangedLines — 600 unless you say otherwise.
Check, before the merge On a workflow whose plan can be replayed, the candidate replays the inputs the cycle froze and is paired, input by input, with the version it wants to replace, under the same judge. By default that version’s side of a past input is the grade it already earned there under the same judge; it is re-run where there is none, and on the input whose grade opened the cycle. The check prefers inputs the analyst was never shown, and its verdict says how many it held out. 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; incumbent: frozen, or replay to re-run the old version on every input; how many inputs, 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 engine re-runs nothing: it reads the entity’s own next graded runs. Under repair it counts them by the rule the trigger uses, asking one question: would this have triggered again? Under evolve it compares them, as a window, with the window the cycle opened on, and reads the objective’s gain through a confidence interval, so noise in the objective settles as inconclusive, never as a regression. A change that regressed gets its revert opened. 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, the deadline, the interval’s confidence, and whether a change it could not prove is kept or reverted.

The product draws the same loop for every brain that turns it on . One job climbing through it is the next screen — one job ↓ — and every job it runs is the screen after that — the fleet ↓. The write surface it runs under, with the receipts behind it — self-evolution ↓.

It wrote every step up. It reverted every miss.

Short Maker, views at 72 hours from Jul 21 to now on the dashboard: a stepped level line climbing through merged changes, one red dashed step that was reverted, and the latest step being proven.Short Maker, views at 72 hours from Jul 21 to now on the dashboard: a stepped level line climbing through merged changes, one red dashed step that was reverted, and the latest step being proven.
kept cycle 1 · #102 Aug 27
Open on the payoff: the first second shows the answer shot, then the cut rewinds to the question.

features/publishing/playbook/hook.md

Accepted from Telegram, merged at the auto gate, then proven over the next 10 graded runs against the window before — a pipeline can’t be replayed, so the proof comes after the merge. It held.

reverted cycle 3 · #124 ↺ #142 Sep 20
Cut to a new shot every two seconds, the answer shot included.

features/publishing/playbook/edit.md

Merged, then watched Sep 20 – Oct 3. A guard came out worse, so the loop opened its own revert, #142 — and filed the loss as a lesson the next cycles recall.

kept cycle 4 · #150 · a teammate’s idea Oct 8
Put the most-liked viewer question from the channel’s last three shorts on screen over the first frame.

features/publishing/playbook/hook.mdfeatures/publishing/playbook/edit.md

Opened on Theo’s queued idea, “Lead with what commenters asked for.” Maya refined round one over Telegram — “Use the comments, not our copy.” Round two shipped, was proven, and stayed.

proving cycle 5 · #178 Oct 22
End on an open loop: the last frame teases the result of the channel’s next short.
3 of 10 graded since the merge · deadline Nov 5

features/publishing/playbook/outro.md

Maya pushed back on round one — “Calls to action feel cheap. Make them want the next one.” Round two merged at the auto gate; every graded run since is compared with the window before, and the verdict, kept or reverted, becomes the lesson the next analyst is shown.

It may move the numbers. It never moves the ruler. The analyst that proposes each change can neither read nor edit the rubric it is graded by.

Sixty Seconds Studio, a fictional demo studio How the loop works

Your company, run as a controlled experiment.

It doesn’t tell you what broke. It opens the fix — and grades it against what it replaces.

Every job on the loop, one list. Each against its own objective.

You switch the loop on job by job. Each card shows what that job’s loop is doing right now, and whether it needs you.

reading one card — Hook Lab

preset
evolve or repair. Hook Lab is on evolve: it keeps pushing its number up. A repair job acts only when runs go bad.
state
what its loop is doing now — waiting, changing, proving — or that it needs you.
trend
its number over time. Every step up is a change that merged.
Where it stops the honest limit

Only workflows can be tested before they ship — and only those safe to re-run. A safe workflow is re-run on the same inputs, new version against old. A pipeline, a heartbeat or a chat role can’t be, so its change ships first and is judged on the runs after it — like Short Maker, the job climbing above.

Every job on the loop, grouped by feature — which are mid-change, and which need you.

Related screens

It waits for the world to answer. Then it changes one thing at a time.

A run is graded on what it caused — views three days later, replies a week later — read from your own data. Jobs that move the same number can take turns, so each result has one cause.

  1. the run ends
  2. the world answers
  3. graded on what it caused
Where it stops the honest limit

You decide what counts, and when to look. The loop reads the numbers you point it at, after the wait you set for each job. By default it grades a run the moment it ends, and jobs don’t take turns until you group them.

Short Maker’s change, judged on the posts after it against the posts before — on views at 72 hours.

Related screens

Others reopen the issue. It reverts the change.

Before a workflow’s change merges, the new version re-runs recent inputs and is scored against the old one on each. After any change merges, the loop watches the runs that follow — and if they’re worse, it opens the revert itself.

Most tools

  1. fix merged
  2. issue recurs
  3. ticket reopened

The loop

  1. tested before the merge
  2. watched after it
  3. worse? it opens the revert
after a fix ships · surveyed september 2026
Where it stops the honest limit

A revert goes through the same gate as the change. It is a pull request too: if a person merges your changes, a person merges the revert.

Script Batch’s change scored a little better but cost and ran far past its limits. The check closed the PR before it merged.

Related screens

Autonomy is earned, one agreement at a time.

Where taste matters, people rate runs until the AI judge agrees with them — then they only spot-check. A streak of regressions hands both approvals back to a person.

Calibration

  1. people rate runs
  2. the judge agrees
  3. spot checks only

The breaker

  1. regressions in a row
  2. a person approves again
Where it stops the honest limit

Nothing is autonomous until you say so. By default a person approves every change and merges every PR. Rating cards and waiting for the judge to agree are opt-in; the breaker is on from the start.

Turning on ‘wait for a calibrated judge’ for Fan DMs: while the judge disagrees with people too often, a person approves and merges.

Related screens

Arguments end in a verdict. Even yours.

Anyone on the team can post a hunch — in chat, on the dashboard, or through an agent. The job’s next cycle tests it like any other change, and reports how it ended.

  1. a hunch
  2. queued
  3. the next cycle tests it
  4. a verdict
  5. a lesson
Where it stops the honest limit

A hunch skips the line, not the checks. It goes ahead of the loop’s own ideas, but waits for the current change to settle — then faces every test and approval the loop’s own changes do.

Two hunches in line behind the change being watched, each with who posted it and when. An earlier one of Theo’s was tested and kept.

Related screens

20 more screens around the loop — open any

Sixty Seconds Studio, a fictional demo studio, on the real dashboard

You own the brain. You inherit the framework.

Hosted platforms rent you their runtime. Here you own it — and upgrading it is an agent’s job.

scale — one tick, one week of build estimate · 12 files authored, 104 modules inherited

≈1 week · you author the brain ≈3 years · the framework under it, already built 1 : 156

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.

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 …
…
  • --- name: Competitor Watch enabled: true schedule: every day at 9am agent: modelRef: smart@high skills: [battlecard] deliverable: storage: inline format: markdown --- ## Steps 1. Collect — pricing, changelog, jobs … constitution/Scenarios/<Category>/*.scenario.md
  • --- name: Account Manager description: Owns the book, not the ticket modelRef: smart@high skills: - discovery-call capabilities: - database:read - notification:send --- You own the account. Report what moved and what it will cost us if nobody moves. … constitution/Agents/*.agent.md
  • --- name: Ops Debrief enabled: true schedule: every weekday at 6pm agent: account-manager --- Close the day: what moved, what stalled, and the one thing that needs a human tomorrow. Report only what changed since this morning. … constitution/Heartbeats/*.heartbeat.md
  • --- name: Best Move Advice enabled: true schedule: "0 9 * * 1" agent: account-manager memoryFlush: true evaluation: enabled: true --- One move — the one with the best expected value this week, with the reasoning shown. … constitution/Heartbeats/*.heartbeat.md
  • export default restate.workflow({ name: 'dunning', handlers: { run: withInputSchema.workflow(Input, async (ctx, input) => { const draft = await runAgent(ctx, { agent: { name: 'dunning' }, prompt: `Dunning note for ${input.id}`, }); await awaitApproval(ctx, { title: 'Send it?', message: { text: draft.result ?? '', parseMode: 'plain' }, }); await kvSet(ctx, 'dunning', input.id, 'sent'); … features/<name>/code/*.pipeline.ts
  • --- name: Churn Signal event: ingest:event enabled: true agent: account-manager filter: source: hubspot type: deal.stage_changed --- A churn signal landed from {{source}}: {{type}}. Read the account's last three notes before you say anything, then say the one thing worth saying. … constitution/Hooks/*.hook.md
  • --- name: discovery-call description: How we run a discovery call — the questions, the order, the disqualifiers. NOT for renewals or QBRs. --- ## When to use A first call with a company that has not bought yet. Not a renewal. … skills/<name>/SKILL.md
  • --- name: customer-voice description: Grades a deliverable the way the customer would read it --- # Task Evaluation Read {{inputFile}} and {{outputFile}}. Would the customer act on this, or ask a question back? Name the question. # Run Evaluation … constitution/Evaluation/Methods/*.md
  • export const creditIssueTool = createTool({ name: 'credit_issue', description: 'Issue a service credit.', schema: z.object({ accountId: z.string(), amountUsd: z.number().max(500), }), risk: 'moderate', providesCapabilities: ['billing:credit'], label: 'Issue Credit', category: 'billing', async execute({ accountId, amountUsd }, ctx) { … tools/*.ts → registerTools()
  • export const hubspot = defineEventSource({ name: 'hubspot', extract({ headers, rawBody, body }) { const sig = headers['x-hubspot-signature']; if (!verify(rawBody, sig)) return null; const e = body as HubspotEvent; return { type: 'deal.stage_changed', payload: e.properties, idempotencyKey: e.eventId, }; }, }); … ingest/*.ts → defineProject({ ingest })
  • export default defineProject({ name: 'acme', rootAgent: { name: 'omni' }, bots: [ { name: 'omni', tokenEnv: 'TELEGRAM_BOT_TOKEN' }, { name: 'omni-pa', tokenEnv: 'PA_BOT_TOKEN', secretary: true }, ], locale: { timezone: 'Europe/Amsterdam' }, memory: { embeddingModel: 'text-embedding-3-small', }, ingest: { sources: [hubspot] }, tools: registerTools, services: { bot: true, worker: true, scheduler: true, webhooks: true }, … <brain root>/omnislash.config.ts
  • memory/2026/08/2026-08-13.md Acme moved the renewal to Q4 — Priya wants the migration finished before she signs, and said so twice. --- Northwind reads the weekly digest, nobody else on that account does. Send them nothing else. … memory/YYYY/MM/YYYY-MM-DD.md · memory/MEMORY.md

12 files · diffable · yours

inherited — you did not build this

infrastructure

the substrate it lives on, deploys as, and is watched through

  • The engine owns runtime — execution, queues, schema, CLI, Docker, monitoring. You own behaviour — prompts, roles, scenarios, skills, your own tables — as files in your own git repo, so every change to how the operation behaves is a diff you can review and revert, not a row in a vendor’s database. One typed config file is the entire contract between them, validated before the runtime boots. defineProject() — one file, no codegen, no generated directoryyour Zod env schema merged into the engine’s at loadtyped extension points: tools, integrations, ingest, engagement, dispatch, lifecyclefixed directories are convention, not configurationfail-fast validation with an actionable hint, not a stack trace docs/eaaf-criteria.md
  • An engine upgrade is one command and one agent’s task. The command moves the pin, regenerates the files the engine owns and writes upgrade/TASK.md; a coding agent works that task to the end — names your files still spell the old way, read-only checks against production before the deploy, data fixes after it. Every release that needs something of your brain ships the prompt for it, and nothing upgrades a brain from CI. one entry per change, in order, across every release you crossbefore-deploy, in-repo and after-deploy steps — each detected, applied, verifiedthe deploy’s first gate fails while a step that must ship first is untickedstop-the-world deploys: old and new never run side by side, so a release ships its final shapeengine migrations applied by the deploy; each entry says what they need from your brainidempotent — fix the cause and re-run the command it hints docs/brain-dev/upgrading.md
  • Every agent is a Restate virtual object keyed by its id; workflow runs, planners, the eval service and your own pipelines are durable handlers. Kill the process mid-run, redeploy, lose the network — the same invocation resumes where it stopped, including across a human pause of days or weeks — no timeout ends the wait, and it costs zero compute while it lasts. one durable owner per agent id — the per-agent queue is nativethe human pause holds inside the same invocationjournaled steps, replay-safe, exactly-once terminalsthe database row is a projection, never the control surfaceorphans reconciled against Restate’s own tables, not guessed proven against real Restate in the engine’s integration suite
  • One long-running service owns your brain’s git state, so no application process ever races another over a checkout. On a fixed interval it commits what the agents wrote, rebases, pushes, and refreshes the baseline that per-run sandboxes branch from. Nothing else boots until the first sync lands. a sparse checkout of exactly the writable set, and nothing elsecommit before pull, deliberately — agent work is committed, never stashedevery brain-consuming service gated on the first successful ticka rebase conflict spawns a resolver agent and holds all git until it verifies cleansync now from chat, from the dashboard, or from a push webhook docs/brain-dev/operations.md
  • One HTTP process serves the whole tool catalogue to every agent, whatever it runs under — Claude Code, Codex, OpenCode or an API model. Each turn opens a session carrying the caller’s own identity, so the same tool name resolves to a different permission set depending on who is asking, and a harness can never call a name it was never shown. Streamable HTTP on /mcp, plus stdio for desktop clientsper-session catalogue filtering, re-checked at call timeprogress and cancellation notificationsread-only resources by URI (skills, own pending cards)idle session reaper, body and session capsloopback bind + origin allowlist against DNS rebinding docs/mcp.md
  • Your agents work across every repo you own, not just the brain. A scenario names its target; each run gets its own clone of that repo whose origin is the real upstream, so a branch and a push land where you expect. Skills are handed over as absolute paths rather than copied in, so git status in someone else’s checkout stays clean. a JSON name → git-url map, cloned on deployper-run sandbox per repo, same path in Docker and local devwrite-back and an engine-opened PR from inside the runskills delivered out-of-tree so the checkout is never dirtiedevery resolved repo path validated before anything boots docs/extra-repos.md
  • Three blast radii, declared per agent: the live brain, its own git clone off a read-only baseline — independent index, HEAD and stash, sharing objects and nothing else, origin rewritten to your real upstream so a push lands — or a full bubblewrap jail that refuses to start if it cannot actually jail. runIn: live | clone | sandbox, declared in frontmatterper-scope checkouts sharing objects through git alternatesmount, PID and IPC namespaces, dying with the parentsame absolute paths inside and outside the jailpath containment on every file operationa database search path that hides engine tables from agent SQL docs/agent-isolation.md
  • bot · worker · scheduler · monitoring · mcp · webhooks · pipelines · dashboard · sync all route off one entrypoint. One image to build, one to pull, one to roll back — and your brain extends it with a two-line Dockerfile that joins the engine’s workspace, so there is exactly one physical copy of every package. entrypoint command routing, dumb-init as PID 1FROM ghcr.io/omnislash-ai/engine:X.Y.Z + your own layerthree CLI harnesses and their sandbox shims baked inskill install specs baked and verified at build timecompose generated per mode, with an override file when you need one docs/distribution.md
  • Point the database URL at RDS, Neon or Supabase and the generated compose drops its own Postgres container, its exporter and its backup sidecar. Same for Redis. Nothing about the code changes; the deployment simply stops carrying what you already pay for. external infrastructure detected from env, not toggled by a flagcompose, exporters and probes all derived from that detectiona tuned Postgres 17.9 when you would rather not run oneone image and one CLI either way
  • Grafana, Prometheus, Loki, Sentry and a queue inspector, provisioned as code rather than clicked together — nine dashboards and forty alert rules up on the first deploy. And an alert does not only page you: it POSTs back in as an ordinary external event, where a hook wakes an agent that chooses between an idempotent fix, a pull request, or escalating to a person. nine dashboards and forty rules as code, routed to chatblackbox probes and per-container restart detectionthe firing alert re-enters through the engine’s own event doora disaster-recovery skill on the remediation pathlogs as JSON into Loki, run and agent ids as metadata rather than labels docs/observability.md
  • Anything that can POST becomes a trigger. You declare the source; the engine gives it an endpoint, authorizes it and records it in one durable inbox — and only that recorded row sets work in motion, so your hooks fire once per event however often a job is retried. There is no provider-specific code anywhere in the engine. defineEventSource with your own extract(), returning null to refusethe endpoint provisioned for you, per sourcededup by persisting — one upsert decides new, revived or duplicatean accepted event cannot be lost: a row nothing routed is re-routed within minutesper-source secrets, several of them, each revocable on its ownthe ingest log and a generated event-schema catalogue in the dashboard docs/webhooks.md
  • You describe an integration once — its auth, its webhooks, its tools — and the engine registers it everywhere: MCP, worker, pipelines, chat. No per-integration boilerplate. OAuth connections live in one encrypted store that refreshes tokens in the background, so a long-running agent never wakes up logged out. defineIntegration — tools and webhooks in one validated objectregistration fan-out to every surface that builds a registryper-subject connection store, AES-256-GCM at the columnbackground refresh and best-effort upstream revokeOAuth that completes on a server with no inbound port open docs/integrations.md
  • One HTTP door into the running brain, and everything behind it is already wired: run a tool by name, fire a workflow, take an inbound event, finish an OAuth callback, serve a published artifact. Raw bodies are captured before parsing, so an HMAC signature verifies real bytes rather than re-serialized JSON. POST /tool/:name under a headless context — HITL tools unreachable by constructionPOST /event/:source for ingestyour integration routes, authorized by your own signature checkOAuth init, callback and statusthe published-artifact origin with ETag and a CSP sandboxthe endpoint catalogue rendered in the dashboard docs/webhooks.md
  • A markdown file names an event and an agent; the engine does the rest. One subscription covers the whole closed event set, so a hook added or edited while the system runs fires at its next matching event with no restart. N worker replicas collapse onto one keyed job, so it fires once, not once per replica. one file: event, agent, prompt — no subscription code anywhereexactly-once across replicas, with retries and a dead-letter queuehot reload behind a bounded probea hook naming an impossible event is caught at boot, not at 3amper-fire declared grants with a real call ceilingrun-scoped hooks that live and die with one workflow run docs/events-system.md
  • Everything a run produces is a file in one declared tree: outputs handed between phases, files sent back to chat, the bytes behind a published link. Each subtree names its own lifecycle, so the retention sweeper is derived from that one table and a new subtree cannot quietly escape it. content-addressed blob store behind one routerrun artifacts as file-based context passing — manifest in, pull what you needper-task stored artifacts that outlive the run directorylarge step payloads offloaded to blobs instead of a rowTTL and size-budget reaper, oldest-firstin-chat file and folder browser with drill-down docs/artifacts.md
  • A photo, a voice note or a document arrives in chat and reaches the agent as a real file — one representation carried unchanged from the ingress, through the tool results, into both agent boundaries, and rebuilt into the conversation history on every later turn. The message text stays exactly what the person typed. one persistence type across every ingress, transport shape stops at the doorvoice replaces text rather than duplicating itan album arriving as N updates folded into one turnthe URL resolved at the door, so no lazy resolver leaks into the domainsending a file back blocks until it actually landed docs/attachments.md
  • Sixteen named queues are the at-least-once substrate under everything that is not a durable handler: planning, notifications, evaluation, improvement, heartbeats, hook fires, memory operations, delivery. Job ids are derived from the event itself, so replicas collapse onto one job and retries and a dead-letter queue come free. deterministic keyed job ids derived from the payloadper-domain retry chains — eval backs off past its own leaserepeatable crons reconciled by diff, never nuke-and-pavedelayed jobs behind scheduling, snoozes and boss expirya queue inspector and depth metrics on the first deploygraceful drain with a cancellation signal into live git and agent work
  • Your tables are first-class, not "just the public schema". Two ordered, versioned migration lines run on every deploy — the engine’s own schema first, yours second, each with its own journal — so an engine upgrade and your own schema change never fight over one history. engine in its own schema, yours in public, composed by importthe table is the only source of types — rows and params derive from itgenerate / migrate / status; push never runs on an automatic pathconcurrent-index migrations with invalid-index cleanup on failurea dump sidecar with day/week/month rotation and its own probe docs/migrations.md
  • One command and the substrate is up: Postgres, Redis, Prometheus and the durable runtime in containers, migrations applied by the same code path production uses, then every service started as a watched child process you can attach a debugger to. Nothing to install and nothing to wire — and the first Ctrl-C takes the containers down with it rather than orphaning them. infra in Docker, apps as watched processes with the inspector availablemigrations run through the production runner, never a dev shortcutboot a slice of the system when you only need a slicea per-app readiness gate, so one slow service never blocks the othersshutdown waits for the children, then stops compose exactly once docs/run-modes.md
  • One check library, two consumers: about forty-five checks from the CLI before you deploy, two dozen container-safe ones inside the running dashboard afterwards. Every check is wrapped and deadlined by construction, so a wedged Docker daemon or an unreachable server produces a named failure instead of a hung terminal. environment, configuration and infrastructure, every check self-describinga throw becomes a correctly-named failure; ten seconds is the ceilingyour writable paths, declared grants, eval ceilings and skill binaries all checkedevery warning carries its remedy, and one tap hands it to an agent that applies itthe dashboard set and the diagnostic tool derive from one sourceunpersistable and merely degraded are different verdicts, not one warning docs/doctor.md
  • An agent asked why something broke reads what you would read: the container logs Loki holds — by service, level, run or agent id and a literal search —, the events as they crossed the bus, and the configuration as the engine runs it, every value with the tier that set it. A secret answers by its presence alone, and its value is scrubbed out of every string the answer carries. retention said out loud — a window older than Loki keeps reads empty, not quietpolled, not followed: ask again from where the last page endedevery MANIFEST key marked as the engine’s default or your brain’severy declared environment variable, with whether it is setthe event tail refused to a turn answering one chat, because it carries every chat docs/brain-dev/features.md
  • 104 typed events across 20 domains, each one a schema in the engine’s registry, validated where it is emitted and again where it is received. Two substrates behind one vocabulary: pub/sub for the real-time surfaces, Redis Streams with consumer groups for anything that must not miss a message. payload types derive from the schema — no hand-written event interfacespub/sub or streams, chosen per consumer rather than per eventrequest-response over pub/sub, so cross-process calls need no second channelwildcard subscriptions with typed matching, not string sniffinga brain declares its own events through the same contract docs/events-system.md
  • An agent that opened a pull request does not poll it. It watches the PR, and the reviews, comments, settled CI, a new conflict and the merge arrive in its inbox as batched turns — a review with six inline comments is one turn, not seven. Its own acts come back as echoes and are dropped, CI about a commit a push already replaced is dropped, and a pipeline waits on the same resource durably instead of holding an agent open. one watch per agent and resource; watching again renews itone batch per burst — debounced, and never later than its longest waittrusted authors by default; every dropped event ledgered with its reasonit ends only in a delivery: the terminal event, the expiry or the budget, said out loudthe claim and the inbox entry commit together, so a retry never delivers twiceyour own event sources key their events; pipelines wait through subscribeResource docs/brain-dev/features.md § Resource Watches
  • The engine holds its own git identity instead of borrowing the host’s SSH key: an agent posts one card, a person clicks through GitHub’s registration and install screens, and every repo resolves to a lane the agent can name. The same App is the receiver for every PR, review, check and push — and because GitHub never retries a failed delivery, the engine reads the App’s own delivery log and pulls back whatever it missed. registered through GitHub’s manifest flow, from one agent card or the dashboardwhich credential authenticates each repo, and why, answerable by an agentone signed receiver for the whole event family, verified over the raw bodymissed deliveries recovered from GitHub’s own three-day logsignals GitHub never sends: every check settled, a PR that began or stopped conflictingsubscription drift reported by doctor, not discovered by a silent agent docs/brain-dev/integrations.md
  • Set a domain and an email and the proxy becomes a Let’s Encrypt terminator with a subdomain per service — bot, dashboard, grafana, webhooks, artifacts. Certificates persist across recreates, admin vhosts sit behind basic auth, and the public URLs other features need are derived from the domain instead of being declared a second time. nine service subdomains routed from one variablecertificates in their own volume, so a redeploy does not re-issueadmin vhosts and private published artifacts behind the same credential pairwebhook and artifact origins derived, so OAuth installs need no second variablea self-signed fallback for a server that has no domain at all docs/production.md
  • One named volume per durability class, and the classes are the design. The brain’s git state is mounted whole only by the sync daemon — every other service sees per-path subpath views, so no application container can reach the .git directory it might corrupt. git state exposed to services as subpaths, never as a repositorya read-only baseline clone as the object source for per-run checkoutsrun sandboxes surviving restarts, so a paused run can still resumethe artifacts root a sibling of the brain, so a sandbox mount cannot shadow itdumps, certificates and log positions each in their own volume docs/distribution.md
  • Every path under the brain is exactly one of three things: git-backed and writable, image-baked and read-only, or host-bound runtime output. That one classification drives the sparse checkout, the daemon’s commit set, the container mounts and the ignore file — so "will this write survive a container recreate" is a design-time question with an answer, not a 3am discovery. one resolver feeds checkout anchors, mounts, commit set and ignore fileadditive only — a brain extends the writable set, never shrinks the baselinestructural and blast-radius paths refused where you declare themdirectories only, because the checkout anchor never matches a filenew files inside the set are hot; a new dependency still needs a build docs/runtime/contract.md
  • Every failure the engine can produce carries a machine-readable code and a hint naming the next action — one taxonomy across the CLI and config layer, a typed family across the runtime. A brain author reads a code and a sentence, not a stack trace from inside a package they did not write. code, hint and a JSON form on every error the engine throwstyped families for agent, tool, service, auth and database failuresconfig validation fails before boot, with the offending field namedthe same codes reach the dashboard, not only the logs
  • One shutdown path for every app: a signal drains in-flight work through the same cancellation primitive the rest of the runtime uses, so a deploy never severs a git push mid-write or leaves an agent subprocess orphaned. A watch-mode restart is told apart from an admin’s stop, because they deserve different behaviour. one registration call gives any app the whole contractthe abort signal reaches live git and agent work, not just the HTTP servera hot-reload signal is not mistaken for a shutdowninfrastructure teardown runs exactly once, in a finally
  • The helper surface your pipeline code writes against: run an agent, block on a human approval, ask a question, call any tool through the full gateway, keep state between invocations, report progress. Every helper is journaled, so all of it replays correctly after a crash — with an escape hatch to the raw runtime for anything not yet wrapped. runAgent with a Zod schema — the answer comes back parsed and typed, or as a typed failurerunWorkflow — a planned scenario as one durable step, idempotent on its keyawaitApproval holds the handler open, under a deadline your brain sets — a week by defaultcallTool goes through authorization, rate limiting and risk-based approvala Postgres-backed key-value with a TTL, for state across invocationsprogress that lands on the live card without polluting the step log docs/restate-pipelines.md
  • Media that arrives is understood, not just stored: magic-byte type detection that outranks both the extension and what the sender claimed, image resize and conversion, PDF text extraction that falls back to rendering the pages for the model when a document turns out to be scanned, and transcription across a provider chain that fails over on its own. sniffed type wins over the extension and over the declared onea transcription chain of three providers, each enabled by its own keytranscripts cached by the file’s platform identity — first write winsone document reader: PDF, Word, Excel, slides, OpenDocument, EPUB and HTML, as markdownevery remote fetch DNS-pinned per redirect hop and capped mid-streamper-kind byte caps, with a local path allowed past the chat platform’s own limit docs/media.md
  • A tool can answer with pictures meant for the agent that called it, not for the person in the chat: a scanned PDF too thin to read as text arrives as its rendered pages, a widget preview as screenshots. An API agent reads them as image parts of the tool result, a CLI agent as MCP image blocks — and no transcript, journal or event ever stores the bytes. declared per tool; the result still says in words what the images showat most ten images a call, 5 MB each and 20 MB togethera provider that takes no image in a tool result gets a one-line note instead, per chain steponly an agent’s call carries them — a pipeline or a page gets the result withouta newer image under the same key supersedes the older one within the turnscanned pages past the first ten named, and read on the next call by page number docs/brain-dev/features.md
  • One command emits a standalone brain — chat-only, scheduled-ops or pipeline-heavy — already pinned to the registry and installable on its own. A drift test keeps what it generates byte-identical to the fixture the engine itself develops against, so a new brain never starts life as a stale copy of someone’s working tree. three flavors, each a working project rather than an empty folderregistry-pinned peers, so the singleton contract holds from minute onethe Dockerfile and deploy workflow are engine-owned and regenerate on upgradean override sentinel per generated file, when you do want to own it
  • One limiter in Redis, shared by every process — bot, worker, MCP and pipelines draw from the same budget instead of each keeping a private counter. Per-minute and per-day windows are checked and incremented in a single atomic script, so two containers cannot both squeeze through the last remaining call. one script per decision, returning which window was actually exceededthe metric label and the counter key are separate, so per-id limits never explode the metricsa read-only inspector over the live countersrejection arrives as a typed error the caller can branch on
  • One process discovering a dead provider trips the breaker for every container at once. Closed opens after three failures, half-opens after a cooldown, and expires on its own if nothing touches it again — all in atomic Redis scripts, so there is no window where half the fleet still hammers an endpoint the other half has given up on. closed → open → half-open, with the state shared rather than per-processa state-change callback, so a trip is announced instead of inferredper-provider state readable live, and rejections countedkeys expire by themselves — a forgotten breaker cannot wedge a provider forever

intelligence

what it thinks with, reaches for, and learns from

  • The engine improves what it runs — workflow and pipeline scenarios, heartbeats, chat roles — and every change is a pull request against your own repo, never a push. A pattern in the graded window opens a cycle: an analyst proposes one change to the thing that ran, a separate implementer writes it, and the engine commits only the files that passed its diff gate. One live change per target at a time. Every settled verdict is filed as a lesson the next analysis has to cite, credited or charged by what happened. repair opens on k bad runs out of n; evolve runs on a cadence even when nothing is wrongthe editing agent holds no git credential and no shell — the engine commits and opens the PRit touches only the files the accepted proposal names, its own pipeline code includeda lesson per verdict: hypothesis, files, metric deltas, and your note if you rejected itevery settled cycle graded: improvement, regression, tradeoff, tie or inconclusivea spend bound per cycle, a cooldown after a regression, a daily cap on analyses docs/brain-dev/self-evolving.md
  • Before a workflow change can merge, the engine replays the candidate from the PR head and the incumbent from the base commit on the same frozen past inputs — partly held out from the agent that proposed it — and compares them input by input under the same judge. The verdict is an ordered rule over your metrics, posted as a commit status on the exact commit it checked, so a branch rule can require it. A candidate that loses closes its own PR: nothing shipped, nothing to revert. paired, not batch against batch — two batches on different inputs measure the inputsthe failure being fixed is always in the set; the rest are held out from the proposer firstreplays act on nothing: a tool that would touch the world is authorized, then not performeda crashed candidate counts as the change failing, never as a missing data pointwhen you require a gain, it has to clear a noise band to count as onefor workflow scenarios with a replayable plan; everything else is watched after merge docs/brain-dev/self-evolving.md § What the check does
  • Every change is watched after it lands, on the entity’s own next graded runs, counted from when it went live rather than when the PR opened. It settles validated, regressed or unvalidated, and unvalidated stays an honest terminal: “not checked” never becomes “checked and fine”. A regression opens a mechanical revert PR through the same gate the change shipped under, and the entity opens no new cycle until that revert settles. A heartbeat is never forced to run just to score itself — that would send real messages. every verdict labelled by its strength: paired, measured or blinda watch that sees a sibling’s change or a hand edit closes confounded — no credit, no revertlock groups: one variable at a time across entities that share an outcomean unproven change can be reverted too, if you say sothe revert PR is merged by a person unless you let changes auto-mergeduring the watch the target skips sampling, so no run goes unread docs/brain-dev/self-evolving.md
  • The agent that rewrites a prompt cannot read the rubric it will be graded by, and cannot edit the judge, its model, the loop’s own code, its tolerances or its own autonomy — not even those blocks inside the very file it is allowed to rewrite. Enforced in the harness’s permissions, in the sandbox where one runs, and by a digest-pinned diff gate after the turn, so a violation never becomes a PR. The judge is frozen for the whole cycle: a grade from a moved judge is not comparable, never a loss. a floor a brain can add to and never shrink: eval methods, loop code, models, memory, deploy filesthe measurement blocks deep-compared before and after the editone change capped at 600 lines, counted off the real diff — no prompt bloatthe judge pinned by a four-part fingerprint for the whole cycletoo many ungraded runs settle “judge unhealthy” — nothing is reverted on a broken instrumentsymlinks, git hooks and engine-skill shadowing refused at the gate docs/brain-dev/self-evolving.md § What the loop may not touch
  • You decide what “better” means. An entity declares named metrics — each an objective, a guard or only observed — with floors, tolerances and per-input vetoes, and a metric can be read by your own code from the business rather than from the transcript. When the outcome only exists later, a video’s views at 72 hours or a delivery rate that settles overnight, the judge waits that long before it grades. Once anything else is the objective, quality becomes a guard on its own, so the loop cannot buy a number by getting worse. objective, guard or observe — a guard past its band vetoes before any score is reada critical metric vetoes on a single inputmeasure() in your own code: a CRM, a warehouse, an analytics APIgrading delayed until the outcome exists, per entityup to six business KPIs on the overview, readable by agents tooa metric edited mid-cycle is a judge change, never a silent rescore docs/brain-dev/self-evolving.md · docs/brain-dev/kpis.md
  • Two gates, declared apart: who accepts a proposal and who merges the PR — each a person or the engine, a person by default. An automatic merge means arming GitHub’s own auto-merge on the commit that was checked, so your required checks stay a gate; a direct merge does not exist at any level. Two regressions in a row, or one change that shipped on its own and could not be measured, hand both gates back to a person, and only a person re-arms them. There is no timer. accept and merge set separately, per entity, over a brain-wide defaultthe arm bound to the checked commit — a moved head disarms itauto gates can stay closed until the judge agrees with peoplean admin-issued standing grant to auto-accept, bounded in calls and timea person switching auto-merge off on the PR is heard, not assumedthe implementer can never grant itself autonomy — the block is walled off docs/brain-dev/self-evolving.md
  • A person’s chat with a role is cut into episodes, first message to the end of that dialog, and each episode is graded whole: every message, reply and tool call, with earlier talks with the same person as context if you want it. A chat role that declares a loop enters it the way a scenario does. A change is never replayed against real people — it is judged on the role’s next episodes under one role version. an episode closes when the chat goes idle, or when the agent ends it itselfevery turn records the role version, so an episode spanning a change counts for neither sidea rubric or budget edit is not a new version — only what the role doesone privacy rule governs how the judge and the proposer write about peoplea rating card for you, if you want your own score in the mixcompaction moves an episode’s turns aside, never deletes what the judge reads docs/brain-dev/self-evolving.md
  • The same scenario escalates without being rewritten. Tier 1 is one markdown file and the planner works out the steps. Tier 2 locks the plan it produced into a blueprint you can edit. Tier 3 replaces the plan with typed TypeScript that still inherits the whole engine — agents, tools, human approval, memory, monitoring — as callable infrastructure. Which tier runs is decided by which files exist, not by a setting. Tier 1 — one scenario file, planned fresh each runTier 2 — a frozen blueprint you edit by hand or in the wizardTier 3 — a pipeline in code, all three durable primitivesthe engine picked by file presence, overridable in frontmatterone scenario can own a primary pipeline plus auxiliariespipeline code hot-reloads in production, not just in dev docs/automation-tiers.md
  • A run is graded against the definition of done it was given, requirement by requirement — not a generic rubric — with a grounding check that catches a confident report of work that never happened, per-tool metrics and a typed failure category. Anything the engine runs unattended owes a daily grading ceiling, enforced where the money is spent rather than at parse time, so no config path can route around it. two levels: per-task definition of done plus run-level criteriathe deliverable verified from disk, not from the database copysampling by hashed rate plus a rolling per-day capgrading methods are brain files you can replacea failure taxonomy that groups entities failing the same waybooked before queued, so the reservation the cap counts is real docs/brain-dev/evaluation-and-improvement.md
  • When a run fails the engine spawns a recovery agent that diagnoses it, patches the plan blueprint itself and re-drives the run — the failure becomes an edit rather than a post-mortem. Categorised errors retry on their own, stuck tasks reset, and a process killed mid-run is swept back to a consistent state by a reconciler. a diagnosis tool, a blueprint patch and a retry, in one dialoguea patch that would orphan an existing task is rejected outrightbounded attempts, enforced inside the same compare-and-setduplicate triggers collapse onto one recovery per runa lost-run sweep for rows nothing is driving any more docs/workflow-fsm.md
  • Hybrid search by meaning and by word — the word leg matched by stem in the languages you list — deduplicated at write time, decayed exponentially, re-ranked for diversity — and searched automatically before every turn, so the agent never has to remember to remember. Every write lands in your git, committed by the sync daemon within minutes: diff what it learned last week, find the commit a bad fact arrived in, revert it. 0.85 meaning / 0.15 keyword, calibrated on real embeddings; age orders, never filterstwo zones: the engine-managed log and your own authored vaulta post-turn curator that saves corrections, gotchas and decisions onlya multi-process index that rebuilds and swaps itself atomicallydegrades to keyword-only rather than dying without an embedding keythe sync daemon commits every write to your own branch within minutes docs/memory.md
  • An agent that has to remember structured things — paused until 14:00, a streak, today’s challenge and its status — designs its own Postgres tables and evolves them with plain DDL mid-turn: no deploy, no migration, no PR. Every view named for its namespace is rendered into its context on every turn, and only a view that changed is sent again. Postgres computes the summary; no model summarizes it. one line in a role file turns it ontables are facts, views are what it sees, a query reaches the restscoped by role, so the next heartbeat sees the pause set from chata view, row and character budget per role, with an honest “more exist” markertwo roles may share a namespace — a writer and its reviewerdeterministic views, so an unchanged state costs nothing to resend docs/brain-dev/state.md
  • A feature’s rules and data used to live in the role, so every turn paid for every feature the role served. Now the feature keeps them in a file of its own, and the engine attaches it only to a turn linked to it — a run that reaches it, a reply to a message such a run sent, a chat bound to it, a role that always carries it, or the agent opening it from its catalog. A turn with no link pays nothing. an entity key — one ticket, one client — filters its views to that entity’s rowsa role lists the contexts it may open or infer; none listed, none — a run’s own context and a chat’s binding still arrivethe catalog sits byte-stable in the system prompt; what attaches rides the turn’s taila CLI session is sent a view again only when its rows changea budget per context and per turn — what does not fit arrives as a stub saying how to open itwhat each turn carried, and through which link, recorded on the spend ledger docs/brain-dev/contexts.md
  • CLI agents and API models sit behind one interface — the caller picks with a string and never calls a different API. And an agent is not a request: it has a durable inbox, so a message you send mid-turn is picked up at the next stopping point instead of being dropped or starting a second run. CLI mode: child process, resumable session, tools over MCPAPI mode: in-process stream, history rebuilt each turn, tools injected directlysend / enqueue / call — one verb per intent, all durably queuedinterrupt preempts without eating the message it preemptedan agent puts a prompt on its own calendar — remind, snooze, nag until answereda stream-idle watchdog kills a silent harness instead of parking it forever docs/agent-flow.md
  • Two ways to turn a goal into a plan. Cascade runs up to twelve focused stages — clarify, research, decompose, map capabilities, define done, group context, plan artifacts, review — each of which is a brain file you can rewrite. HTN does genuine recursive decomposition into a task network, bounded by construction and journaled step by step, so a crash resumes mid-tree. every stage prompt is a file in your repoeach stage validates itself and gets exactly one correction re-runclarification asks you real questions before it plansHTN linearizes its tree onto phases deterministicallya one-shot path for scenarios that do not need twelve stagesa live planning card, and cancellation that actually stops the model docs/workflow-planner.md · docs/htn-planner.md
  • Tasks carry a phase number: phases run in order, everything inside a phase runs at once. A named context group runs its tasks one after another on a single shared agent that keeps its session across phases, while ungrouped tasks race in parallel — so "these three must build on each other, those five are independent" is a property of the plan rather than orchestration code you write. parallel within a phase, sequential between — read off the blueprint alonea context group keeps one agent session, across phasesa task can ask for its agent to be compacted before the next one runsoptional tasks can fail without failing the phase or the runrun status derived from the task rows, never stored and never disagreeinga resume skips finished phases and rebuilds the agent map from what completed docs/workflow-engine.md
  • The judge earns trust instead of assuming it. A run can end with one rating card for a person — buttons for a single metric, a number per metric otherwise — and the answers are paired with the judge’s own grades. Until calibrated, cards keep coming; once judge and people agree they stop, a spot check carries on, and the loop’s automatic gates can be held closed until that agreement exists. never, always or until calibrated — per entityagreement measured per metric, over the newest pairs under the current judgetoo few pairs reads unknown, not finea tenth of runs keep their card after calibrationa new judge starts calibration over docs/brain-dev/self-evolving.md
  • Anyone with a hunch — you, a teammate, an agent — posts it for one entity: “try a shorter opener”. That entity’s next cycle works the oldest idea before anything the loop would propose itself, and every stage after the analysis is unchanged, so the idea comes back as a measured experiment with a verdict instead of an opinion. /idea in chat, a tool for agents, a panel on the dashboard — one entry point behind all threefirst in, first out, one idea per cycle, no priority knobevery surface refuses the same things in the same wordswithdraw an idea while it is still queuedthe idea stays linked to the cycle that took itposting one asks a person first, unless your brain says otherwise docs/brain-dev/self-evolving.md
  • A skill is a folder with a SKILL.md and optional scripts — the same open format Claude Code, Codex, Cursor and Copilot already read. The catalogue is three levels deep: names and descriptions in every system prompt, the body loaded when it triggers, reference files fetched on demand, so a hundred skills cost about ten thousand tokens instead of the whole window. the standard format, portable across every harnessprogressive disclosure with a graded budget, not a hard cutdeclared requirements — env, binaries, OS — checked before it is offeredinstall specs baked into the image and verified at buildper-skill enable and disable from the dashboardrecommendation without restriction: focus, never a lockout docs/skills.md
  • One JSON file decides which engine and integration tools exist for your brain — by tool or by whole category, as an allowlist or a denylist out of the same mechanism. A disabled tool is rejected by name everywhere: the gateway, MCP, the webhook door. There is no "hidden but still callable" state. layered document, resolved most-specific-firstone gate covers both listing and resolutionyour own tools are exempt — the policy cannot lock you out of themhot reload, with unknown keys warned rather than swalloweda broken file keeps the last good policy instead of stripping every tool docs/tool-registry.md
  • A task is not written once and executed. It starts as a title and a description, then accumulates its capabilities, its definition of done, its context group and its output artifacts across separate stages — each guarded by a coverage assert, so a task can never quietly lose a field between stages. id-keyed enrichment with a coverage assert at every stagecapabilities mapped before anything is authorizedthe definition of done written before the run, graded against after itcontext groups decide what shares one agent and what runs in parallelartifacts declared, then probed on disk when the task claims them
  • One closed-format string names a model everywhere — the create wizard, the chat command, role frontmatter, your registry, the database column. claude · openai:gpt-4o · claude:openrouter:x-ai/grok-4.1 · smart@high · claude@high,codex@medium. Every name must be one the system knows: a typo fails at parse with a did-you-mean, never as a silent nonexistent role. a router segment points any CLI harness at OpenRouter’s four hundred modelsa per-step reasoning-effort suffix from minimal to xhighCLI harness and API provider are different fields, never one overloaded nameclosed-world parse: structure case-insensitive, the model tail verbatima single ref is a chain of length one, so nothing has a failover special casethe availability gate stays separate from the grammar gate docs/llm.md
  • A provider marked auto-authorize hands its consent screen to a browser agent: it logs in, takes the one-time code out of the mailbox, clicks approve. Best-effort by construction — the human card is minted either way and simply stays put if the robot fails. And a token that later dies announces itself by name in chat and is re-authorized from that card, on a server with no inbound port open. an engine-shipped browser role with an anti-injection promptcredentials read inside the handler, never carried on the job payloadone-shot nonce, verifier and binding — a failure asks for a fresh cardthe human consent card is minted unconditionally, so nothing is lostthe blast radius is documented rather than hidden
  • A chain is one string: claude,codex. A role word resolves to an ordered list of concrete models out of your own registry, so "smart" means what you decided it means, per brain. What is worth failing over — a dead provider, an exhausted quota — is classified rather than guessed, so a genuine error still surfaces as an error instead of quietly burning the whole chain. a role word resolves to an ordered list of concrete modelsclassification decides what is worth failing over and what is a real errorrerouting is a first-class stream event, not a log linechains are same-mode and concrete — a CLI step never silently becomes an API callthe run-level retry sits above the chain, so a blip is not a failovera harness that dies mid-task hands its successor a transcript rebuilt from your Postgres docs/agent-flow.md
  • Two halves of one question. The policy watches a live agent’s window and acts on the crossing — a nudge, then a compaction the agent queues on itself, journaled, so a restart cannot lose it and a second replica cannot repeat it, behind whatever you already sent instead of killing it. The budget answers what filled the window before the first message: tool definitions priced at their exact wire bytes, the prompt cascade attributed section by section, the context envelope part by part. per-role marks, edge-triggered, so a compaction re-arms them by data alonethe compaction never interrupts the turn you just senton-wire cost and deferred cost never conflated into one flattering numberanything known but unpriced counts as unmeasured, never as zerofindings that name the lever: no tool deferral, unused tools, memory-heavypercentages only where the runtime actually reported a window packages/context-budget/docs/context-budget.md
  • What goes into a turn is placed by how often it changes, never by topic, because a provider’s cache breaks from the top down. The role’s system prompt stays byte-stable and is shared by every agent of the role; what moves rides the message stream, and only the sections that moved are re-sent. API models are cached per fallover step in that provider’s own dialect, and a role with a wide tool set pays for its few eager tools plus one search over the rest, not every definition on turn one. one cached prefix shared by a whole fleet of same-role agentsonly the sections that moved are re-sent, each as a self-describing updateAPI caching per chain step, in each provider’s own dialecta wide tool set deferred behind one provider-agnostic tool searcha tool the role always needs stays eager, by its own declaration docs/brain-dev/features.md § Context Placement
  • One composer builds the system prompt for the CLI path, the API path and the budget report, so a report can never describe a prompt nobody sends. It assembles in fixed modules — identity, role, persona, environment, memory instructions, language, question policy, skills catalogue — each tagged, and each replaceable by putting a file at the same path in your own repo. engine defaults overridden file by file, not forked wholesaleevery section tagged, so the budget can attribute tokens to iteach harness takes it through its own instruction channel, with its own question rulesshort rules on every turn; the reference material fetched only when it is neededa role-prompt budget that names the sections that grewfourteen engine roles, your own personas over them, and a role gets only what it declares
  • A role speaks in a voice of its own and hears through a transcription chain of its own, both declared in its file — a warm Russian coach and a teacher reading drills in standard Dutch never share a timbre. Switch voice replies on in a chat and every answer arrives twice: the text first, as always, then the same answer as a voice note in the answering role’s voice. a role’s chain replaces the brain’s whole — no inherited fallback in the wrong languagea whisper step takes a prompt, so a speaker who mixes two languages is heard in bothhot: an agent changes a role’s voice with one write, and the next synthesis uses itthe voice reads the answer, not the markup — code and bare links stay in the textpipeline code speaks as a role by naming it, with no agent in between docs/brain-dev/voice.md
  • One append-only table is an agent’s history, and everything reads it: the chat card, the dashboard, and the API agent rebuilding its whole context every turn. Rows are ordered by a monotonic id rather than a timestamp, and compaction deletes a prefix without renumbering, so every cursor and checkpoint stays valid across it. one write path — stream write, then persistence, then derived notificationswhat persists is a closed list; deltas collapse into their terminal rowthe system half of the prompt stored content-addressed, rejoined byte-identicallytwo turns with different prompt hashes make a cache break diffablea paused turn writes its own ledger row, so pre-pause spend is never lost
  • The plan is a YAML file next to the scenario — no blueprint table, no server-side drafts. A run freezes a snapshot at creation and never re-reads it, so editing the plan mid-flight cannot change what is already executing, and the run’s slug is minted from its own id rather than a count, which keeps the artifact directory and the git branch valid forever. the file is the source of truth; git is the only historya frozen snapshot per run, task specs derived from it in memorythe run slug unique by construction — no count, no racecontent hashes decide when a plan has actually gone stalea readable title alongside the machine-readable slug
  • A headless browser as a sidecar service, reachable as ordinary tools — navigate, click, read, screenshot — from every CLI harness. It comes with an engine-shipped browser role that has the browser pre-attached and an anti-injection prompt, because a page you did not write is exactly where a prompt injection lives. a service you can turn off; nothing else changes when you dothe one role allowed to carry its own MCP serversany agent can spawn it as a sub-agent for a single jobthe same role the robot consent flow drives
  • A scenario whose frontmatter stopped parsing does not silently drop off the calendar. The repairer runs ahead of every reconcile, rewrites what it can atomically on disk — so the daemon commits a diff you can read and revert — and announces both outcomes to your status channel. What it cannot repair is reported once, not on every tick. runs at start, on a manual sync, and on every content changean atomic write, so a crash never leaves half a filerepairs arrive as a reviewable commit, not a hidden mutationunrepairable files deduped per path, so one bad file is not a siren
  • Edit a scenario and the plan regenerates itself. Every reconcile tick hashes the manifest, the scenario files and the blueprints, skips what has not changed and what was just touched, and enqueues planning for the rest. Two layers of deduplication and a cross-process lock mean one change never plans twice, and a pass that failed halfway leaves the hash unset so the next tick retries. content hashes, not timestamps, decide what is stalea recently-modified guard, so saving mid-edit does not trigger a plana distributed lock across processes plus in-process coalescingthe hash advances only on a complete passskips and failures are events, not silence
  • A browsable catalogue of remote MCP servers with a two-click install: the official registry mirrored hourly, your own pasted entries, and whatever your config declares. Installing branches on the auth kind — an OAuth redirect, a pasted token, or nothing at all — and archival only happens after a successful non-empty sync, so a registry blip cannot wipe your catalogue. three sources: the official mirror, added by hand, and brain-declareda reverse-DNS allowlist when you want the official list curatedconnected entries pinned to the first page, computed in one batched joinarchival only after a good pass; a returning entry un-archives itselfsync results and entry counts as metrics rather than as a hope

control

who is allowed, who is watching, who owns the record

  • A question, a permission request, an approval, a typed input form, a person intercepting an agent — one row in one table with one event pair, not six bespoke services with six ways to get stuck. Nine parallel requests hitting the same wall collapse into a single card, because the unit of decision is you, this scenario, these capabilities — not the request; one answer fans back out and wakes all nine, whether you give it in a minute or next week. six kinds × seven producers, each cell explicitly defined or refusedthe answer commits before its consequences, so a crash replays instead of re-askingresolve on any surface and the card closes on all of thema dedicated inbox chat, or your own DM if you never set oneevery interaction bound to a conversation, so timelines render without a joinanything left undispatched is swept by a reconciler, not lost packages/hitl-gateway/docs/hitl.md · HitlGateway.ts — one upsert; (xmax = 0) names the first writer
  • An agent, a pipeline or a hook opens a page for a person — in Telegram as a Mini App behind a button, on the dashboard, or in Claude, ChatGPT and VS Code as an MCP App. It runs both ways: what the person does there arrives as events your code reacts to or as turns of the agent, and the agent pushes state back while the page is open. A widget is one self-contained HTML file in your feature. every kind of Telegram chat the bot is in, plus its menu buttona sandboxed frame with no network by default; what it may reach is frozen when it opensevery tap, submit and tool call runs as the person at the page, checked against their tier therean approval can bring its own page — still one request, decided from any surfacethe agent previews the page as a person will see it, before anyone doesoutside Telegram, a plain browser signs the person in with Telegram docs/brain-dev/widgets.md
  • Every grant carries exactly one scope — scenario, agent, heartbeat or subject — with a TTL, a call ceiling and instant revocation. Approve a subset of what was asked, or answer in free text and let the model re-read what you actually meant, with the whole correction history kept for the audit. Nothing is ever decided by a timeout: there is no fast-approve, and no silent expiry into yes. four scope kinds; a grant attached to nothing is unrepresentablemint precedence heartbeat > scenario > agent — never principal-widedeclared grants pre-authorize an automation with no card at allan approved grant widens the agent everywhere it acts — its tools, its shell, its webatomic consume under the ceiling, plus scheduled and probabilistic cleanupnothing cascades: revoking is explicit, and the audit row survives docs/grants.md
  • Dollar ceilings on metered spend — the brain by day and month, a scenario by run, day and month, a role by day and month — checked at the one point every agent turn passes, before any model is called. A spent budget refuses the turn and raises one card for that budget: +50%, ×2 or a figure you type, and the raise resumes the runs it parked. Agents may lower a limit on their own; raising one is always a person’s call. only metered spend counts — subscription usage never eats a budgetengine, brain and entity tiers, merged window by windowa workflow run parks and resumes, its finished tasks keptone card per budget and window, however many turns it refuseda pipeline reads the refusal as a typed category and decides what to dowith every budget spent, you still lift the stop from the chat you are in docs/brain-dev/budgets.md
  • One command halts the whole operation: the scheduler braked, every queued, running or retrying workflow and pipeline run paused, every agent turn in flight cancelled — recorded as one action. Resume undoes exactly what that stop did and nothing more: a brake or a paused run that was there before stays. An agent may call either, and a person approves it. a capability of its own, granted to no role but a wildcard onewhat was in flight stops; a new chat message, hook or scheduled prompt still starts a turna run that will not resume keeps the stop standing for it alone“Stop everything…” on the dashboard; its notice offers only Resume while it standswhether a stop stands is one read any agent can make docs/brain-dev/features.md
  • Over 260 reads and commands, each defined once in the engine’s op kernel and bound twice: the agent’s tool and the MCP tool. Every dashboard page reads and writes through them, so whatever a page shows, an agent can answer — with the same guards, the same refusals and the same words. Writes to brain files dry-run first and commit only against the bytes they read; anything that adds power goes through a widening op a person approves. grants, skills, memory files, models, providers, connections and repos — all opsrun traces and comparisons, the action log, your tables and key-value store — all readable by an agentdry run, diff, then compare-and-swap on the file’s hashrole files, chat access, model routing and budgets each split into narrow and widena refusal is a typed answer with a hint, never a crashevery committed command recorded as its caller docs/brain-dev/dashboard.md · docs/brain-dev/contract.md
  • The whole operation as one live map: every role, scenario, heartbeat, skill, tool, integration and memory line, linked by what actually ran through them. Scrub back to any minute of the last week and watch it replay — each run drawn as a trace from its trigger through the role, the model and the tools to the memory it touched. Traffic your config never declared is drawn dashed, so drift between what you set up and what happens is something you see rather than grep for. clustered by engine layer or by business area, one per featurelive by default; replay at up to an hour a seconda red ring for failures, an amber one for work waiting on a persona failed data source reads unreadable, never zerorebuilt from the run ledger the engine already keeps — no extra event logsearch every entity, dormant ones included, with what is failing on it now docs/brain-dev/features.md § Brain Atlas
  • Every self-evolving cycle on one page: each job in the loop as a card with its objective’s trend and whether it needs you, and one job opened on a single time axis — every merged change a step, every revert marked, the cycle in flight told in five phases from the grades that opened it to the lesson it filed. The policy each job runs under reads as sentences, with the tier that set every value. one list of everything the loop waits on you for, each with its one movethe pre-merge check drawn metric by metric, guards and objective apartthe proposal verbatim: current text, suggested text and whyaccept, skip or refine a proposal in your own words, from the pagegate and idea cards land in your chat — accept, refine or skip from the phonethe loop and grading kill switches on top, above every entity
  • Rebuilt phone-first: twelve places one level deep, one live stream per tab. The Inbox is a triage desk — every request owed to a person, two or more from one run folded into one stack, Boss mode on its tab row. Home reads in tiers, from “does anything need me?” down to the vitals; Runs reads what is going now, then the days before it; a session page is the whole conversation; the chat dock is the chief’s DM, one thread with Telegram. one Cmd+K across runs, agents, scenarios, skills, requests and people/go/ links that outlive a page move — the links agents write into chatthe features as a map of lego figures, each as big as what it is built ofa bottom bar on the phone, installable to the home screenyour own logo and favicon, served from the running braina browser shell into the brain root or any running service, replayed on reconnect docs/brain-dev/dashboard.md
  • Not a notification sink — the primary interface. Commands, declared wizard flows, inline keyboards, live cards, file exchange, voice in and voice out. Nearly everything the dashboard does, you can do from a chat on your phone, including running a pipeline handler by name. per-chat active agent and model overridemulti-step wizard flows declared, not hand-rolled per commandany pipeline handler runnable straight from a chat commandsend resilience: format degradation, group migration self-heal, rate-limit retrydeep links straight into a run or a pipeline handlerin-chat introspection — ask it what it is doing right now docs/channels.md
  • A bot marked secretary answers your chosen private chats as you, with zero bot chrome visible to the other side — no cards, no keyboards, no typing indicator, no failure bubble. Your own manual replies are recorded and time-stamped, so your engagement policy can read "the owner just answered this one" and back off. the connection owner is the auth principal; counterparts are never allowlistedidentity survives disconnect, reconnect and credential rotationapproval and question cards rerouted to your control DMa per-counterpart persona, so it speaks differently to different peoplehistory predating the connection readable under a blast-radius guard docs/secretary-mode.md
  • A coordinating agent watches the same queue you do and works it by policy — auto-approving what you delegated, routing questions to specialists, escalating only what genuinely needs a person. Start it from the Inbox, or ask an agent to: an agent’s start waits for a person’s yes, because it hands over a person’s authority. It acts through the same tools, the same compare-and-set and the same audit trail as a human would. a time-boxed run with every security knob fixed at startyou get first refusal on every card, by a configured head startit can never answer or cancel an interaction it produced itselfthe capabilities it may approve are an allowlist, not a prompt instructiona run summary: duration, turns, tools by count, decisions by kind and status docs/brain-dev/boss-mode.md
  • Step into a live agent’s conversation while it works, steer it with ordinary messages, then hand control back — no cancel-and-restart, no losing what the run already knows. A plain message supersedes a pending question; a permission card is never dissolved by unrelated chatter, because permissions are decided explicitly. the pending row is the session marker, single-active enforced in the databaserelease re-dispatches a continuation turn and resumes the runevery other resume path is refused while you hold the wheelfrom the session page, or straight from the chat
  • An agent that hits a capability it does not hold neither fails silently nor needs everything pre-approved: the tool returns a structured missing-grant error naming a remediation path this particular caller can actually take, and the agent asks for exactly that capability, mid-run, naming what it was doing. The escalation tool is always in scope — even for an agent that declared no capabilities at all — so there is no bootstrap hole. a missing grant is a typed tool result, not a crash and not a liethe failure sentence names this caller’s own path, not a generic onethe escalation tool rides turn one, whatever the agent declareda burst of concurrent requests coalesces onto one card, one decisiona delegate is capped at its delegator, so nothing spawns its way around the carda sub-agent’s question goes to its parent first; you see it only if the parent escalates
  • Spend per model, split by billing type and by reasoning versus execution versus cache-hit tokens, attributed down to the scenario and the agent that spent it, with trends and a plain-language read of what moved. Subscription usage and metered usage are counted separately rather than blended into one flattering number. real metered spend and phantom subscription spend split everywhere it aggregatesten pivot dimensions, including who triggered itunit economics: cost per completed run, cost per passed evaluationmoney flow as a Sankey — context → provider → modela forecast gauge and a period-over-period overlay with spike markersthreshold-gated advice: cache leverage, retry overhead, evaluation blind spots
  • One predicate decides what the bot reacts to and how — the single seam you customize per chat. It sees normalized signals only: scope, whether it was addressed, who forwarded what, media kinds, thread identity. No platform types ever reach your code. An ignore short-circuits before any cost: no typing indicator, no download, no agent run. the verdict can carry a steer instruction injected into that turnand an opaque context bag carried verbatim to every tool call, never through the modelengine defaults per scope: DM, group, thread, channel, businessnamed notify channels — an agent picks a name, never invents a chat idevery turn opens with where it came from — chat, thread, sender, your timezonea separate policy per persona on a multi-bot brain docs/brain-dev/engagement.md
  • Several live agents pinned side by side in one grid, each streaming independently, each with its own conversation drawer — a war room rather than a tab per run. Sessions belonging to one lineage collapse into a single row with a status histogram, so a heartbeat that has ticked four hundred times is one line, not four hundred. list, live grid and cards, with the layout derived from the URLlineage rows carrying session counts and per-status histogramsrun-scoped matrices: every agent attached to one run, in one gridkeyset pagination a new session cannot restarttool calls, task lists and plans render as interactive blocks, not log lineseach lineage in one word — running, stuck, needs you, failed docs/agent-grouping.md
  • A full-page visual plan editor with a planner agent sitting inside it: phases and tasks you drag, execution config, the deliverable — and a chat pane editing the same draft you are looking at. It saves to your brain repo as YAML under a compare-and-set on the file’s hash, so git is the only history and there are no server-side drafts to reconcile. a rail of every blueprint, ad-hoc and repo-baseda planner-role chat pane working on the draft in front of youdrag-and-drop phases and tasks, with execution config and deliverableatomic YAML write guarded by the hash you loadedan unsaved-work guard on navigation and on unloada raw-YAML escape hatch with lock status
  • A run, a plan, a pipeline, an agent turn — each gets one card that rewrites itself in place as it happens, debounced and back-pressured, instead of a stack of progress messages you scroll past. The answer streams into its own message alongside it, so the record of what was said stays separate from the record of what was happening. one message per turn, on a slot model, throttled and back-pressuredterminal stickiness — a finished card can never revert to a live keyboardanswer text streams into its own message, off the status carda reaction on your own message as a status channel: seen, working, donea plain outcome notice for a failure that had no agent to speak for itits control row: stop, run the queue now, cancel one queued message by its preview docs/channels.md
  • A conversation you continue on the dashboard shows up in the bound chat as the full conversation — delivered silently, so you are not re-pinged for something you just typed yourself. The surface that started the turn gets the notification; every other bound surface gets the quiet mirror. origin notified, everyone else served the silent copyfailed and cancelled turns advance the cursor without deliveringa card resolved on one surface loses its buttons on all of thema finished turn is guaranteed to deliver, reconciled from the rows
  • Every scheduled scenario and every heartbeat on one timeline — cron, next fire, last run, last result, and whether the grant it needs is still covered. Plus queue depth, reconciler status and a force-reconcile button, because "why did it not fire" should be one page, not three. a lane per job on one clock, its next fires up to a week aheadgrant coverage shown per scheduled entry, before it failslast result includes a tick whose delivery tool failed — not a false greenqueue stats and reconciler state beside itforce a reconcile from the page, live on scheduler eventsmissed fires counted per schedule: Late, then Down — a re-enable or an edit never trips it docs/heartbeats.md
  • Is the circuit open right now — not how many rejections there were last hour. The page reads the shared breaker and the shared limiter straight out of Redis, so what you see is the state every process is actually routing on, with the cooldowns ticking down in front of you. Beside it every tool call is metered — volume, latency, failures by type and the agent that made it — so the tool quietly failing one call in ten is found before a run trips on it. live breaker state per provider, discovered rather than configuredthe current limiter counters beside itthe state the fleet routes on, not a derived metrica snapshot poll, plus a faster feed for the events themselvestool calls by risk, source and error type, denied apart from failed
  • Once a day the chief writes you a brief in your own direct message: what ran, what failed and why, what waits on you, what it cost. The facts come from the run ledger, not from memory, and the brief is an ordinary message of that chat — reply to it and the conversation simply continues. A quiet day sends nothing. your hour, in your timezone, or offthe chief’s voice, the engine’s factsone brief a day, even when a tick is delivered twicesend one now, from chat or from the dashboardthe doctor says why when there is no chief DM to write into docs/brain-dev/features.md § Daily brief
  • Everything the engine posts unasked — the card of a run nobody in that chat started, a failed hook, a model falling back, an alert — passes one gate that remembers what each chat was told. The same thing again edits the earlier message with a count instead of pinging you; a recovery marks it resolved; below your level, nothing is sent. The level governs the engine’s words, never an agent’s. routine, news or failure — your level brain-wide, or per scenario, heartbeat and hook“↻ ×N since 12:00” on one message instead of N notificationsa failure that persists is posted again after a window you seta message a person asked for is never gatedwhat stays quiet is still a row — the brief counts it, an agent lists it docs/brain-dev/notifications.md
  • Who decided what, on every surface: each committed command — from the dashboard, an agent’s tool or MCP — each card answered in Telegram, each run cancelled from its card, each sub-agent question a parent answered, each change the loop accepted or reverted is one row with the actor, the person behind it, the op and the object. Agents read it through a tool, and a year of it is kept by default. a dry run, a refusal or a no-op writes nothingfilter by actor, person, object, feature or opa loop entity’s history includes the answers to its gate cardsa failed record never fails the decision it recordsretention is one manifest line, forever included docs/brain-dev/features.md § Action Log
  • One vocabulary for “what may this agent do”: a domain:capability string with a risk level and an approval flag. Least privilege is the default reading of it: a role holds what its own file says — silence grants nothing, and “everything” is always written out — and the tools offered and Claude’s own shell, file and web tools derive from that one list. Skills and memory have allowlists of their own, read the same way — silence is none. tools declare what they provide, plan tasks what they require, and the two meet in the middlerisk is informational; the approval flag is what actually gatesClaude’s built-ins follow the grant; a new one stays off until the engine names ita role’s skills list is an allowlist — no list, no catalogthe role file is read every turn: a narrowing reaches live agents at oncea brain flips any engine default without forking the list docs/brain-dev/contract.md
  • Anything the engine did not write — an email body, a fetched page, a webhook payload, a tool result marked external — is fenced with cryptographic boundary markers before it reaches a model. Invisible characters are stripped and lookalike angle brackets folded, so a payload cannot forge the end of its own fence. one wrapper on every external-content path, not per-integration guessworkboundary markers a payload cannot reproducehomoglyph and fullwidth bracket foldingsuspicious patterns logged, content preserved — no silent deletion
  • The role belongs to the chat: everyone in it talks to the same role, with that role’s tools and memory. Each person there is an owner, a member, a stranger or blocked, and only an owner approves — wherever the card lands, and no setting changes that. A chat rule caps what a member’s turn may reach, whatever the role holds. You set it by telling the agent, on the dashboard, or in one file. a member’s turn is the role’s grant cut to the rule’s ceiling — none by defaultthe ceiling covers what the turn spawns, schedules and recalls, not only its toolsa narrowing applies at once; a widening waits for a person’s yes“why didn’t it answer Alex?” traced step by step, through your own policy codeevery button owner-only, except an answer from the person a question askedrefusals are private — the bot never refuses in public in a group docs/brain-dev/chat-access.md
  • An entry point can declare an input schema, and then nothing runs until it is filled: the card opens, no run row is created, and the answer re-enters through the same submit path. You can fill the fields, or say them in free text — or by voice — and the translator parses them back into the schema. a form before the run, not a half-created row waiting to be fedfree text and voice parsed back into the declared fieldsthe same mechanism mid-run, resolved through a durable waitno expiry by design — one card lives until it is answered or cancelled
  • One firehose across agents, runs, pipelines, human decisions, hooks, the scheduler and the queues — live, searchable and correlated. A collector subscribes once at boot and keeps a replay buffer mirrored into Redis, so a tab opened an hour later catches up instead of starting blank. one subscription at boot, twenty thousand entries of replay behind itthe system-versus-user split declared in the event schema, not hardcoded in the UIevery envelope keyed by the first correlation id present in the payloadvirtualized rendering, so a busy brain does not melt the tabone shared reader — feature panels filter it instead of keeping a second bufferthe log tail beside it, filtered by run, agent or pipeline id — no query language
  • One session’s whole thread, live: messages, reasoning, work groups, plans and per-message usage. It also answers the forensic question — copy the exact full prompt that was sent, and open a diff on the turns where the system prefix moved, which is usually why a cache stopped hitting or a behaviour quietly changed. copy the full prompt, rejoined byte-identically from both stored halvesa marker on turns where the system prompt changed, opening a diffpending human decisions answerable inline in the timelinecleared conversations still reachable by deep linkstop, compact, clear, retitle, re-model and flush the inbox from the same page
  • Every public link the brain ever minted, on one page — live, expired and revoked alike. Filter by status, visibility or publisher, preview the content inline, edit the title or the expiry, flip public to private, or revoke it outright. The audit trail records who published, who replaced and who revoked. an expired link can be un-expired, because a mistake is not a one-way doorpublic takes a person’s approval; private needs the admin logininline preview, so revoking is never a guesspublished, replaced and revoked, each attributed docs/artifact-publishing.md
  • What is connected, and what could be: every provider with its status, its env keys and its configured models, alongside the live OAuth connections with reconnect, force-refresh and revoke. The server catalogue browses on the same page, one click to install. the provider inventory read from the running config, not a static listreconnect, force a token refresh, or revoke — per connectionconnection health visible before an agent discovers it the hard waythe catalogue and your own connections side by side
  • One brain, several bot personalities — each with its own token, persona and engagement policy, all sharing memory, skills, grants and database. Per-chat state is keyed by chat and bot together, because in a direct message the chat id is identical across every bot you run. the persona declares the name of an env var, never a tokenthe bot id derives from the token prefix, computable in any process with no API callone live turn per personality per chat, by constructionambient response elected deterministically — nobody, or exactly oneomit the list and you have exactly today’s single-bot behaviour docs/multi-bot.md
  • A forum topic binds to an agent, so inside that topic the thread is the agent selection — no command, no prefix. Each lane has its own live turn, status card, queue and delivery cursor, which means two agents stream side by side in one chat. One coordinate carries it, so every surface-keyed mechanism keeps working unchanged. the thread is the selection; commands become thread-scopedparallel lanes, each with its own card, queue and cursorone coordinate makes routing, gating and stream rebinding work unchangeda deleted topic degrades to the main stream instead of losing messagesa card tap inside a thread operates that thread’s agent, not the chat’s

the stack that’s normally a three-year project — ships with the engine

None of that is a roadmap. Here it is, running.

Company knowledge, versioned like code.

Everything it learns is committed within minutes. A bad lesson rolls back like bad code.

You draw the memory lines — one for the whole company, or one per role. No agent writes outside its own.
  • writes its own line
  • reads what its role names
How the memory works stored, written, read, searched, summarised, scoped

Stored as markdown in your brain repo, under memory/<line>/: a MEMORY.md for what every turn must know, and one log per day. brain-sync commits and pushes it every five minutes.

Written by the agent’s memory_write — to today’s log, or to MEMORY.md when marked priority. A model check drops an entry that adds nothing new; the rest lands word for word. After a turn, a strict curator can re-read it and save what is worth keeping — on most turns, nothing.

Read before every turn, each part capped: MEMORY.md 12k chars, the latest weekly, monthly, quarterly and yearly summaries 6k, today’s log 4k, the four best search hits 3k. 25k at most, however large the memory grows; older logs stay searchable.

Searched by meaning and by words: 0.85 × embedding similarity + 0.15 × the share of the message’s stemmed words a note contains. Only notes at 0.41 or above are injected, newer ones first. If search is down, the turn is told so instead of getting silence.

Summarised nightly, once you turn it on: every closed week, month, quarter and year gets a file written from the level below, yours to edit or delete. No model rewrites MEMORY.md: past 10k chars its oldest dated entries drop, then writes are refused.

Scoped: an agent writes one line and reads its own plus any its role names. The line comes from the run, not from the tool call. Replays and A/B checks get read-only memory.

the brain’s 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

acme/brain live · hot-reload
  • features/ all behaviour, one folder per feature 6 on · 1 off
  • support/ one feature, opened
  • FEATURE.md name, icon, README, on/off switch on
  • support-lead.agent.md the lead — the role that minds this feature
  • support-lead.heartbeat.md its tick — checks in, escalates to the chief next · 09:30
  • weekly-digest.scenario.md a playbook the engine plans and runs next · mon 07:00
  • weekly-digest.pipeline.ts the same playbook as durable code hot-reloaded
  • new-ticket.hook.md wakes an agent when an event lands fired · 4m ago
  • constitution/ config and prompts — no behaviour
  • access.yaml who may use which bot, where
  • MANIFEST.yaml brain-wide defaults: memory, loop, budgets
  • models.json the model catalog and its smart / fast chains
  • engine-capabilities.json risk and approval, per capability gates every tool call
  • skills/ SKILL.md catalog · from any git URL hot-reloaded · 2m
  • memory/ what the company knows, by line +3 commits · today
before every turn coarse to fine ↓
  1. forever MEMORY.md yours 12k
  2. year 2026.md ← quarters 6k
  3. quarter 2026-Q3.md ← months
  4. month 2026-08.md ← weeks
  5. week 2026-W35.md ← days
  6. today 2026-08-25.md yours 4k
  7. the ask recall ← every rung 3k
  • LLM dedup on write
  • 30-day decay ½-life
  • vector + full-text
  • 27 languages, stemmed
A git repo, not a wiki — every memory write is committed within minutes: diffable, auditable, yours. The loop files its lessons here too, won or lost

Agents do the work. You draw the line.

An agent that works your queue for a window you set.

sees
grant_request
head start
1 min · yours
window
1 h · then a hard stop
may approve
eval:rateloop:analyzeloop:supervisechat:sendagent:interceptskill:installinfrastructure:discoverintegration:revokeemail:sendmessaging:sendtelegram:invoke— and nothing else 11 of 25 gated — the rest stay yours

75 act alone an agent that holds one just calls it

  • runtime:read
  • queue:read
  • governance:read
  • config:read
  • feature:read
  • skill:read
  • context:read
  • db:read
  • event:read
  • brain:sync
  • hitl:read
  • hitl:request
  • usage:read
  • schedule:read
  • planning:read
  • eval:read
  • run:read
  • loop:read
  • pipeline:read
  • research:read
  • email:read
  • drive:read
  • sheets:read
  • calendar:read
  • tasks:read
  • messaging:read
  • contact:read
  • access:read
  • telegram:invoke_read
  • docs:read
  • design:read
  • n8n:read
  • media:process
  • writing:read
  • file:read
  • memory:read
  • boss:read
  • artifact:publish
  • agent:execute
  • queue:write
  • config:write
  • feature:write
  • skill:write
  • context:bind
  • db:write
  • event:write
  • event:watch
  • schedule:write
  • planning:write
  • eval:execute
  • run:execute
  • loop:hold
  • loop:configure
  • episode:write
  • integration:execute
  • endpoint:send
  • drive:write
  • sheets:write
  • calendar:write
  • tasks:write
  • messaging:manage
  • contact:write
  • access:write
  • notification:send
  • docs:write
  • design:write
  • n8n:execute
  • writing:write
  • engineering:execute
  • file:write
  • harness:subagent
  • memory:write
  • memory:edit
  • role:write
  • run:kill

25 ask first the call stops and raises a card; the run waits at zero compute for an answer

  • eval:rate
  • loop:analyze
  • loop:supervise
  • chat:send
  • feature:widen
  • loop:autonomy
  • loop:auto_accept
  • drive:delete
  • access:widen
  • memory:delete
  • role:widen
  • artifact:widen
  • agent:intercept
  • governance:write
  • skill:install
  • infrastructure:discover
  • hitl:write
  • integration:revoke
  • email:send
  • messaging:send
  • access:admin
  • telegram:invoke
  • budget:widen
  • system:stop
  • boss:execute

How the line holds the file it is · who answers at it · around it · over it

A prompt asks an agent to behave. Your line is a file in your repo — and every tool call is checked against it.

when a call stops at the line, one of three answers it

01 you

You, on your phone.

One card, however many runs ask for the same thing. Approve it, approve part of it, or deny it — the run waits at zero compute until you do.

02 a grant

A grant you signed earlier.

One scope, a time limit, a ceiling on calls — approved once, or declared in the scenario that needs it. Inside it, no card is raised.

03 a boss

A boss you started.

An agent that works your queue for a window you set. You get a head start; it approves only what you listed, never a card it raised itself, and past its hard stop it cannot act. An agent may start one; you say yes.

and around it

mid-run

Intercept an agent.

Freeze it, talk it through, let it go.

How

One button holds any live workflow run — the current turn finishes, then the run waits at zero compute. You talk to the agent under the run’s own grants, then release: it finishes the task with your guidance folded in, and that continuation is the task’s result. Every other resume path is refused while you hold it.

interception · the session page

between runs

Nothing ships unwatched.

A replayable change beats the version it replaces before it merges. Every change is graded on its own runs once it lands — unless you switch that watch off.

How

The loop proposes; you drew the yardstick and it cannot redraw it. On a workflow whose plan can be replayed, the candidate is replayed at the PR’s head on the inputs the cycle froze before it can merge, and the verdict lands there as a commit status your branch rules can require . A pipeline, a heartbeat or a chat role can’t be replayed, so its change is judged on its next graded runs after it lands; a regression opens the revert. A job can switch that watch off; then every change it ships settles as unmeasured, on the record. Two in a row, and both gates fall back to you until you re-arm . Per job and per gate, a person or the machine decides , and everything it waits on you for is one list .

evaluation: · watch: · omnislash/validation · maxConsecutiveRegressions: 2

the record

Every answer is on the record.

Who answered, what, and when — on the screens you run it from , and on your phone at 3am.

and over all of it

before it starts

Only what its file names.

A role holds what its file lists. A file that lists nothing holds nothing.

How

Every agent of a role starts with exactly its file’s capabilities — nothing inherited — and its skills list is an allowlist too . Claude’s own shell, file and web tools follow the same grant. An agent it spawns holds at most what it holds. It may ask for more, or write a grant itself — either way, a person says yes first.

capabilities: · skills: · grant_create

before it spends

A ceiling in dollars.

Spent out, the next turn is refused before any model is called.

How

Limits in USD, per day and month on the whole brain and on each role, and per run, day and month on a scenario. When one runs out, the next turn it covers is refused and a card asks you whether to raise it . Only metered API spend counts — a subscription never does. An agent can tighten a limit by itself; loosening one waits for your yes.

budget: · budget_update · budget_widen

all at once

Stop everything.

One command brakes the scheduler, pauses every run, stops every agent mid-turn.

How

Every queued, running or retrying workflow and pipeline run is paused and every turn in flight is cancelled, recorded as one action. On the dashboard it is one menu item, no approval asked; an agent of a wildcard role can pull it too, after a person approves. Resume undoes exactly what that stop did — a run paused before it stays paused, a cancelled turn is not rerun. Messages, hooks and scheduled prompts still start new turns.

system_stop · system_resume · system:stop

Outgrow the agent. Skip the migration.

Agent platforms send you to a separate SDK for code. Workflow builders stop at the canvas. Here one workflow climbs from a sentence to typed code.

the same path, screen by screen

AI end-to-end

for business owners

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

AI + blueprint lock

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.

  • the plan yours
  • the steps agents
  • the runtime engine

Code-defined

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.

  • the plan yours
  • the steps yours
  • the runtime engine

describe & run → lock the blueprint → engineer it — per workflow, not per account

who offers which tier · october 2026
platform tier 1 tier 2 tier 3 moves up
n8n · Zapier · Make agent stepAI builder——
LangSmith · OpenAI · Microsoft yes—separate SDKexport
OpenClaw · Hermes yespartialpartial—
Paperclip · Vybe · Polsia · Pion yesprose only——
Temporal · Restate ——yes—
Omnislash yesyesyesyes

Others cover one or two tiers, often as separate products. This spans all three on one engine — and a workflow moves up without a migration.

Why tier 3 is not another product one engine under every tier

Most platforms are built for exactly one of these tiers. A Tier-3 pipeline here 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

what one instance runs · illustrative mix 63 workflows · one deployment
  • 50 · tier 1 — AI end-to-end
  • 10 · tier 2 — AI + blueprint lock
  • 3 · tier 3 — code-defined

A workflow that climbs a tier stays on the same instance. Nothing is migrated.

Other agents take notes. Ours keep a database.

Say it once. It designs the table, writes the row, and sees it every turn after.

sponsors_overdue in its context, every turn 2 nudged · 1 held
invoice sponsor due held until nudges
INV-2026-039 Brightkiln Cookware Sep 02 null 0 1
INV-2026-044 Quillnest Notebooks Sep 09 Thu 09:00 null 0 1 skipped
INV-2026-047 Orbitkit Sep 17 null 0 1

invoice-chaser · a new session

db_execute UPDATE sponsors_invoices SET nudges = nudges + 1 WHERE invoice IN ('INV-2026-039', 'INV-2026-047');

send_email ×2 — waits for your approval

Drawn · Sixty Seconds Studio, a fictional demo studio
  • 0 migrations, deploys or PRs when it reshapes its tables
  • 1 line in the role file turns it on state: { namespace: sponsors }
  • Every turn its views are in context — in chat, on a schedule, after a redeploy

Agents usually talk in text. Omnislash agents talk in mini apps.

The agent builds one in minutes and speaks through it. The engine handles sign-in, delivery and security; it opens in a Telegram Mini App or any browser. Everything you do there — click, type, drag — reaches the agent as your reply.

Niche Draft 3 niches · 9 sources

Why it lost Saturated: 40 channels posted this week.

AI cover 01 / 03

Desk snacks for gamers

  • Demand 82
  • Competition 94
  • Buyer value 31
0:06

Five snacks that never touch your keys.

3 sources ↗ · pilot hook, generated voice

AI cover 02 / 03

Spreadsheet hacks for nurses

  • Demand 71
  • Competition 22
  • Buyer value 88
0:06

Stop re-typing your shift log tonight.

3 sources ↗ · pilot hook, generated voice

Niche chosen

Locked in.

First Short · tomorrow 09:00

  1. Tue VLOOKUP in 30 seconds
  2. Wed The shift-swap sheet
  3. Thu Med-pass timer, no app
  4. Fri Overtime, auto-summed
  5. Sat Handoff notes in one tap
  6. Sun Your PTO, color-coded
  7. Mon Template reveal · $29

Graded on signups / 1k engaged views

AI cover 03 / 03

Tiny gardens for renters

  • Demand 64
  • Competition 48
  • Buyer value 52
0:06

A balcony salad that moves with you.

3 sources ↗ · pilot hook, generated voice

live

  1. agent Made 3 covers, 3 voiced hooks image_generate
  2. agent Scouted 3 niches, 9 sources widget_update
  • A tap, a pick, a voice answer — each arrives as an event the agent reacts to, a burst of them as one turn. Your brain’s code pushes the next screen, voice and images straight to the open page, with no state relayed through the model.

    widget.submitwidgets.push(id, { state, media })voice_render · image_generate

    receipt · docs/brain-dev/widgets.md § 3, § 5

  • The engine is the host: sign-in, who may open it, live sync both ways, the sandbox, media, the Telegram controls. The agent writes one HTML page against its SDK — the MCP Apps standard — previews it in the real frame, and opens it.

    connect()widget_previewwidget_create({ draft })

    receipt · docs/brain-dev/widgets.md § 2, § 6, § 16

  • A Mini App in any chat the bot is in, or on its menu button. The same link opens in a plain browser after a Telegram sign-in. The dashboard opens every widget, and Claude, ChatGPT and VS Code render the file — there the host’s own model opens it.

    menu: truelaunch: false → urlui://<feature>/<name>

    receipt · docs/brain-dev/widgets.md § 9, § 13, § 14, § 15

Example apps — the trainer is modelled on a real coach.

18 ways in. 8 ways out. One gate.

Most stacks wire each trigger on its own. Here every one passes one gate — nothing runs anonymous.

ways in · what wakes it 18

a person says so

  • a message · DM, group, or as you
  • a voice note or a file
  • an action in the dashboard
  • an answer to a card
  • a tap on a page it opened

the clock

  • a schedule · “every weekday 9:30”
  • a heartbeat · no plan, no run
  • a one-shot it set itself

the world

  • a signed event · your verify
  • an integration’s webhook
  • a GitHub event · even a missed one
  • an HTTP tool call
  • an MCP call

the system itself

  • an engine event → a hook
  • an agent → an agent
  • a grade → an improvement
  • a lost run → recovery
  • a changed file → reconcile

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 8

  • a messenger · as a bot or as you
  • a page you tap · Telegram · Claude
  • a connected account · 80+
  • an API you declared · n8n · a browser
  • a link you can open
  • a pull request · you merge it
  • a file
  • its own memory

Name the failure you’ve lived. Here’s the code that kills it.

One of them no lab will ship every vendor’s agent, under one gate

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.

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

Kill the worker mid-run. It resumes the same turn — not the task from scratch.

durable run
run ▶ step 3 / 7
✕ crash
server killed · redeploy · network lost
↻ reconcile orphan
(sys_invocation = liveness oracle)
run ▶ resume @ step 3 / 7 ← not step 1
mailbox · HITL pause · scheduled turn · stop — all survive
How it works the mechanism, and the test that proves it

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.

One run in flight: plan, phases and agents, durable.

Durability · the bug only production shows you

You dispatch an agent and hit stop a millisecond later. The naïve design no-ops and the agent runs on.

ground truth vs the projection
stop fired 1ms after dispatch
agent row.current_invocation_id
= NULL ← projection lags
sys_invocation status
= running ← truth
→ gate on sys_invocation. the stop lands.
orphan sweep: classify in ONE query (status != completed)
re-verify EACH run before resume · recover via stealFrom CAS
How it works the mechanism, and the test that proves it

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.

  • Every engine event on one record, here the loop's own: the change that touched the rate card, stopped before anything was committed.
  • Every event the engine emits, with its payload shape, typed field by field.

Governance · the rogue-agent fear, as a database problem

Nine parallel runs need the same permission. You get one approval card, not nine — and you’re never re-asked.

coalesce & fan-out
9 pipelines + 1 agent + 1 workflow ─▶ hit: calendar:write
ON CONFLICT (dedup_key) WHERE status='pending' → 1 row, 11 subs
owner approves ··· once
fan-out (idempotent): awakeable · paused VO · workflow FSM
decision committed BEFORE grant → die in gap → 15s sweep replays
forged actionId on the wire → rejected vs the declared set
one hitl_interactions table · 4 fragmented pipelines deleted
budget spent → 1 card per window · an agent may not answer it
stop everything → 1 command · runs paused · turns cancelled
How it works the mechanism, and the test that proves it

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. Money runs through the same queue: a spent budget refuses the next turn, and every refusal in that window joins one card that only a person can answer.

receipt · HitlGateway.ts:486-552 (the one upsert; xmax = 0 names the first writer) · validateApprovalActions.ts:111-124 (forged-button rejection) · hitl.ts:198-207 (the budget card, human-only) · docs/brain-dev/budgets.md.

  • Everything waiting on a person in one inbox; the $18,500 sponsor deal open, with exactly what will be sent.
  • Which capabilities an agent asks for, and the call it is blocked on.
  • Live grants with usage counters and hard limits; the ringed one belongs to the Boss run and ends with it.

Isolation · “cool demo” → “I’d run it on my prod”

The vendor’s CLI owns its own subprocess and never hands you argv. So we jail it through the one seam it exposes.

the jail topology
bwrap shim (via the SDK’s one executable-path override)
--ro-bind / / --tmpfs /tmp --proc /proc
--unshare-pid --unshare-ipc --die-with-parent
bind per-run checkout → /app/brain (writes trapped, disposable)
bind artifacts root → RW (agent write = validator read, one inode)
per-run repo = git clone --shared --local · alternates → 0 copy · gc off
boot gate probes the EXACT combo → can’t jail? refuses to start.
How it works the mechanism, and the test that proves it

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).

A shell in the brain, in the browser.

Model fabric · the outage every subscription team has lived

Claude Code prints “resets 3:10pm (Europe/Amsterdam)”. We parse that into an epoch and pin the provider across the whole fleet.

one ModelRef column
claude
CLI harness · your Max subscription
claude:openrouter:x-ai/grok-4.1
same harness · Grok via env override
openai:gpt-5.2
in-process AI-SDK call
claude,codex
cross-harness fallover chain
→ billing auto-flips subscription ⇄ metered
“resets 3:10pm (Europe/Amsterdam)” → epoch → Redis-Lua pin OPEN
a role moved onto codex / opencode
own shell, whatever the grant → a person approves
How it works the mechanism, and the test that proves it

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 · parseResetTime.ts (“resets 3:10pm (Europe/Amsterdam)” → an instant) · redisCircuitBreaker.ts:138 (OPEN_UNTIL, one Lua script) · handoff.ts:92-102.

Which model runs which role, with prices and fallbacks, in one file.

Context budget · the prompt that grows one feature at a time

Each feature you add writes its rules into the role prompt. From then on the heartbeat chasing one overdue invoice pays, every tick, for the support desk’s tone guide.

what one turn carries
ticket.context.md · rules + views
attaches only on a link
run
a beat, hook or task that reaches it
chat
the room is bound to it
reply
answers a message the run sent
ask
opened from a one-line catalog
no link
not in the turn · pays nothing
entity T-481
its keyed views show that ticket only
acme’s group
context_open(globex) → refused
over budget
rows cut, then a stub: “context_open it”
the prefix
cached · API tools past 30 deferred by default
How it works the mechanism, and the test that proves it

Here a feature brings its rules and its data in a file it owns — features/<f>/<name>.context.md — and the engine attaches it only to a turn with a link to it: a run of an entity that reaches it, a reply to a message such a run sent, a chat bound to it, the agent opening it from a one-line catalog, a role that always carries it, or your code. A turn with no link pays nothing. A link can carry an entity key — one ticket, one client — and a view filtered by that key shows its rows and no other; in a group bound to client@acme every other key is refused, so the same line is tenant isolation. Nothing is dropped silently: past its budget a context loses rows under a marker, then becomes a one-line stub that says how to open it, and instructions are never cut mid-text — half a rule reads as the whole rule. Every turn records what it carried, by link, key and size.

receipt · resolveTurnContexts.ts:118 (links in, the chat pin applied — another key refused) · turnContexts.ts:133 (the fit: instructions first, rows cut, then a stub, strongest link first) · decision 0028 (a feature context arrives by link) · docs/brain-dev/contexts.md.

  • The bill itself, measured — what one role’s context window is spent on.
  • Every tool, the engine’s and your own, with its schema, its risk and the capability it needs.

Planning · the silent corruption one-shot planners ship

A JSON schema can assert “an array of {taskId}”. It cannot assert “this set of task IDs equals the set produced three stages ago.”

the planner as a state machine
11-stage cascade · durable to the stage · resumable mid-pipeline
stage 1 → researchNeeded? → the ONLY ['*'] privileged stage
greps the real repo → 1 task per discovered item
enrich: each merge → assertTaskCoverage → drop task-3? throw w/ ID
final review → schema-whitelisted to 5 fields → can’t add/delete a task
kill @ stage 7 → resume @ stage 8 · 0 re-spent tokens
How it works the mechanism, and the test that proves it

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).

  • The plan behind a job, frozen as phases and tasks on a board.
  • Each task's contract — definition of done, agent, model and spend — is what the grade is measured against.

Isolation · live edit vs pull request, decided at the git layer

An agent that edits its own repo is a good demo. The question production asks is which files it may touch while it runs.

the write surface
runIn ladder
live ⊂ clone (+own git) ⊂ sandbox (+bwrap)
live (default)
writes the running checkout · daemon commits + pushes
clone
own pushable clone, no jail → durable edit → PR
sandbox
that clone, inside the bwrap jail
the push surface
memory/ · constitution/ · skills/ · features/
write outside it
succeeds → gone on recreate → now fails at boot
must be a directory
a sparse anchor never matches a blob
forbidden outright
docker/ (socket → own container) · .github (CI = code)
cold files
config · tools/ · db/ → the clone rung → commit → PR
How it works the mechanism, and the test that proves it

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).

  • What the agents produced, previewed and audited: next week's 21-post slate.
  • The proposed change, verbatim: the current text, the suggested text and why, over the file it edits.

Self-evolution · autonomous, because it’s fenced

Most self-editing loops trust the model not to edit its own grader. That’s a prompt instruction it ignores the moment editing the test is the cheapest way to pass.

the surface one proposal runs under
one proposal → one apply turn
may write
the files it named
may not write
eval methods · db/
may not read
its own rubric
the rule no path can hold
evaluation:
in the file it edits
improvement:
any move → rejected
How it works the mechanism, and the test that proves it

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.

  • A change that made things worse never ships: the check closed its PR.
  • Worse after the merge? It opens its own revert and waits for the undo before trying again.
  • Two regressions in a row and the machine hands its gates back to a person until someone re-arms them.
  • Every knob — cadence, check, gates, budget — shows which tier set it: engine default, your constitution, or this job. Your own measurement code is named.
  • The judge is a file you write: the studio's brand rubric, versioned.

Depth · the protocol most frameworks skip

Vanilla MCP OAuth assumes one user at a localhost loopback redirect. Our agent is headless and the human is on a phone, hours later.

redirect → durable card
agent hits OAuth-protected MCP server (headless)
DCR (RFC 7591) → per-issuer Redis lock serializes registration
auth() → redirectToAuthorization() → mints oauth_consent HITL row
state = HMAC · timing-safe · SET-NX replay · GETDEL one-shot PKCE
human taps approve in Telegram (hours later) → run resumes w/ token
token persist fails → RFC 7009 revoke (never strand a live grant)
one table backs: question·grant·approval·input·consent·interception
How it works the mechanism, and the test that proves it

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.

  • Your accounts, connected once, each with its health and when its token renews.
  • Which capabilities an agent asks for, and the call it is blocked on.

Depth · the capability that needs a fence, not a disclaimer

An agent replying as you, in your own DMs, is one API call away. Not being able to read the rest of your account is the hard part.

acting as the owner
someone writes to your account
engagement gate → agent turn → one plain reply, sent as you
status cards · keyboards · typing · reactions — all suppressed
turn fails → they see nothing; you get one note in your control DM
approval card → your DM, never theirs
credential ≠ identity — the connection id rotates on every rights edit
state keyed (chat, bot, owner) → survives disconnect + rotation
blast radius — every MTProto call pinned to THIS chat
dialogs · global search · a named account → refused, permanently
their turns reach only the bot’s DM ceiling — nothing by default
your own agent, in your own DM, keeps full access
How it works the mechanism, and the test that proves it

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.

  • Posting publicly is a restricted capability: a person grants it, per call or per window.
  • Live grants with usage counters and hard limits; the ringed one belongs to the Boss run and ends with it.

Bring one operation. Watch it run.

Not a slide deck. I map it to a brain and run it in front of you — on the real engine.

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
hi@omnislash.ai

Screens from Sixty Seconds Studio, a fictional demo studio, running on the real dashboard.