create-pmos 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +65 -4
  2. package/bin/create-pmos.js +4 -1
  3. package/package.json +1 -1
  4. package/payload/AGENTS.md +27 -2
  5. package/payload/KIT-VERSION +2 -2
  6. package/payload/README.md +10 -2
  7. package/payload/SECURITY.md +53 -0
  8. package/payload/okf/core/concepts/design-craft.md +97 -0
  9. package/payload/okf/core/concepts/design-loop.md +19 -8
  10. package/payload/okf/core/templates/design-brief-template.md +1 -1
  11. package/payload/okf/core/templates/prd-template.md +3 -0
  12. package/payload/okf/core/templates/prototype-brief-template.md +64 -0
  13. package/payload/scripts/frontier.sh +60 -0
  14. package/payload/scripts/metrics.py +57 -17
  15. package/payload/scripts/pmos-log.sh +16 -6
  16. package/payload/skills/SKILL-FORMAT.md +66 -9
  17. package/payload/skills/eval-rubric.skill +8 -1
  18. package/payload/skills/evaluator.skill +65 -20
  19. package/payload/skills/explain-run.skill +9 -6
  20. package/payload/skills/ingest-repo.skill +4 -3
  21. package/payload/skills/pmos-router.skill +57 -0
  22. package/payload/skills/prd.skill +18 -2
  23. package/payload/skills/prototype.skill +80 -0
  24. package/payload/skills-native/copywriting/SKILL.md +57 -0
  25. package/payload/skills-native/discovery/SKILL.md +71 -0
  26. package/payload/skills-native/eval-rubric/SKILL.md +159 -0
  27. package/payload/skills-native/evaluator/SKILL.md +182 -0
  28. package/payload/skills-native/explain-run/SKILL.md +121 -0
  29. package/payload/skills-native/ingest-repo/SKILL.md +120 -0
  30. package/payload/skills-native/okr/SKILL.md +70 -0
  31. package/payload/skills-native/pmos-router/SKILL.md +59 -0
  32. package/payload/skills-native/prd/SKILL.md +109 -0
  33. package/payload/skills-native/prototype/SKILL.md +82 -0
  34. package/payload/state/tickets/.gitkeep +0 -0
  35. package/payload/templates/ticket-template.md +18 -0
package/README.md CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  **A product manager's operating system you can adopt in five minutes — no coding expertise
4
4
  required.** One command puts a disciplined, eval-driven PM workflow inside your own repo:
5
- initiative → PRD → eval rubric → agreed contract → build → three gates. Your AI coding agent
6
- (e.g. Claude Code) does the building. You do the judging. Everything stays in your folder — no
7
- database, no account, no network calls, no telemetry.
5
+ initiative → PRD → eval rubric → agreed contract → build → three gates. **Any capable coding
6
+ agent** does the building — Claude Code, Codex/ChatGPT, Cursor, Gemini, Copilot; PMOS is
7
+ provider- and model-agnostic. You do the judging. Everything stays in your folder — no database,
8
+ no account, no network calls, no telemetry.
8
9
 
9
10
  ## Whose task is what
10
11
 
@@ -43,7 +44,7 @@ What you'll see:
43
44
 
44
45
  Next steps in /home/you/my-product:
45
46
  1. cp pmos/templates/pmos-gate.yml .github/workflows/pmos-gate.yml (only if on GitHub)
46
- 2. Add to the repo's CLAUDE.md: "This product is PMOS-managed (file mode) — read pmos/AGENTS.md before any work."
47
+ 2. Wire PMOS into your agent's instruction file (CLAUDE.md, AGENTS.md, .cursorrules, GEMINI.md, or copilot-instructions): "This product is PMOS-managed (file mode) — read pmos/AGENTS.md before any work."
47
48
  3. Commit the pmos/ folder. Then follow pmos/AGENTS.md for every run.
48
49
  ```
49
50
 
@@ -249,6 +250,66 @@ Refreshes the skills, concepts, and scripts only. Your records — `state/`, `pl
249
250
  `okf/product/` — are yours, and an update never touches them. `pmos/KIT-VERSION` always says
250
251
  exactly what you're running.
251
252
 
