create-pmos 0.34.0 → 0.37.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 (83) hide show
  1. package/bin/create-pmos.js +15 -3
  2. package/package.json +1 -1
  3. package/payload/AGENTS.md +2 -0
  4. package/payload/KIT-VERSION +2 -2
  5. package/payload/okf/core/concepts/agent-harness.md +2 -2
  6. package/payload/okf/core/concepts/design-loop.md +5 -5
  7. package/payload/okf/core/concepts/eval-driven-pm.md +1 -1
  8. package/payload/okf/core/concepts/okr-anti-optimism.md +1 -1
  9. package/payload/okf/core/concepts/okr-tree.md +2 -2
  10. package/payload/okf/core/concepts/output-eval.md +2 -2
  11. package/payload/okf/core/concepts/sdlc-loop.md +1 -1
  12. package/payload/okf/core/concepts/self-refining-harness.md +3 -3
  13. package/payload/okf/core/templates/content-brief-template.md +1 -1
  14. package/payload/okf/core/templates/design-brief-template.md +1 -1
  15. package/payload/okf/core/templates/eval-rubric-template.md +1 -1
  16. package/payload/okf/core/templates/log.md +1 -1
  17. package/payload/okf/core/templates/prd-template.md +1 -1
  18. package/payload/okf/core/templates/spike-brief-template.md +1 -1
  19. package/payload/scripts/frontier.sh +6 -2
  20. package/payload/scripts/gate-initiative.sh +24 -3
  21. package/payload/scripts/metrics.py +20 -4
  22. package/payload/scripts/read-jsonl.js +53 -0
  23. package/payload/scripts/workflow-state.js +144 -35
  24. package/payload/scripts/workflow-sweep.js +39 -22
  25. package/payload/skills/SKILL-FORMAT.md +1 -1
  26. package/payload/skills/copywriting.skill +1 -1
  27. package/payload/skills/correction-signal-derive.skill +1 -1
  28. package/payload/skills/design-brief.skill +4 -4
  29. package/payload/skills/design-reconcile.skill +1 -1
  30. package/payload/skills/discovery.skill +3 -3
  31. package/payload/skills/eval-rubric.skill +4 -4
  32. package/payload/skills/evaluator.skill +1 -1
  33. package/payload/skills/explain-run.skill +1 -1
  34. package/payload/skills/explain-surface.skill +6 -6
  35. package/payload/skills/harness-refine.skill +1 -1
  36. package/payload/skills/ingest-repo.skill +6 -6
  37. package/payload/skills/okr.skill +2 -2
  38. package/payload/skills/pmos-router.skill +8 -8
  39. package/payload/skills/prd.skill +5 -5
  40. package/payload/skills/prototype-grill.skill +8 -8
  41. package/payload/skills/prototype.skill +7 -7
  42. package/payload/skills/skill-creator.skill +1 -1
  43. package/payload/skills/source-to-concept.skill +1 -1
  44. package/payload/skills/ste-term-map.md +69 -0
  45. package/payload/skills/strategic-brief.skill +4 -4
  46. package/payload/skills/technical-writing-ste.skill +176 -0
  47. package/payload/skills-native/copywriting/SKILL.md +1 -1
  48. package/payload/skills-native/correction-signal-derive/SKILL.md +1 -1
  49. package/payload/skills-native/design-brief/SKILL.md +4 -4
  50. package/payload/skills-native/design-reconcile/SKILL.md +1 -1
  51. package/payload/skills-native/discovery/SKILL.md +3 -3
  52. package/payload/skills-native/eval-rubric/SKILL.md +4 -4
  53. package/payload/skills-native/evaluator/SKILL.md +1 -1
  54. package/payload/skills-native/explain-run/SKILL.md +1 -1
  55. package/payload/skills-native/explain-surface/SKILL.md +6 -6
  56. package/payload/skills-native/harness-refine/SKILL.md +1 -1
  57. package/payload/skills-native/ingest-repo/SKILL.md +6 -6
  58. package/payload/skills-native/okr/SKILL.md +2 -2
  59. package/payload/skills-native/pmos-router/SKILL.md +8 -8
  60. package/payload/skills-native/prd/SKILL.md +5 -5
  61. package/payload/skills-native/prototype/SKILL.md +7 -7
  62. package/payload/skills-native/prototype-grill/SKILL.md +8 -8
  63. package/payload/skills-native/skill-creator/SKILL.md +1 -1
  64. package/payload/skills-native/source-to-concept/SKILL.md +1 -1
  65. package/payload/skills-native/strategic-brief/SKILL.md +4 -4
  66. package/payload/skills-native/technical-writing-ste/SKILL.md +178 -0
  67. package/workspace/bin/pmos.js +9 -3
  68. package/workspace/lib/engine/read-jsonl.js +53 -0
  69. package/workspace/lib/engine/workflow-state.js +144 -35
  70. package/workspace/lib/file-mode-parse.js +19 -4
  71. package/workspace/lib/tree-share.js +69 -1
  72. package/workspace/package-lock.json +2 -2
  73. package/workspace/package.json +1 -1
  74. package/workspace/public/pm/board-read.js +38 -0
  75. package/workspace/public/pm/data.js +102 -1
  76. package/workspace/public/pm/modes.js +50 -28
  77. package/workspace/public/pm/panel-detail.js +2 -17
  78. package/workspace/public/pm/panel-initiatives.js +3 -20
  79. package/workspace/public/pm/panel-newsess.js +14 -1
  80. package/workspace/public/pm/panel-tabs.js +53 -14
  81. package/workspace/public/pm/tab-term.js +30 -2
  82. package/workspace/server.js +95 -70
  83. package/workspace/test-run.js +51 -9
@@ -13,7 +13,7 @@ the **interactive agent runtime** — any capable coding agent; heavy judgment b
13
13
  an Edge Function ([D09](/DECISIONS.md)/[D34](/DECISIONS.md), amended 2026-07-23). PMOS-self runs it in
