Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions .codex/agents/code-reviewer.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ the other.
Use `Bug`, `Security`, `Performance`, or `Maintainability` for Standards
findings. Use `Spec` for a plan mismatch.

Verdicts. Select exactly one:
- `pass`: No `CRITICAL` or `HIGH` finding stands unfixed. Advisory `MEDIUM` and
`LOW` lines may ride along on a `pass`: the manager records them as follow-ups
and does not change reviewed bytes after the pass; they never trigger a
re-review.
- `fixes-required`: At least one evidenced `CRITICAL` or `HIGH` defect. The
manager fixes it and dispatches exactly one repair re-review.
- `blocked`: Required review input is unreadable or contradictory, so no safe
verdict can be reached.
A pass block carries only advisory MEDIUM and LOW lines, or none. A
fixes-required or blocked block has at least one finding line.

Remain read-only. Never apply a fix and never ask for approval to apply one.
Return one readable `Code-review:` markdown block to the manager. These inline
Standards buckets, severity caps, and Spec axis keep this wrapper complete when
Expand Down
16 changes: 8 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,20 @@ carries no hash, permit, run identity, lock, or bundle, and the `plan.mjs`
shipped inside the installed `plan-lifecycle` plugin is the only lifecycle tool.
An `export` writes the sha256 of the body it copied beside the copy so a stale
copy cannot revert the record; that digest detects staleness and authorizes
nothing. This lifecycle creates zero commits and never pushes. Commit when the
user asks, under `docks:commit-discipline`.
nothing. Routine plan issue publication and post-review landing through a
branch, commit, normal push, and closing pull request carry the settled mode's
authorization and need no repeated prompt. After the checks policy passes, the
manager asks immediately before merge. Without a fresh `Merge now` answer, it
leaves the pull request and issue open. `plan.mjs archive` verifies the merged
closing pull request after landing.

Every Steps row carries an `Effect` of exactly
`local|probe|production_access|publish|push|release|deploy`. A step whose
`Effect` is not `local` requires an in-session `ask` confirmation immediately
before it runs; when `ask` is unavailable the step is set `blocked` and the plan
reason becomes the first `## Open questions` line, `Blocked: <reason>`.
Persisted effects record intent only.

Work lands through a pull request whose body carries `Closes #<issue>` and whose
base is the repository default branch. `plan.mjs archive` is a verifier: it
requires completed closure, terminal steps, an exact `Code-review: pass` line,
and a merged closing pull request into that branch; it writes no status.
Persisted effects record intent only. Routine issue publication and landing
actions are outside the Steps table.

Render a plan body verbatim only when the user names that plan and asks to see it. After a write, report the one-line header strip and the changed lines only; a write never re-renders the body.

Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ directly. The docks pipelines route to these skills and stop, naming the missing
`plan-lifecycle` plugin, when they are unavailable.

The lifecycle runs six phases: decide, draft, research, one plan review,
implement, and one post-implementation code review. Plans use a markdown-only v2
record with `plan_contract: v2` frontmatter and eight sections. The lifecycle
creates zero automatic commits and never pushes.
implement, and one post-implementation code review. After review passes, it
commits and pushes the reviewed branch, opens the closing pull request, and
waits for repository CI. It then asks `Merge now` or
`Leave pull request open`. Without a fresh `Merge now` answer, it leaves the
pull request and issue open. After an approved merge, `plan.mjs archive`
verifies the merged closing pull request.

Every Steps row has `Effect` exactly
`local|probe|production_access|publish|push|release|deploy`. Each non-`local`
Expand Down
89 changes: 64 additions & 25 deletions docs/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ Legal step transitions are `planned → in-flight | done | blocked | skipped`, `
all Steps rows to be terminal (`done` or `skipped`), a line matching exactly
`Code-review: pass` in `## Review`, and an issue already closed as completed by
an eligible merged pull request. It writes no status. On success it removes any
stale phase label and prints `plan #<n> finished (closed by <url>)`.
stale phase label and prints `plan #<n> finished (closed by <url>)`. The pass
line may carry advisory `MEDIUM` and `LOW` finding lines beneath it; only an
unfixed `CRITICAL` or `HIGH` keeps a plan from archiving.

