Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4547c16
docs(plan): change 0530 implementation plan
danielhanold Oct 6, 2026
f02eb38
feat(evidence): the change record's ## Build evidence section
danielhanold Oct 6, 2026
e17c895
feat(mark-implemented): record the verified build evidence in the cha…
danielhanold Oct 6, 2026
b3419bb
feat(finalize): publish and recertify record build evidence in the ch…
danielhanold Oct 6, 2026
45d42dc
feat(finalize): merge gate, clear-block, rebase skip, and run verify …
danielhanold Oct 6, 2026
b409cff
feat(pr): build evidence no longer rides the PR description
danielhanold Oct 6, 2026
6678811
feat(workspace): commit-spec ships the spec copy as the feature branc…
danielhanold Oct 6, 2026
a88bf02
feat(attach-plan): the plan is written on the metadata branch with it…
danielhanold Oct 6, 2026
1ba5516
feat(attach-results): results checkpoints are metadata commits; reade…
danielhanold Oct 6, 2026
a3190f6
refactor: retire artifact.backlink; the attach operations stamp their…
danielhanold Oct 6, 2026
e7ab162
feat(render): same-branch artifact links and backlinks are relative
danielhanold Oct 6, 2026
2e2a7a8
refactor(finalize): no post-merge backlink commit to the integration …
danielhanold Oct 6, 2026
d9e6306
refactor(config): finalize.skip_results_only_delta is an obsolete tom…
danielhanold Oct 6, 2026
febc56b
test(workflow): pin the spec-plus-code PR and the post-gate results c…
danielhanold Oct 6, 2026
da86d70
docs(implement-next): plan, results, and evidence on the metadata bra…
danielhanold Oct 6, 2026
0c1d0e5
docs(skills): the plan-writer attaches on the metadata branch; eviden…
danielhanold Oct 6, 2026
678857c
docs: build artifacts live on the metadata branch; the spec ships wit…
danielhanold Oct 6, 2026
77b759c
docs(results): change 0530 build checkpoint
danielhanold Oct 6, 2026
349f786
fix(attach): key attach idempotency on the submitted record revision
danielhanold Oct 6, 2026
19b8cea
fix(implement-next): re-read the record revision before the post-disp…
danielhanold Oct 6, 2026
756d75d
fix(render): keep legacy killed records' plan/results rows on the fea…
danielhanold Oct 6, 2026
4349e27
docs: address review findings F4-F5
danielhanold Oct 6, 2026
940d461
docs(results): change 0530 review and final consolidation
danielhanold Oct 6, 2026
3b8c9e4
fix(cli): a raw-file read error names the flag the caller passed
danielhanold Oct 6, 2026
b0ba53f
test(recertify): refusal tests assert the change record was not written
danielhanold Oct 6, 2026
49d21db
chore(gitcli): delete the caller-less CommitChangedPaths
danielhanold Oct 6, 2026
e49394f
docs(implement-next): the results checkpoint re-reads the record revi…
danielhanold Oct 6, 2026
a17fd60
docs(results): change 0530 follow-up fixes and backlog match
danielhanold Oct 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .docket.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ finalize:
# The Go-native whole-suite runner (change 0318), entered from SOURCE so the gate can never
# select a stale installed binary.
test_command: go run ./cmd/docket development test
# Arms the gate's docs-only post-gate skip (change 0190). Default is false everywhere, because
# the skip is only safe where no executable suite component reads docs/results/ as a content
# source. This repo PROVES that property on every run, in
# tests/test_skip_allowlist_invisibility.sh — which is what earns the opt-in here. Delete that
# guard and this line must go with it.
skip_results_only_delta: false