14
14
  Claude Code, but the runtime is not Claude-specific.
15
15
 
16
- > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1
16
+ > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). Level 1
17
17
  > frontmatter above is the trigger. This Level 2 body is the full procedure.
18
18
 
19
19
  ## Non-negotiable stance
@@ -23,7 +23,7 @@ accrues **cognitive debt** and makes the non-delegable Acceptance Gate ([D12](/D
23
23
  *formally* human — the PM as their own [watermelon](/okf/core/concepts/watermelon-flag.md)
24
24
  ([skills-and-understanding](/planning/research/skills-and-understanding-research.md)).
25
25
 
26
- > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)).
26
+ > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)).
27
27
  > Level 1 frontmatter above is the trigger; this Level 2 body is the full procedure.
28
28
 
29
29
  ## Non-negotiable stance
@@ -19,13 +19,13 @@ and it costs more there. A misread at acceptance costs one rejected run; a misre
19
19
  inherited by the contract, the build, the rubric and the evaluator, and **every gate passes over it**.
20
20
  A [watermelon](/okf/core/concepts/watermelon-flag.md) planted at the root.
21
21
 
22
- The gap is sharpest in the [prd skill](/skills/core/prd.skill)'s own grilling rule — *"if a fact can
22
+ The gap is sharpest in the [prd skill](/skills/prd.skill)'s own grilling rule — *"if a fact can
23
23
  be found by exploring the environment, look it up rather than asking."* That rule is right, and its
24
24
  side effect is that **the agent acquires the understanding and the PM does not.**
25
25
 
26
- > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)).
26
+ > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)).
27
27
  > L1 above is the trigger; this L2 body is the procedure.
28
- > **Not [`ingest-repo`](/build-skills/ingest-repo.skill).** That builds an *agent-facing*,
28
+ > **Not [`ingest-repo`](/skills/ingest-repo.skill).** That builds an *agent-facing*,
29
29
  > whole-repo, one-time OKF reference layer — a capability ledger is a lookup table, not a teaching
30
30
  > artifact. This is PM-facing, one region, per-initiative, and pedagogically ordered. Read whatever
31
31
  > layer `ingest-repo` produced as substrate; **treat the code as ground truth.**
@@ -76,8 +76,8 @@ explainer output decayed to *never* by the second run.
76
76
 
77
77
  | Subject shape | Organise by | Reuse |
78
78
  |---|---|---|
79
- | A **user-facing surface** | the surface: views, states, controls, current copy | [design-reconcile](/skills/core/design-reconcile.skill)'s capability ledger §A–D — every control **backed vs. watermelon** — and the product's design system ([D38](/DECISIONS.md), D60(c)) |
80
- | A **subsystem / flow** | execution and logical flow, never file order | the [explain-run](/build-skills/explain-run.skill) convention |
79
+ | A **user-facing surface** | the surface: views, states, controls, current copy | [design-reconcile](/skills/design-reconcile.skill)'s capability ledger §A–D — every control **backed vs. watermelon** — and the product's design system ([D38](/DECISIONS.md), D60(c)) |
80
+ | A **subsystem / flow** | execution and logical flow, never file order | the [explain-run](/skills/explain-run.skill) convention |
81
81
  | A **data model** | entities, their invariants, what a migration must preserve | `ingest-repo`'s per-table `Reference` docs |
82
82
  | A **gate / policy surface** | the decision it makes, its fail-closed behaviour, its escape hatches | the gate's scripts + the decisions locking it |
83
83
  | A **harness surface** (skill, protocol) | trigger → procedure → stance, and what depends on it | SKILL-FORMAT's three levels |
@@ -96,7 +96,7 @@ explainer output decayed to *never* by the second run.
96
96
  - **Constraints** — what will **bite a change here**: coupling, invariants, gates, migrations,
97
97
  backfill, fail-closed behaviour. The cheapest possible place to learn these.
98
98
  - **Open questions** — what you **could not determine from the code**. Genuine unknowns, never
99
- rhetorical ones. This section feeds the [prd skill](/skills/core/prd.skill)'s grilling directly
99
+ rhetorical ones. This section feeds the [prd skill](/skills/prd.skill)'s grilling directly
100
100
  and is the honest alternative to a confident guess.
101
101
  - **Quiz** — five questions (rules below), then a `---` divider, then **Answers**.
102
102
  4. **Force counterfactuals in the BODY, not only in the quiz.** As you walk the region, repeatedly
@@ -83,7 +83,7 @@ field's "agents improving their own tools" loop while staying at the **L3 ceilin
83
83
  - The sibling detect→draft→PR loop: [okf-author](/build-skills/okf-author.skill),
84
84
  [D42](/okf/products/pmos/adr/d42-okf-author-on-demand.md).
85
85
  - The evidence surfaces: recurring friction themes and self-reported context pressure, read from
86
- file-mode state ([discoveries.md](/discoveries.md) and `runs.jsonl`; the hosted
86
+ file-mode state ([discoveries.md](/state/discoveries.md) and `runs.jsonl`; the hosted
87
87
  `v_friction_recurrence` / `v_context_budget` views went with the backend in D66) plus
88
88
  [eval-calibration.md](/planning/evals/eval-calibration.md).
89
89
  - The cadence it serves: [D23](/okf/products/pmos/adr/d23-quarterly-cadence.md) (harness-assumption
@@ -19,7 +19,7 @@ the stack, assuming wrong, producing work the PM must heavily correct — the no
19
19
  ingest-repo goes **code → what the product *is***. It emits a **draft** OKF
20
20
  reference layer + a repo registration and then **stops for PM approval**.
21
21
 
22
- > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). L1
22
+ > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). L1
23
23
  > frontmatter above is the trigger; this L2 body is the full procedure.
24
24
  > **Where it runs:** in **the interactive agent runtime** (any capable coding agent; PMOS-self uses
25
25
  > Claude Code), in the tenant's own conversation, read-only — never a server-side scanner