253
+ ## What's new in 0.5.0
254
+
255
+ 0.4.0 opened the front of the loop. 0.5.0 makes explicit what was always the intent: **the kit is
256
+ provider- and model-agnostic**, and the harness kernel now says so in its own words.
257
+
258
+ - **Any capable coding agent runs the loop — not just Claude Code.** The runtime amendment
259
+ (D09/D34, ratified 2026-07-23) generalizes the evaluator, ingest, and design skills from
260
+ "runs in Claude Code" to "runs in the interactive agent runtime — any capable coding agent;
261
+ PMOS-self happens to use Claude Code, but the runtime is not Claude-specific." Point Codex,
262
+ Cursor, Gemini, or Copilot at `pmos/AGENTS.md` and the same protocol holds.
263
+
264
+ > Works the same in any of them: open your product folder in the agent, then
265
+ > "Read pmos/AGENTS.md and follow it." The gates, records, and metrics don't care which model
266
+ > wrote the code.
267
+
268
+ - **Per-model calibration.** When you log a run or an eval you can now name the model that did the
269
+ work (`model`) or the judging (`evaluator_model`), so the evaluator's calibration is read *per
270
+ model* instead of silently pooling providers — `scripts/metrics.py` warns when labeled evals span
271
+ more than one evaluator model, because a trust score one model earned isn't inherited by another.
272
+ The design surface is documented as pluggable too (any surface that can take a brief and export a
273
+ component library), not tied to one vendor.
274
+
275
+ - **A stated security posture that travels with the kit** (`pmos/SECURITY.md`), a `frontier.sh`
276
+ metrics helper, a file-mode `ticket-template.md`, and a sharper `SKILL-FORMAT.md` — all now part
277
+ of the vendored kernel.
278
+
279
+ **Upgrade note:** `npx create-pmos@latest --update` brings all of this in and never touches your
280
+ `state/`, `planning/`, or `okf/product/` records. Purely additive — no change to how the gate
281
+ behaves on your existing initiatives.
282
+
283
+ ## What's new in 0.4.0
284
+
285
+ 0.3.0 sharpened the judging. 0.4.0 adds the **front of the loop** — deciding *what* to build and
286
+ whether a user-facing idea is even right *before* a PRD locks it in.
287
+
288
+ - **A front door: the `pmos-router` skill.** Not sure which lane a piece of work takes? Start here.
289
+ It maps any entry — "I have an idea", "is this feasible?", "production is broken", "we need copy",
290
+ "just upkeep" — to its lane, its spec artifact, the next skill, and the gates to expect, running
291
+ a sharpness check ("can you *state* the question yet?") and a prior-rejection check on the way. It
292
+ decides nothing; it routes to lanes that already exist.
293
+
294
+ > Read pmos/AGENTS.md, then follow pmos/skills/pmos-router.skill: I want to [X] — route it.
295
+
296
+ - **The prototype lane: see it before you spec it.** For a user-facing idea, the new
297
+ `prototype` skill runs a pre-PRD visual validation — you give a *quick* brief, a design agent
298
+ produces 2–3 genuinely different lookable options with real draft copy, a designer-grade grilling
299
+ sharpens them (a dialogue, never a score), and you dispose promote / iterate / kill. Promote
300
+ derives the PRD from what you actually validated. It's the cheapest way to kill a bad idea — before
301
+ it's a spec, not after four rebuilds.
302
+
303
+ > Follow pmos/skills/prototype.skill: here's my idea — [two sentences]. Give me lookable options.
304
+
305
+ - **A design-craft concept + prototype-brief template** now ship, and the `prd`/`eval-rubric`
306
+ skills gained a "grill before you write, write for durability (name interfaces, not file paths)"
307
+ discipline.
308
+
309
+ **Upgrade note:** `npx create-pmos@latest --update` brings all of this in and never touches your
310
+ `state/`, `planning/`, or `okf/product/` records. Purely additive — nothing about how the gate
311
+ behaves on your existing initiatives changes.
312
+
252
313
  ## What's new in 0.3.0
253
314
 
254
315
  0.2.0 made the workflow fit real work. 0.3.0 goes after the two ways the *judging* half quietly
