Internal: which agent runs each executor and how it is dispatched; read before dispatching a dev-pipeline agent.
Resources
1Install
npx skillscat add idontlikedrinkpivo/web-dev-pipeline-codex-plugin/executor-catalog Install via the SkillsCat registry.
Codex runtime. Before using this skill, read
../executor-catalog/references/codex-runtime.md. It defines tool mappings, named-agent dispatch and stage-chat orchestration; use it for inherited Claude Code terms below.
Executor Catalog
Plans name executors. This file says who each executor is and when
it runs: its tier, its branch, and the skill that dispatches it. How it
runs lives in one agent file per row, _agents/<name>.md in this skills
folder: the model, the effort, the tools, and a short system prompt. The
agent's name is the row's Name. A model rename, a price change, or an effort
change edits one agent file and nothing else; no plan is rewritten, no skill
hardcodes a model.
This file is what a stage needs at dispatch time. Why each row has its model
and effort: references/model-economics.md. How to add, retire, or re-point a
row: references/maintaining.md. Neither is needed to dispatch.
A name belongs to its branch (the table's Branch column): a name borrowed
from another branch because its tier looks right is a failed dispatch — it runs
the right model on the wrong packet.
Names: skills carry the plugin prefix, agents do not
Everything in this set ships as the dev-pipeline plugin. In the text of
any skill, a short name — work, plan, screen-spec, impl-ui — means
the one from this plugin. Whenever a skill is invoked, use its full name, dev-pipeline:work
(typed $dev-pipeline:work). An agent is dispatched by its plain name, impl-ui:
Codex custom agents carry no plugin prefix. A short name in prose is for
reading; a full name in a call is for routing, so a same-named skill or
agent from elsewhere never runs instead (Dispatch contract → subagent_type).
The catalog
Every row names its dispatcher; a row nobody dispatches is deleted. Every Name
is also an agent, dispatched as subagent_type: "<name>"; its file, not this
table, holds the model and effort.
| Tier | Branch | Name | Dispatched by | Runs |
|---|---|---|---|---|
| 0 | code | mechanical-worker |
work (unit or nested) |
renames, moves, config values, regeneration, applying a settled shape to N sites; also the fix-it hand for a mechanical review finding |
| Low | code | impl-lite |
work |
transcribing a fully specified artifact into working code against an existing local pattern — including README / changelog / doc-comment units |
| Mid | code | impl-medium |
work |
closing the local decisions a Mid unit leaves open, then proving them |
| High | code | impl-hard |
work |
designing the missing part inside given boundaries: auth, money, transaction and idempotency shape, cross-cutting contracts |
| Escalation | code | impl-critical |
work (escalation only) |
the tier above High, for a unit that came back BLOCKED or HARDER_THAN_EXPECTED; it repeats while each round makes progress (pipeline → references/convergence.md). Same model as impl-hard: a new dispatch with the previous report, not a stronger model. Not a retry of impl-ui |
| UI | code | impl-ui |
work |
frontend that implements a screen spec citing a Figma nodeId: the screen and its states, or a component whose shape comes from that frame; or the theme unit that carries the 🎨 Tokens variables into the theme file after a ui-design restyle. Any grade. A retry stays on this row. UI units never run in parallel (work). Not a Figma drawing (figma-sonnet, figma-opus) |
| Mid | review | review-medium |
code-review-unit |
a Mid unit's diff against its unit spec; also the batched pass over accumulated Low units |
| High | review | review-hard |
code-review-unit |
adversarial review of a High unit — deliberately not the implementer's alias |
| Run | review | review-full-plan |
code-review-full |
once per run: cross-unit drift, aggregate invariant/AC coverage, критерии готовности, over the whole branch diff |
| Handover | docs | handover-checker |
a nested session of pipeline, at its stage's close or hand-over |
the stage's conversation (a digest) against the files it wrote: each decision the user settled in the chat that no file holds, quoted. Read-only, one dispatch per close (pipeline → references/handover-check.md) |
| Feedback | plugin | session-reviewer |
reflect |
at the iteration's close: one dispatch per session digest, finding where the plugin itself worked badly, with the user's quotes. Read-only |
| Audit | security | security-auditor |
security-audit |
once per iteration, over the whole application: one dispatch per area tracing each operation from route to data, one for the application-wide settings and the scanner findings, one MODE verify that tries to disprove the P0/P1. Read-only |
| Audit | code | code-auditor |
upgrade-code |
on request, over an existing project: one dispatch per module and one for the design documents, judging technical decisions against the plugin's design and stack rules — every deviation with file:line, the rule, how it should be and what fixing it touches. Read-only |
| Mid | plan-review | plan-review-medium |
plan-review |
the structural half of a plan review: dependency graph, parallel safety, files completeness, citation integrity, coverage ledger, executor validity, existing work, service version, plan hygiene |
| High | plan-review | plan-review-hard |
plan-review |
the judgment half: whether a unit can land green alone, whether its grade survives the cascade, whether a scenario is writable before the code |
| Low | docs-review | doc-review-low |
doc-review |
coherence and feasibility: the document agrees with itself. Always on |
| Mid | docs-review | doc-review-medium |
doc-review |
design language and scope, when those signals are present — not whether the premise is right |
| High | docs-review | doc-review-hard |
doc-review |
premise, security decisions, or falsifying the document |
| Set | docs-review | docs-consistency-checker |
docs-consistency |
the finished document set read together: traceability both ways and one meaning per name, field, enum, number, status, error, and role. Read-only, one dispatch per check |
| Write | requirements | srs-author |
srs-writer; grill-me called directly on an SRS (MODE grill-reversal, at the close); the session for a decision changed after the SRS was finished (pipeline → references/decision-changes.md) |
settles the SRS, including a grill-reversal pass. No grade cascade. The session asks and grills. Prints the file itself (Nesting → doc-typist) |
| Low | design | design-lite |
clean-architecture-design (every mode: foundation, domain model, scenarios of an area), db-schema-design, openapi-spec-generator |
judgment for a bounded one-table / few-operation / plain-CRUD document. Prints it itself |
| Mid | design | design-medium |
same three | close local design decisions for a Modest / one-slice document. doc-typist prints it |
| High | design | design-hard |
same three | Full-trigger, security-heavy, or cross-section design judgment. doc-typist prints it |
| Low | plan-writer | plan-lite |
plan |
slice a fully bounded increment along seams the design already drew. Prints the plan itself |
| Mid | plan-writer | plan-medium |
plan |
close the remaining slice and grade decisions. doc-typist prints the plan |
| High | plan-writer | plan-hard |
plan |
Full-trigger, security, or cross-section slicing. doc-typist prints the plan |
| docs | doc-typist |
nested by design-medium, design-hard, plan-medium, plan-hard; dispatched by the session for a changed decision, a print defect or a check's lines, and by grill-me called directly on another contract document or a plan (Nesting) |
prints a document those rows already settled, including sibling D2 and open-questions.md rows the settlement named, or edits a finished document for a decision the user changed or a print defect the session spelled out (MODE revise). No new decision |
|
| Read-only | any | code-explorer |
plan (inventory of the code an increment or a brownfield plan reaches), grill-me (facts), brainstorm (scout and claim verifier) |
locating patterns, files, and call sites in a repo whose code is the design; never edits |
| Edit | figma | figma-sonnet |
ui-design |
elements added or changed on frames that already exist, or those frames restyled to a chosen visual direction. Not a new screen and not a redesign |
| Build | figma | figma-opus |
ui-design |
frames from an empty file, a new screen, or a redesign of an existing screen, from the SRS; the style tiles of a visual direction |
| Write | screen | screen-writer |
screen-spec; the session for a changed element, text or state of a finished screen (pipeline → references/decision-changes.md) |
one front-end spec per screen from the frames and the OpenAPI contract; writes the file itself; decides no behaviour the frames did not |
| Write | ui-test | ui-test-writer |
ui-test-cases (mode write); docs-consistency and screen-spec (MODE increment, cases whose trace broke); the session for a changed expected result (pipeline → references/decision-changes.md) |
user test cases from SRS acceptance criteria and screen specs; decides no behaviour |
| Run | ui-test | ui-test-runner |
ui-test-cases (mode run) |
Playwright tests from the cases, run against the app started locally, screens compared with frames; never edits app code |
plan writes only names from references/assignable-implementers.md;plan-review checks that list, not this table.
Dispatch contract
Every skill in a Dispatched by cell calls its row with Claude Code's Agent
tool like this. Consumers point here instead of restating it.
- The row picks itself. The grade, the cascade, or the routing table below
names the row; dispatch it. Do not ask the user which row or model to use.
Instead, the stage's closing report names every row it dispatched, with the
grade when a cascade picked it (Mid · plan-medium), so the user sees who
did the work. subagent_typeis<Name>, and the call passes nomodel. Under Codex an agent has no plugin
prefix:<Name>is thenamein its~/.codex/agents/<Name>.toml. The role file pins model and effort; omit overrides to preserve its contract.
Nevergeneral-purpose,Explore, or another built-in agent: those carry
none of the row's model, effort, tools, or prompt.- Before every
Agentcall, show the resolved row in this turn — one line
the user reads, in the user's language around the untranslated names
(pipeline→ Names): «ЗапускаюName | subagent_type», prefixed with the
grade when a cascade picked the row (Mid | design-medium | design-medium). It is not a working note: the user sees who
does the work, and writing it makes you check the row before the call. You
may append the model and effort read from the agent file (· opus · high);
copy them from the file, never from memory. - A model the user names. Custom agent files pin model and effort and take
precedence. Do not claim an override changes a pinned role. Explain when a
requested Claude model is unavailable under Codex; never pass Claude model
aliases as Codex model names. Modify a role configuration only when requested. - A rejected
subagent_type: retry once with the bare name. If both are
rejected, the agent is not installed.
Stop and tell the user to install or update thedev-pipelineplugin
and restart the session. Notinstall.shon top of an installed plugin:
it installs every skill a second time. Do not fall back togeneral-purposewith a hand-typed model, and do not do the row's work on
the session model. - Paths, not pasted documents. A packet names what the agent reads from
disk — the documents, their parts, the plugin's own files — by path, and
pastes only what is on no disk: the user's answers and the decisions of
this session, and the session's own short derivations (a ledger, a list
of findings, the few rows one unit cites). A secret's value is never in a
packet — its variable name is (pipeline→ Secrets). A pasted document is paid on
every dispatch, and a long one arrives cut. A split document is named by all its parts: the SRS issrs.mdand everyareas/*.md, the APIopenapi.yamland every file
underpaths/andcomponents/, the schemaschema.mdandmigrations/. - Short reports. An agent's last message — its report — comes back into
the dispatching session and stays there, paid on every later call. It is
about 2,000 characters: the packet's fields, one line each where they
allow; what is long (lists, evidence, reasoning, a file-by-file account)
goes to a details file under$(git rev-parse --path-format=absolute --git-common-dir)/pipeline-work/
whose path the report gives. What needs the session's decision is never
only in that file (pipeline→references/context.md). SKILLS ROOTis absolute. The agent works in the project; the plugin
sits elsewhere (its cache). Every packet that names a plugin file carriesSKILLS ROOT: the absolute folder that holds this plugin's skills — the
parent of the dispatching skill's base directory, theBase directory for this skillline printed when the stage loaded.SKILLand every<skill>/references/…path in a packet or in a skill the agent reads
resolve under it; a repo-relative path to a plugin file is not found.- Parallel dispatches (a
workwave) each passisolation: "worktree"so
workers never share a working directory. Before integrating (workStep
5.1), merge or cherry-pick each worker's worktree branch into the main tree;
if that is not possible, run the wave serially.
Mid | impl-medium | impl-medium
Agent(subagent_type: "impl-medium", prompt: <worker packet for U4>)Wrong: Agent(subagent_type: "general-purpose", model: "sonnet") — the row's
effort, tools, and prompt are gone and the model was typed from memory. Also
wrong: Agent(subagent_type: "impl-medium", model: "sonnet") when the user
named no model — the role file sets the model.
Slug hygiene. A model alias is written in exactly one place: the model:
line of the row's agent file. No plan, packet, skill, or dispatch line carries
one — a model in a plan is a plan-review finding. If the harness rejects the
alias in an agent file, that is a stop: do not edit the file to a
neighbour, do not pass a different model on the call, and do not fall back
to the session model or general-purpose. Report the file, the rejected
alias, and the tier, and let the user re-point that file.
Scope. This catalog routes pipeline dispatch only. Work outside the
dispatching skills — a question, a debugging detour — runs on the session
model, unrouted: grading is a planning-time decision recorded in a plan or a
design grade. A change to the product's code the user asks for in chat
between runs is not such work: it goes through work → A change asked in
chat outside a run (an executor, a review, the affected tests), never
straight from the session into a commit. Ad-hoc work heavy enough to want
routing is heavy enough to be a plan.
Nesting
A dispatched row may hand work to one nested target; nested targets dispatch
nothing further (session → row → nested target). A nested call follows the
Dispatch contract like any other, with no model.
mechanical-worker— a code unit's implementer may hand out the typing
named in the plan'sЧто делает вложенныйand keep the decision.planmay name only
this nested target. It pays off when the mechanical part is settled and
repetitive; two files is not worth the dispatch.doc-typist— the writers on Opus (design-medium,design-hard,plan-medium,plan-hard) hand the printing here after the document's
decisions are settled: a long document's output tokens are the expensive
part, and the typist prints them on Sonnet. Packet:references/doc-typist-prompt.md. The writers already on Sonnet —srs-author,design-lite,plan-lite— print the document
themselves, by that packet's RULES, and reportDELEGATED none: the
same model printing gains nothing, and a nest cost a fresh agent's start
(~64,000 tokens) and two minutes a document (live run 2026-10-31). The
session does not ask about it, and a plan file never names it. Direct
dispatches, allMODE revisewith oneSETTLEMENTline per change:- a decision changed after its document was finished — the user already
settled it (pipeline→references/decision-changes.md); the
reversals of agrill-mecalled directly on a contract document or a
plan are such decisions, sent once at the grill's close
(grill-me→ When the user invoked this directly); - a print defect the session found when it inspected a printed document
and can state as a finished line: a columnnote:with its text from
the SRS, aredocly linterror with its fix at the JSON pointer, a
missing diagram embed. Sending such a defect back to the writer pays an
Opus round for typing. A defect whose fix needs a decision — a missing
response, a table, a rule — goes back to the writer; - a check's lines —
doc_check.py,redocly lint,table_docs.py --check,check_spec.py— three or more in a document's body, each
sent as oneSETTLEMENTline with the check's text and the fix it
names; the session reruns the check on the report. One or two lines the
session fixes itself (a dispatch costs more than two Edits), and so it
does lines in what it wrote itself — the stamp'sversion,updated,
journal rows and pins. A line whose fix needs a decision is the
writer's, as above.
- a decision changed after its document was finished — the user already
| Rule | Why |
|---|---|
| Only those two are nested targets, and the typist only under a writer on Opus | anything else has judgment that does not delegate cleanly |
| Nesting never raises capability | a harder document gets a higher writer, not a smarter typist; a harder unit gets a higher Исполнитель |
| The parent owns the output | it reads the file and may re-dispatch the typist once. It does not type the correction |
| The parent does not paste the finished document | that spends the output tokens the nest exists to save. The prompt carries a settlement — one line per decision — plus paths to read |
| Deciding what a test asserts never nests | mechanical-worker may only replicate an assertion the implementer already wrote across N settled cases |
A two-phase unit is one executor, twice. Both phases of a work two-phase
dispatch go to the unit's named implementer and count as one round of that
unit (work/references/two-phase-dispatch.md); how many rounds a unit gets
is pipeline → references/convergence.md, nowhere else.
Escalation
A question is not a failure. A writer row — srs-author, a design-*
or plan-* row, screen-writer, ui-test-writer — that returns BLOCKED
with a question only the user can answer (an engine, a status the SRS left
open, a classification) is not escalated: a higher tier would answer it by
guessing, and the user would never see it. Ask it in the chat, one question
per message (pipeline/references/question-format.md), add the answer to
the packet's answers slot, and dispatch the same row again. Only aBLOCKED without such a question, or HARDER_THAN_EXPECTED, moves up a
tier.
A unit returning BLOCKED or HARDER_THAN_EXPECTED moves up one tier per
failure: grade 0 → Low → Mid → High → impl-critical.
- Re-dispatch carries the previous attempt's report — what was tried, what
failed, what it observed. A blind retry buys nothing. - At
impl-criticalthe unit repeats, with every previous report, while
each round makes progress; when progress stops it is a stop — the
unit is under-specified or the design is wrong, and both belong to the
user (pipeline→references/convergence.md). impl-criticalis terminal. On the code branch the higher tier stays on the
same alias (its agent file may raise the effort); the retry's value is the
previous report in a fresh dispatch. The one change of alias is grade 0 →
Low:mechanical-workerandimpl-literun on different models, each
named in its agent file.impl-uiis not on that ladder: a difficulty return re-dispatchesimpl-ui
with the report, round after round while it makes progress (pipeline→references/convergence.md).- At
impl-critical, when the premise check finds the unit's approach
itself false, the next round dispatches twoimpl-criticalwith two named
approaches from one base commit; the tests pick the winner
(work/references/two-approaches.md). - Where an escalation is recorded:
workStep 6. If the same kind of unit
escalates repeatedly across runs, fix the cascade inplan/references/complexity.md, not the individual grades.
Routing
Each dispatching skill owns what its executor does; these tables own only
who runs it. Do not do a row's work on the session model to "save a
dispatch", and do not replace a failed dispatch with the session.
Review routing
| Unit grade | Review (code-review-unit) |
|---|---|
| 0 | none — the orchestrator's diff inspection is the review |
| Low | none per unit; one review-medium pass over the batch |
| Mid | review-medium on the unit diff |
| High | review-hard on the unit diff, plus a second risk pass |
an impl-ui unit, any grade |
its own pass — review-medium at 0, Low and Mid, review-hard (and the risk pass) at High; never a batch and never none (code-review-unit → Step 3. Dispatch by grade) |
The whole-run review is one review-full-plan pass over the whole diff per
run (code-review-full), never doubled and never re-dispatched with amodel. Its re-reviews read only the fix commits and repeat while each
round makes progress (pipeline → references/convergence.md); a second
pass over the whole diff is not done.
Plan-review routing
| Half | Executor | Lenses |
|---|---|---|
| Structural | plan-review-medium |
dependency graph, parallel safety, files completeness, citation integrity, coverage ledger, executor validity, existing work, service version, plan hygiene |
| Judgment | plan-review-hard |
commit atomicity, grade calibration, test-first writability |
Never point the judgment half at plan-review-medium: arguing with a grade is
the same work that produced it.
Document-review routing
| Persona | Executor |
|---|---|
coherence-reviewer, feasibility-reviewer |
doc-review-low |
design-lens-reviewer, scope-guardian-reviewer |
doc-review-medium |
product-lens-reviewer, security-lens-reviewer, adversarial-document-reviewer |
doc-review-hard |
doc-review decides which personas fire. Do not point a hard persona at a
lower row to save a dispatch.
The whole-set check is not a persona: docs-consistency dispatchesdocs-consistency-checker once, and never a doc-review-* row in its
place.
SRS-writer routing
Every SRS goes to srs-author; no grade. Grill reversals are a second
dispatch of the same row, which edits the file itself: one
dispatch at the grill's close carrying the whole ledger — every reversal inREVERSALS, every deferred question in DEFERRED — never one per round.
Packet: references/srs-writer-prompt.md.
Design-writer routing
Grade (references/design-complexity.md) |
Executor |
|---|---|
| Low | design-lite |
| Mid | design-medium |
| High | design-hard |
The writer settles the document and its D2 files and prints them by the
packet's PRINT: Mid and High nest doc-typist, Low prints itself
(Nesting). Packet: references/design-writer-prompt.md.
Plan-writer routing
Grade (references/plan-complexity.md, not the unit cascade) |
Executor |
|---|---|
| Low | plan-lite |
| Mid | plan-medium |
| High | plan-hard |
The writer settles the units and prints the file by the packet's PRINT:
Mid and High nest doc-typist, Low prints itself (Nesting). Packet:references/plan-writer-prompt.md.
A revise after plan-review is graded separately, by its blocking
findings, not by the plan: references/plan-complexity.md → Grading a
revise. A plan graded High whose review asks only for spelled-out text
fixes is revised by plan-lite.
Figma routing
Situation (ui-design decides) |
Executor |
|---|---|
| Empty file, a new screen, a redesign, or the whole interface redrawn on a new page | figma-opus |
Style tiles for choosing the visual direction (MODE direction) |
figma-opus |
| Elements only, on frames that already exist | figma-sonnet |
The existing frames take a chosen visual direction; structure, texts and ids stay (MODE restyle) |
figma-sonnet |
Renaming a designer's layers by action and adding annotation frames (MODE rename, nothing visible changes) |
figma-sonnet |
Packet: references/figma-packet.md.
Screen-spec routing
Every screen spec goes to screen-writer; no grade. Packet:screen-spec/references/writer-prompt.md.
References
references/assignable-implementers.md— the only namesplanmay write.references/worker-prompt.md— the packet a code executor receives and the
report it returns (used bywork).references/design-complexity.md,references/plan-complexity.md— the
cascades that grade a design document and a plan.references/srs-writer-prompt.md,references/design-writer-prompt.md,references/plan-writer-prompt.md,references/doc-typist-prompt.md,references/figma-packet.md— the writer and Figma packets.security-audit/references/auditor-prompt.md— thesecurity-auditor
packet;upgrade-code/references/auditor-prompt.md— thecode-auditor
packet.references/model-economics.md— why each row has its model and effort, and
what was measured. Read before re-pointing a tier.references/maintaining.md— adding, retiring, or re-pointing a row._agents/<name>.md— one agent per row: model, effort, tools, short prompt._agents/README.md,install.sh,.claude-plugin/plugin.json— the two
ways to install them.doc-review(skill) — the personas and their packets.