@@ -35,7 +35,7 @@ reference layer + a repo registration and then **stops for PM approval**.
35
35
  var *names* (`.env.example`, config keys). **Secret-scan the repo content AND git history** (real
36
36
  repos leak keys in committed code/history); if a secret value is found, **never** place it in a doc,
37
37
  a log, or the registry — note only that a leak exists and where, by path, so the PM can rotate it.
38
- - **Default-to-refute on capability** (the [design-reconcile](/skills/core/design-reconcile.skill)
38
+ - **Default-to-refute on capability** (the [design-reconcile](/skills/design-reconcile.skill)
39
39
  stance applied to code): a control/route is **watermelon** until a concrete backend read/write path
40
40
  is found in the code. Unbacked controls land in **§D**, not invented as capability.
41
41
  - **Everything is a DRAFT ([D37](/okf/products/pmos/adr/d37-tenant-okf-db-native.md)/[D12](/okf/products/pmos/adr/d12-three-tier-eval-gate.md)).**
@@ -67,7 +67,7 @@ reference layer + a repo registration and then **stops for PM approval**.
67
67
  **no** value; record only "possible secret at `<path>`" for the PM.
68
68
  4. **Emit the reference layer** — via `save_okf_doc(..., status:'draft', product_slug:<slug>)`,
69
69
  namespaced `products/<slug>/...`, **each body carrying situating context + the exact repo path(s)**
70
- it was derived from (the [source-to-concept](/skills/core/source-to-concept.skill) rule + the
70
+ it was derived from (the [source-to-concept](/skills/source-to-concept.skill) rule + the
71
71
  analyze-product-infra cited-line bar, applied to code). Minimum six kinds:
72
72
 
73
73
  | Doc | OKF `type` | id (under `products/<slug>/`) | derived from |
@@ -80,7 +80,7 @@ reference layer + a repo registration and then **stops for PM approval**.
80
80
  | ADR seed(s) | `ADR` | `adr/<slug>-<n>-<topic>` | README / ADRs / commit history |
81
81
 
82
82
  5. **Bootstrap the per-tenant capability ledger** (the artifact
83
- [design-reconcile](/skills/core/design-reconcile.skill) consumes, [D50](/okf/products/pmos/adr/d50-design-loop-product-scoped.md)
83
+ [design-reconcile](/skills/design-reconcile.skill) consumes, [D50](/okf/products/pmos/adr/d50-design-loop-product-scoped.md)
84
84
  pattern — generic method, per-tenant instance). Classify **every** user-facing control/route into
85
85
  exactly one bucket; each §A/§B entry **names the concrete read/write path** in the code:
86
86
  - **§A — read-backed:** maps to a real backend read (query/endpoint) — cite it.
@@ -113,8 +113,8 @@ reference layer + a repo registration and then **stops for PM approval**.
113
113
  approve them in PR review — the file-mode form of draft→approved. (D37's database-native tenant OKF
114
114
  and its `save_okf_doc` tool were retired by [D66](/DECISIONS.md).)
115
115
  - The ledger method: [design-loop concept](/okf/core/concepts/design-loop.md),
116
- [design-reconcile](/skills/core/design-reconcile.skill), [watermelon-flag](/okf/core/concepts/watermelon-flag.md).
117
- - Extraction discipline: [source-to-concept](/skills/core/source-to-concept.skill).
116
+ [design-reconcile](/skills/design-reconcile.skill), [watermelon-flag](/okf/core/concepts/watermelon-flag.md).
117
+ - Extraction discipline: [source-to-concept](/skills/source-to-concept.skill).
118
118
  - Scan location: [D51](/okf/products/pmos/adr/d51-scan-location.md). There is no longer a central
119
119
  registry to register into — the hosted `product_repos` table and `register_product_repo` went with
120
120
  the backend (D66); the product repo that carries the kit IS the registration.
@@ -17,14 +17,14 @@ measurable key results, structured as a tree that initiatives and agent runs lad
17
17
  operationalizes the [okr-tree](/okf/core/concepts/okr-tree.md) concept.
18
18
 
19
19
  > **Format note:** three-level progressive disclosure
20
- > ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is the
20
+ > ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is the
21
21
  > procedure; rare variants go to Level 3 sub-files.
22
22
 
23
23
  ## When to use vs. not
24
24
 
25
25
  - **Use** to set strategy for a planning period, or to re-anchor an initiative that has drifted from
26
26
  its parent KR.
27
- - **Do not use** to spec a single piece of work — that is the [PRD skill](/skills/core/prd.skill).
27
+ - **Do not use** to spec a single piece of work — that is the [PRD skill](/skills/prd.skill).
28
28
  OKRs sit one level above initiatives.
29
29
 
30
30
  ## Procedure
@@ -20,7 +20,7 @@ whose pieces half-existed). This skill performs the mapping. **It decides nothin
20
20
  lanes and gates that already exist; where it and an authority disagree, the authority wins and the
21
21
  router is the bug (fix it via the weekly harness scan).
22
22
 
23
- > **Format note:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)).
23
+ > **Format note:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)).
24
24
  > 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.
25
25
 
26
26
  ## Step 0 — three checks before any route
@@ -28,7 +28,7 @@ router is the bug (fix it via the weekly harness scan).
28
28
  1. **Sharpness (the fog/ticket test):** *can the PM state the question or idea precisely now — not
29
29
  answer it, state it?* If not, it is **fog**: not ready for intake. Name what would sharpen it
30
30
  (a conversation, a datum, a spike) and stop — do not open an initiative to hold fog.
31
- 2. **Prior rejection:** check [planning/out-of-scope/](/planning/out-of-scope/README.md) for the
31
+ 2. **Prior rejection:** check [planning/out-of-scope/](/README.md) for the
32
32
  concept. If a file exists, **read it first** and surface it to the PM — the concept returns only
33
33
  if the PM overrides the recorded reasoning, and the file is updated either way.
34
34
  3. **The specimen test — ASK it, do not wait to be told** (D60 as amended 2026-07-24):
