Ekbasis does not chat. You give it a state (what the world looks like now), an action and a few typed questions, and it answers each question with calibrated probabilities, in one forward pass. This page shows how to think about it, how to write a state it can use, and what it really answers.
It is not only for code. It works for anything you can describe in the state — git and the shell, payments, databases, email, calendars, cloud and Kubernetes — and has been measured in 21 domains. See real answers by domain.
Every answer on this page is a real response of Ekbasis-27B-INT4 on the hosted API, recorded on 2026-10-10 (34 calls), unless it is marked as measured in the cookbook.
Building an agent? Point it at openinterp.org/ekbasis/agents.md — the same guide written for language models: exact formats, when to consult, decision rules, failure handling.
You describe the world as it is now and the action about to happen. It tells you what the world will look like afterwards, as probabilities over answers you defined.
It never writes text. There is no conversation, no "hello", no explanation. Every request is a state plus typed questions; every answer is numbers.
It does not decide what is allowed or good. It says what will happen; your code (or a person) decides what to do with that, using thresholds you choose.
The closest everyday analogy is a weather forecast: it does not argue with you or tell you to stay home. It says “70% rain”, and you decide about the umbrella. Ekbasis says “99%: this loses uncommitted work”, and your tool decides whether to stop. Because nothing is generated, you pay only for the input tokens it reads.
The facts now: files, balances, branches, rules, what the screen shows.
What is about to happen, usually written into the state (“About to: …”).
Typed, with the possible answers listed: choice, yes/no, score.
A probability for every option, the pick and its confidence. One pass, no text.
{
"state": "Checking account available balance: $180.20. About to: transfer $250.00 to a friend.",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens with the transfer?",
"options": [
"transfer succeeds",
"transfer fails: insufficient funds"
]
}
}
}state: the facts and the action, in plain English. The numbers are there.questions: a map of names to questions; you pick the names (here q).type: choice with options: the answer is always one of these.{
"answers": {
"q": {
"type": "choice",
"choice": "transfer fails: insufficient funds",
"probabilities": {
"transfer succeeds": 0.03514484688639641,
"transfer fails: insufficient funds": 0.964855134487152
},
"confidence": 0.964855134487152
}
},
"usage": {
"input_tokens": 131,
"output_tokens": 0
}
}choice: What happens with the transfer?
confidence 0.965
Read it as: “the transfer fails, 96.5% sure”. The state decided the outcome ($180.20 < $250.00), so the model is confident.
All three use the same hosted endpoint and key. Get the key in the console (sign in, create a key, buy credits).
The CLI reads your repository with read-only git commands, writes the state for you and asks the trained git questions. You write no state at all.
# 1. get a key: https://openinterp.org/console → Create API key (then buy credits)
# 2. install the client (Python ≥ 3.9, no dependencies)
pip install ekbasis
# 3. point it at the hosted API
export EKBASIS_URL=https://openinterp.org/api/v1
export EKBASIS_API_KEY=ekb_... # the key from the console
ekbasis health # setup check: free, needs no key
# 4. ask before you run
cd your-repo
ekbasis git-check -- "git reset --hard"
ekbasis git-check -- "git checkout main" && git checkout main # only runs if exit 0Ekbasis: RISKY (lose uncommitted work: 99%)| exit | meaning | do |
|---|---|---|
| 0 | no risk found | run it |
| 2 | RISKY: may lose work or file content | stop, read the reason, decide |
| 3 | cannot foresee (server unreachable, no key, no credits, unreadable repo, parts it cannot evaluate) | treat as risky |
| 1 | usage error | fix the command |
Also: ekbasis shell-check -- "rm -r build/" (prototype) and ekbasis preflight -- "sqlite3 app.db < migrations/0012.sql" (which step of a multi-step change fails first). --fail-open turns exit 3 into 0; do not use it for anything destructive.
Claude Code hook. Before every Bash call that runs git, the hook asks Ekbasis. If the command may lose work, Claude Code asks you to confirm, with the reason. Put EKBASIS_URL and EKBASIS_API_KEY in your shell profile, then add to ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "ekbasis-claude-hook", "timeout": 30 }]
}
]
}
}EKBASIS_GUARD_MODE=deny blocks instead of asking; EKBASIS_SHELL_GUARD=1 also checks non-git lines that change files (prototype). On top of the model the hook adds a rule layer for committed work (e.g. git branch -D of a branch with unique commits). When it cannot foresee, it asks.
MCP (any MCP client). Three tools: check_git_commands, predict_consequences (your own rules, state, actions and questions) and preflight_command.
pip install "ekbasis[mcp]" # Python ≥ 3.10
claude mcp add --scope user ekbasis \
-e EKBASIS_URL=https://openinterp.org/api/v1 -e EKBASIS_API_KEY=ekb_... -- ekbasis-mcpTo teach an agent when to ask (and when not to: over-asking trains people to click through), give it the ekbasis-guard skill.
client.ask(state, questions) sends every question about one state in one request. The helpers write the question dicts for you: yes_no, choice, number, and world_state for the rules / state / actions layout.
from ekbasis import Ekbasis, choice, yes_no, world_state
client = Ekbasis("https://openinterp.org/api/v1", api_key="ekb_...") # or EKBASIS_URL / EKBASIS_API_KEY
state = world_state(
rules="A card purchase is approved only if the available balance covers it. "
"A refund counts only once it has arrived.",
state="Card available balance: $15.00. A $40 refund was issued yesterday; it arrives in 3-5 business days.",
actions=["Pay a purchase of $18.00 today."],
)
ans = client.ask(state, {
"approved": yes_no("Is the $18.00 purchase approved?"),
"balance": choice("What is the available balance afterwards?", ["$15.00", "$55.00", "-$3.00"]),
})
for name, a in ans.items():
print(name, a.value, round(a.confidence, 3), {k: round(v, 3) for k, v in a.probabilities.items()})approved False 0.981 {'yes': 0.019, 'no': 0.981}
balance $15.00 0.974 {'$15.00': 0.974, '$55.00': 0.003, '-$3.00': 0.023}
Each answer has .value (True/False or the chosen label), .confidence, .probabilities and, for yes/no, .p_yes. Errors raise CannotJudge (a subclass of ekbasis.EkbasisError): catch it and treat the action as risky. Any language works: it is one JSON POST (see the curl under every example below).
This is where first answers go wrong. The model knows how actions behave; it does not know your world. Whatever decides the outcome has to be in the text. Three pairs, same question, real answers:
Weak state
state · Account balance is a bit low. About to: transfer $250.00 to a friend.
choice: What happens with the transfer?
confidence 0.755
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Account balance is a bit low. About to: transfer $250.00 to a friend.",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens with the transfer?",
"options": [
"transfer succeeds",
"transfer fails: insufficient funds"
]
}
}
}'Better state
state · Checking account available balance: $180.20. About to: transfer $250.00 to a friend.
choice: What happens with the transfer?
confidence 0.965
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Checking account available balance: $180.20. About to: transfer $250.00 to a friend.",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens with the transfer?",
"options": [
"transfer succeeds",
"transfer fails: insufficient funds"
]
}
}
}'Same pick, but 75.5% instead of 96.5%: with “a bit low” it is guessing, and the confidence says so.
Weak state
state · About to: rm ~/thesis/draft.docx
choice: What happens to the thesis draft?
confidence 0.936
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "About to: rm ~/thesis/draft.docx",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the thesis draft?",
"options": [
"lost permanently",
"recoverable from the cloud version history"
]
}
}
}'Better state
state · File ~/thesis/draft.docx is synced to cloud storage with version history (two-way sync on). About to: rm ~/thesis/draft.docx
choice: What happens to the thesis draft?
confidence 0.947
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "File ~/thesis/draft.docx is synced to cloud storage with version history (two-way sync on). About to: rm ~/thesis/draft.docx",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the thesis draft?",
"options": [
"lost permanently",
"recoverable from the cloud version history"
]
}
}
}'Without the fact it assumes the usual case, rm of a file nobody backed up: 93.6% lost. It cannot see your cloud sync until you write it down; with it, 94.7% recoverable.
Weak state
state · Trip booked as one round-trip ticket: outbound flight Friday, return flight Sunday. About to: cancel the outbound flight on Friday (the traveller will drive there instead).
choice: What happens to the return flight on Sunday?
confidence 0.593
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Trip booked as one round-trip ticket: outbound flight Friday, return flight Sunday. About to: cancel the outbound flight on Friday (the traveller will drive there instead).",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the return flight on Sunday?",
"options": [
"it stays booked",
"it is cancelled too"
]
}
}
}'Better state
state · Trip booked as one round-trip ticket: outbound flight Friday, return flight Sunday. Airline rule for this fare: if the outbound flight is cancelled or not flown, every later flight on the same ticket is cancelled automatically. About to: cancel the outbound flight on Friday (the traveller will drive there instead).
choice: What happens to the return flight on Sunday?
confidence 0.965
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Trip booked as one round-trip ticket: outbound flight Friday, return flight Sunday. Airline rule for this fare: if the outbound flight is cancelled or not flown, every later flight on the same ticket is cancelled automatically. About to: cancel the outbound flight on Friday (the traveller will drive there instead).",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the return flight on Sunday?",
"options": [
"it stays booked",
"it is cancelled too"
]
}
}
}'Without the fare rule it leans on the common case at 59.3%, close to a coin flip. With the rule written in the state, 96.5% the other way.
Put the numbers in the state
Write "balance: $180.20, transfer: $250.00", not "the balance is a bit low". Amounts, counts, sizes, times and limits are what decide most outcomes.
Say what is irreplaceable, and what is backed up
The model cannot see your disk. "The only copy, never backed up" and "synced with version history" lead to opposite answers for the same rm.
Write out the hidden rules
If the consequence comes from a rule that is not visible on the screen (a fare that cancels the return flight, a folder link that shares subfolders), state the rule. This is the #1 reason a first answer looks wrong.
Send the slice the action touches
3–8 concrete facts beat three pages of context. States over ~32k tokens are refused (HTTP 422); the git client caps itself at 8 files and 12 branches.
Make the options exhaustive and distinct
Each option should be a different outcome that you would act on differently. The probabilities are spread over your options only.
Separate rules, state and actions
The client helper world_state(rules, state, actions) writes the layout the model was trained on. To make a rule count, repeat it right before the question with recap() (the client docs measure the gain).
A question is {type, instructions, …}. You always define the possible answers; the model spreads its probability over them.
choice · pick one of options (a list) or criteria (label → description)
state · The organizer creates a meeting for 9:00 AM New York time (Eastern). An attendee is in San Francisco (Pacific, 3 hours behind).
choice: What time does the San Francisco attendee see?
confidence 0.995
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "The organizer creates a meeting for 9:00 AM New York time (Eastern). An attendee is in San Francisco (Pacific, 3 hours behind).",
"questions": {
"q": {
"type": "choice",
"instructions": "What time does the San Francisco attendee see?",
"options": [
"6:00 AM their local time",
"9:00 AM their local time"
]
}
}
}'noul · yes/no; optional criteria say what true and false mean
state · Working tree: app.py, utils.py and README.md have uncommitted changes (2 hours of edits, never committed or stashed). About to: git reset --hard
noul: Will uncommitted work be lost?
confidence 0.985
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Working tree: app.py, utils.py and README.md have uncommitted changes (2 hours of edits, never committed or stashed). About to: git reset --hard",
"questions": {
"q": {
"type": "noul",
"instructions": "Will uncommitted work be lost?",
"criteria": {
"true": "uncommitted changes are gone",
"false": "nothing is lost"
}
}
}
}'score · how many / how much, over labelled values
state · Working tree: app.py, utils.py and README.md have uncommitted changes (never committed or stashed). About to: git reset --hard
score: How many of the 3 modified files keep their changes?
confidence 0.974
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Working tree: app.py, utils.py and README.md have uncommitted changes (never committed or stashed). About to: git reset --hard",
"questions": {
"q": {
"type": "score",
"instructions": "How many of the 3 modified files keep their changes?",
"criteria": {
"0": "none",
"1": "one",
"2": "two",
"3": "all three"
}
}
}
}'Put every question about the same state in one request: one round trip, and every answer is the same as if asked alone. Usage still counts the state once per question (399 input tokens here). Note the subtle one: reset --hard keeps the untracked file.
state · Working tree: app.py and utils.py have uncommitted changes; notes.txt is a new untracked file. Nothing is stashed. About to: git reset --hard
lostnoul: Will uncommitted changes to tracked files be lost?
confidence 0.991
untrackednoul: Is the untracked file notes.txt deleted?
confidence 0.996
recoverablenoul: Can the lost changes be recovered from a stash or a branch afterwards?
confidence 0.988
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Working tree: app.py and utils.py have uncommitted changes; notes.txt is a new untracked file. Nothing is stashed. About to: git reset --hard",
"questions": {
"lost": {
"type": "noul",
"instructions": "Will uncommitted changes to tracked files be lost?"
},
"untracked": {
"type": "noul",
"instructions": "Is the untracked file notes.txt deleted?"
},
"recoverable": {
"type": "noul",
"instructions": "Can the lost changes be recovered from a stash or a branch afterwards?"
}
}
}'For yes/no questions, probability is p(true): “how likely is the bad thing”. For choice and score, probabilities has one number per option, summing to 1.
The probability of the answer it picked. 0.95–0.99 when the state decides the outcome; it drops when the state does not. Low confidence is information, not an error: it means a fact is missing.
state · A service whose configuration file content is unknown (never inspected). About to: restart the service with the new config file that was just dropped in place by someone else.
noul: Will this cause an outage?
confidence 0.693
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "A service whose configuration file content is unknown (never inspected). About to: restart the service with the new config file that was just dropped in place by someone else.",
"questions": {
"q": {
"type": "noul",
"instructions": "Will this cause an outage?",
"criteria": {
"true": "an outage is likely",
"false": "no outage"
}
}
}
}'state · A production database whose schema and contents are unknown to the team. About to: run a migration script from a vendor (its contents were not reviewed).
noul: Will this cause data loss?
confidence 0.827
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "A production database whose schema and contents are unknown to the team. About to: run a migration script from a vendor (its contents were not reviewed).",
"questions": {
"q": {
"type": "noul",
"instructions": "Will this cause data loss?",
"criteria": {
"true": "data loss is likely",
"false": "no data loss"
}
}
}
}'| p(bad outcome) ≥ 0.5 | pause: show the person the reason, do not proceed without confirmation |
| 0.2 ≤ p(bad) < 0.5 | the git CLI already calls this RISKY (its default --lost-threshold is 0.2): confirm first |
| p(bad) < 0.2 and confidence ≥ 0.9 | no warning: the guard stays quiet. That is not a guarantee: keep your normal confirmations and backups for anything irreversible |
| confidence < 0.9 on a destructive action | a fact is probably missing: go and read it (the file, ps, the calendar) and ask again |
| cannot foresee (exit 3, any HTTP error) | treat as risky: never as "ok" |
From the cookbook’s guard skill and the CLI defaults. Tune them to how bad the bad outcome is. A low p(bad) means the model found no risk in what you described; it is not a proof that the action is safe.
With no key, no credits or no server, the client tools answer cannot foresee (exit 3), which they treat as risky. A guard that runs out of credits never silently turns into “everything is fine”. In your own code, do the same: any non-200 means “do not proceed unattended”.
| HTTP | meaning |
|---|---|
| 200 | answers, plus usage.input_tokens (what you are billed for) |
| 401 | no key, or an invalid or revoked key |
| 402 | out of credits: buy more in the console |
| 403 | the account is restricted |
| 422 | the request cannot be read, e.g. a state over ~32k tokens (the reason is in the body) |
| 503 | the model server is unreachable |
{
"error": "unauthorized: send the Authorization: Bearer header"
}Most states below are scenarios from the cookbook’s re-runnable suites; the answers are the hosted API’s. Open “Copy this request” on any card to run it yourself (with EKBASIS_URL and EKBASIS_API_KEY exported).
The same repository (3 files with uncommitted edits), two plans. The questions are the ones the git CLI asks, worded as in training. Stashing first changes the answer.
You are looking at a git repository on a developer machine (a Linux shell; 'origin' is its remote). The commands below are run in order in the repository root; a command that fails changes nothing more and the next one still runs. State before: Current branch: main Branches (last commit message): main (add total()) Remote origin/main last commit: add total() (the current branch is up to date with it) git status: README.md (unstaged modified); app.py (unstaged modified); utils.py (unstaged modified) Stash entries: 0 Commands, in order: 1. git reset --hard The questions are about the state after all these commands.
lostnoul: Do these commands permanently lose any uncommitted work (a version of a file that existed before and afterwards is in none of: the working directory, the staging area, any branch, any stash)?
confidence 0.990
in_progressnoul: After these commands, is a merge or rebase left unfinished (in progress)?
confidence 1.000
fails_1noul: Does command 1 fail (exit with an error)?
confidence 0.999
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "You are looking at a git repository on a developer machine (a Linux shell; '\''origin'\'' is its remote). The commands below are run in order in the repository root; a command that fails changes nothing more and the next one still runs.\n\nState before:\nCurrent branch: main\nBranches (last commit message): main (add total())\nRemote origin/main last commit: add total() (the current branch is up to date with it)\ngit status: README.md (unstaged modified); app.py (unstaged modified); utils.py (unstaged modified)\nStash entries: 0\n\nCommands, in order:\n1. git reset --hard\n\nThe questions are about the state after all these commands.",
"questions": {
"lost": {
"type": "noul",
"instructions": "Do these commands permanently lose any uncommitted work (a version of a file that existed before and afterwards is in none of: the working directory, the staging area, any branch, any stash)?"
},
"in_progress": {
"type": "noul",
"instructions": "After these commands, is a merge or rebase left unfinished (in progress)?"
},
"fails_1": {
"type": "noul",
"instructions": "Does command 1 fail (exit with an error)?"
}
}
}'the git layout the CLI builds, written by hand (ekbasis.prompts.git_state + the trained questions)
You are looking at a git repository on a developer machine (a Linux shell; 'origin' is its remote). The commands below are run in order in the repository root; a command that fails changes nothing more and the next one still runs. State before: Current branch: main Branches (last commit message): main (add total()) Remote origin/main last commit: add total() (the current branch is up to date with it) git status: README.md (unstaged modified); app.py (unstaged modified); utils.py (unstaged modified) Stash entries: 0 Commands, in order: 1. git stash 2. git reset --hard The questions are about the state after all these commands.
lostnoul: Do these commands permanently lose any uncommitted work (a version of a file that existed before and afterwards is in none of: the working directory, the staging area, any branch, any stash)?
confidence 0.997
in_progressnoul: After these commands, is a merge or rebase left unfinished (in progress)?
confidence 1.000
fails_1noul: Does command 1 fail (exit with an error)?
confidence 1.000
fails_2noul: Does command 2 fail (exit with an error)?
confidence 1.000
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "You are looking at a git repository on a developer machine (a Linux shell; '\''origin'\'' is its remote). The commands below are run in order in the repository root; a command that fails changes nothing more and the next one still runs.\n\nState before:\nCurrent branch: main\nBranches (last commit message): main (add total())\nRemote origin/main last commit: add total() (the current branch is up to date with it)\ngit status: README.md (unstaged modified); app.py (unstaged modified); utils.py (unstaged modified)\nStash entries: 0\n\nCommands, in order:\n1. git stash\n2. git reset --hard\n\nThe questions are about the state after all these commands.",
"questions": {
"lost": {
"type": "noul",
"instructions": "Do these commands permanently lose any uncommitted work (a version of a file that existed before and afterwards is in none of: the working directory, the staging area, any branch, any stash)?"
},
"in_progress": {
"type": "noul",
"instructions": "After these commands, is a merge or rebase left unfinished (in progress)?"
},
"fails_1": {
"type": "noul",
"instructions": "Does command 1 fail (exit with an error)?"
},
"fails_2": {
"type": "noul",
"instructions": "Does command 2 fail (exit with an error)?"
}
}
}'the git layout the CLI builds, written by hand (ekbasis.prompts.git_state + the trained questions)
With the CLI on real repositories (measured in the cookbook’s guard battery, client 0.1.6):
git reset --hard (3 modified files)
RISKY, 99% · exit 2
git clean -fd (2 untracked files)
RISKY, 98% · exit 2
git stash drop / git stash clear (1 real stash)
RISKY, 99% · exit 2
git stash pop (1 real stash)
ok, 3% · exit 0
9 safe commands on clean repos (status, log, add -A, commit, …)
ok, 0% (no false alarms) · exit 0
rm -rf / (shell-check)
RISKY, 90% · exit 2
dd if=/dev/zero of=/dev/sda (shell-check)
cannot foresee → treated as risky · exit 3
Facts about the filesystem in the state; the shell semantics come from the model.
state · Directory: data/ has 40 GB of datasets. symlink_to_data is a symbolic link pointing to data/. About to: rm symlink_to_data
choice: What happens to the datasets?
confidence 0.977
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Directory: data/ has 40 GB of datasets. symlink_to_data is a symbolic link pointing to data/. About to: rm symlink_to_data",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the datasets?",
"options": [
"safe: only the symbolic link is removed, the 40 GB stay",
"deleted: the datasets are gone"
]
}
}
}'state · The environment variable TMPDIR is unset (empty). About to: rm -rf "$TMPDIR/"*
choice: What happens?
confidence 0.953
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "The environment variable TMPDIR is unset (empty). About to: rm -rf \"$TMPDIR/\"*",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens?",
"options": [
"the command expands to rm -rf /* : everything at the root is deleted",
"it deletes only an empty temp folder"
]
}
}
}'state · File results.txt exists with 3 days of analysis output (not backed up, not in git). About to: run ./analyze.sh > results.txt
choice: What happens to the old content of results.txt?
confidence 0.986
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "File results.txt exists with 3 days of analysis output (not backed up, not in git). About to: run ./analyze.sh > results.txt",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the old content of results.txt?",
"options": [
"overwritten and lost: the redirect truncates the file",
"kept: the output is appended"
]
}
}
}'Blast radius before a statement runs. Note the lower confidence on the backup-then-drop plan: the state does not say the dump succeeded.
state · Table logs: 50M rows of audit history. About to: DELETE FROM logs (no WHERE clause)
choice: What happens?
confidence 0.983
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Table logs: 50M rows of audit history. About to: DELETE FROM logs (no WHERE clause)",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens?",
"options": [
"all 50M rows are deleted",
"only logs older than 30 days are deleted"
]
}
}
}'state · About to run: BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id=7; ROLLBACK;
choice: What is the account balance afterwards?
confidence 0.977
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "About to run: BEGIN; UPDATE accounts SET balance = balance - 100 WHERE id=7; ROLLBACK;",
"questions": {
"q": {
"type": "choice",
"instructions": "What is the account balance afterwards?",
"options": [
"unchanged: the ROLLBACK discards the update",
"reduced by $100"
]
}
}
}'state · About to run: 1) pg_dump the full database to backup.sql (takes 20 min), 2) DROP TABLE users
choice: What happens to the data?
confidence 0.893
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "About to run: 1) pg_dump the full database to backup.sql (takes 20 min), 2) DROP TABLE users",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the data?",
"options": [
"recoverable: the backup completes before the drop",
"lost permanently"
]
}
}
}'For actions that are not shell commands, the state is what the screen and the account show.
state · Account balance: $1,020.00. About to: send an international wire of $1,000.00 with a $25.00 wire fee added to it.
choice: What happens with the wire?
confidence 0.960
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Account balance: $1,020.00. About to: send an international wire of $1,000.00 with a $25.00 wire fee added to it.",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens with the wire?",
"options": [
"succeeds",
"fails: $1,025 total exceeds the $1,020 balance"
]
}
}
}'state · Card available balance: $15.00. A refund of $40 was issued yesterday but takes 3-5 business days to arrive. About to: pay a purchase of $18.00 today.
choice: What happens with the purchase?
confidence 0.965
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Card available balance: $15.00. A refund of $40 was issued yesterday but takes 3-5 business days to arrive. About to: pay a purchase of $18.00 today.",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens with the purchase?",
"options": [
"declined: the refund has not arrived yet, only $15.00 available",
"approved: the refund counts immediately"
]
}
}
}'state · Weekly team meeting every Monday 10:00, recurring, 40 future occurrences. About to: delete only THIS Monday's occurrence (this event only).
choice: What happens to the other Mondays?
confidence 0.985
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Weekly team meeting every Monday 10:00, recurring, 40 future occurrences. About to: delete only THIS Monday'\''s occurrence (this event only).",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the other Mondays?",
"options": [
"they continue as scheduled",
"they are all deleted"
]
}
}
}'state · Email thread: 11 colleagues + 1 external client. The draft reply contains internal pricing tables. About to: click Reply All.
choice: Who sees the internal pricing?
confidence 0.984
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Email thread: 11 colleagues + 1 external client. The draft reply contains internal pricing tables. About to: click Reply All.",
"questions": {
"q": {
"type": "choice",
"instructions": "Who sees the internal pricing?",
"options": [
"everyone, including the external client",
"only the internal colleagues"
]
}
}
}'state · You received an email where you and 8 others were on BCC (hidden). About to: click Reply All.
choice: What happens to the BCC recipients?
confidence 0.932
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "You received an email where you and 8 others were on BCC (hidden). About to: click Reply All.",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the BCC recipients?",
"options": [
"their addresses get revealed to everyone in the reply",
"they stay hidden"
]
}
}
}'Contexts, volumes and versioning: the facts that make the same command harmless or destructive.
state · Current kubectl context: production. File staging.yaml defines replicas=1 and DEBUG=true. About to: kubectl apply -f staging.yaml
choice: What happens?
confidence 0.958
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Current kubectl context: production. File staging.yaml defines replicas=1 and DEBUG=true. About to: kubectl apply -f staging.yaml",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens?",
"options": [
"production gets 1 replica and debug mode",
"staging gets updated, production is untouched"
]
}
}
}'state · docker-compose.yml: app + postgres with a named volume for its data. The volume holds 3 years of records. About to: docker compose down -v
choice: What happens to the records?
confidence 0.984
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "docker-compose.yml: app + postgres with a named volume for its data. The volume holds 3 years of records. About to: docker compose down -v",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the records?",
"options": [
"the volumes are removed: the records are gone",
"they survive: -v only stops the containers"
]
}
}
}'state · S3 bucket data has versioning ENABLED. About to: overwrite s3://data/curated/users.csv with a wrong file
choice: What happens to the previous file?
confidence 0.980
curl -s "$EKBASIS_URL/v1/systemone" \
-H "Authorization: Bearer $EKBASIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "S3 bucket data has versioning ENABLED. About to: overwrite s3://data/curated/users.csv with a wrong file",
"questions": {
"q": {
"type": "choice",
"instructions": "What happens to the previous file?",
"options": [
"it is lost: overwrites are permanent even with versioning",
"it stays recoverable as a previous version"
]
}
}
}'Ekbasis-27B-INT4, October 2026, hand-verified ground truth: use-case map. These are the authors’ own scenarios, not an independent benchmark: measure on your own cases before relying on it.
curl … | bash and kill -9 -1 pass it today, and patterns like dd of=/dev/sda return "cannot foresee" (exit 3).git push --force: the model alone does not see it. Since client 0.1.7 the Claude Code hook asks when a force-push would overwrite commits only the remote holds.$0.04 per 1M input tokens, no output charges (it generates none), prepaid credits, no subscription. Pricing assumes ~1.5k input tokens for a git-guard check, ≈ $0.00006 per check ($0.06 per 1,000); the requests on this page used 107–1,060 input tokens each; every response reports usage.input_tokens. Self-hosting is free under Apache-2.0.
EKBASIS_URL to your server. A self-hosted server has no authentication, so keep it on a network you trust. Setup guides: GPU · Mac (MLX).More: the Ekbasis page (results and papers), the API reference, the client on GitHub, or [email protected].