---
name: pmos-router
description: Not sure which lane or flow a piece of work takes — START HERE. Maps any entry ("I have an idea", "it's broken", "is this feasible?", "we need copy", "upkeep") to its lane, spec artifacts, next skill, and gates; runs the intake sharpness test and the prior-rejection check on the way. The explicit front door for the D56/D58/D60 lane map.
version: 1.0.0
owner: wawan
risk: low
category: planning
scope: read:okf, read:planning
---

# pmos-router — Route work to its lane

The explicit front door. The lane map grew across
[D56](/okf/products/pmos/adr/d56-initiative-lanes.md)/[D58](/okf/products/pmos/adr/d58-builder-profiles.md)/[D60](/okf/products/pmos/adr/d60-prototype-loop.md)
while living implicitly across AGENTS.md, CLAUDE.md and the intake checklist — and the recorded cost
of an implicit map is the `prototype-loop` discoverability failure (the PM could not find a flow
whose pieces half-existed). This skill performs the mapping. **It decides nothing** — it routes to
lanes and gates that already exist; where it and an authority disagree, the authority wins and the
router is the bug (fix it via the weekly harness scan).

> **Format note:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)).
> Sources of truth: the AGENTS.md lane list, the initiative gate (PMOS-self: `.github/scripts/initiative-gate.sh`; a vendored kit: `pmos/scripts/gate-initiative.sh`), D56/D58/D60.

## Step 0 — three checks before any route

1. **Sharpness (the fog/ticket test):** *can the PM state the question or idea precisely now — not
   answer it, state it?* If not, it is **fog**: not ready for intake. Name what would sharpen it
   (a conversation, a datum, a spike) and stop — do not open an initiative to hold fog.
2. **Prior rejection:** check [planning/out-of-scope/](/README.md) for the
   concept. If a file exists, **read it first** and surface it to the PM — the concept returns only
   if the PM overrides the recorded reasoning, and the file is updated either way.
3. **The specimen test — ASK it, do not wait to be told** (D60 as amended 2026-07-24):

   > **Can the PM judge this from a description, or do they need an instance of it in front of them?**

   Put it to the PM in their own terms for this piece of work. If no description settles it, the
   route is **prototype**, *whether or not the work has a user interface* — the lane is no longer
   UI-gated. This check is asked here because the recorded failure is discoverability: a PM who does
   not know the lane exists cannot ask for it, and a step left to memory decays to never.

   **It must discriminate in both directions.** Most feature work — an MCP tool, a migration, a CI
   gate — *is* judgeable from a description and routes straight to its PRD untaxed. Over-firing twice
   running is a D41 tripwire on the test's wording.

4. **Existing-surface check — does the PM understand what is already there?** Ask:

   > **Would specifying this honestly require reading code that already exists?**

   Yes → an [explain-surface](/skills/explain-surface.skill) pass runs **first**, before the
   spike brief / prototype brief / PRD is authored, in a fresh context. Greenfield → skip it. This is
   standard, not optional: the PRD skill's own rule ("look it up rather than asking") means the
   *agent* acquires the understanding and the PM does not, and a spec built on facts the PM never saw
   is a watermelon at the root.

## The routes