@@ -48,7 +48,7 @@ router is the bug (fix it via the weekly harness scan).
48
48
 
49
49
  > **Would specifying this honestly require reading code that already exists?**
50
50
 
51
- Yes → an [explain-surface](/build-skills/explain-surface.skill) pass runs **first**, before the
51
+ Yes → an [explain-surface](/skills/explain-surface.skill) pass runs **first**, before the
52
52
  spike brief / prototype brief / PRD is authored, in a fresh context. Greenfield → skip it. This is
53
53
  standard, not optional: the PRD skill's own rule ("look it up rather than asking") means the
54
54
  *agent* acquires the understanding and the PM does not, and a spec built on facts the PM never saw
@@ -58,12 +58,12 @@ router is the bug (fix it via the weekly harness scan).
58
58
 
59
59
  | The PM says… | Route | Lane / artifacts / next skill | Gates to expect |
60
60
  |---|---|---|---|
61
- | "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/core/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) |
62
- | A **new bet** — new product/capability/direction whose *whether* is unargued | **Offer the strategic brief** (recommended, skippable — D61) | [strategic-brief skill](/skills/core/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) |
63
- | A **validated direction or known feature** (incl. a promoted prototype) | **Feature lane** | `type: feature`; PRD + eval rubric ([prd](/skills/core/prd.skill) + [eval-rubric](/skills/core/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/core/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 |
64
- | "**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/core/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) |
61
+ | "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) |
62
+ | 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) |
63
+ | 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 |
64
+ | "**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) |
65
65
  | "**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) |
66
- | 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/domains/copywriting.skill). Copy for a prototype rides the prototype instead (D60) | Initiative Gate (content brief) |
66
+ | 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) |
67
67
  | **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) |
68
68
 
69
69
  **Every route** still takes the universal steps: anchored initiative row (`create_initiative`),
@@ -18,7 +18,7 @@ strategy, so a generator agent and the PM share one definition of the work befor
18
18
  agreed.
19
19
 
20
20
  > **Format note:** this skill follows three-level progressive disclosure
21
- > ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is Level 2;
21
+ > ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is Level 2;
22
22
  > rare variants are pushed to Level 3 sub-files referenced by name.
23
23
 
24
24
  ## When to use vs. not
@@ -27,13 +27,13 @@ agreed.
27
27
  - **Do not use** to make the strategic case for *whether* to do the initiative — that is the
28
28
  `strategic-brief` skill. The PRD assumes the initiative is already chosen.
29
29
  - **Do not use** to define how output is judged — that is the
30
- [eval-rubric skill](/skills/core/eval-rubric.skill). PRD and rubric are authored together (see
30
+ [eval-rubric skill](/skills/eval-rubric.skill). PRD and rubric are authored together (see
31
31
  [eval-driven-pm](/okf/core/concepts/eval-driven-pm.md)) but are separate artifacts.
32
32
 
33
33
  ## Procedure
34
34
 
35
35
  0a. **Existing surface? Understand it first — before grilling.** If specifying this honestly
36
- requires reading code that already exists, an [explain-surface](/build-skills/explain-surface.skill)
36
+ requires reading code that already exists, an [explain-surface](/skills/explain-surface.skill)
37
37
  pass runs on that region **first**, in a fresh context and **not by you**. Its *Open questions*
38
38
  section is a declared input to the grilling below: those are the things that could not be
39
39
  determined from the code, and they must be resolved with the PM or carried explicitly into the
@@ -64,7 +64,7 @@ agreed.
64
64
  5. **State success as outcomes, not output.** Success criteria describe a change in the world tied
65
65
  to the anchor — the parent KR, or the declared budget's purpose (D59) — not a list of artifacts
66
66
  produced.
67
- 6. **Pair with a rubric.** Flag that the [eval-rubric](/skills/core/eval-rubric.skill) must be
67
+ 6. **Pair with a rubric.** Flag that the [eval-rubric](/skills/eval-rubric.skill) must be
68
68
  authored before the build starts — the eval is written first.
69
69
  7. **Write for durability.** The PRD (and the contract derived from it) waits while work is
70
70
  scheduled, so write what stays true: name **interfaces, types, and behavioral contracts — never
@@ -113,5 +113,5 @@ its situating sentence (D58); the eval rubric is queued to be written first.
113
113
  (author on first need).
114
114
  - Spike / discovery work where the deliverable is a learning, not a feature, is **not a PRD
115
115
  case** — take the discovery lane ([D56](/okf/products/pmos/adr/d56-initiative-lanes.md)):
116
- [discovery skill](/skills/core/discovery.skill) +
116
+ [discovery skill](/skills/discovery.skill) +
117
117
  [spike-brief template](/okf/core/templates/spike-brief-template.md).
@@ -16,7 +16,7 @@ The [D60](/okf/products/pmos/adr/d60-prototype-loop.md) lane skill. The division
16
16
  point: **the PM briefs; the agent builds the specimen.** The PM should never have to author a design
17
17
  system, a convention set, or a prototype to validate an idea.
18
18
 
19
- > **Format note:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)).
19
+ > **Format note:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)).
20
20
  > Level 1 above is the trigger; this body is Level 2.
21
21
  > **Scope note (2026-07-24 amendment):** this lane is **no longer gated on the work being a user
22
22
  > interface**. D60's mechanism — *make it examinable, then grill it, before committing to a spec* —
@@ -43,7 +43,7 @@ system, a convention set, or a prototype to validate an idea.
43
43
  [design loop](/okf/core/concepts/design-loop.md): design-brief → design → reconcile, open to new
44
44
  surfaces per D60's D48 amendment).
45
45
  - **Do not use** when you hold a *question* rather than a *candidate* — that is the
46
- [discovery lane](/skills/core/discovery.skill):
46
+ [discovery lane](/skills/discovery.skill):
47
47
 
48
48
  | | You hold | Deliverable | Closes on |
49
49
  |---|---|---|---|
