Two local Codex skills for running a strict two-model workflow in the same repository:
workspace-pm-reviewerworkspace-worker
This setup is for shared-workspace collaboration where one model owns decomposition, constraints, and acceptance, while another model owns bounded execution.
Here, a task means a bounded work item, not only a product feature. A task may be a feature, bugfix, refactor, chore, docs, or review-followup.
It is intentionally not fully automatic.
The design goal is simple:
- keep scope small
- keep ownership clear
- make fake completion hard
- keep the human in the loop only at decision points
workspace-pm-reviewer
- reads the user goal
- writes task packets
- updates the progress view
- defines
write_set, constraints, and acceptance - reviews worker output
- decides
accepted,rework,blocked, orcancelled
workspace-worker
- reads the task packet
- edits only the assigned files
- verifies the result
- writes a worker report
- does not maintain progress
- blocks instead of guessing
user
- opens two clients if needed
- chooses when a task is ready to send to the worker
- asks the PM skill for review
- resolves disputes, priority changes, and unclear product decisions
flowchart TD
A["User defines goal"] --> B["PM skill writes or updates a work item packet"]
B --> C["PM updates progress.md"]
C --> D["Worker skill executes inside write_set"]
D --> E["Worker writes report with evidence"]
E --> F["User asks PM skill to review"]
F --> G["PM updates progress.md for review"]
G --> H{"Review outcome"}
H -->|accepted| I["PM writes acceptance note and marks done"]
H -->|rework same scope| J["PM records rework and bumps packet revision"]
H -->|new scope or new risk| K["PM creates follow-up item"]
H -->|blocked| L["PM marks blocked"]
J --> D
K --> D
L --> B
The human is not a message relay.
The human only needs to intervene at these points:
- when a new task should be created
- when priorities change
- when the worker says
blocked - when the PM says
rework - when product intent is unclear and cannot be inferred from the repo
If nothing above happens, the worker should just read the repo work-item files and execute.
Recommended control surface inside the target project:
docs/execution/
progress.md
tasks/
reports/
acceptance/
Ownership:
- PM writes
progress.md - PM writes
tasks/ - Worker writes
reports/ - PM writes
acceptance/
Product files are assigned per task via write_set.
progress.md is the single human-readable progress view.
These skills are plain folders. Install them by copying or symlinking them into your Codex skills directory.
Typical local install:
mkdir -p ~/.codex/skills
ln -s "$(pwd)/workspace-pm-reviewer" ~/.codex/skills/workspace-pm-reviewer
ln -s "$(pwd)/workspace-worker" ~/.codex/skills/workspace-workerIf you prefer copying:
mkdir -p ~/.codex/skills
cp -R ./workspace-pm-reviewer ~/.codex/skills/
cp -R ./workspace-worker ~/.codex/skills/Then start a new Codex session or reopen the client so the skills can be discovered again.
If the second model can read local files and follow repository instructions, you can skip manual install steps and tell it to install the skill for itself.
Example:
Read the current repository README and install the workspace-worker skill for your own client. Then open the target repository, read the current work item packet under docs/execution/tasks/, and operate only inside the declared write_set.
This works well when you use one client as PM and another client as worker.
Keep the boundary hard:
- the PM-side client should load
workspace-pm-reviewer - the worker-side client should load
workspace-worker - do not let the worker improvise its own task definition just because it installed the skill successfully
Automatic skill matching may happen, but it is not part of the protocol.
For these two role skills, the protocol assumes explicit role injection by a human. Do not rely on automatic matching for correctness.
Explicit injection is required when:
- a new client session starts
- work is handed from PM to worker
- work is handed from worker back to PM for review
- the active role changes
- the task is important enough that role drift would be costly
Explicit injection is not optional protocol sugar. It is the small human control layer that keeps the system simple without building a heavier control plane.
At handoff time, a human should explicitly inject the intended role. That can be as simple as opening the correct client, asking it to read the corresponding SKILL.md, and restating the role in one sentence.
Example PM-side injection:
Read workspace-pm-reviewer/SKILL.md in this repository. Act only as the PM and reviewer. Do not become the main implementation worker.
Example worker-side injection:
Read workspace-worker/SKILL.md in this repository. Act only as the execution worker for the current task packet. Stay inside write_set and report with evidence.
This extra human step is intentional. It reduces accidental role drift and does not require adding more workflow machinery.
Use two clients:
- client A runs
workspace-pm-reviewer - client B runs
workspace-worker
The PM client creates or updates work item packets.
The worker client reads them from the repository and writes reports back into the repository.
The PM client alone maintains progress.md.
This avoids chat-based message relaying and keeps the collaboration state on disk.
transport/
README.md
USER_MANUAL.md
LICENSE
workspace-pm-reviewer/
SKILL.md
references/
workspace-worker/
SKILL.md
references/
- Install both skills.
- In the target repository, create
docs/execution/. - Ask the PM skill to write a work item packet.
- Switch to the worker client and ask it to execute strictly from that packet.
- When the worker reports completion, switch back and ask the PM skill to review.
For the detailed workflow, see USER_MANUAL.md.