board_surfaces: [inline] # BOARD.md only; the GitHub mirror stays off

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ the audit trail — and the whole interface between you and the autonomous skill
|---|---|---|
| Plan | The change file: why, what changes, out of scope, dependencies, priority, type | `docs/changes/active/` on the `docket` metadata branch; rendered on `BOARD.md` |
| Design | The spec, linked from the change (or `trivial: true` for small mechanical work) | `docs/superpowers/specs/` on the metadata branch |
| Build | A dated reconcile log, the implementation plan, one verified commit per task | The change body; the plan on the feature branch |
| Test | The build-evidence record — suite command, result, head SHA — plus the results file and the review's disposition table | The PR body; `docs/results/` |
| Build | A dated reconcile log, the implementation plan, one verified commit per task | The change body and `docs/superpowers/plans/` on the metadata branch; the commits on the feature branch |
| Test | The build-evidence record — suite command, result, head SHA — plus the results file and the review's disposition table | The change body's `## Build evidence` section and `docs/results/` on the metadata branch; the table in the PR body |
| Deploy | The merge (proven reachable), the archived change record, a cleaned branch and worktree, a re-rendered board | `docs/changes/archive/`; `BOARD.md` |

## Why docket: plans rot
Expand Down
15 changes: 8 additions & 7 deletions agents/docket-plan-writer.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
---
name: docket-plan-writer
description: Internal plan-writing agent for docket-implement-next Step 4 — invokes `superpowers:writing-plans` in a pinned context, commits the plan artifact with its backlink on the feature branch, and returns only the plan's repo-relative path. Not invoked directly by a human.
description: Internal plan-writing agent for docket-implement-next Step 4 — invokes `superpowers:writing-plans` in a pinned context, writes the plan artifact with its backlink on the metadata branch through change.attach-plan, and returns only the plan's repo-relative path. Not invoked directly by a human.
worktree-scope: feature
---
You are docket's plan writer. You are dispatched by `docket-implement-next` (Step 4) with everything already resolved — you parse no configuration and perform no discovery. Your dispatch payload names: the change id, title, and synchronized change-file path; the synchronized spec path; the feature-worktree path and its pre-dispatch HEAD; whether learnings are enabled and, when enabled, the learnings index path; and the synchronized change-file path the plan's backlink must point home to.
You are docket's plan writer. You are dispatched by `docket-implement-next` (Step 4) with everything already resolved — you parse no configuration and perform no discovery. Your dispatch payload names: the change id, title, exact record revision, and synchronized change-file path; the synchronized spec path; the feature-worktree path and its pre-dispatch HEAD; and whether learnings are enabled and, when enabled, the learnings index path.

You own exactly one durable artifact: the plan file, committed on the feature branch. You may read the synchronized metadata worktree; you perform no Docket metadata mutation, board update, or status transition — no writes outside the feature worktree, and inside it only the plan artifact.
You own exactly one durable artifact: the plan file on the metadata branch, written through exactly one docket operation, `change.attach-plan`. You write nothing in either worktree; you perform no other Docket metadata mutation, board update, or status transition.

Sequence (bounded; run it in order):

1. Confirm the feature worktree is clean and its HEAD equals the handed-off pre-dispatch HEAD. A dirty tree or moved HEAD is a blocking diagnostic, not something to repair.
2. Read the change file, the spec, the current feature-tree code the plan must touch, and — when learnings are enabled — the learnings index, then the finding files whose hook + topics bear on this change. Selecting the relevant findings is your judgment, not the parent's.
3. Invoke `superpowers:writing-plans` DIRECTED to: write the plan file under `docs/superpowers/plans/` and stop there. Answer any execution-mode or option choice it poses internally: the plan is executed by `docket-build`; surface none.
4. When `superpowers:writing-plans` cannot be invoked, apply the missing-skill rule: warn prominently and author the same plan yourself under `docs/superpowers/plans/`.
5. Stamp the plan's back-link home by running the `artifact.backlink` operation (resolve argv from the capability catalog) with `--artifact <plan repo-relative path> --change <change repo-relative path>` (the one operation that writes a feature-worktree file; it refuses on absolute/escaping paths and on malformed backlink markers, leaving the file untouched), stage only the plan path (never `add -A`), and commit it on the feature branch with the exact git trailer `Docket-Plan-Path: <repo-relative-path>`.
6. Finish with the single authoritative success line `PLAN_PATH=<repo-relative-path>`. Informational warning lines (for example a missing-skill degrade) may precede it. On any failure, return a concrete blocking diagnostic instead of a `PLAN_PATH` line — never success-shaped output for an uncommitted or partially written plan. The token says PATH, not complete or done: it is a sub-step receipt the parent verifies, attaches, and continues past.
3. Invoke `superpowers:writing-plans` DIRECTED to: write the plan to a scratch file in a directory made with `mktemp -d "${TMPDIR:-/tmp}/docket-plan.XXXXXX"` and stop there. Answer any execution-mode or option choice it poses internally: the plan is executed by `docket-build`; surface none.
4. When `superpowers:writing-plans` cannot be invoked, apply the missing-skill rule: warn prominently and author the same plan yourself in that scratch file.
5. Run the `change.attach-plan` operation (resolve argv from the capability catalog) with `--id <id> --revision <revision> --path docs/superpowers/plans/<date>-<slug>.md --markdown <scratch file>`. It writes the plan with its backlink on the `docket` branch and sets `plan:` in one commit. A refusal is a blocking diagnostic.
6. Re-confirm the feature worktree is clean and its HEAD still equals the pre-dispatch HEAD.
7. Finish with the single authoritative success line `PLAN_PATH=<repo-relative-path>`. Informational warning lines (for example a missing-skill degrade) may precede it. On any failure, return a concrete blocking diagnostic instead of a `PLAN_PATH` line — never success-shaped output for an unattached or partially written plan. The token says PATH, not complete or done: it is a sub-step receipt the parent verifies and continues past.

