Skip to content
commission

Worked configurations

You will be able to copy a .commission.json that matches how your team actually works — solo, a small engineering team, or a regulated organisation — and know which keys change behaviour today and which are accepted but not yet enforced.

Every key is defined in the generated config reference. This page is the opposite of that: not exhaustive, just four files that work, with the reasoning attached.

The precedence rule, once

defaults < db < file < local < env < flags

.commission.json is committed and shared. .commission.local.json is gitignored and yours. Environment variables beat both; command flags beat everything. When a value is not what you expected, ask commission rather than reading files:

commission config explain context.warnOnDrift
context.warnOnDrift = false
  set by: local (.commission.local.json)
  overrode: file = true
  overrode: defaults = true
  precedence: defaults < db < file < local < env < flags

explain answers “which layer won”, which is the question that actually gets asked when a setting looks wrong. It does not answer “is this key wired up” — see the next section.

Read this before you copy anything

Some blocks are validated, merged, and reported, but not yet applied. They pass commission config validate, appear in commission config show, and are attributed correctly by commission config explain — and change no behaviour.

blockwhat happens todaywhat to do instead
gatescommission gates reports none; commission add --gate <name> is refusedcommission gates --set shipped=pr,test, or commission init --gates '{"shipped":["pr","test"]}'
execution.*closing is unaffected by defaultAutonomy, requireApproval, mayExecuteset it per task: commission edit <id> --autonomy supervised, --may-execute, --preferred-actor
agentDefaults.*lease and budget do not move the defaults; requireNoteOnDone does not refusepass --lease / --budget per command; use context.bundleBudget for a project-wide budget
branch.*branch names stay commission/<id>-<slug>integrations.github.branchPrefix — that is the prefix commission branch actually reads
notifications.*nothing is deliveredpoll commission inbox

Only integrations and actors are reconciled from the file into the project row on every command; execution policy and gate profiles are read from that row, which is why declaring them in the file has no effect. The blocks that are read straight from the file are context, workspace, providers, and notices.

This is stated here rather than left to be discovered because a configuration file that validates, displays correctly, and quietly does nothing is the most expensive kind of wrong. See execution policies for what is enforced.

Solo founder

You are the only human, everything is autonomous, and the file should be almost empty. Two keys carry it: the project, and the guidance you want versioned alongside the work.

{
  "$schema": "https://commission.sh/schema/commission-config.schema.json",
  "version": 1,
  "project": "myapp",
  "context": {
    "track": ["CLAUDE.md", ".claude/**", "docs/adr/**"],
    "bundleBudget": 6000,
    "warnOnDrift": true
  }
}

context.bundleBudget is the highest-value key here for one person running several agents: it caps what every context bundle costs, drops sections in a fixed order, and declares what it omitted, so a long-running project does not quietly start spending more per task than it used to.

Everything else you need is a command, not a key:

commission gates --set shipped=pr,test
export COMMISSION_ACTOR=blaze

Engineering team

Several humans, several agents, one repository. Actors are declared so commission knows who is a person; work happens in a worktree per task so parallel agents do not fight over the checkout; the environment comes from .env because nobody wants a vault dependency to run tests.

{
  "$schema": "https://commission.sh/schema/commission-config.schema.json",
  "version": 1,
  "project": "myapp",
  "actors": [
    { "name": "blaze", "kind": "human", "roles": ["owner", "approver"] },
    { "name": "sam", "kind": "human", "roles": ["approver"] },
    { "name": "claude:api", "kind": "agent", "capabilities": ["implement", "test"] },
    { "name": "claude:web", "kind": "agent", "capabilities": ["implement"] }
  ],
  "workspace": {
    "strategy": "worktree",
    "dir": ".worktrees",
    "providers": ["dotenv"],
    "ports": { "range": [4300, 4399], "perTask": 2 },
    "setup": [{ "name": "install", "run": "bun install" }]
  },
  "context": {
    "track": ["CLAUDE.md", "AGENTS.md", ".claude/**", "docs/adr/**"],
    "warnOnDrift": true
  },
  "integrations": {
    "github": { "repos": ["acme/myapp"], "branchPrefix": "commission/" }
  }
}

Declaring actors is what makes approval mean anything: an actor whose kind is agent cannot approve or answer a blocking question, and the refusal says so by name. With no actors declared, nothing is restricted — see execution policies.

Add .worktrees/ to .gitignore. Commission warns if you forget, but it warns after the fact.

Regulated organisation

Jira is still the system of record, the security team owns the allowlist, and secrets come from Vault with .env filling in the boring local defaults.

{
  "$schema": "https://commission.sh/schema/commission-config.schema.json",
  "version": 1,
  "project": "payments",
  "actors": [
    { "name": "priya", "kind": "human", "roles": ["owner", "security"] },
    { "name": "claude:payments", "kind": "agent", "capabilities": ["implement"], "autonomy": "supervised" }
  ],
  "integrations": {
    "jira": {
      "baseUrl": "https://acme.atlassian.net",
      "projects": ["PAY", "SEC"],
      "fields": { "rank": "customfield_10019", "severity": "customfield_10390" },
      "statusMap": { "in_review": "Awaiting QA" }
    },
    "github": {
      "repos": ["acme/payments"],
      "autoCloseOnMerge": false,
      "branchPrefix": "commission/"
    },
    "selection": ["severity", "due", "priority", "rank", "age"]
  },
  "workspace": {
    "strategy": "worktree",
    "providers": ["vault", "dotenv"],
    "ports": { "range": [4500, 4599] }
  },
  "providers": {
    "vault": { "type": "vault", "path": "payments/dev", "app": "kv" },
    "dotenv": { "type": "dotenv", "files": [".env"] }
  }
}

Three things this file buys you:

  • integrations is an allowlist, not a hint. A project that does not declare a Jira site or a repo prefix cannot bind to it, so one project can never write into another’s systems. Site identity is checked on observe, push, and import.
  • autoCloseOnMerge: false keeps a merged PR from closing a task. Gates still apply either way; this is about who gets to say the work is finished.
  • Provider order is precedence. ["vault", "dotenv"] means a key defined by both comes from Vault, and every shadowed key is reported by name in the prepare warnings. See workspaces.

Machine-local overrides

.commission.local.json, gitignored, never fingerprinted, never shared:

{
  "version": 1,
  "context": { "track": ["notes/**"], "warnOnDrift": false }
}

The local layer is additive only as far as guidance tracking is concerned. It can add files for your machine; it cannot remove a committed file from the shared set, because a subtraction you made on your laptop would move a number your teammates compare against. See context and drift.

One rough edge: commission config validate with no arguments validates each discovered file standalone, and a local override with no project key fails that check even though it is perfectly valid as a layer. commission doctor validates the merged result and reports file + local config valid. Prefer commission doctor in CI on a repo that ships a local example, or validate the committed file by name:

commission config path
commission config show
commission doctor

path prints which files were considered, in order. show prints the merged, effective result — which, per the caveat above, is not the same question as “what will commission enforce”.

Unknown keys are refused, not ignored, and the refusal names the nearest declared key. That is deliberate: a silently ignored typo in a config file is indistinguishable from a feature that does not work.


Part of Reference.

This page is docs/reference/config-examples.md in the Commission repository, rendered in place — the site keeps no copy of it. The repository is private, so there is no edit link to follow.