The verifier reads the issue's `closedByPullRequestsReferences` with
`excludeUserLinked: true`. It accepts only keyword-linked merged pull requests.
Expand Down Expand Up @@ -289,9 +291,17 @@ Code-review: pass|fixes-required|blocked
- HIGH · Security · plugins/x/y.mjs:41 — user input reaches a shell command unquoted — pass an argument array
```

A `pass` record has no finding lines. Every other verdict has at least one
finding line. A plan-review finding is exactly one of `goal_fit`, `research_gap`,
or `security_risk`; nothing else is a finding. A sufficient plan passes.
A code-review `pass` means no `CRITICAL` or `HIGH` finding stands unfixed; it
carries only advisory `MEDIUM` and `LOW` lines, or none. Record each advisory as
a follow-up and do not change reviewed bytes after a pass; an advisory never
triggers a re-review.
`fixes-required` names at least one evidenced `CRITICAL` or `HIGH` defect and
forces exactly one repair re-review;
if that re-review still returns `fixes-required`, the manager appends
`Code-review: blocked` and sets the plan `blocked`. A `blocked` verdict has at
least one finding line. A plan-review finding is exactly one of `goal_fit`,
`research_gap`, or `security_risk`; nothing else is a finding. A sufficient plan
passes.

## Phases

Expand All @@ -300,37 +310,66 @@ or `security_risk`; nothing else is a finding. A sufficient plan passes.
3. **Research.** Verify repository facts and external claims, record their sources, choose the durable fix, bind the exact files, complete Acceptance, pass `plan.mjs check`, and set the plan `planned`.
4. **Plan review.** Dispatch exactly one pre-implementation review. Append its verdict and findings. Fix reproduced findings before implementation. A user-only decision goes in `## Open questions`. A plan-only run stops at `planned` after this review.
5. **Implement.** Set the plan `ongoing`, move each step through its legal states, and record real Acceptance output in `## Verification Results` before the closing merge.
6. **Code review.** Review the declared change, fix every critical and high finding, and review again only after such a fix. Every step must be terminal and code review must pass before the closing merge; archive verifies those facts afterward.
6. **Code review.** Review the declared change, fix every critical and high finding, and run exactly one repair re-review after such a fix; if that re-review still returns fixes-required, append `Code-review: blocked` and set the plan `blocked`. Every step must be terminal and code review must pass before the closing merge; archive verifies those facts afterward.

Build the review diff from what actually changed: `git status --porcelain` names
the paths and the diff covers exactly those. Name every changed path that no
Steps `Files` cell mentions in the review request, so the reviewer judges
undeclared scope instead of the manager blocking on bookkeeping.
Build the review diff from the complete candidate pull request, not only the
dirty worktree. Resolve and fetch the repository default branch, then compute
`<merge-base>` with `git merge-base <default-remote-ref> HEAD`. Cover one net
tracked candidate with `git diff <merge-base> -- <changed paths>`. Add one
`git diff --no-index /dev/null <path>` hunk for each untracked path.
`git status --porcelain` still names dirty paths. Name every changed path that
no Steps `Files` cell mentions in the review request.

If a code-review round returns the same finding-id set as the previous round and
no file changed between the two rounds, stop, append `Code-review: blocked`
naming that set, and set the plan `blocked`.
After pull-request creation, record `headRefOid` and compare the changed paths
and hunks from `gh pr diff` with the reviewed net candidate. Any mismatch
invalidates the pass and blocks merge.

If that repair re-review again returns `fixes-required`, stop: append
`Code-review: blocked` naming the surviving findings, and set the plan
`blocked`.

A step whose `Effect` is not `local` requires an in-session `ask` confirmation
immediately before it runs; when `ask` is unavailable the step is set `blocked`
and `Blocked: <unconfirmed effect>` is recorded first in `## Open questions`.

This lifecycle creates zero commits and never pushes.
Routine plan issue publication is authorized by the settled mode and needs no
repeated repository picker.

## Landing

Work lands through a pull request whose body carries `Closes #<issue>` and whose base is the repository default branch, because GitHub interprets a closing keyword only in a pull request that targets the default branch. `plan.mjs archive` verifies that merged pull request rather than performing the merge.

Only the pull request that lands the completed work carries `Closes #<issue>`. A
partial pull request carries a plain `Refs #<issue>` instead, because GitHub
closes the issue as soon as the first pull request carrying a closing keyword
merges into the default branch.

