Devplane

The decision log

Why a command ran without anybody being asked, and why there is a pull request on this branch — answerable months later, with the authority and the rule or check named.

The event log records what happened to Devplane. The decision log records what Devplane did or refused, and on whose authority, so why did that command run without anybody being asked? and why is there a pull request on this branch? stay answerable months later.

devplane audit                   # the latest 50 decisions
devplane audit <run-or-change>   # narrowed to one run or change
devplane audit --without-me      # only what was decided instead of you
devplane audit --otel            # OpenTelemetry GenAI log records on stdout
2026-09-13T18:04:11 person   github:pr.create https://github.com/acme/app/pull/142
                     ↳ offered as a draft
2026-09-13T18:04:09 person   git:push         change/fix-the-flaky-login-test-a1b2c3
                     ↳ offered the change
2026-09-13T18:04:02 devplane gate:run         pnpm typecheck && pnpm test -- --run
                     ↳ check passed
2026-09-13T17:58:40 rule     agent:tool.use   Bash: rm -rf /tmp/build
                     ↳ refused by Bash(rm *)
2026-09-13T17:58:31 person   agent:tool.use   rm -rf node_modules
2026-09-13T17:41:09 timer    agent:tool.use   Bash: pnpm publish
                     ↳ a clock refused it after 4h — set in devplane.toml
2026-09-13T17:22:55 nobody   agent:question   req-7c03
                     ↳ the run ended under the question

The same rows are in the workbench’s Ledger, and on each change’s Ledger tab.

The ledger: what Devplane recorded as decided, when, on whose authority, and the rule behind each verdict

What a row says

The authority, the action (agent:tool.use, agent:question, gate:run, git:push, github:pr.create, change:archive), the subject, the outcome, and the reason: not “refused” but “refused by Bash(rm *)”.

AuthorityWhat it means
personsomebody was asked and answered — in the workbench or with devplane answer
rulea never_auto or always_ask rule matched. The rule is in the reason, and re-evaluating it reproduces the verdict
timernobody answered before the deadline your project set in [questions]; the duration and file are in the reason
nobodyasked, never answered, and the moment passed — the run ended under the question, or a held permission lapsed. Quitting the host cleanly does not produce this: the question survives
devplaneDevplane doing what your project wrote down: running a gate, stopping a change at its budget. A push and a pull request are person: you offered the change

There is no unknown: a row whose authority cannot be established is not written. --without-me leaves out person and devplane rows. With --otel, the authority rides on each gen_ai.tool.call.decision record; nothing is sent anywhere. devplane modes shows which sessions run with no prompts at all.

Decisions are never pruned

When a host starts, events, telemetry and transcripts older than 30 days, and finished runs older than 7 days, are pruned. Decisions and asks are appended and kept.

An upgrade that changes the store’s schema is the exception: the whole file is moved aside as ~/.devplane/devplane.v<n>.<time>.bak (never deleted by Devplane) and a new store starts, so devplane audit and the Ledger start empty. The old log is still in that file, readable with sqlite3. See Troubleshooting.

The hook writes its decision straight to the store, so no host has to be running. If the store will not open, the decision goes to ~/.devplane/pending-decisions.jsonl; devplane doctor counts what is waiting there, and the next host files it, marked as filed late.

What became of a report

A report writes up to three actions on the record of the change that filed it:

ActionAuthorityWhen
report:resolvedpersonanswered: fixed, rejected or deferred with a reason, or a GitHub draft discarded
report:openedpersona GitHub draft opened under your GitHub sign-in; the issue address is the reason
report:deliveredrulethe target’s [reports] deliver_from named the source, so the report was handed to its live run

Filing a report writes no decision. See Reports between projects.

What is not in the log

  • An undecided call. When no rule matches, your agent shows its own dialog. Devplane does not see your answer there, so it writes nothing.
  • Calls under a standing “allow always”. That choice lives in the agent’s session. When you choose it in a run Devplane drives, the row’s outcome says allow_always, so you know later matching calls will not appear.

Limits

Devplane’s own actions are accounted for; the agents’ actions are supervised. The log is append-only in a local SQLite file, not tamper-evident. See Security.

Everything Devplane does to the world is safe to repeat: a gate is a read, pushing a branch twice is one branch, and an existing pull request is looked up before one is opened.

Something wrong or out of date? Edit this page.