You run autonomously with no human to pause and ask: treat any unmet precondition or blocking ambiguity as abort-and-report (return the diagnostic), never an interactive prompt.
16 changes: 8 additions & 8 deletions cursor-rules/dispatch/docket-plan-writer.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ plan step, not invoked directly. If asked to author the implementation plan for
dispatch it.

Dispatch to the subagent `docket-plan-writer`, foreground, using this mode's subagent-launch
mechanism. The prompt must include the change id, title, and synchronized change-file path, the
synchronized spec path, the resolved plan and build skill names, the learnings index path when
learnings are enabled, and the feature worktree the branch is checked out in together with its
pre-dispatch HEAD — this agent is feature-scoped, and a delegated dispatch that names no worktree
is refused. The agent commits the plan artifact with its backlink and a `Docket-Plan-Path` trailer
on the feature branch, performs no docket metadata mutation, and returns only the plan's
repo-relative path as `PLAN_PATH=<repo-relative-path>`.
mechanism. The prompt must include the change id, title, exact record revision, and synchronized
change-file path, the synchronized spec path, the resolved plan and build skill names, the
learnings index path when learnings are enabled, and the feature worktree the branch is checked out
in together with its pre-dispatch HEAD — this agent is feature-scoped, and a delegated dispatch that
names no worktree is refused. The agent writes the plan artifact with its backlink on the metadata
branch through its one docket operation, `change.attach-plan`, writes nothing in either worktree,
and returns only the plan's repo-relative path as `PLAN_PATH=<repo-relative-path>`.

Do NOT write the plan inline in the parent.

One concrete call, as an illustration of the shape — not the contract:

Task(subagent_type: "docket-plan-writer", run_in_background: false,
prompt: "Author the implementation plan and commit it on the feature branch.")
prompt: "Author the implementation plan and attach it on the metadata branch.")
8 changes: 4 additions & 4 deletions docs/comparison/ai-native-sdlc-playbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ fail-closed operations. In return docket has depth the playbook never mentions.