Landing sits outside the six phases. This lifecycle creates zero commits and
never pushes, so the branch, the commits, the push, the pull request, and the
merge are the user's to run, on request, under `docks:commit-discipline`. No
Steps row exists for them, and `archive` reads the result rather than causing
it. A plan that never lands is retired, not archived.
Work lands through a pull request whose body carries `Closes #<issue>` and whose
base is the repository default branch.

After `Code-review: pass`, the manager runs landing without another prompt:
ensure a non-default branch, commit exactly the reviewed bytes under
`docks:commit-discipline`, push normally, and create or update one pull request
that carries `Closes #<issue>` and targets the repository default branch.

Never treat an empty first checks result as success. Retry
`gh pr checks --json name,bucket` at most 12 times with a 10-second delay until
checks appear. If required checks exist, run
`gh pr checks --watch --required`; if CI checks exist but none are required,
run `gh pr checks --watch` to wait for all reported CI. Any failed check blocks
merge. If no checks appear, continue only when repository inspection confirms
that no pull-request CI is configured; otherwise leave the pull request open
with a named no-checks blocker and do not show the merge prompt.

When the checks policy passes and GitHub reports the pull request mergeable,
ask immediately with exactly two options: `Merge now` or
`Leave pull request open`. Merge only on that fresh answer. If the user
declines, or `ask` is unavailable, leave the pull request and the issue open
and report the pull request URL. Never auto-merge, force-push, bypass branch
protection, or merge on a stale or assumed answer.

Immediately before merge, re-read `headRefOid` and `gh pr diff`. If the head SHA
or diff changed, block merge. Invoke `gh pr merge` with
`--match-head-commit <reviewed-head-sha>` and the repository's configured merge
strategy only after the fresh `Merge now` answer.

Only the pull request that lands the completed work carries `Closes #<issue>`.
A partial pull request carries plain `Refs #<issue>`. `archive` verifies the
merged result rather than causing it. A plan that never lands is retired, not
archived.

## Portability

Expand Down
11 changes: 7 additions & 4 deletions plugins/docks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,13 @@ Plus `write-skill`, `multi-tool-bridge`, and `zoom-out` under `productivity/`.

The plan lifecycle ships separately as the self-versioned `plan-lifecycle`
plugin in this same marketplace. It includes three skills, the shipped
`plan.mjs`, a markdown-only v2 plan contract, and the read-only `plan-reviewer`
and `code-reviewer` wrappers. Its six phases are decide, draft, research, one
plan review, implement, and code review, with zero automatic commits. Every
docks route into that lifecycle is fail-loud:
`plan.mjs`, a markdown-only v3 plan contract, and the read-only `plan-reviewer`
and `code-reviewer` wrappers. After review passes, the manager commits and
pushes the reviewed branch, opens the closing pull request, waits for repository
CI, and asks `Merge now` or `Leave pull request open`. Without a fresh
`Merge now` answer, it leaves the pull request and issue open. After an approved
merge, `plan.mjs archive` verifies the merged closing pull request. Every docks
route into that lifecycle is fail-loud:

Prerequisite: `plan-lifecycle` must be installed. If `plan-workspace` or `plan-manager` is unavailable, STOP, name the missing `plan-lifecycle` plugin, and do not create or mutate a plan.

Expand Down
4 changes: 2 additions & 2 deletions plugins/docks/skills/engineering/refactor/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ description: "Use when auditing a codebase for structural issues — dead code,
user-invocable: true
metadata:
pattern: pipeline
updated: "2026-08-20"
content_hash: "c496105fbaf3735e9dd2c189e5a011970ce02516c4cc10087a28739c123b85b9"
updated: "2026-08-21"
content_hash: "3c2e953bdcd16540ffb49f86bc4b157b3072e1a0793c755f5d4c9b1d20620f43"
---

# Refactor (cross-tool pipeline)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ A *documented* deviation is judged on merit, not reflex-blocked; an