| The PM says… | Route | Lane / artifacts / next skill | Gates to expect |
|---|---|---|---|
| "I have an idea" the PM **can't judge from a description** — they need an **instance** in front of them (a UI not yet seen; equally *does this skill's output teach?*, *does this API feel right to call?*) | **Prototype first — before any PRD** | `type: prototype`; quick brief at `prd_path` declaring **the judgement exercised + the specimen format** (**no rubric BY DESIGN** — grilled, never scored); [prototype skill](/skills/prototype.skill). Format fits the work: lookable UI, a worked sample output, call/response transcripts, a schema sketch. **The class's conventions are a BLOCKING precondition** (design system for UI; SKILL-FORMAT, D19 ACI, migration/RLS conventions elsewhere) — absent → the agent authors them from the same brief, PM approves, first. | Initiative Gate (brief exists); web-ci quarantine; PM disposition (promote/iterate/kill) |
| A **new bet** — new product/capability/direction whose *whether* is unargued | **Offer the strategic brief** (recommended, skippable — D61) | [strategic-brief skill](/skills/strategic-brief.skill) → `planning/briefs/<id>-brief.md`; go → feature route below; no-go → file in out-of-scope/ | none (the brief is never a gate) |
| A **validated direction or known feature** (incl. a promoted prototype) | **Feature lane** | `type: feature`; PRD + eval rubric ([prd](/skills/prd.skill) + [eval-rubric](/skills/eval-rubric.skill) skills), rubric authored alongside (D13); contract before build (D16). A promoted prototype's PRD is **derived from the validated option**. New surface → leg B: [design-brief](/skills/design-brief.skill) as the build's reference, held to the [design-reference rubric](/planning/evals/design-reference-eval-rubric.md) | Initiative Gate (PRD+rubric); full three-tier gate |
| "**Is this feasible / should we / how would we…?**" — a **question** with an unknown answer, findable by investigation | **Discovery lane** | `type: discovery`; spike brief at `prd_path` ([discovery skill](/skills/discovery.skill)); question + timebox + disposition. Deliverable is a **learning**, and it closes on the **timebox** ("inconclusive" is a recordable outcome). Contrast the row above: that one holds a **candidate** whose rightness no description settles, delivers a **validated direction**, and closes on a **disposition against a specimen**. Widening this lane to cover that was considered and **rejected** in D60 | Initiative Gate (spike brief) |
| "**Production is broken**" | **Incident lane** | `type: incident`; fix now, record post-hoc within 48h at `prd_path` (the one sanctioned inversion; [incident template](/okf/core/templates/incident-record-template.md)) | Initiative Gate (record, post-hoc) |
| A **text deliverable** (landing page, microcopy, release notes, campaign) | **Content lane** | `type: content`; content brief at `prd_path`, rubric recommended not required (D58); [copywriting skill](/skills/copywriting.skill). Copy for a prototype rides the prototype instead (D60) | Initiative Gate (content brief) |
| **Upkeep** — refactor/ops/security with no honest KR | **Chore lane, health-anchored** | `type: chore`; one-paragraph intent in `status`; anchor `health:<id>` from [health-budgets](/planning/okrs/health-budgets.md) (D59) — never a faked KR | Initiative Gate (intent + anchor) |

**Every route** still takes the universal steps: anchored initiative row (`create_initiative`),
branch `initiative/<id>`, and the human Acceptance Gate at the end (D12) — the router never bypasses
[working-in-pmos](/okf/core/playbooks/working-in-pmos.md).

## Step 5 — WRITE THE ANSWERS DOWN (this is what makes any of it enforceable)

Steps 0.3 and 0.4 used to be asked aloud and then discarded, and the cost was exactly what you would
predict: nothing could check that a *needs-an-instance* answer was followed by a prototype, or that
an *existing surface* was explained before it was specified. An unrecorded answer is an
unenforceable one. So both land on the initiative record, as a **leading token plus your reasoning**:

```yaml
specimen_test: "needs-instance — no description settles whether …"       # or "description-judgeable — …"
predecessor: <prototype-initiative-id>       # required when the answer is needs-instance
surface_check: "existing — the Initiative Gate"                          # or "greenfield — …"
explainer_path: planning/explainers/<surface>-explainer.md               # required when it is existing
```

The gate ([`scripts/workflow-state.js`](/scripts/workflow-state.js)) reads the **token** and the
**ordering of the paths it implies** — the prose is for the PM. It fails a PR whose PRD first
appeared before its prototype brief (**O3**) or before its surface explainer (**O4**). It does not
judge whether the answer was *right*: no deterministic check can decide that, and over-firing the
specimen test twice running stays a D41 tripwire on the test's wording, not a gate condition.

Check your position at any time with `node scripts/workflow-state.js <id>`.

## Edge rules

- **Two shapes at once** (an idea that is also a bet): sharpness first, then the brief-offer, then
  prototype — *whether* precedes *look*, but only when the whether is genuinely open; if the PM has
  already decided to explore, go straight to prototype.
- **Anchor-free trivia** (a typo, a broken link): the `no-initiative` label, no lane. Real work
  never takes the hatch.
- **Unknown shape after the checks:** ask the PM one routing question with a recommended answer —
  do not guess a lane.