| Capability | Playbook | docket | Status |
|---|---|---|---|
| Plan committed before code | Plan-mode interview; `plan.md` committed. | `docket-plan-writer` authors via the `plan` role, commits on the feature branch with a trailer; the parent verifies from git facts; `change attach-plan` records it. | Both |
| Plan committed before code | Plan-mode interview; `plan.md` committed. | `docket-plan-writer` authors via the `plan` role and attaches it on the metadata branch through `change attach-plan`; the parent verifies from git facts. | Both |
| Human approves the plan | The engineer validates before code. | Deliberately absent; the human's checkpoint is the PR. | Playbook only (by design) |
| Refresh a stale change before planning | Not described. | The reconcile pass after claim, before the worktree: re-reads against related/archived changes, ADRs, and code; rewrites scope; `## Reconcile log`; kills obsolete, halts invalidated. | docket only |
| Institutional knowledge file | `CLAUDE.md`; mistake twice → into the file. | `AGENTS.md` is the promotion destination for learnings; criterion *will the agent know to search for this?*; human-gated. | Both |
Expand All @@ -82,7 +82,7 @@ fail-closed operations. In return docket has depth the playbook never mentions.
| Capability | Playbook | docket | Status |
|---|---|---|---|
| Agent verifies before human review | Tests, builds, screenshots; quantifiable targets. | The build gate runs `build.test_command` once after all tasks; unconfigured halts. | Both |
| Verification output as proof of done | Output pasted before "complete". | Build-evidence record (command, result, head SHA, time) minted from the run directory, written into the PR body, required by the reviewer, read by finalize. | Both |
| Verification output as proof of done | Output pasted before "complete". | Build-evidence record (command, result, head SHA, time) minted from the run directory, written into the change record's `## Build evidence` section, required by the reviewer, read by finalize. | Both |
| Suite outlives one foreground call | Not described. | `docket gate drive` slices; `gate_observation_budget` fails closed; forked children block. | docket only |
| Red suite repaired in-loop | Implied. | One synthetic integration-repair task, one tier above default. | Both |
| Block test edits during a fix | A hook forbids editing tests in fix tasks. | Prose contract only. | Playbook only |
Expand Down Expand Up @@ -131,8 +131,8 @@ fail-closed operations. In return docket has depth the playbook never mentions.
|---|---|---|
| 1 | `intent.md` | Change file on `docket`: frontmatter + Why / What changes / Out of scope / Open questions; board row. |
| 2 | `spec.md` | Spec file on `docket` with a backlink header; `spec:` and `## Artifacts` on the change; or `trivial: true`. |
| 3 | `plan.md` + the diff | `## Reconcile log` and `reconciled: true`; plan on the feature branch (frozen once merged); one verified commit per task. |
| 4 | PR with test results | Build-evidence record in the PR body; results file; review disposition table. |
| 3 | `plan.md` + the diff | `## Reconcile log` and `reconciled: true`; plan on the metadata branch (frozen once closed out); one verified commit per task. |
| 4 | PR with test results | Build-evidence record in the change record; results file; review disposition table in the PR body. |
| 5 | Merged PR / commit | Merge proven reachable; change archived as `archive/<date>-<id>-<slug>.md` with optional `## Closeout notes`; branch and worktree cleaned; board re-rendered. |
| 6 | Incident record → new `intent.md` | ADRs; learnings findings; discovered work in the run report → human-filed change. Nothing from production. |

Expand Down
14 changes: 7 additions & 7 deletions docs/concepts/build-tiers-and-gate.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ all the pieces are assembled — and leave proof that they did, so the next read
trusts a record rather than a claim.

Docket answers both halves with routing and a gate. The **plan** — the
task-by-task breakdown a build follows, written on the feature branch — is a
task-by-task breakdown a build follows, written on the metadata branch — is a
list of tasks, and each is routed to a **build tier**: one of four workers
(economy, standard, premium, max) chosen by risk. After
the last task lands, the **build gate** — the full test-suite run at the end of a
Expand Down Expand Up @@ -83,10 +83,10 @@ build that must be green before review — runs the whole suite once and records
build halts with the remedy `docket repository configure-tests` (add
`--command "<cmd>"` when discovery cannot find the suite).
- Build evidence is minted by `docket evidence record` from the passed run and
checked by `docket evidence verify`. It lives in the pull request body's
build-evidence block and is never committed, so the reviewer reads a durable
record of the gate run instead of trusting a worker's word that the suite
passed.
checked by `docket evidence verify`. The reviewer reads that record of the
gate run instead of trusting a worker's word that the suite passed, and when
the change is marked implemented the record lands in the change file's
`## Build evidence` section on the metadata branch, never in the code.

## The invariants