@@ -21,8 +21,10 @@ const PKG = require(path.join(__dirname, '..', 'package.json'));
21
21
  const KERNEL = [
22
22
  'AGENTS.md',
23
23
  'README.md',
24
+ 'SECURITY.md',
24
25
  'KIT-VERSION',
25
26
  'skills',
27
+ 'skills-native',
26
28
  'okf/core',
27
29
  'scripts',
28
30
  'templates',
@@ -59,7 +61,8 @@ function vendor(targetRoot) {
59
61
  Next steps in ${targetRoot}:
60
62
  1. If the repo is not git yet: git init
61
63
  2. If it lives on GitHub: cp pmos/templates/pmos-gate.yml .github/workflows/pmos-gate.yml
62
- 3. Add to the repo's CLAUDE.md: "This product is PMOS-managed (file mode) — read pmos/AGENTS.md before any work."
64
+ 3. Wire PMOS into your agent's instruction file (CLAUDE.md, AGENTS.md, .cursorrules, GEMINI.md, or
65
+ .github/copilot-instructions.md): "This product is PMOS-managed (file mode) — read pmos/AGENTS.md before any work."
63
66
  4. Commit the pmos/ folder. Then follow pmos/AGENTS.md for every run.`);
64
67
  }
65
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-pmos",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "Scaffold the PMOS portable kit — run the PMOS product-management workflow (initiative → lane-fit spec → contract → build → three gates, with work-type lanes for features, research, maintenance, incidents, and content) entirely inside your own repo, with all state as git-versioned files. No database, no network, no telemetry.",
5
5
  "license": "MIT",
6
6
  "bin": {
package/payload/AGENTS.md CHANGED
@@ -24,8 +24,8 @@ yourself wanting an MCP tool, use the state adapter below instead.
24
24
  | `get_skill` | read `pmos/skills/<name>.skill` |
25
25
  | `get_okf_concepts` | read `pmos/okf/…` (index-first, then the concept body — progressive disclosure) |
26
26
  | `get_eval_rubric` | read `pmos/planning/evals/<id>-eval-rubric.md` |
27
- | `log_agent_run` | append one JSON line to `pmos/state/runs.jsonl` (`{run_id, initiative_id, pre_run_contract, self_eval, human_corrections, date}`) |
28
- | `save_eval` | append one JSON line to `pmos/state/evals.jsonl` (`{run_id, initiative_id, rubric_path, score, verdict, dimensions, date}`) |
27
+ | `log_agent_run` | append one JSON line to `pmos/state/runs.jsonl` (`{run_id, initiative_id, pre_run_contract, self_eval, human_corrections, date, model}`) — record `model` = the model that produced the run so metrics stay honest across model switches |
28
+ | `save_eval` | append one JSON line to `pmos/state/evals.jsonl` (`{run_id, initiative_id, rubric_path, score, verdict, dimensions, date, evaluator_model}`) — record `evaluator_model` = the model that rendered the verdict; κ is calibrated **per evaluator model** (a model swap does not inherit a prior κ) |
29
29
  | `record_acceptance` | append one JSON line to `pmos/state/acceptances.jsonl` (`{run_id, initiative_id, accepted, pm_label, note, date}`) — **written only on the PM's explicit word** |
30
30
  | `record_outcome_check` | append one JSON line to `pmos/state/outcome_checks.jsonl` (`{initiative_id, disposition, evidence, date}`) — the D57 post-acceptance outcome verdict (`validated | refuted | inconclusive`; evidence required for the first two). **PM's word only — never auto-dispose from metrics**; a re-judgment is a new line |
31
31
  | `save_okf_doc` | write the doc under `pmos/okf/product/…` marked as a DRAFT; the PM approves it via PR review (the file-mode form of draft→approved) |
@@ -93,6 +93,22 @@ honest.
93
93
  not install the pmos gate, or mirror the initiative file locally** — a vendored sibling gate
94
94
  fails closed on a missing local record by design (S5 Review Gate finding).
95
95
 
96
+ ## Decomposing an initiative into tickets (file mode has no board)
97
+
98
+ When an initiative is bigger than one run, break it into **tickets** — the plain-file equivalent of
99
+ the hosted product's SDLC board. One file per ticket in `pmos/state/tickets/NNN-slug.md`, numbered
100
+ in **dependency order**, from [templates/ticket-template.md](templates/ticket-template.md):
101
+
102
+ - Frontmatter: `id` (the NNN), `title`, `status` (`todo | doing | done`), and `blocked_by` — an
103
+ explicit list of the ticket ids that must be `done` first. Blocking edges are **text**, not a
104
+ hidden graph.
105
+ - **Work the frontier.** `pmos/scripts/frontier.sh` lists exactly the tickets that are not done and
106
+ whose every blocker is done — the workable set. Start only from there. If it reports the frontier
107
+ is *blocked*, there is a cycle or an undone blocker to resolve before more work is startable.
108
+ - Each ticket names **one deliverable**, behaviorally (interfaces/types/contracts, never file paths
109
+ or line numbers — they stale while the ticket waits). Tickets decompose an initiative; they do not
110
+ replace it — the initiative record, PRD, rubric, and the three gates are unchanged.
111
+
96
112
  ## New agent paths — the lethal-trifecta audit
97
113
 
98
114
  Before creating any new agent path or widening a tool grant, verify it does **not** hold all three
@@ -117,6 +133,15 @@ deployment until this repo has accumulated its own PM-vs-evaluator record (appen
117
133
  `pmos/scripts/metrics.py` computes the north star (human corrections per accepted run), pass rates,
118
134
  and the Goodhart tripwire from `pmos/state/`.
119
135
 
136
+ **Model-awareness (any provider).** PMOS is provider/model-agnostic — any capable coding agent can
137
+ run this loop — but calibration is a property of the **evaluator model**, not of "the Review Gate"
138
+ abstractly. Record the model on every run/eval (the `model` / `evaluator_model` fields above); a
139
+ model swap **forks** the calibration record — you do not inherit a κ another model earned, and
140
+ `metrics.py` warns when labeled evals pool more than one evaluator model. The high-judgment roles
141
+ (the adversarial evaluator, `explain-run`) assume a **frontier-tier reasoner**: a weaker model
142
+ degrades *silently* to leniency and grep-clean while its output still looks well-formed — the
143
+ per-model κ is what makes that degradation visible.
144
+
120
145
  ## PM protocol (weekly)
121
146
 
122
147
  Scan `discoveries.md`; a friction theme seen twice with no resolving decision must be promoted to a
@@ -1,3 +1,3 @@
1
- kernel-source: pmos@25d32ad
2
- assembled: 2026-07-20
1
+ kernel-source: pmos@917d29e
2
+ assembled: 2026-07-23
3
3
  mode: vendor
package/payload/README.md CHANGED
@@ -13,16 +13,24 @@ personally-owned PMOS backend).
13
13
  - `AGENTS-HUMAN.md` — the same loop for a **human** builder (D58): plain terms + the
14
14
  `scripts/pmos-log.sh` helper that appends validated state records in one command. Mixed
15
15
  human+agent teams share the same state.
16
+ - `SECURITY.md` — the kit's **security posture**: skills are executable instructions, what the kit
17
+ does structurally to be safe to install, and what stays your responsibility. Read it before you
18
+ install skills into your agent.
16
19
  - `skills/` — the PMOS skill kernel (prd, eval-rubric, okr, evaluator, …). Single-sourced from the
17
20
  PMOS repo; where a skill names a hosted tool, apply the AGENTS.md state adapter.
21
+ - `skills-native/` — the same skills in **Agent-Skills standard** form (`<name>/SKILL.md`
22
+ directories), generated from `skills/` so a Claude Code / Codex / skills.sh harness can load them.
23
+ The flat `skills/` files stay the source of truth; this is the portable mirror.
18
24
  - `okf/core/` — kernel concepts (the sdlc loop, the three-tier gate, watermelon flags, …).
19
25
  `okf/product/` — YOUR product's knowledge; drafted by ingest, approved via PR review.
20
26
  - `planning/` — okrs, PRDs, rubrics (`agent-run-eval-rubric.md` is the per-initiative template),
21
27
  `eval-calibration.md` (append every PM override of an evaluator verdict).
22
28
  - `state/` — the operational record, **append-only**: `initiatives/<id>.md`, `runs.jsonl`,
23
- `evals.jsonl`, `acceptances.jsonl`, `discoveries.md`.
29
+ `evals.jsonl`, `acceptances.jsonl`, `discoveries.md`. `tickets/NNN-slug.md` decompose an
30
+ initiative into ordered, dependency-numbered work (file-mode's board — see AGENTS.md).
24
31
  - `scripts/` — `gate-initiative.sh` (the fail-closed CI gate), `metrics.py` (north star +
25
- calibration + Goodhart tripwire), `kit-update.sh` (kernel refresh).
32
+ calibration + Goodhart tripwire), `kit-update.sh` (kernel refresh), `frontier.sh` (lists the
33
+ workable tickets — those not done whose blockers are all done).
26
34
  - `templates/pmos-gate.yml` — CI drop-in; copy to `.github/workflows/`.
27
35
  - `KIT-VERSION` — which PMOS kernel this was assembled from.
28
36
 
@@ -0,0 +1,53 @@
1
+ # PMOS kit — security posture
2
+
3
+ A skill is not a document. It is **instructions that run inside your agent**, with your agent's
4
+ tools and your agent's access. Anything the kit ships into your repo can shape what your agent does.
5
+ This file states, concretely, what the PMOS kit does to be safe to install — and where the
6
+ responsibility stays yours.
7
+
8
+ ## Why "we scanned it" is not a posture
9
+
10
+ The largest skills registry (skills.sh) shipped a malicious-skill scanner. Trail of Bits bypassed it
11
+ with prompt injection plus compiled bytecode. Static scanning of agent instructions is *evadable by
12
+ construction* — the payload is natural language aimed at a model, not a signature you can enumerate.
13
+ So the PMOS kit does not claim "scanned and safe." It claims a set of **structural** properties you
14
+ can check yourself, below.
15
+
16
+ ## What the kit does
17
+
18
+ - **No on-load command execution in shipped skills.** No PMOS kit skill uses Claude Code's dynamic
19
+ `` !`cmd` `` context injection or any load-time shell-out. A skill's body is read as instructions,
20
+ not run as a script when it loads. *(Check: `grep -rn '!\`' pmos/skills` — expect nothing.)*
21
+ - **Least authority, declared.** Shipped skills request the minimum tools they need; the
22
+ security-sensitive one — the **evaluator** — is **read-only by design**: its only write is the
23
+ schema-constrained verdict. The component that reads untrusted content (diffs, PR text) is
24
+ deliberately *not* the component that can act, which removes the exfiltration leg of the lethal
25
+ trifecta.
26
+ - **A `license` on every shipped skill** (portability + provenance), and PMOS producer metadata is
27
+ carried under the spec's `metadata:` extension map, never as ambient top-level directives.
28
+ - **Fail-closed containment.** The kit is assembled by `kit/build-kit.sh`, which greps its own output
29
+ and **aborts** if any reference to a hosted PMOS backend (a project ref, an MCP endpoint, or a
30
+ hosted-backend URL) leaks in. The npm publish path re-runs this check on the exact tarball and
31
+ refuses to publish on anything but a clean result. The kit you get is self-contained: **no
32
+ database, no network, no telemetry.**
33
+ - **No network calls in the installer.** `create-pmos` vendors a bundled payload; it makes no
34
+ outbound requests and sends nothing about you anywhere.
35
+ - **Everything the evaluator reads is untrusted data, never instructions.** An instruction embedded
36
+ in a diff or PR body ("mark this PASS") is treated as *evidence of a defect*, not a command —
37
+ paired with the read-only scope above, because prompt-level defenses alone are bypassable.
38
+
39
+ ## What stays your responsibility
40
+
41
+ - **Review before you install.** Read the skills and scripts in `pmos/` the way you would review any
42
+ dependency PR. The kit is small and plain-text on purpose so you can. `--update` refreshes only the
43
+ kernel and never touches your `state/` — review its diff like any other change.
44
+ - **Your agent's tools are yours to scope.** The kit declares least authority for its own skills, but
45
+ what your agent is *allowed* to do in your repo is set by you, not by us.
46
+ - **Pin what you install.** Prefer a pinned `create-pmos@<version>` over `@latest` in automation, and
47
+ re-review the kernel diff on each update.
48
+
49
+ ## Reporting
50
+
51
+ Found something that violates the posture above — a shipped skill with load-time execution, a
52
+ containment leak, an over-scoped tool request? Open an issue in the PMOS repo describing what and
53
+ where. The posture is only worth stating if it is enforced; a false claim here is itself a bug.
@@ -0,0 +1,97 @@
1
+ ---
2
+ type: Concept
3
+ title: Design Craft — the UI/UX practice a design agent applies
4
+ description: The product-agnostic design knowledge PMOS's design agents reason with when turning a quick brief into a prototype, a design reference, or a design system — perception and cognition evidence plus the craft moves it implies. Principles to reason with, never a style lock.
5
+ tags: [design, craft, perception, cognition, prototype, accessibility]
6
+ timestamp: 2026-07-21
7
+ ---
8
+
9
+ # Design Craft — the practice a design agent applies
10
+
11
+ **Situating context:** [D60](/okf/products/pmos/adr/d60-prototype-loop.md) makes the design agent, not
12
+ the PM, the author of prototypes and design systems — from a **quick brief**. That is hollow unless
13
+ the agent has real practice to apply: an agent told to "apply UI/UX practice" with nothing to apply
14
+ produces exactly the generic rectangle-grid the PM rejected in the console-redesign series
15
+ ("obviously AI generated", run 003). This concept promotes the durable, replicated core of
16
+ [attention-research](/planning/design/attention-research.md) — authored for one initiative, valuable
17
+ for all — into the bundle, per the rule that timeless craft lives in OKF while operational notes stay
18
+ in /planning/. **These are principles to reason with, never a style lock**: a checklist that forces
19
+ one look would reproduce the very monotony this exists to prevent.
20
+
21
+ ## How to use this (design agent)
22
+
23
+ Retrieve this concept before any prototype, design reference, or design-system authoring. Reason from
24
+ the principles to the *specific* product and brief — never apply them as a template. The test of good
25
+ use is that two different briefs produce two visibly different designs, each defensible from these
26
+ principles under [grilling](/okf/products/pmos/adr/d60-prototype-loop.md).
27
+
28
+ ## The evidence core (perception & cognition)
29
+
30
+ Replicated classics; citations in [attention-research](/planning/design/attention-research.md).
31
+
32
+ 1. **Working memory holds ~4 chunks** (Miller 1956; Cowan 2001). Six-plus co-equal clusters on one
33
+ screen force re-scanning instead of absorption.
34
+ 2. **Cognitive load is a budget** (Sweller 1988). Layout noise, redundant chrome, and
35
+ undifferentiated density steal capacity from the judgment the user came to make.
36
+ 3. **Progressive disclosure outperforms everything-at-once** (Nielsen 2006) on speed *and* error
37
+ rate. Detail should be *available*, not *ambient*.
38
+ 4. **Attention is serial after the first glance** (eyetracking F/Z patterns; serial-position,
39
+ Murdock 1962). A screen needs ONE focal entry point and a deliberate last word — not a uniform
40
+ grid where every cell competes.
41
+ 5. **Pre-attentive vision is fast and specific** (Treisman & Gelade 1980; Cleveland & McGill 1984).
42
+ Hue, size, curvature, position and motion are read in <200 ms; position along a common scale beats
43
+ box-vs-box comparison. Encode status in hue/size/position, not in N identical bordered boxes.
44
+ 6. **Grouping does not need boxes** (Gestalt; Palmer 1992; Tufte's data-ink). Whitespace, alignment
45
+ and type contrast carry structure at near-zero ink; enclosure is the *heaviest* grouping device,
46
+ so spend it only where load-bearing.
47
+ 7. **Humans prefer curves** (Bar & Neta 2006). Sharp-cornered uniformity reads mechanical —
48
+ "template output" — regardless of palette.
49
+ 8. **Dual coding** (Paivio 1971). A number paired with a spatial encoding (position, sparkline) is
50
+ absorbed and recalled better than the number alone.
51
+ 9. **Aesthetic-usability effect** (Kurosu & Kashimura 1995). Polish is not decoration; it changes
52
+ tolerance, trust, and measured usability.
53
+
54
+ ## The craft moves (what the evidence implies)
55
+
56
+ - **Visual hierarchy & focal structure.** One focal opening per surface; secondary material
57
+ subordinated by size, weight, and position — not just placed elsewhere. End deliberately (the last
58
+ thing shown is remembered).
59
+ - **Chunking & density.** ≤4 co-equal chunks above the fold. Density is fine — *undifferentiated*
60
+ density is not; differentiate by hierarchy, not by removal.
61
+ - **Progressive disclosure.** Secondary sections collapse to honest one-line summaries; things that
62
+ need attention may open themselves. Disclosure must never hide alarms.
63
+ - **Typographic & spatial rhythm.** A deliberate type scale and a consistent spacing unit; vary
64
+ rhythm to mark importance, keep it steady to mark sameness.
65
+ - **Contour & geometry variation.** De-rectangle: boxes only where enclosure is load-bearing; group
66
+ by whitespace and alignment; mix radii/organic forms deliberately. A wall of same-radius rectangles
67
+ is the recorded failure.
68
+ - **Motion with restraint.** Motion is pre-attentive — spend it only on what is genuinely live or
69
+ needs attention; ambient motion is load.
70
+ - **Task-fit — organise around the user's job, not the data model.** The layout mirrors the domain
71
+ workflow and leads with "what needs me." Perception science applied generically *loses* task-fit —
72
+ that was the run-004 rejection: a beautiful surface that hid the work the user actually manages.
73
+ - **Real words are part of the design** ([D60](/okf/products/pmos/adr/d60-prototype-loop.md): copy
74
+ rides the prototype). Draft real headlines and microcopy; lorem defers the judgment the prototype
75
+ exists to enable.
76
+
77
+ ## Accessibility floors (non-negotiable, in every fidelity)
78
+
79
+ Floors, not aspirations — they bind prototypes too, because a direction validated below the floor is
80
+ a direction that will fail later: **WCAG contrast (4.5:1 body, 3:1 large text)** · **touch/click
81
+ targets ≥ 44px** · **`prefers-reduced-motion` respected wherever motion is used** · **never encode
82
+ meaning in hue alone** (pair with position, shape, or label — also how RAG status stays legible to
83
+ color-blind users) · **keyboard reachability for anything interactive** in leg-B references.
84
+
85
+ ## Anti-patterns (each one recorded, not hypothetical)
86
+
87
+ From the [console-redesign series](/planning/evals/eval-calibration.md): **the rectangle wall** (same
88
+ box, same radius, everywhere — run 003) · **cosmetics over unchanged structure** (a new skin on the
89
+ same IA does not clear "surprise me" — run 002) · **generic perception-science minimalism that loses
90
+ the job** (run 004) · **safe, scoreable sameness** (optimising for a rubric instead of for the user —
91
+ the reason leg A is grilled, never scored).
92
+
93
+ ## Related
94
+
95
+ - [design-loop](/okf/core/concepts/design-loop.md) — the workflow this craft is applied inside.
96
+ - [d60-prototype-loop](/okf/products/pmos/adr/d60-prototype-loop.md) — why the agent designs and the PM briefs.
97
+ - [attention-research](/planning/design/attention-research.md) — the evidence base with full citations (operational note, stays in /planning/).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  type: Concept
3
3
  title: The Design Loop
4
- description: How a PM runs UI/UX design as a first-class, repeatable, product-scoped sub-flow of the Build stage — brief → design → reconcile → build → design-sync — gated by the Review Gate, presentation-only, never a data decision. PMOS's own app is one instance.
4
+ description: How a PM runs UI/UX design as a first-class, repeatable, product-scoped sub-flow of the Build stage — brief → design → reconcile → build → design-sync — gated by the Review Gate. Presentation-only for redesigns; a new surface downstream of an approved PRD may define its decided views and flows (D60), making the design the reference the build works from. PMOS's own app is one instance.
5
5
  tags: [design, ui, workflow, build, reconciliation, watermelon]
6
6
  timestamp: 2026-07-01
7
7
  ---
@@ -32,7 +32,8 @@ An initiative with a user-facing surface runs four legs *inside* Build:
32
32
  1. **Brief** — the [design-brief skill](/skills/core/design-brief.skill) writes the context handoff: what
33
33
  to design and the hard, presentation-only constraints, each surface tied to a real data source. It is to
34
34
  design what the [PRD](/skills/core/prd.skill) is to build.
35
- 2. **Design** — the design is made in claude.ai/design (external to this repo).
35
+ 2. **Design** — the design is made in an external design surface (PMOS-self uses claude.ai/design;
36
+ any capable design surface fits — external to this repo).
36
37
  3. **Reconcile + build** — the [design-reconcile skill](/skills/core/design-reconcile.skill) classifies
37
38
  every surface against **the product's capability ledger** and the PM signs off before any code; then the
38
39
  design is built into the product's app on its design system, verified by the product's CI. (For PMOS's own
@@ -42,15 +43,25 @@ An initiative with a user-facing surface runs four legs *inside* Build:
42
43
  to claude.ai/design (for PMOS, see [.design-sync/conventions.md](/.design-sync/conventions.md)), so the
43
44
  next design starts from the product's actual parts.
44
45
 
45
- Legs 2 and 4 are external tools PMOS *references*; legs 1 and 3 are the PMOS skills that make the loop
46
+ The design surface (legs 2 and 4) is **pluggable and provider-agnostic** — PMOS-self uses
47
+ claude.ai/design, but the loop is not tied to it; any capable design surface that can consume a brief
48
+ and export a component library fits (harness-model-agnosticism). Legs 2 and 4 are external tools PMOS *references*; legs 1 and 3 are the PMOS skills that make the loop
46
49
  repeatable.
47
50
 
48
51
  ## Presentation-only is the load-bearing constraint
49
52
 
50
- Design is **behavior-preserving**: no new views, no new data, no changed flows — presentation only. If a
51
- design implies a data or feature change, it is **flagged back as a separate decision**, never smuggled into
52
- the build. This is what keeps design at [control altitude](/okf/core/concepts/control-plane.md) and stops it
53
- from becoming a backdoor for architecture the PM never decided.
53
+ For a **redesign of an existing surface**, design is **behavior-preserving**: no new views, no new data,
54
+ no changed flows — presentation only. If such a design implies a data or feature change, it is **flagged
55
+ back as a separate decision**, never smuggled into the build.
56
+
57
+ **Scoped by [D60](/okf/products/pmos/adr/d60-prototype-loop.md) (2026-07-21):** for a **new surface
58
+ downstream of an approved PRD**, the design *may* define the new views and flows — because the PRD already
59
+ decided them. The constraint exists to stop design smuggling in features **nobody decided**; a PRD-decided
60
+ feature is not smuggling. In that case the design produced here is **the reference the build works from**
61
+ (D60 leg B), carrying the scored designer-grilling bar — not a Build-stage ornament. Anything the design
62
+ implies **beyond** what its PRD decided is still flagged back, exactly as before. This is what keeps design
63
+ at [control altitude](/okf/core/concepts/control-plane.md) in both cases: the PM's decisions bound the
64
+ design; the design never makes them.
54
65
 
55
66
  ## Reconciliation is the watermelon defense for UI
56
67
 
@@ -111,7 +122,7 @@ PMOS's own instance: the `web/` app, the [D38](/okf/products/pmos/adr/d38-design
111
122
  [eval-driven](/okf/core/concepts/eval-driven-pm.md) style (the fidelity rubric before the build).
112
123
  - Reconciliation is [watermelon-flag](/okf/core/concepts/watermelon-flag.md) applied to UI.
113
124
  - PMOS stays a [control plane](/okf/core/concepts/control-plane.md): it specs and evaluates design; the design
114
- itself is made in claude.ai/design and built by a build agent.
125
+ itself is made in an external design surface (e.g. claude.ai/design) and built by a build agent.
115
126
  - Formalized by [D48](/okf/products/pmos/adr/d48-design-loop.md); made product-scoped by
116
127
  [D50](/okf/products/pmos/adr/d50-design-loop-product-scoped.md); composes with the design *system* (D38,
117
128
  PMOS's own instance).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  type: Template
3
3
  title: Design Brief Template
4
- description: The scaffold for a design brief instance — the context handoff from Claude Code to claude.ai/design. Copy into /planning/design/ and fill; presentation-only.
4
+ description: The scaffold for a design brief instance — the context handoff from the interactive agent to an external design surface (e.g. claude.ai/design). Copy into /planning/design/ and fill; presentation-only.
5
5
  tags: [template, design, brief, planning]
6
6
  timestamp: 2026-07-01
7
7
  ---
@@ -82,3 +82,6 @@ copy is an operational instance and does not live in the OKF bundle.
82
82
  - [ ] Paired eval rubric queued to be written first.
83
83
  - [ ] Every link carries one situating sentence; parent-KR text quoted (dual-audience, D58).
84
84
  - [ ] Stays at control altitude — specs *what/why*, not application code or the agent's path.
85
+ - [ ] **Durable**: names interfaces/behavioral contracts, never file paths or line numbers (they
86
+ stale while work waits); criteria behavioral + independently verifiable. Exception: a
87
+ prototype-derived snippet trimmed to its decision-rich parts (D60).
@@ -0,0 +1,64 @@
1
+ ---
2
+ type: Template
3
+ title: Prototype Brief Template
4
+ description: The scaffold for a QUICK leg-A prototype brief (D60) — the idea, the user, the moment, the feel, draft copy seeds. Deliberately short; if it needs PRD-level detail the flow has failed its purpose. Copy into prototype/<initiative-id>/brief.md and set it as the initiative's prd_path.
5
+ tags: [template, prototype, design, lane]
6
+ timestamp: 2026-07-21
7
+ ---
8
+
9
+ # Prototype Brief Template
10
+
11
+ **Situating context:** The [prototype lane](/okf/products/pmos/adr/d60-prototype-loop.md)'s contract
12
+ artifact. The PM writes THIS — quick, sketchy, incomplete is fine — and the **design agent does the
13
+ rest**: picks up the product's design system, applies the
14
+ [design-craft layer](/okf/core/concepts/design-craft.md), drafts real copy, and returns divergent
15
+ lookable options. The brief is deliberately NOT a PRD: it exists so the PM can see something *before*
16
+ committing to a spec. If filling it in starts to feel like writing requirements, stop — that detail
17
+ belongs in the PRD that follows a successful prototype, not here.
18
+
19
+ > Usage: copy into `prototype/<initiative-id>/brief.md`; set it as the initiative's `prd_path`
20
+ > (`create_initiative`, `type: 'prototype'`). Every section may be a single sentence. Only the first
21
+ > two are required.
22
+
23
+ ---
24
+
25
+ ```markdown
26
+ # Prototype Brief: <working title>
27
+
28
+ - initiative_id: <id>
29
+ - product_slug: <product_slug>
30
+ - date: <YYYY-MM-DD>
31
+
32
+ ## The idea (required)
33
+ <!-- One or two sentences. What is this thing? -->
34
+
35
+ ## Who it's for, and the moment they'd use it (required)
36
+ <!-- The user and the situation — "a PM opening the board on Monday morning", not a persona doc. -->
37
+
38
+ ## How it should feel
39
+ <!-- Adjectives and references beat specification: "calm, dense, fast to scan", "more like a
40
+ cockpit than a report". Leave blank to let the agent propose. -->
41
+
42
+ ## Copy seeds
43
+ <!-- Any words you already hear: a headline, a button label, the tone. The agent drafts REAL copy
44
+ (D60 — copy rides the prototype, no lorem); seeds steer it. Blank is fine. -->
45
+
46
+ ## What this is NOT
47
+ <!-- One line if you already know a direction to avoid. -->
48
+
49
+ ## Existing surface?
50
+ <!-- If this improves an existing screen/flow, name it. New idea → leave blank. -->
51
+ ```
52
+
53
+ ---
54
+
55
+ ## What the agent does with this (not the PM's job)
56
+
57
+ 1. **Design-system check first (blocking, D60):** no design system on this product → the agent
58
+ authors one from this same brief and the PM approves it *before* any prototype.
59
+ 2. Produces **divergent low-fidelity options** — one safe direction is a weaker outcome than three
60
+ arguable ones — with **real draft copy**, into `prototype/<initiative-id>/`.
61
+ 3. Submits to **designer grilling** (dialogue, never a score — D60): one question at a time, a
62
+ recommended answer with each.
63
+ 4. The PM **disposes**: promote (→ a new feature-lane initiative; PRD + rubric derived from the
64
+ validated option) / iterate / kill.
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env bash
2
+ # frontier.sh — list the workable tickets in a file-mode PMOS kit (E9).
3
+ #
4
+ # "Work the frontier": a ticket is workable when it is NOT done and EVERY ticket it is blocked_by is
5
+ # done. This is the plain-file equivalent of a board's dependency structure — one file per ticket in
6
+ # state/tickets/NNN-slug.md, numbered in dependency order, blocking edges as text.
7
+ #
8
+ # scripts/frontier.sh # from the kit root; lists workable tickets
9
+ # scripts/frontier.sh state/tickets # explicit tickets dir
10
+ #
11
+ # Dependency-free and portable: POSIX-ish bash, no associative arrays (runs on bash 3.2, e.g. stock
12
+ # macOS). No network, no board. Reads only the YAML frontmatter fields id / status / blocked_by.
13
+ set -euo pipefail
14
+
15
+ DIR="${1:-state/tickets}"
16
+ [ -d "$DIR" ] || { echo "frontier: no tickets dir at '$DIR' (nothing to do)"; exit 0; }
17
+
18
+ # --- field readers (frontmatter only: stop at the closing --- fence) ----------------------------
19
+ fm() { awk 'NR>1 && /^---[[:space:]]*$/{exit} {print}' "$1"; } # lines between the opening and closing ---
20
+ field() { printf '%s\n' "$1" | sed -n "s/^$2:[[:space:]]*//p" | head -1 | sed 's/^["'\'']//;s/["'\'']$//;s/[[:space:]]*$//'; }
21
+ # blocked_by is an inline list "[\"002\", \"005\"]"; extract the bare ids (digits) in order.
22
+ blockers() { printf '%s\n' "$1" | sed -n 's/^blocked_by:[[:space:]]*//p' | head -1 | grep -oE '[0-9]+' || true; }
23
+ # derive an id: explicit `id:` field, else the leading NNN of the filename.
24
+ idof() { local i; i="$(field "$1" id)"; [ -n "$i" ] && { printf '%s' "$i"; return; }; basename "$2" | grep -oE '^[0-9]+' || basename "$2" .md; }
25
+
26
+ shopt -s nullglob
27
+ files=("$DIR"/*.md)
28
+ [ ${#files[@]} -eq 0 ] && { echo "frontier: no tickets in '$DIR' (nothing to do)"; exit 0; }
29
+
30
+ # --- pass 1: collect the done ids (newline-delimited; no associative arrays for bash-3.2 portability)
31
+ DONE_IDS=""
32
+ OPEN=0
33
+ for f in "${files[@]}"; do
34
+ meta="$(fm "$f")"; id="$(idof "$meta" "$f")"; st="$(field "$meta" status)"
35
+ if [ "$st" = "done" ]; then DONE_IDS="$DONE_IDS$id
36
+ "; else OPEN=$((OPEN+1)); fi
37
+ done
38
+ is_done() { printf '%s' "$DONE_IDS" | grep -qx "$1"; }
39
+
40
+ # --- pass 2: a ticket is on the frontier when not done and every blocker is done -----------------
41
+ found=0
42
+ for f in "${files[@]}"; do
43
+ meta="$(fm "$f")"; id="$(idof "$meta" "$f")"; st="$(field "$meta" status)"; st="${st:-todo}"
44
+ [ "$st" = "done" ] && continue
45
+ workable=1
46
+ while IFS= read -r b; do
47
+ [ -z "$b" ] && continue
48
+ is_done "$b" || workable=0
49
+ done < <(blockers "$meta")
50
+ if [ "$workable" -eq 1 ]; then
51
+ printf ' ▸ %-5s %-8s %s\n' "$id" "[$st]" "$(field "$meta" title)"
52
+ found=$((found+1))
53
+ fi
54
+ done
55
+
56
+ if [ "$found" -eq 0 ]; then
57
+ # distinguish "all done" from "everything is blocked" — a stuck frontier is a real signal.
58
+ if [ "$OPEN" -eq 0 ]; then echo "frontier: all tickets done ✓"
59
+ else echo "frontier: $OPEN open ticket(s), NONE workable — the frontier is blocked (check for a cycle or an undone blocker)."; fi
60
+ fi