| Verdict | When | Action |
|---|---|---|
| **APPROVE** | plan identity matches, criteria pass, scope is clean, and quality holds | Return the reviewed diff and executor result to main-context `plan-manager`. It applies the reviewed diff, reruns verification, records `## Verification Results`, dispatches the single post-implementation code review, and archives with `plan.mjs archive <issue>` once that review returns `Code-review: pass`. |
| **APPROVE** | plan identity matches, criteria pass, scope is clean, and quality holds | Return the reviewed diff and executor result to main-context `plan-manager`. It applies the reviewed diff, reruns verification, records `## Verification Results`, dispatches the single post-implementation code review, and follows the manager's full Landing flow. It archives only after an approved merge lands the closing pull request. |
| **REVISE** | fixable gaps | Send the same executor specific, actionable feedback. Allow at most two executor revision rounds, then return a failure result to `plan-manager`. |
| **BLOCK** | STOP hit, scope violated unrecoverably, or revisions exhausted | Return the evidence to `plan-manager`; it sets the plan `blocked` with a reason and does not re-run the plan review. |

Expand All @@ -100,8 +100,8 @@ approved diff to the main working tree.

- The executor never writes lifecycle state, `## Review`, or
`## Verification Results`; main-context `plan-manager` owns them.
- The executor creates no commit. This lifecycle creates zero commits and never
pushes, merges, or applies directly to the main working tree. Its only handoff
is the reviewed diff and result.
- The executor creates no commit, pushes nothing, and never merges or applies
directly to the main working tree. Its only handoff is the reviewed diff and
result; main-context `plan-manager` owns landing.
- Off Claude, or when worktree isolation is unavailable, this mode is skipped;
`plan-manager` runs Phases 7–8 in context.
13 changes: 9 additions & 4 deletions plugins/plan-lifecycle/agents/code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ buckets or the Spec axis defined below.
8. Re-read every locator and verify that the proposed fix resolves the defect
without violating another plan step or invariant.
9. Select one verdict:
- `pass`: Neither axis has a finding.
- `fixes-required`: At least one evidenced defect can be fixed by the manager.
- `pass`: No `CRITICAL` or `HIGH` finding stands unfixed. Advisory `MEDIUM`
and `LOW` lines may ride along on a `pass`: the manager records them as
follow-ups and does not change reviewed bytes after the pass; they never
trigger a re-review.
- `fixes-required`: At least one evidenced `CRITICAL` or `HIGH` defect. The
manager fixes it and dispatches exactly one repair re-review.
- `blocked`: Required review input is unreadable or contradictory, so no safe
verdict can be reached.
10. Order findings `CRITICAL`, `HIGH`, `MEDIUM`, then `LOW`. Return once.
Expand All @@ -101,8 +105,9 @@ Each finding uses one line:
SEVERITY · CATEGORY · file:line — defect — fix
```

Use only `pass`, `fixes-required`, or `blocked`. A `pass` verdict has no finding
lines. A non-passing verdict has at least one finding line. Use `Bug`,
Use only `pass`, `fixes-required`, or `blocked`. A `pass` verdict carries only
advisory `MEDIUM` and `LOW` lines, or none. A `fixes-required` or `blocked`
verdict has at least one finding line. Use `Bug`,
`Security`, `Performance`, or `Maintainability` for Standards findings. Use
`Spec` for a plan mismatch. Keep both analysis axes distinct even though the
single review record orders all findings by severity.
Expand Down
11 changes: 6 additions & 5 deletions plugins/plan-lifecycle/skills/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ The synchronized surface is the v3 first-line marker, no-frontmatter rule,
eight sections, both table headers, four open-work phases (`drafting`, `planned`,
`ongoing`, `blocked`), the GitHub `state` + `stateReason` derivation truth table,
the three plan-review kinds (`goal_fit`, `research_gap`, `security_risk`), the
two review-record shapes, the zero-commit rule, lifecycle-tool ownership, issue
write preconditions, archive-as-verifier landing proof, and marker-only
classification: any body without the exact v3 opening is unreadable and no
parser is attempted. Legacy workspace migration leaves old files unopened and
creates fresh records only for user-restated goals.
two review-record shapes, default issue and pull-request publication, explicit
merge confirmation, lifecycle-tool ownership, issue write preconditions,
archive-as-verifier landing proof, and marker-only classification: any body
without the exact v3 opening is unreadable and no parser is attempted. Legacy
workspace migration leaves old files unopened and creates fresh records only
for user-restated goals.

When any part changes, synchronize the three skills,
`plan-manager/references/plan-contract.md`,
Expand Down
Loading