@@ -59,7 +59,7 @@ system, a convention set, or a prototype to validate an idea.
59
59
  1. **Open the lane.** `create_initiative({id, title, parent_kr, type:'prototype', stage:'intake'})` —
60
60
  anchored like all work (D21/D59). Branch `initiative/<id>`.
61
61
  1b. **Improving something that already exists? Understand it first.** If the specimen will replace
62
- or alter an existing surface, run an [explain-surface](/build-skills/explain-surface.skill) pass on
62
+ or alter an existing surface, run an [explain-surface](/skills/explain-surface.skill) pass on
63
63
  it — fresh context, **before** the brief. Divergent options against a surface nobody has
64
64
  characterised diverge from a guess, and the PM cannot grill them honestly. Brand-new → skip.
65
65
  2. **Take the quick brief.** The PM fills the
@@ -75,7 +75,7 @@ system, a convention set, or a prototype to validate an idea.
75
75
  | Class | Its conventions live in |
76
76
  |---|---|
77
77
  | A user interface | the product's **design system** — tokens, type scale, components (PMOS's own app: [D38](/DECISIONS.md); tenants checked at onboarding) |
78
- | A skill | [SKILL-FORMAT](/skills/core/SKILL-FORMAT.md) — three-level progressive disclosure |
78
+ | A skill | [SKILL-FORMAT](/skills/SKILL-FORMAT.md) — three-level progressive disclosure |
79
79
  | A tool or API | [D19](/okf/products/pmos/adr/d19-aci-design.md)'s ACI principle |
80
80
  | A knowledge doc | the OKF spec + [frontmatter-format](/okf/core/concepts/frontmatter-format.md) |
81
81
  | A schema | the repo's migration + RLS conventions |
@@ -107,12 +107,12 @@ system, a convention set, or a prototype to validate an idea.
107
107
  5. **Produce divergent specimens** into `prototype/<id>/` — low-fidelity, self-contained, examinable
108
108
  (whatever renders or reads fastest). **2–3 genuinely different directions, not one safe one with
109
109
  variants** — divergence is the point in any medium. **Real draft content, never placeholder**
110
- (D60: copy rides the prototype — [copywriting.skill](/skills/domains/copywriting.skill) craft
110
+ (D60: copy rides the prototype — [copywriting.skill](/skills/copywriting.skill) craft
111
111
  applies in-loop; claim-sourcing waits for the content lane at production). The non-visual analogue
112
112
  is the same rule: real inputs and real outputs, because fake ones hide exactly the friction the
113
113
  specimen exists to surface. Respect the accessibility floors even at low fidelity.
114
114
  6. **Grill — dialogue, never a score. Dispatch
115
- [`prototype-grill`](/build-skills/prototype-grill.skill).** A craft-grade critic (fresh context,
115
+ [`prototype-grill`](/skills/prototype-grill.skill).** A craft-grade critic (fresh context,
116
116
  default-to-refute stance, the class's craft loaded) interrogates each specimen: *why this
117
117
  structure? what job does the focal element serve? what would the best practitioner in this class
118
118
  say is wrong? what was NOT tried?* It writes `prototype/<id>/grilling.md`. Sharpen the specimens
@@ -133,7 +133,7 @@ system, a convention set, or a prototype to validate an idea.
133
133
  work has a surface, then runs inside that initiative's Build.
134
134
  - **iterate** → back to step 5 with the PM's reaction folded in.
135
135
  - **kill** → record one honest line on the initiative, **file the concept into
136
- [planning/out-of-scope/](/planning/out-of-scope/README.md)** (decision, reasoning, what would
136
+ [planning/out-of-scope/](/README.md)** (decision, reasoning, what would
137
137
  reopen it) so it is not re-prototyped from scratch, and close. A cheap kill is this lane
138
138
  *succeeding*.
139
139
  8. **Log.** `log_agent_run` with the disposition; friction to discoveries.md (`#friction`).
@@ -13,16 +13,16 @@ metadata:
13
13
  # prototype-grill — The second party in D60's dialogue
14
14
 
15
15
  [D60](/okf/products/pmos/adr/d60-prototype-loop.md) clause (d) makes leg A **grilled as dialogue,
16
- never scored**, and [`prototype.skill`](/skills/core/prototype.skill) step 6 has always described the
16
+ never scored**, and [`prototype.skill`](/skills/prototype.skill) step 6 has always described the
17
17
  critic correctly. What it never had was a way to *dispatch* one — so the cheapest path was to grill
18
18
  your own specimens, and **a dialogue with one party is a monologue with extra steps**. This skill is
19
- step 6 made dispatchable, the way [`evaluator`](/build-skills/evaluator.skill) made the Review Gate
20
- first-class and [`explain-surface`](/build-skills/explain-surface.skill) made the understanding pass
19
+ step 6 made dispatchable, the way [`evaluator`](/skills/evaluator.skill) made the Review Gate
20
+ first-class and [`explain-surface`](/skills/explain-surface.skill) made the understanding pass
21
21
  standard.
22
22
 
23
- > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)).
23
+ > **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)).
24
24
  > L1 above is the trigger; this L2 body is the procedure.
25
- > **Not [`evaluator`](/build-skills/evaluator.skill).** That one *scores a finished diff against a
25
+ > **Not [`evaluator`](/skills/evaluator.skill).** That one *scores a finished diff against a
26
26
  > rubric* and writes a verdict. This one **never scores anything** and writes no verdict. They share
27
27
  > only the adversarial stance. Confusing them is the single most likely way to violate D60 here.
28
28
 
@@ -51,7 +51,7 @@ standard.
51
51
  - **Use** at `prototype.skill` **step 6** — specimens exist in `prototype/<id>/`, the PM has not yet
52
52
  disposed. Also on **iterate**: a second round earns a second grilling, not a re-read of the first.
53
53
  - **Do not use** to compare finished implementations (that is `evaluator`), to judge a design against
54
- a design system (that is [`design-reconcile`](/skills/core/design-reconcile.skill)), or on a lane
54
+ a design system (that is [`design-reconcile`](/skills/design-reconcile.skill)), or on a lane
55
55
  that is not `prototype`. No other lane is ungraded, so this skill's no-score rule would be wrong