Expand All @@ -100,8 +100,8 @@ build that must be green before review — runs the whole suite once and records
only the tests a single task enumerated.
- The gate's suite command is read from configuration (`build.test_command`),
never from a second copy, so it tests the exact checkout under review.
- Build evidence is recorded in the pull request body before review begins, so
review rests on a recorded gate run rather than a claim.
- Build evidence is recorded before review begins, so review rests on a
recorded gate run rather than a claim.
- An empty test command never reads as a red suite: it halts with a remedy
instead of manufacturing a repair task.

Expand Down
24 changes: 12 additions & 12 deletions docs/concepts/finalize-sequencer.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ to it.
│ └─(red)─► integration repair: minimal fix, then retest
│ (at most finalize.repair_max_attempts)
▼
finalize publish: push the rebased head, update the PR's build evidence
finalize publish: push the rebased head, record its build evidence
│
▼
finalize merge: rebase, merge commit, or squash
Expand All @@ -63,8 +63,8 @@ to it.
test by combining two correct changes. A red suite here goes to a bounded
integration-repair step — a minimal fix, never a weakened test — and the suite
is re-run, at most `finalize.repair_max_attempts` times, before the sequence
continues. When the rebase was a no-op and the branch already carries green
build evidence for that exact head, produced by the same test command, the
continues. When the rebase was a no-op and the change record already carries
green build evidence for that exact head, produced by the same test command, the
suite is not run again.
- A repair that turns the suite green merges like any other green change; the
run report and the archived record's closeout notes name what broke and the
Expand All @@ -73,8 +73,9 @@ to it.
repair removes the approval and the merge waits for a fresh one.
- `finalize.gate: off` skips the rebase and the retest entirely; the remaining
steps still run in order.
- Publish pushes the rebased head and updates the build-evidence block in the
pull request body, so the evidence names the exact commit that will merge.
- Publish pushes the rebased head and records its build evidence in the change
record's `## Build evidence` section on the `docket` branch, so the evidence
names the exact commit that will merge. The pull request body is not touched.
- The merge is a policy gate, kept separate from the mechanical ones: whether a
human approval is required is configured ahead of time
(`finalize.require_pr_approval`), and the single-maintainer path is branch
Expand All @@ -83,19 +84,18 @@ to it.
squash.
- Closeout proves the merge landed, then marks the change `done` and archives it
on the `docket` branch (a stacked change merged into its parent is marked
`stacked-merged` instead), and retargets the backlinks in the change's spec, plan,
and results files to the archived record. It also repoints the backlink at the
top of the merged pull request's description to the archived record. A
`stacked-merged` instead), and in that same metadata commit retargets the
backlinks in the change's spec, plan, and results files to the archived record.
It also repoints the backlink at the top of the merged pull request's
description to the archived record, best-effort. A
description edit that fails leaves a `pr-backlink-pending` finding (the change
stays `done`), and `docket finalize cleanup` and the maintenance sweep retry it.
The full maintenance sweep (`--scope full`) also repoints, without a preview, any
merged pull request whose description backlink still names a change's old
`active/` path, however long ago that change was archived;
`docket repository repair --pr-backlinks` is the explicit way to preview and
repoint them all at once. Nothing is copied to the
integration branch. A backlink retarget that fails leaves a
`final-backlink-pending` finding (the change stays `done`), which
`docket finalize cleanup` repairs.
repoint them all at once. Nothing is pushed to the integration branch at
close-out: it receives only what a pull request merges.
- Cleanup removes the feature branch and its worktree, and is fail-closed: it
never leaves the repository half-destroyed, so an interrupted close-out is
recoverable rather than a worktree gone with its change not closed out.
Expand Down
4 changes: 3 additions & 1 deletion docs/concepts/reconcile.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ taken — and the first line of code.
and not just in the builder's head.
- The refreshed spec is read from the **metadata branch** — the `docket`
git branch where the backlog, specs, and decisions are stored, separate
from the code — during the build, never carried on the feature branch.
from the code — during the build. The feature branch carries only a copy
of it, its first commit, so the spec reaches the integration branch with
the pull request.

Reconcile is docket's one addition to the standard build chain that other
AI-native workflows do not describe. The
Expand Down
Loading
Loading