Permission Rules, Modes and Session Budgets

medium10 minpermissions.ts

A coding agent should run your tests without asking, never read .env or push, plan before it edits, and stop when a session has spent enough.

What it shows

  • Allow, ask and deny rules in the grammar of Claude Code, read from .claude/settings.json too
  • Plan mode keeps the agent read-only until a person approves its plan
  • Every decision lands in the thread log, a budget pauses the run instead of failing it

The code

permissions.ts
import { Agent, Cogitator, LocalWorkspace, workspaceTools } from '@cogitator-ai/core';

const workspace = new LocalWorkspace({ root: process.cwd() });

const cog = new Cogitator({
  memory: { adapter: 'memory' },
  permissions: {
    allow: ['Bash(npm test *)', 'Bash(git status)', 'Read'],
    ask: ['Bash(git push *)'],
    deny: ['Read(.env)', 'Bash(rm -rf *)'],
    settings: true,
  },
  budget: { session: { maxCostUsd: 1, maxToolCalls: 50 } },
});

const coder = new Agent({
  name: 'coder',
  model: 'ollama/qwen2.5:7b',
  instructions: 'You fix bugs. In plan mode, present your plan with exit_plan_mode first.',
  tools: workspaceTools(),
  workspace,
});

const threadId = 'bugfix-42';
const paused = await cog.run(coder, {
  input: 'The date parser drops the timezone, fix it.',
  threadId,
  permissions: { mode: 'plan' },
  onPermissionDecision: (event) => console.log(event.decision, event.toolName, event.reason),
});

const plan = paused.interrupts?.find((entry) => entry.kind === 'plan');
if (plan) {
  console.log(plan.details?.plan);
  const done = await cog.resume(coder, threadId, {
    responses: { [plan.id]: { approved: true, mode: 'acceptEdits' } },
  });
  const budget = done.interrupts?.find((entry) => entry.kind === 'budget');
  if (budget) {
    await cog.resume(coder, threadId, { responses: { [budget.id]: { action: 'stop' } } });
  }
  console.log(done.output, done.sessionSpend);
}

await workspace.dispose();
await cog.close();

Run it

install · bash
pnpm add @cogitator-ai/core
ollama pull qwen2.5:7b
run · bash
npx tsx permissions.ts

Or run the full example from a clone of the repository (keys in .env):

repository · bash
npx tsx examples/core/26-permissions.ts

Learn more