56
56
  everywhere else.
57
57
 
@@ -60,7 +60,7 @@ standard.
60
60
  1. **Load the ground.** The initiative record, the quick brief at `prd_path` — specifically **the
61
61
  judgement being exercised** and **the specimen format**, which are what the grilling hangs on —
62
62
  and every specimen in `prototype/<id>/`. Then load the **artifact class's craft**: the design
63
- system for UI, [SKILL-FORMAT](/skills/core/SKILL-FORMAT.md) for a skill,
63
+ system for UI, [SKILL-FORMAT](/skills/SKILL-FORMAT.md) for a skill,
64
64
  [D19](/okf/products/pmos/adr/d19-aci-design.md)'s ACI principle for a tool or API, the OKF spec for
65
65
  a knowledge doc, the migration/RLS conventions for a schema. **A critic without the class's craft
66
66
  produces taste, not a grilling.**
@@ -96,7 +96,7 @@ standard.
96
96
  not a griller pre-empting it. Volunteering it is the violation.
97
97
  8. **Log.** Append the run (`log_agent_run`; file-mode `planning/runs/agent-runs.jsonl`) with
98
98
  `self_eval` recorded as **unscored by design**, so the absence reads as deliberate rather than as
99
- a skipped gate. Friction to [discoveries.md](/discoveries.md) tagged `#friction`.
99
+ a skipped gate. Friction to [discoveries.md](/state/discoveries.md) tagged `#friction`.
100
100
 
101
101
  ## Hard rules
102
102
 
@@ -12,7 +12,7 @@ metadata:
12
12
  (for AI-draft) spawns a local session to sharpen it. This skill is that session's procedure. It exists
13
13
  because a scheduler skill runs **unattended on a cadence** — a body that is vague or mis-grounded fails
14
14
  silently, at 2am, into a corrupted queue. The authority for body quality is
15
- [SKILL-FORMAT](/skills/core/SKILL-FORMAT.md); do not restate its rules here, apply them.
15
+ [SKILL-FORMAT](/skills/SKILL-FORMAT.md); do not restate its rules here, apply them.
16
16
 
17
17
  A workspace `.skill` differs from a `skills/core/` skill in one way: it keeps **runtime frontmatter**
18
18
  the scheduler reads (`label`, `run: agent`, `agent: claude`, `output:` list = the consistency contract).
@@ -22,7 +22,7 @@ into a curated OKF concept in `core/concepts/` or `products/<product_slug>/`, pr
22
22
  and conforming to the [OKF spec](/okf/core/concepts/okf-governance.md).
23
23
 
24
24
  > **Format note:** three-level progressive disclosure
25
- > ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1 is the trigger; this body is the spec of
25
+ > ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). Level 1 is the trigger; this body is the spec of
26
26
  > the procedure; Level 3 holds rare extraction variants.
27
27
 
28
28
  ## Intended procedure (specification)
@@ -13,18 +13,18 @@ metadata:
13
13
  # strategic-brief — Make the Strategic Case
14
14
 
15
15
  Produces a strategic brief: the argument for *whether* an initiative should exist, made **before** a
16
- [PRD](/skills/core/prd.skill) specs *what and why in detail*. The PRD assumes the bet is already
16
+ [PRD](/skills/prd.skill) specs *what and why in detail*. The PRD assumes the bet is already
17
17
  chosen; the brief is where that choice is argued. **Activated by [D61](/DECISIONS.md)** (2026-07-21)
18
18
  after being spec-only since P0 — its own activation criteria (OKRs on a regular cadence; initiative
19
19
  volume where informal prioritization strains) are now met.
20
20
 
21
21
  > **Format note:** three-level progressive disclosure
