Your agent can only do what you said it could.
Thskyshield gives every agent run a declared boundary — how much it may spend, how many steps it may take, which tools it may call, and whether it may write. The check happens before the call fires. Three SDK calls. Any loop.
$ npx @thsky-21/thskyshield-demoNo signup. No API key. No network. About four seconds.
Works with LangGraph · CrewAI · OpenAI Agents SDK · any framework
$ npx @thsky-21/thskyshield-demoReal output, verbatim — this is what the command above prints.
A stuck agent doesn't crash, and an off-track agent doesn't ask.
A stuck agent doesn't crash.
It retries. It re-asks. Every individual call returns a clean 200 — your monitoring shows a healthy service, because nothing ever throws. The loop is the failure, and a loop has no stack trace. By the time a human notices the bill, the run has been repeating itself for however long nobody was watching.
An off-track agent doesn't ask.
It hits an obstacle — a permission it doesn't have, a file it can't write, a step that keeps failing — and it does what an agent does: it looks for a way through. Sometimes that way through is reasonable. Sometimes it's a tool call nobody scoped it for, reaching a system nobody meant it to reach. It doesn't pause to check, because nothing told it where the edge was.
Six things every run declares.
Three are contained the moment you switch enforce on. Three are measured from day one, and enforced when you decide they should be.
Tools it may call
A run declares its tool allowlist up front. A call to anything outside it is denied before it fires — killed_scope_tool.
What it may write
Every step declares how destructive it is — read-only, reversible, or destructive. A step over the run's ceiling is denied — killed_scope_mutation.
The same prompt again
The same prompt fingerprint repeated past the loop threshold is denied before the next call — killed_loop.
Dollars
A hard budget ceiling in USD. Reserved before the call, settled to the actual cost after — killed_budget.
Wall clock
A run that's been open too long is denied on its next step — killed_timeout.
Step count
A hard ceiling on how many steps a run may take, independent of what each one costs — killed_iterations.
We don't kill a run mid-task unless you tell us to. You'll see what would have happened first.
Three calls. That's the integration.
Wrap your agent loop with beginRun, beforeStep, and afterStep. One atomic round-trip, under 10ms, prompts hashed in your own process, fails open at every layer. There is no agent to run and nothing to host.
shield.beginRun()Set a dollar ceiling, a step cap, a timeout, a loop threshold, which tools may be called, and how destructive a write may be.
run.beforeStep()One round-trip checks every boundary — tools, writes, loop, budget, steps, time — before your API call fires.
run.afterStep() + run.end()afterStep settles the real token cost against the reservation. Nothing on the record is an estimate.
import { Thskyshield, ShieldKilledError } from '@thsky-21/thskyshield'
const shield = new Thskyshield({ siteId, apiKey })
const run = await shield.beginRun({
budgetLimitUsd: 2.00,
iterationLimit: 30,
loopThreshold: 5,
allowedTools: ['search', 'read_file'], // the only tools this run may call
maxMutationClass: 'reversible', // no destructive writes
})
try {
while (!done) {
const { requestId } = await run.beforeStep({
stepType: 'tool',
toolName: 'search',
mutationClass: 'read_only',
estimatedTokens: { input: 500, output: 200 },
promptInput: currentPrompt,
})
const result = await callYourTool(currentPrompt)
await run.afterStep({
requestId,
actualTokens: result.usage,
model: 'gpt-4o-mini',
})
}
} catch (e) {
if (e instanceof ShieldKilledError) {
// e.reason: 'killed_scope_tool' | 'killed_scope_mutation' | 'killed_loop'
// | 'killed_budget' | 'killed_iterations' | 'killed_timeout'
console.log(`Agent stopped: ${e.reason}`)
}
} finally {
await run.end()
}It watches before it touches anything.
Handing a kill switch to something you installed this morning is a lot to ask, so we don't ask for it. Every new project starts in observe mode.
You get the report either way. Enforcement is the part you turn on once you have read it — and there is nothing to undo if you never do.
- Observe mode runs every check and stops nothing. Your agents behave exactly as they do today.
- Each run records the decision it would have made — which boundary, and where. No card, nothing blocked.
- Flip a project to enforce when you're ready. The switch applies to the next run, never one already in flight.
killed_scope_toolkilled_scope_mutationkilled_loopkilled_timeoutkilled_iterationskilled_budgetWe'd rather tell you what we don't know.
A boundary that fails silently isn't a boundary — it's a guess you stopped checking. Every number and every verdict on this product is built to be wrong in only one direction: understated, never inflated.
- When we can't reach a verdict, your agent runs anyway — and we say so. Every step carries a reason: a real decision, or exactly which part of our system was down when it went through unchecked.
- A model we don't have a price for is priced at the floor of what we know, never a guess above it. A total can come in too low. It never comes in too high.
- What you're billed against is never an estimate held over. The number before the call is a reservation; the number after it is replaced by what the call actually cost.
Policy that outlives the process.
The boundary isn't a constant in your code. It's a setting on your project, read fresh at the start of every run. Change it and the next run picks it up — no redeploy, no restart, no code review.
Every agent your team points at that project inherits the same boundary. One place declares it. Every run enforces the one that was declared, not whatever the code happened to ship with.
shield.beginRun({ ... })Mode, budget, allowlist, and mutation ceiling — resolved from your project's current settings, not baked into a deploy.
Applies to the next run your agent starts. Runs already in flight finish under the boundary they started with.
Watch for free. Talk to us to enforce.
- Every decision recorded — the full counterfactual
- Nothing blocked
- Unlimited history — nothing expires
- No card required
- —Enforce mode
- All six boundaries enforced — tools, writes, loop, budget, steps, time
- Denies the call before it fires, not after
- Priority support, direct to the founder
Enforce is priced per team while we're early — tell us what you're running and we'll walk you through it.
Things people ask us.
Give it a boundary it can't cross.
Free to watch, no card. Or watch it stop an agent at its boundary first — one command, nothing to install.
$ npx @thsky-21/thskyshield-demo