Install
$ agentstack add skill-jdpalumbo2-claude-skills-clodex-plan ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
clodex-plan — ground, decide, get an approved plan
Overview
This stage owes the run exactly four things, all of them facts in the run's event log:
- A plan file in the repo, at the profile's plans directory.
plan:recorded(orplan:amended) carrying that file's **version, path, and
sha256 hash**.
- Every plan-review finding disposed —
fixed,accepted,rejected, or
deferred-to-build.
verification:declaredfor each evidence class, thenplan:approved**bound
to the current plan hash**.
When those exist, the plan is approved and clodex-build can start.
Where this stage ends. You declare owned paths and done when per batch. clodex-build composes the full batch contract from them (forbidden paths, test expectations) and executes. You never write code, never open a batch, and never commit anything at all — clodex-ship commits run-owned paths.
You arrive here from clodex, which owns preflight, the profile, lane classification, the change boundary, and the run directory. If you were invoked without an absolute run directory, stop and invoke clodex — do not go looking for a run yourself.
0. Paths and commands
CLODEX_HOME="${CLODEX_HOME:-$HOME/.claude/skills/clodex}" # the router's dir, not this one
STATE="$CLODEX_HOME/state/clodex_state.py"
RUNNER="$CLODEX_HOME/runner/run-codex.sh"
RUN_DIR=""
SNAP="$(python3 "$STATE" rebuild "$RUN_DIR")"
REPO="$(printf '%s' "$SNAP" | python3 -c 'import json,sys;print(json.load(sys.stdin)["repo"])')"
PLAN="$(printf '%s' "$SNAP" | python3 -c 'import json,sys;print(json.load(sys.stdin)["plan"]["path"] or "")')"
cd "$REPO"
PROFILE="$REPO/.clodex/profile.json"
Shell variables do not survive between command invocations — re-establish this block at the top of every shell you run these procedures in. Everything below runs from $REPO.
$PLAN is empty until §6 records a plan; after that it is whatever the manifest says, never a path you remember. §8 hands it to the runner, so a shell that skipped this block passes --input '' and dies with usage error 64.
Engine verbs, payload on stdin:
python3 "$STATE" status "$RUN_DIR" # human summary
python3 "$STATE" rebuild "$RUN_DIR" # the manifest: full snapshot JSON
python3 "$STATE" append "$RUN_DIR" ` — this run is at stage ``, not plan."* The
router owns picking the right stage skill; do not pick one yourself.
**Resume map** — read the manifest (`python3 "$STATE" rebuild "$RUN_DIR"`) **and
the plan file it points at** in `plan.path`. Match the first row that is true:
| What you find | You are | Go to |
|---|---|---|
| `plan.hash` is `null` | nothing written yet | §2 |
| plan recorded, the plan file's `Direction gate:` line says `yes`, and `approvals` has no entry with `scope: "direction"` — **ever, revoked or not** | premise never approved | §7 |
| any `findings` entry with `disposition: "open"` | mid review loop | §9 (dispose what is open), then §8 for the next round |
| all findings disposed, and no un-revoked `approvals` entry with `scope: "plan"` on the current hash | ready to ask | §10 |
| an un-revoked `approvals` entry with `scope: "plan"` on the current hash | approved | §11 |
Row 2 asks whether a direction approval was **ever** granted, not whether one
stands. Every amendment revokes it, including one that only fixed a review
finding — so testing for a *standing* one would re-present the premise after
every revision. A revoked direction approval is re-granted inside the single
approval message (§7, §10), not at its own gate.
An approval whose `revoked` is non-null does not count anywhere else. An
amendment revoked it on purpose; the plan needs approving again.
---
## 2. Ground before you ask anything
Read the profile and the repo first. Every question you ask that a file already
answers costs the user a round trip and buys nothing.
```bash
python3 - "$PROFILE" ` | nothing extra |
| **yes** | a `## Direction` section: the **premise** (one paragraph: what this will be and why that is the right call), **comps** (2–3 references, or 2–3 named alternatives you rejected and why), and **acceptance criteria for taste** (what "good" means here, in checkable words) | run §7, the direction checkpoint |
---
## 5. Write the plan
**Every plan declares, without exception:** the brief verbatim · what in the repo
it is grounded in · its prior art — the existing mechanism here that solves an
isomorphic problem, and why it is or is not the shape used · its assumptions ·
its direction-gate answer · one *Done when* · what is in and out of scope · its
batches, each with owned paths and its own *Done when* · its evidence classes ·
its risks · its docs impact.
File: `/-.md`, slug kebab-cased from the brief. If
`plans_dir` already holds files, match their naming convention instead.
Every heading below is required. An empty section is an answer ("Out: nothing")
— a missing one is an unanswered question the reviewer will find.
```markdown
#
Run: · Plan version: · Repo:
## Brief
## Grounding
What in this repo this builds on: the files read, the existing pattern followed,
the architecture docs consulted. Name paths.
## Prior art
The existing mechanism in this repo that solves an isomorphic problem, cited by
path, and why it is or is not the shape used here. "None exists" is legal only
after naming where you looked. When the direction gate's tie-break (§4) answered
`no` because this follows an existing pattern, cite the same mechanism here.
## Assumptions
One line each, falsifiable, resolved by reading — not by asking.
## Direction gate
Direction gate: yes|no —
## Direction
Premise · Comps · Acceptance criteria for taste.
## Scope
Done when:
### In
### Out
Named things this deliberately does not do.
## Batches
| # | Owned paths | Done when |
|---|---|---|
| 1 | `src/thing/`, `docs/plans/` | |
Owned paths are the only paths that batch may touch. They must be disjoint
across batches. Include this plan file itself in a batch — otherwise ship, which
commits run-owned paths only, will leave it uncommitted.
Release-owned — no batch may own these:
- version source: ``
- changelog: ``
- tags: ``
Print the set resolved from the profile, the way `clodex-build` §2 derives it —
not the rule in the abstract. The changelog, the version source, and tags belong
to `clodex-ship`, which closes them from evidence inside the release
authorization; build categorically forbids them whatever the plan says, so a
batch that owns one is a plan defect that otherwise surfaces at the first line
of build — after every review round has passed it.
Docs impact: none |
Does this change alter behavior the profile's `docs.architecture` files
describe? `none` is an answer. Paths mean a batch listed above owns updating
them — name the batch. Architecture docs are read at plan time; without an
owner here, nothing ever maintains them.
Claims:
Collision-prone resources this plan takes: migration numbers, ports, workflow
ids, property names. Check each against the ledger (`clodex` §1 check 8)
before recording the plan — a resource already held stops the plan here, at
the cheapest possible moment. The ledger is orchestrator-owned; this plan
NAMES what it needs, it never writes the file.
## Evidence
| Class | What will prove it |
|---|---|
| tests | `` — covering |
| real-data | |
Classes come from: tests · real-data · live-check · visual. Any default class
this plan drops gets a line here saying why.
## Risks
What could go wrong, and what the plan does about it.
6. Record the plan
The plan hash is the sha256 of the plan file's bytes. Compute it after the file is final and before you append:
PLAN="/.md" # then keep it in $PLAN (§0)
python3 -c 'import hashlib,sys;print(hashlib.sha256(open(sys.argv[1],"rb").read()).hexdigest())' "$PLAN"
(shasum -a 256 "$PLAN" | awk '{print $1}' gives the same digest.)
First plan — write to $RUN_DIR/plan-recorded.json and append:
{"e": "plan:recorded", "version": 1,
"path": "/.md",
"hash": ""}
Every revision after that is plan:amended, never a second plan:recorded. A second plan:recorded with a different hash is refused: "a plan is already recorded; supersede it with plan:amended". Bump the version, carry a real new hash different from the one it supersedes, and declare what re-review it needs:
{"e": "plan:amended", "version": 2,
"path": "/.md",
"hash": "",
"note": "fixed r1-F001: batch 2 owned paths were missing the migration",
"required_review": ["plan-reviewer"]}
Material or immaterial — the test that fills required_review
An amendment is material when it touches any of: Brief · Scope (including the top-level Done when) · Batches (any owned path, any batch Done when) · Evidence · Direction. An amendment that changes none of those — wording, formatting, a clarification that adds no new claim — is immaterial. That is the whole test; there is no third category and no judgment beyond reading which sections the diff touched.
| | required_review | The review loop | Approval | |---|---|---|---| | material | ["plan-reviewer"] | re-opens — it needs a complete round against the new hash (§8) | approve again, on the new hash | | immaterial | [] | stays converged — nothing the last round examined changed | approve again, on the new hash |
Either way the hash moved, so the plan must be approved again. There is no amendment that costs nothing.
Do not invent values for required_review. It names Codex roles, and the vocabulary is fixed outside this skill: properties.role.enum in $CLODEX_HOME/runner/envelope.schema.json — plan-reviewer, implementer, code-reviewer, advisor. The same enum names a finding's source (§9), so the whole run uses one set of names. clodex-ship is blocked until every declared re-review exists against the current hash, so a ["plan-reviewer"] you never satisfy is a run that cannot ship.
An amendment revokes every approval bound to the superseded hash. Inside this stage, before approval, that revokes nothing — which is exactly why revising during the review loop is cheap and revising after approval is not.
The typed mandate — pre-granted gates for a delegated run
A lane run under an orchestrator's standing brief satisfies some gates on that brief's authority. Untyped, that authority lived in free text — and two lanes of the same weekend answered the same gate class differently: one satisfied plan approval on the brief, the other raised a blocking modal, same skill, same repo. Typed, it is one event, recorded immediately after plan:recorded when the brief (or the user, asked once) pre-grants gate classes:
{"e": "approval:granted", "scope": "mandate", "by": "user",
"plan_version": 1, "plan_hash": "",
"actions": [{"grants": "finding-disposition"},
{"grants": "plan-approval"},
{"grants": "direction-approval"}]}
actions[].grants draws on a vocabulary of exactly three: finding-disposition (accept or reject a finding, with grounds), plan-approval, and direction-approval. Verification-debt acceptance and release authorization cannot be granted — those gates open their modal in every run, mandate or not; they are the human-owned core the design reserves, and a mandate claiming them is ignored where those gates read it.
Consult it before every modal it could cover. A standing (un-revoked) mandate whose grants cover the gate: satisfy the gate on its authority, set by: "mandate" on the event so the manifest says which kind of run this was, and let the disposition note cite the mandate instead of quoting a user who was never asked — "under mandate (grants finding-disposition): ". No standing mandate, or a gate outside its grants → the modal opens as ever.
The mandate binds to the plan hash like every approval, so every amendment revokes it. Accepted v0.2 behavior, not an accident: re-grant it against the new hash on the authority that granted it first — one append, and the log shows the re-grant. A mandate you cannot honestly re-grant after an amendment is a mandate the amendment invalidated, which is the system working.
7. The direction checkpoint — only when the gate is yes
Present it after the plan is recorded (the approval must bind to a hash) and before the review loop (so a rejected premise does not burn review rounds).
One message: the premise, the comps, the acceptance criteria, and the explicit ask — approve this direction, or tell me what to change. Do not start the review loop until they answer. A standing mandate granting direction-approval (§6) answers this gate itself: present the same content as a record rather than a question, and append the direction approval with by: "mandate".
Approved → append:
{"e": "approval:granted", "scope": "direction", "by": "user",
"plan_version": 1, "plan_hash": ""}
Changed → revise the ## Direction section, amend (§6), re-present. The amendment revoked the old direction approval mechanically; the new one binds to the new hash.
Every later amendment revokes this approval too, including ones that only fixed a review finding. Run the checkpoint a second time only when the ## Direction section itself changed — that is the same materiality test as §6, narrowed to one section. For every other amendment, re-grant the approval on the final hash inside the single approval message (§10). Same gate, one message.
8. Codex plan review, to convergence
Plan review is default-on. It is not skipped because the plan looks simple, and it is not skipped because the ask was small.
One round = one runner invocation against the current plan file.
Write the prompt to a file (never a shell string):
$RUN_DIR/plan-review-r.prompt.md — `` is the round number.
Everything in angle brackets below is a placeholder to fill in, not literal text:
You are reviewing an implementation plan before any code is written. The repo
root is your working directory; read whatever you need.
Plan:
The ask it must satisfy, verbatim:
Round:
Check, in this order:
1. Does the plan satisfy the ask? Name anything asked for that no batch delivers.
2. Is it grounded in this repo? Open the files it names. Flag any assumption the
code contradicts, and any file it plans to edit that does not exist.
3. Interrogate `## Prior art`, with the repo open — not from the plan's prose.
Is the cited mechanism actually isomorphic to this problem? Is the stated
reason for using or diverging from its shape real? Search the repo for a
mechanism the author missed that solves an isomorphic problem — this
question has passed the most expensive defects when nobody owned it. Cite
repo paths for every claim, including "found nothing".
4. Are the batches' owned paths sufficient and disjoint? Flag work no batch
owns, any path two batches own, and any owned path that appears in the
release-owned set printed beside the Batches table (version source,
changelog files, tags) — build refuses those categorically, so a batch that
owns one is a plan defect now, not at the first line of build.
5. Is each "done when" checkable by someone who did not write the plan?
6. Does the declared evidence actually prove the change works? Flag a class that
cannot be produced in this repo, and any risk the evidence would not catch.
7. Does the change alter behavior that any of the profile's `docs.architecture`
files describe while the plan's `Docs impact:` line says `none`, or names
paths no batch owns updating?
8. What breaks in production that this plan does not consider?
Report findings only. Do not edit the plan and do not write code. Use
blocker/high/medium for anything that would produce wrong or unshippable work,
low/info for improvements. Retu
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [jdpalumbo2](https://github.com/jdpalumbo2)
- **Source:** [jdpalumbo2/claude-skills](https://github.com/jdpalumbo2/claude-skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.