22
- > ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is Level 2.
22
+ > ([SKILL-FORMAT](/skills/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is Level 2.
23
23
 
24
24
  ## When to use vs. not (D61 — optional, router-recommended)
25
25
 
26
26
  - **Use** when the work is a **new bet** — a new product, capability, or direction whose "whether"
27
- has not been argued — typically on the [pmos-router](/skills/core/pmos-router.skill)'s
27
+ has not been argued — typically on the [pmos-router](/skills/pmos-router.skill)'s
28
28
  recommendation at intake. The PM may always demand one.
29
29
  - **Skippable by design.** The brief is never a gate. Skipping it on a new bet is the PM's call;
30
30
  the router recommends, it does not require. (Mandatory briefs recreate the ceremony-pressure
@@ -51,7 +51,7 @@ volume where informal prioritization strains) are now met.
51
51
 
52
52
  - `planning/briefs/<initiative-id>-brief.md` — operational instance, never in the OKF bundle.
53
53
  - An accepted brief becomes the PRD's parent rationale (the PRD links it). A **no-go** files the
54
- concept into [planning/out-of-scope/](/planning/out-of-scope/README.md) so it is not re-litigated.
54
+ concept into [planning/out-of-scope/](/README.md) so it is not re-litigated.
55
55
 
56
56
  ## Level 3 sub-cases
57
57
 
@@ -0,0 +1,178 @@
1
+ ---
2
+ name: technical-writing-ste
3
+ description: Apply the PMOS-STE writing profile — the ASD-STE100 writing rules, scoped by register — when you write or rewrite text a reader must act on: a skill body, a gate or CI failure message, an MCP tool description, workspace copy, an explainer, an OKF concept, a README. Do NOT use it on argumentative text (ADRs, PRD rationale, briefs, eval verdicts, PR bodies), where graded confidence is the payload and the profile deliberately does not apply.
4
+ license: MIT
5
+ metadata:
6
+ pmos-version: 1.0.0
7
+ pmos-owner: wawan
8
+ pmos-risk: low
9
+ pmos-category: domain
10
+ pmos-scope: read:okf, write:any-prose
11
+ ---
12
+
13
+ # technical-writing-ste — Write text a reader can act on once
14
+
15
+ PMOS's output is read under load: an agent parsing a skill body, a PM reading a red CI line. This
16
+ skill carries the **PMOS-STE profile** — the [ASD-STE100](/okf/core/concepts/simplified-technical-english.md)
17
+ writing rules, bound by **register** instead of repo-wide. The scoping is the whole design. That
18
+ concept's *one-meaning trade* section is why: applied uniformly, STE deletes the graded confidence
19
+ that eval verdicts and decision records are made of.
20
+
21
+ > **Format:** three-level progressive disclosure (`SKILL-FORMAT.md`).
22
+ > **This file demonstrates the profile it defines.** The procedure below is Class A. The rationale is
23
+ > Class B. Read the two registers against each other — that contrast teaches faster than the rules do.
24
+
25
+ ## Two things to know before you apply it
26
+
27
+ **PMOS adopts the writing rules, not the vocabulary control.** ASD owns the ~900-word dictionary and
28
+ grants free reproduction only to named aerospace and defense categories. PMOS is in none of them, so
29
+ the word list is neither vendored nor checkable here. **Never write that PMOS output is
30
+ "STE-compliant."** Write "PMOS-STE" and mean the writing rules only. The stronger claim is false.
31
+
32
+ **Nothing mechanical enforces this profile.** No lint runs, and no gate reads it. An advisory
33
+ `ste_lint.py` is a named follow-on, not a shipped thing. The only mechanism is that you read this and
34
+ comply, and the only check is a human at the Acceptance Gate. Treat availability as availability. A
35
+ standard that reads as enforced when it is not is a [watermelon](/okf/core/concepts/watermelon-flag.md).
36
+
37
+ ## Step 1 — Classify the text. Do this first.
38
+
39
+ Ask what the reader must do with it. Derive the class from the path, not from feel.
40
+
41
+ | Class | What the reader must do | Where it lives |
42
+ |---|---|---|
43
+ | **A — instructional** | **Act**, correctly, on one reading | `skills/**` · playbooks and runbooks · gate and CI failure strings · UI copy and microcopy · tool descriptions · template usage notes |
44
+ | **B — descriptive** | **Understand**, not obey | `okf/**` concepts and references · explainers · `**/README.md` · design and data-model docs |
45
+ | **C — argumentative** | **Weigh a judgement under uncertainty** | ADRs and decision records · `planning/prd/**` · briefs · the discoveries log · eval verdicts · PR bodies |
46
+
47
+ The three classes are the rule. **The paths are your repo's, so write them down once.** In PMOS they
48
+ also cover `build-skills/**` and `okf/core/playbooks/**` (A), `planning/explainers/**` and
49
+ `planning/design/**` (B), and `pm-decisions.md` and `discoveries.md` (C). In a product repo they
50
+ cover your CLI output, your error strings and your component copy (A), and your architecture notes
51
+ (B). When a path is not on your list, ask the question in column two and add the answer to the list.
52
+
53
+ Two boundary rules. **Text the PM wrote is Class C**, whatever it is about. And the profile binds
54
+ **new and modified text only** — never rewrite an existing corpus to satisfy it.
55
+
56
+ **Done when:** you can name the class and the row that put it there.
57
+
58
+ ## Step 2 — If the text is Class C, stop here.
59
+
60
+ Class C keeps four things and nothing else:
61
+
62
+ - Short sentences, where they fit.
63
+ - One topic per sentence.
64
+ - Active voice by default.
65
+ - **One term per concept** (1.11, 9.4). This is the one hard rule that binds in every class.
66
+
67
+ Then write freely.
68
+
69
+ **Why this exemption exists — read it, because the reason is the rule.** Class C's payload *is* the
70
+ hedge. "Confidence: medium", "probably", "this should be re-run before the number is quoted" — these
71
+ carry the actual content. STE has no approved way to write them: its recurring-errors list replaces
72
+ `should` and `may` with `MUST`. Apply it here and a recommendation becomes an obligation, an estimate
73
+ becomes a certainty. The text ends up **more certain than its author was**. That inverts the
74
+ [anti-optimism](/okf/core/concepts/okr-anti-optimism.md) stance PMOS reports by. The exemption is not
75
+ leniency for hard-to-constrain prose. It is the profile refusing to damage its own repo.
76
+
77
+ **Done when:** you have applied the four principles and stopped.
78
+
79
+ ## Step 3 — For Class A, write to act on.
80
+
81
+ Apply these. Rule numbers point into the standard.
82
+
83
+ - **≤20 words per sentence** (5.1). Count under 8.4–8.7. Each of these counts as **one word**:
84
+ - a number, or a number with its unit
85
+ - an abbreviation, or an alphanumeric identifier
86
+ - a parenthetical
87
+ - a hyphenated word
88
+ - **One instruction per sentence** (5.2), unless the actions happen at the same time.
89
+ - **Imperative form** (5.3). Say "Run the gate", not "the gate should be run".
90
+ - **Condition first, then a comma, then the command** (5.4). "If the branch is `claude/*`, name the
91
+ initiative in the PR body."
92
+ - **Notes inform. Notes never instruct** (5.5).
93
+ - **Active voice** (3.6). Simple verb forms only (3.2). Keep `-ing` inside a technical noun (3.5).
94
+ - **Noun clusters: three words maximum** (2.1).
95
+ - **Keep every word** (4.2). No contractions, no dropped articles.
96
+ - **Vertical lists for anything complex** (4.3).
97
+ - **No semicolons** (8.1).
98
+ - **Every pronoun resolves to one antecedent** (GR-3, GR-4). This one earns its place in agent
99
+ instructions: an unresolvable "it" is where a run silently guesses.
100
+ - **Inclusive language** (GR-7). Use they/them when a person's pronouns are not stated.
101
+ - **Warnings carry three parts** (7.1–7.3): the risk level, the command, the consequence. Use this for
102
+ every destructive or irreversible action.
103
+ - **One term per concept** (1.11, 9.4). Pick the term, then use only that term.
104
+
105
+ **Done when:** every sentence is ≤20 words, every instruction stands alone, and every pronoun resolves.
106
+
107
+ ### A worked pair — a real gate message
108
+
109
+ From PMOS's own workflow gate (`scripts/workflow-state.js`), the `how` line for rule O4:
110
+
111
+ > **Before:** `run build-skills/explain-surface.skill in a FRESH context (not the agent that will
112
+ > write the spec), then set explainer_path:`
113
+ >
114
+ > **After:** `Run build-skills/explain-surface.skill in a fresh context. Do not use the agent that
115
+ > will write the spec. Then set explainer_path.`
116
+
117
+ One command with a prohibition buried in a parenthetical becomes three short commands. The
118
+ prohibition is now impossible to skim past. Nothing was lost.
119
+
120
+ ## Step 4 — For Class B, write to be understood.
121
+
122
+ - **≤25 words per sentence** (6.3), counted the same way.
123
+ - **One topic per paragraph** (6.5). **Six sentences maximum** (6.6).
124
+ - **Give information gradually** (6.1). Let key words carry the structure (6.2).
125
+ - Carried over from Class A, unchanged:
126
+ - **active voice** (3.6) and **≤3-word noun clusters** (2.1)
127
+ - **no semicolons** (8.1) and **keep every word** (4.2)
128
+ - **pronouns resolve** (GR-3, GR-4) and **inclusive language** (GR-7)
129
+ - **one term per concept** (1.11, 9.4)
130
+ - **The imperative stays out.** Description is not instruction (section 6).
131
+
132
+ **Done when:** no sentence passes 25 words, no paragraph holds two topics or seven sentences.
133
+
134
+ ### A worked pair — a real concept sentence
135
+
136
+ From [eval-driven-pm](/okf/core/concepts/eval-driven-pm.md) — 42 words, one semicolon, a nested aside:
137
+
138
+ > **Before:** "The Quality and Review gates check the work against the pre-written rubric
139
+ > mechanically; the PM's scarce attention is spent on the one question the rubric cannot answer —
140
+ > *is this the right thing?* — and on whether the rubric itself was right."
141
+ >
142
+ > **After:** "The Quality and Review gates check the work against the pre-written rubric
143
+ > mechanically. The rubric cannot answer one question: is this the right thing? The PM spends their
144
+ > scarce attention there, and on whether the rubric itself was right."
145
+
146
+ 14, 13 and 18 words. The passive is gone. **State the trade honestly:** the original's aside had more
147
+ bite, and the rewrite is flatter. For reference text that price is worth paying. For an argument it is
148
+ not — which is why Class C exists.
149
+
150
+ ## Step 5 — Check the register held.
151
+
152
+ Read the finished text once more and ask the one question the word counts cannot answer:
153
+
154
+ > **Did an instruction leak into descriptive text, or a hedge get flattened out of an argument?**
155
+
156
+ Two shapes answer yes. A Class B passage has turned imperative. Or a Class C sentence's "probably"
157
+ has become "must". Either one is the failure this profile exists to prevent. Fix it there.
158
+
159
+ **Done when:** the text reads in the register its class names.
160
+
161
+ ## Quality bar
162
+
163
+ Before you call the text done, confirm each of these:
164
+
165
+ - The class is derived from the table, not felt.
166
+ - Class A sentences are ≤20 words. Class B sentences are ≤25. Both counted under 8.4–8.7.
167
+ - One term per concept, throughout.
168
+ - Every pronoun resolves to one antecedent.
169
+ - Class C kept its hedges.
170
+ - Nothing claims "STE compliance".
171
+
172
+ ## Level 3 sub-cases
173
+
174
+ - `ste-term-map.md` — the one-term-per-concept register (1.11,
175
+ 9.4). Read it when you name a concept in **any** register, including Class C. It holds the known
176
+ drift with its evidence, and it proposes canonical terms rather than ruling on them.
177
+ - `ste-safety-instructions.md` — not yet written. Author it on first need, mapping section 7 onto
178
+ destructive-action warnings and confirmation copy.
@@ -357,7 +357,9 @@ async function stop() {
357
357
 
358
358
  function doctor() {
359
359
  const r = spawnSync(process.execPath, [path.join(WS, 'doctor.js')], { stdio: 'inherit' });
360
- return r.status || 0;
360
+ // A child that never ran (or died to a signal) has status null — `null || 0` reported success.
361
+ if (r.error) { say('✗ could not run doctor — ' + r.error.message); return 1; }
362
+ return r.status === null ? 1 : r.status;
361
363
  }
362
364
 
363
365
  (async () => {
@@ -372,8 +374,12 @@ function doctor() {
372
374
  // Escape hatch: pull the latest bundled app and force-reinstall over this global copy. Delegates
373
375
  // to the scaffolder (which owns the install path) rather than reinstalling itself in place.
374
376
  const npx = process.platform === 'win32' ? 'npx.cmd' : 'npx';
375
- code = spawnSync(npx, ['-y', 'create-pmos@latest', 'workspace', '--reinstall', process.cwd()],
376
- { stdio: 'inherit', shell: process.platform === 'win32' }).status || 0;
377
+ const r = spawnSync(npx, ['-y', 'create-pmos@latest', 'workspace', '--reinstall', process.cwd()],
378
+ { stdio: 'inherit', shell: process.platform === 'win32' });
379
+ // `npx` missing from PATH left status null — `null || 0` reported a successful upgrade that
380
+ // reinstalled nothing. A launch failure and a signal-killed child both exit nonzero, and say so.
381
+ if (r.error) { say('✗ could not run ' + npx + ' — ' + r.error.message); code = 1; }
382
+ else code = r.status === null ? 1 : r.status;
377
383
  } else if (cmd === 'help' || cmd === '--help' || cmd === '-h') {
378
384
  say('usage: pmos [<path>|status|ls|stop|doctor|upgrade]');
379
385
  say(' pmos open the current repo as a workspace (starts the server if needed)');