create-pmos 0.1.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.
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/bin/create-pmos.js +103 -0
- package/package.json +26 -0
- package/payload/AGENTS.md +83 -0
- package/payload/KIT-VERSION +3 -0
- package/payload/README.md +56 -0
- package/payload/okf/core/concepts/agent-harness.md +83 -0
- package/payload/okf/core/concepts/control-plane.md +61 -0
- package/payload/okf/core/concepts/design-loop.md +117 -0
- package/payload/okf/core/concepts/eval-driven-pm.md +71 -0
- package/payload/okf/core/concepts/index.md +17 -0
- package/payload/okf/core/concepts/log.md +6 -0
- package/payload/okf/core/concepts/okf-governance.md +159 -0
- package/payload/okf/core/concepts/okr-anti-optimism.md +54 -0
- package/payload/okf/core/concepts/okr-tree.md +67 -0
- package/payload/okf/core/concepts/output-eval.md +81 -0
- package/payload/okf/core/concepts/pm-identity.md +68 -0
- package/payload/okf/core/concepts/product-slug-convention.md +64 -0
- package/payload/okf/core/concepts/sdlc-loop.md +69 -0
- package/payload/okf/core/concepts/self-refining-harness.md +77 -0
- package/payload/okf/core/concepts/watermelon-flag.md +66 -0
- package/payload/okf/core/templates/design-brief-template.md +84 -0
- package/payload/okf/core/templates/eval-rubric-template.md +95 -0
- package/payload/okf/core/templates/index.md +8 -0
- package/payload/okf/core/templates/log.md +9 -0
- package/payload/okf/core/templates/prd-template.md +75 -0
- package/payload/okf/product/.gitkeep +0 -0
- package/payload/planning/evals/agent-run-eval-rubric.md +46 -0
- package/payload/planning/evals/check_rubrics.py +108 -0
- package/payload/planning/evals/eval-calibration.md +4 -0
- package/payload/planning/okrs/.gitkeep +0 -0
- package/payload/planning/prd/.gitkeep +0 -0
- package/payload/scripts/gate-initiative.sh +56 -0
- package/payload/scripts/kit-update.sh +16 -0
- package/payload/scripts/metrics.py +99 -0
- package/payload/skills/SKILL-FORMAT.md +89 -0
- package/payload/skills/eval-rubric.skill +122 -0
- package/payload/skills/evaluator.skill +82 -0
- package/payload/skills/ingest-repo.skill +117 -0
- package/payload/skills/okr.skill +68 -0
- package/payload/skills/prd.skill +80 -0
- package/payload/state/acceptances.jsonl +0 -0
- package/payload/state/discoveries.md +2 -0
- package/payload/state/evals.jsonl +0 -0
- package/payload/state/initiatives/.gitkeep +0 -0
- package/payload/state/runs.jsonl +0 -0
- package/payload/templates/agent-run-eval-rubric.md +46 -0
- package/payload/templates/pmos-gate.yml +29 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Concept
|
|
3
|
+
title: The SDLC Loop
|
|
4
|
+
description: The closed agent-driven software development lifecycle PMOS orchestrates — spec, contract, build, evaluate, accept, learn — and how it loops.
|
|
5
|
+
tags: [sdlc, loop, orchestration, lifecycle]
|
|
6
|
+
timestamp: 2026-06-28
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# The SDLC Loop
|
|
10
|
+
|
|
11
|
+
**Situating context:** PMOS is a control plane for an AI-driven SDLC, so it needs one shared picture
|
|
12
|
+
of the loop it controls. This concept defines that loop and names each stage, so skills, gates, and
|
|
13
|
+
AGENTS.md all refer to the same lifecycle. It informs how initiatives flow from
|
|
14
|
+
[OKR](/okf/core/concepts/okr-tree.md) to accepted work and back into knowledge.
|
|
15
|
+
|
|
16
|
+
## The loop
|
|
17
|
+
|
|
18
|
+
PMOS drives a closed lifecycle. Each turn of the loop moves one initiative through six stages:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌──────────────────────────────────────────────────┐
|
|
22
|
+
▼ │
|
|
23
|
+
1. SPEC ──► 2. CONTRACT ──► 3. BUILD ──► 4. EVALUATE ──► 5. ACCEPT ──► 6. LEARN
|
|
24
|
+
(PRD) (pre-run (agent (3-tier (PM, (OKF +
|
|
25
|
+
contract) run) gate) Acceptance discoveries)
|
|
26
|
+
Gate)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
1. **Spec** — the initiative gets a PRD via the [prd skill](/skills/core/prd.skill). The PRD says
|
|
30
|
+
what to build and why, anchored to a KR in the [OKR tree](/okf/core/concepts/okr-tree.md).
|
|
31
|
+
2. **Contract** — generator and evaluator agree a **pre-run contract**: testable done-criteria,
|
|
32
|
+
before any work starts. The PM approves it. (P0: temp file + PM approval; P1+:
|
|
33
|
+
`agent_runs.pre_run_contract`.)
|
|
34
|
+
3. **Build** — the agent executes the run against the contract. One execution = one agent run.
|
|
35
|
+
4. **Evaluate** — output passes through the [three-tier eval gate](/okf/core/concepts/output-eval.md):
|
|
36
|
+
Quality Gate → Review Gate → Acceptance Gate.
|
|
37
|
+
5. **Accept** — the PM clears the **Acceptance Gate**: is this the *right* thing, strategically?
|
|
38
|
+
This is a human decision, not a rubric re-check.
|
|
39
|
+
6. **Learn** — outcomes and friction are written back: agent run logged, discoveries captured,
|
|
40
|
+
durable knowledge promoted into [OKF](/okf/core/concepts/okf-governance.md). The loop closes and
|
|
41
|
+
the next initiative begins with more context than the last.
|
|
42
|
+
|
|
43
|
+
## Why it is a loop, not a pipeline
|
|
44
|
+
|
|
45
|
+
The sixth stage feeds the first. Each turn deposits knowledge (concepts, calibration data, friction
|
|
46
|
+
notes) that sharpens the next spec and tightens the next contract. A pipeline ends; this loop
|
|
47
|
+
compounds. The compounding is the point — it is how the harness gets better without the model
|
|
48
|
+
changing.
|
|
49
|
+
|
|
50
|
+
## The PM sits on the loop, not inside every step
|
|
51
|
+
|
|
52
|
+
PMOS automates stages 1–4 and 6 with agents; the PM's irreducible position is **stage 5**, the
|
|
53
|
+
Acceptance Gate. As autonomy rises (L2 → L3), more of the loop runs without per-step PM
|
|
54
|
+
intervention, but acceptance authority never leaves the human. Designing the loop so the PM can
|
|
55
|
+
always re-enter at stage 5 is what keeps autonomy safe.
|
|
56
|
+
|
|
57
|
+
## Failure mode the loop defends against
|
|
58
|
+
|
|
59
|
+
A loop that reports green at stages 3–4 while drifting from the stage-1 intent is **silent drift**
|
|
60
|
+
(see [watermelon-flag](/okf/core/concepts/watermelon-flag.md)). The Acceptance Gate and
|
|
61
|
+
[anti-optimism reporting](/okf/core/concepts/okr-anti-optimism.md) are the structural checks that
|
|
62
|
+
keep the loop honest turn over turn.
|
|
63
|
+
|
|
64
|
+
## Relationship to other concepts
|
|
65
|
+
|
|
66
|
+
- The loop is what the [control plane](/okf/core/concepts/control-plane.md) controls.
|
|
67
|
+
- Each run executes inside an [agent harness](/okf/core/concepts/agent-harness.md).
|
|
68
|
+
- The whole loop is run in an [eval-driven](/okf/core/concepts/eval-driven-pm.md) style: the eval
|
|
69
|
+
is written before the build.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Concept
|
|
3
|
+
title: The Self-Refining Harness
|
|
4
|
+
description: The harness improves from its own run evidence — a detect → draft → PM-gate loop that turns evals, friction, and calibration data into concrete harness edits, bounded at the L3 ceiling so it never becomes L4 self-mutation.
|
|
5
|
+
tags: [harness, self-improvement, evals, friction, autonomy, context-engineering]
|
|
6
|
+
timestamp: 2026-07-01
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# The Self-Refining Harness
|
|
10
|
+
|
|
11
|
+
**Situating context:** PMOS already frames the [agent as model + harness](/okf/core/concepts/agent-harness.md)
|
|
12
|
+
and already *collects* evidence about its own harness (`evals` defects, `v_friction_recurrence`,
|
|
13
|
+
transcripts, `eval-calibration.md`). What it lacked was a named pattern — and a procedure — for turning
|
|
14
|
+
that evidence back into harness improvements. This concept names it. It was extracted from the
|
|
15
|
+
2026-07-01 "Agent = Model + Harness" research (which found the field converging on *harness engineering*
|
|
16
|
+
as its own discipline, and "agents improving their own tools" as its highest-leverage loop) and it
|
|
17
|
+
informs the [harness-refine skill](/build-skills/harness-refine.skill), [D47](/okf/products/pmos/adr/d47-self-refining-harness.md),
|
|
18
|
+
and the [D23](/okf/products/pmos/adr/d23-quarterly-cadence.md) quarterly harness review.
|
|
19
|
+
|
|
20
|
+
## The pattern
|
|
21
|
+
|
|
22
|
+
`Agent = Model + Harness`. The model improves on someone else's schedule; **the harness is the part
|
|
23
|
+
PMOS controls**, so the harness is where PMOS's own improvement has to come from. A harness that only
|
|
24
|
+
grows by hand improves as fast as a human notices problems. A **self-refining harness** improves as fast
|
|
25
|
+
as it *runs*: every agent run leaves evidence, and that evidence is the raw material for the next
|
|
26
|
+
harness edit. This is what makes "Agent = Model + Harness" a **compounding** system rather than a static
|
|
27
|
+
wrapper — and it is the direct mechanism behind the north star (fewer repeated corrections, because the
|
|
28
|
+
harness edits away the causes of the last ones).
|
|
29
|
+
|
|
30
|
+
## The loop: detect → draft → PM-gate
|
|
31
|
+
|
|
32
|
+
The self-refining harness is the same shape as the OKF upkeep loop
|
|
33
|
+
([D36](/okf/products/pmos/adr/d36-okf-mirror-ci-enforced.md) → [D42](/okf/products/pmos/adr/d42-okf-author-on-demand.md)),
|
|
34
|
+
one level up — applied to the harness itself:
|
|
35
|
+
|
|
36
|
+
1. **Detect** — a deterministic signal shows a gap: a `v_friction_recurrence` theme with no resolving
|
|
37
|
+
decision, a recurring `evals` defect class, a persistent `eval-calibration.md` disagreement, a
|
|
38
|
+
context-budget signal.
|
|
39
|
+
2. **Draft** — the [harness-refine skill](/build-skills/harness-refine.skill) reads that evidence and
|
|
40
|
+
drafts concrete, **evidence-cited** edits, each mapped to one artifact: an MCP tool description
|
|
41
|
+
([ACI](/build-skills/MCP-SPEC.md), D19), a skill body, an OKF concept, or an `AGENTS.md` heuristic.
|
|
42
|
+
It **prunes** as readily as it adds (D23 / [prune the scaffolding](/PRINCIPLES.md)).
|
|
43
|
+
3. **PM-gate** — the edits land as a **PR under the human [Acceptance Gate](/okf/core/concepts/output-eval.md)**.
|
|
44
|
+
The agent proposes; the PM disposes.
|
|
45
|
+
|
|
46
|
+
## Bounded at L3 — why this is not L4
|
|
47
|
+
|
|
48
|
+
A harness that rewrites itself on a schedule with no human in the loop is precisely the **L4
|
|
49
|
+
[silent-drift](/okf/core/concepts/watermelon-flag.md) failure mode** — a green gate over a quietly
|
|
50
|
+
deviating reality. The self-refining harness stays at the **L3 ceiling** by three bounds, locked in
|
|
51
|
+
[D47](/okf/products/pmos/adr/d47-self-refining-harness.md):
|
|
52
|
+
|
|
53
|
+
- **On-demand, never scheduled** — it acts when a PM invokes it or a signal fires, not on a clock.
|
|
54
|
+
- **Proposes, never applies** — it opens a PR; it never merges or self-approves.
|
|
55
|
+
- **Every edit traces to evidence** — a proposal with no run/friction/eval behind it is dropped, so the
|
|
56
|
+
harness cannot drift on the agent's opinion.
|
|
57
|
+
|
|
58
|
+
Self-improvement and self-mutation are different things: the first proposes to a human, the second
|
|
59
|
+
decides alone. PMOS does the first.
|
|
60
|
+
|
|
61
|
+
## Relationship to the field
|
|
62
|
+
|
|
63
|
+
The 2026 literature names this the move from prompt- to context- to **harness engineering**, and credits
|
|
64
|
+
"agents improving their own tools" (refining tool descriptions and instructions from run transcripts)
|
|
65
|
+
with state-of-the-art coding results. PMOS's version is the disciplined one: the improvement is
|
|
66
|
+
*evidence-cited* and *PM-gated*, which avoids the self-evolving-memory risk class (an agent that rewrites
|
|
67
|
+
its own knowledge unbounded). See [harness-knowledge](/planning/research/harness-knowledge.md) for the
|
|
68
|
+
sources.
|
|
69
|
+
|
|
70
|
+
## Related
|
|
71
|
+
|
|
72
|
+
- [agent-harness](/okf/core/concepts/agent-harness.md) — what the harness is; the Summary Gate.
|
|
73
|
+
- [control-plane](/okf/core/concepts/control-plane.md) — why PMOS edits the harness, not the app.
|
|
74
|
+
- [output-eval](/okf/core/concepts/output-eval.md) — the Acceptance Gate this loop submits to.
|
|
75
|
+
- [watermelon-flag](/okf/core/concepts/watermelon-flag.md) — the L4 failure mode the L3 bounds prevent.
|
|
76
|
+
- Skill: [harness-refine](/build-skills/harness-refine.skill). Decision:
|
|
77
|
+
[D47](/okf/products/pmos/adr/d47-self-refining-harness.md).
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Concept
|
|
3
|
+
title: The Watermelon Flag
|
|
4
|
+
description: A status that reads green on automated metrics but is red underneath on strategic alignment — and silent drift, the L4 failure mode it signals.
|
|
5
|
+
tags: [failure-mode, drift, status, evaluation, governance]
|
|
6
|
+
timestamp: 2026-06-28
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# The Watermelon Flag
|
|
10
|
+
|
|
11
|
+
**Situating context:** As PMOS automates more of the [SDLC loop](/okf/core/concepts/sdlc-loop.md),
|
|
12
|
+
the risk shifts from "agents fail loudly" to "agents succeed on the wrong thing, quietly." This
|
|
13
|
+
concept names that risk so PMOS can build structural defenses against it. It informs the
|
|
14
|
+
[output-eval](/okf/core/concepts/output-eval.md) Acceptance Gate and
|
|
15
|
+
[anti-optimism reporting](/okf/core/concepts/okr-anti-optimism.md).
|
|
16
|
+
|
|
17
|
+
## The flag
|
|
18
|
+
|
|
19
|
+
A **watermelon flag** is a status indicator that is **green on the outside, red on the inside**:
|
|
20
|
+
green on automated metrics (tests pass, rubric satisfied, KR dashboard up) while red underneath on
|
|
21
|
+
strategic alignment (the work is drifting away from what the product actually needs).
|
|
22
|
+
|
|
23
|
+
The name is the warning: do not trust the skin. A green automated signal is necessary but not
|
|
24
|
+
sufficient evidence that work is on track.
|
|
25
|
+
|
|
26
|
+
## Silent drift — the named failure mode
|
|
27
|
+
|
|
28
|
+
> **Silent drift:** agents continuously generate outputs that pass automated checks while slowly
|
|
29
|
+
> deviating from strategic product goals.
|
|
30
|
+
|
|
31
|
+
This is the **L4 failure mode** — the characteristic danger of high autonomy. It is *silent* because
|
|
32
|
+
every automated gate stays green: each individual output is locally correct, passes its Quality Gate
|
|
33
|
+
and may even pass its Review Gate, yet the *trajectory* of the work bends away from intent. No single
|
|
34
|
+
run trips an alarm; the drift only shows up when someone compares the accumulated direction against
|
|
35
|
+
the original strategy.
|
|
36
|
+
|
|
37
|
+
The watermelon flag is the **surface signal** of silent drift: the moment you notice green metrics
|
|
38
|
+
sitting on top of strategic misalignment, you are looking at drift in progress.
|
|
39
|
+
|
|
40
|
+
## Why automated gates cannot catch it alone
|
|
41
|
+
|
|
42
|
+
The Quality Gate asks *does it work?* and the Review Gate asks *does it satisfy the rubric?* Neither
|
|
43
|
+
asks *is this still the right thing?* Silent drift lives precisely in that gap: outputs that work and
|
|
44
|
+
satisfy the rubric but should not have been built. By construction, the automated gates are blind to
|
|
45
|
+
it — which is why the defense has to be structural, not another automated check.
|
|
46
|
+
|
|
47
|
+
## Structural defenses
|
|
48
|
+
|
|
49
|
+
PMOS defends against silent drift with two structural mechanisms, not with more automation:
|
|
50
|
+
|
|
51
|
+
1. **The Acceptance Gate** — the human PM's end-of-run strategic judgment
|
|
52
|
+
([output-eval](/okf/core/concepts/output-eval.md)). It is the one gate that asks "is this the
|
|
53
|
+
right thing?", so it is the one gate that can catch drift. This is why acceptance authority never
|
|
54
|
+
leaves the human, even at the L3 autonomy ceiling.
|
|
55
|
+
2. **Anti-optimism reporting** — agents and status reports are required to surface the red
|
|
56
|
+
underneath rather than round up to green
|
|
57
|
+
([okr-anti-optimism](/okf/core/concepts/okr-anti-optimism.md)). Honest pessimistic reporting is
|
|
58
|
+
what makes a watermelon visible before it rots.
|
|
59
|
+
|
|
60
|
+
## How to use the concept
|
|
61
|
+
|
|
62
|
+
- When a status is green, ask explicitly: *green on what?* Distinguish automated-metric green from
|
|
63
|
+
strategic-alignment green. If you can only confirm the former, treat the flag as a watermelon
|
|
64
|
+
until the Acceptance Gate confirms the latter.
|
|
65
|
+
- Treat any initiative whose KRs are all green but whose strategic justification has gone fuzzy as a
|
|
66
|
+
drift candidate, and re-anchor it to its [OKR](/okf/core/concepts/okr-tree.md) parent.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Template
|
|
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.
|
|
5
|
+
tags: [template, design, brief, planning]
|
|
6
|
+
timestamp: 2026-07-01
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Design Brief Template
|
|
10
|
+
|
|
11
|
+
**Situating context:** This template is the canonical scaffold the
|
|
12
|
+
[design-brief skill](/skills/core/design-brief.skill) instantiates — leg 1 of the
|
|
13
|
+
[design loop](/okf/core/concepts/design-loop.md). It is to design what the
|
|
14
|
+
[PRD template](/okf/core/templates/prd-template.md) is to build: the shared definition before work starts.
|
|
15
|
+
Copy the block into `/planning/design/<slug>-design-brief.md` and fill it; the copy is an operational
|
|
16
|
+
instance and does not live in the OKF bundle.
|
|
17
|
+
|
|
18
|
+
> Usage: replace every `<…>` placeholder; delete guidance comments (`<!-- … -->`). **Behavior is locked —
|
|
19
|
+
> only presentation is in scope.** Every surface must tie to a real data source (that is the anti-watermelon
|
|
20
|
+
> move at brief time). An empty out-of-scope list means the brief is not ready.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
# Design Brief: <initiative title> (for claude.ai/design)
|
|
26
|
+
|
|
27
|
+
## Identity
|
|
28
|
+
- initiative_id: <id>
|
|
29
|
+
- product_slug: <product_slug>
|
|
30
|
+
- pm_slug: <pm_slug>
|
|
31
|
+
- parent_KR: <objective.kr reference>
|
|
32
|
+
- date: <YYYY-MM-DD>
|
|
33
|
+
|
|
34
|
+
## Point of view (so the design has one)
|
|
35
|
+
<!-- What the product is and the aesthetic it should read as. Keep it to the design's job. -->
|
|
36
|
+
<e.g. a dense, dark-mode-first operations dashboard — calm, information-first, fast to scan — not a
|
|
37
|
+
marketing site. Every screen answers one operator question.>
|
|
38
|
+
|
|
39
|
+
## Surfaces to design
|
|
40
|
+
<!-- One row per surface. Tie each to the REAL data it shows so the design fits the true shape
|
|
41
|
+
(column counts, empty states, density) — this is where watermelon-UI is prevented up front. -->
|
|
42
|
+
|
|
43
|
+
| Surface | Job (one operator question) | Real data source (RLS-scoped view/table) | Notable states |
|
|
44
|
+
|---|---|---|---|
|
|
45
|
+
| <surface> | <job> | <view/table> | <empty / loading / error / active> |
|
|
46
|
+
|
|
47
|
+
## Semantic token system (the heart of it)
|
|
48
|
+
<!-- Named tokens with light + dark values, NOT one-off swatches. The build maps them to CSS variables
|
|
49
|
+
once; views never touch raw hex again. -->
|
|
50
|
+
- <status tokens, e.g. rag-red / rag-amber / rag-green; pulse-*; eval-*; watermelon>
|
|
51
|
+
- <base tokens: background / foreground / primary / muted / border / destructive>
|
|
52
|
+
|
|
53
|
+
## Component set (deliverables)
|
|
54
|
+
<!-- Reusable components + their variants — exactly what /design-sync carries back as the library. -->
|
|
55
|
+
1. <component> — <variants / sizes>
|
|
56
|
+
2. ...
|
|
57
|
+
|
|
58
|
+
## Hard constraints (do not design around these)
|
|
59
|
+
- **Behavior-preserving** — no new views, no new data, no changed flows. Presentation only.
|
|
60
|
+
- **Accessibility** — status must not rely on color alone (glyph + text; contrast; focus states).
|
|
61
|
+
- **Density** — favor information density and scan-ability over whitespace (if an ops console).
|
|
62
|
+
- <deployment / bundle / platform constraints, e.g. static hosting, bundle budget>
|
|
63
|
+
|
|
64
|
+
## Out of scope (REQUIRED, non-empty)
|
|
65
|
+
<!-- New features, data-model changes, flow changes, secrets/keys in the client. If a design implies a
|
|
66
|
+
data change, FLAG IT BACK — it is a separate decision, not part of this brief. -->
|
|
67
|
+
- <out-of-scope item>
|
|
68
|
+
|
|
69
|
+
## Leg-2 prompt (paste into claude.ai/design)
|
|
70
|
+
<!-- A single prompt that reproduces the above for the design agent. -->
|
|
71
|
+
> <prompt>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Authoring checklist
|
|
77
|
+
|
|
78
|
+
- [ ] `parent_KR` present and real; brief paired to an initiative that passed intake.
|
|
79
|
+
- [ ] Every surface tied to a real data source (no imagined capability).
|
|
80
|
+
- [ ] Token system named with semantic names, not swatches.
|
|
81
|
+
- [ ] Accessibility (not-color-alone) constraint present.
|
|
82
|
+
- [ ] Out-of-scope non-empty; any data-implying idea flagged back as a separate decision.
|
|
83
|
+
- [ ] Component deliverables named; leg-2 prompt included.
|
|
84
|
+
- [ ] Stays presentation-only — no behavior, data, or flow changes proposed.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Template
|
|
3
|
+
title: Eval Rubric Template
|
|
4
|
+
description: The scaffold for an evaluation rubric instance, including weighted dimensions, partial credit, and the sprint contract. Copy into /planning/evals/ and fill.
|
|
5
|
+
tags: [template, eval, rubric, scoring, planning]
|
|
6
|
+
timestamp: 2026-06-28
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Eval Rubric Template
|
|
10
|
+
|
|
11
|
+
**Situating context:** This template was authored as the canonical scaffold the
|
|
12
|
+
[eval-rubric skill](/skills/core/eval-rubric.skill) instantiates, so every rubric uses the same
|
|
13
|
+
weighted-scoring math and carries its sprint contract. Copy the block into
|
|
14
|
+
`/planning/evals/<slug>-eval-rubric.md` and fill it; the copy is operational and does not live in the
|
|
15
|
+
OKF bundle.
|
|
16
|
+
|
|
17
|
+
> Usage: replace every `<…>`. Weights must sum to 1.0. The threshold is pre-committed — set it before
|
|
18
|
+
> any output exists. See [output-eval](/okf/core/concepts/output-eval.md) for the gate model.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
```markdown
|
|
23
|
+
# Eval Rubric: <initiative title>
|
|
24
|
+
|
|
25
|
+
## Frontmatter
|
|
26
|
+
- type: Rubric
|
|
27
|
+
- eval_type: capability | regression <!-- capability = push frontier; regression = guard against backslide -->
|
|
28
|
+
- initiative_id: <id>
|
|
29
|
+
- product_slug: <product_slug>
|
|
30
|
+
- pm_slug: <pm_slug>
|
|
31
|
+
- parent_KR: <reference>
|
|
32
|
+
- pass_threshold: <0.00–1.00> <!-- pre-committed, before output exists -->
|
|
33
|
+
- date: <YYYY-MM-DD>
|
|
34
|
+
|
|
35
|
+
## Gate assignment
|
|
36
|
+
<!-- State which gate each criterion serves. Acceptance Gate is PM-only and NOT rubric-graded. -->
|
|
37
|
+
- Quality Gate (deterministic): <compile / lint / tests that must pass>
|
|
38
|
+
- Review Gate (rubric-scored): the weighted dimensions below
|
|
39
|
+
- Acceptance Gate (PM, strategic): NOT graded here — PM decides "is this the right thing?"
|
|
40
|
+
|
|
41
|
+
## Weighted dimensions (Review Gate)
|
|
42
|
+
<!-- Outcome-only: grade what was produced, not the path/tool-calls. Partial credit required. -->
|
|
43
|
+
|
|
44
|
+
| Dimension | Weight | Score (0–1) | Weighted = W×S |
|
|
45
|
+
|------------------------|-------:|------------:|---------------:|
|
|
46
|
+
| <dimension 1> | <0.x> | <0.x> | <0.x> |
|
|
47
|
+
| <dimension 2> | <0.x> | <0.x> | <0.x> |
|
|
48
|
+
| <dimension 3> | <0.x> | <0.x> | <0.x> |
|
|
49
|
+
| **Total** | **1.0**| | **<sum>** |
|
|
50
|
+
|
|
51
|
+
**Result:** total `<sum>` vs threshold `<pass_threshold>` → PASS / FAIL.
|
|
52
|
+
|
|
53
|
+
## Sprint contract (pre-run)
|
|
54
|
+
initiative_id: <id>
|
|
55
|
+
run_id: <id>
|
|
56
|
+
done_criteria:
|
|
57
|
+
1. <testable criterion>
|
|
58
|
+
2. <testable criterion>
|
|
59
|
+
test_method:
|
|
60
|
+
1. <how criterion 1 is verified, and at which gate>
|
|
61
|
+
2. <how criterion 2 is verified, and at which gate>
|
|
62
|
+
PM_approved: true | false <!-- must be true before work starts; P0 = temp file + PM sign-off -->
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Partial credit / weighted scoring — how to use
|
|
68
|
+
|
|
69
|
+
The rubric is **not** all-or-nothing. Score each dimension on a continuous 0–1 scale (partial credit
|
|
70
|
+
required), multiply by its weight, and sum:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
total = Σ (weight_i × score_i), with Σ weight_i = 1.0
|
|
74
|
+
PASS iff total ≥ pass_threshold
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Rules:
|
|
78
|
+
|
|
79
|
+
- **Weights sum to 1.0.** If they do not, the rubric is malformed.
|
|
80
|
+
- **Partial credit is mandatory.** A dimension that can only score 0 or 1 hides quality gradients and
|
|
81
|
+
defeats weighted scoring — split it or define intermediate anchors.
|
|
82
|
+
- **Anchor the scale.** For each dimension, briefly define what 0, 0.5, and 1 look like, so scoring
|
|
83
|
+
is repeatable across evaluators (and calibratable against
|
|
84
|
+
[eval-calibration.md](/planning/evals/eval-calibration.md)).
|
|
85
|
+
- **Threshold is pre-committed.** Never tune the threshold after seeing the output.
|
|
86
|
+
- **Outcome-only.** Score the artifact produced, not the tool-call sequence or reasoning path.
|
|
87
|
+
|
|
88
|
+
## Authoring checklist
|
|
89
|
+
|
|
90
|
+
- [ ] `eval_type` set.
|
|
91
|
+
- [ ] Weights present and sum to 1.0.
|
|
92
|
+
- [ ] Each dimension supports partial credit with anchored 0/0.5/1.
|
|
93
|
+
- [ ] `pass_threshold` pre-committed.
|
|
94
|
+
- [ ] Gate assignment stated; Acceptance Gate marked PM-only, not graded.
|
|
95
|
+
- [ ] Sprint contract present with `PM_approved`.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# core/templates — Index
|
|
2
|
+
|
|
3
|
+
OKF reserved file (no frontmatter). Directory listing for progressive disclosure — read this
|
|
4
|
+
to pick concepts, then fetch the file(s) you need.
|
|
5
|
+
|
|
6
|
+
- [design-brief-template](design-brief-template.md) — The scaffold for a design brief instance — the context handoff from Claude Code to claude.ai/design (leg 1 of the design loop). Copy into /planning/design/ and fill; presentation-only.
|
|
7
|
+
- [eval-rubric-template](eval-rubric-template.md) — The scaffold for an evaluation rubric instance, including weighted dimensions, partial credit, and the sprint contract. Copy into /planning/evals/ and fill.
|
|
8
|
+
- [prd-template](prd-template.md) — The scaffold for a Product Requirements Document instance. Copy into /planning/prd/ and fill; do not author PRDs from scratch.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# core/templates — Log
|
|
2
|
+
|
|
3
|
+
OKF reserved file (no frontmatter). Change history, newest first, ISO 8601 dates.
|
|
4
|
+
|
|
5
|
+
## 2026-07-01
|
|
6
|
+
- Added `design-brief-template` — the design-brief scaffold (leg 1 of the design loop, D48), instantiated by the [design-brief skill](/skills/core/design-brief.skill). Distilled from the first instance, `planning/design-brief.md`.
|
|
7
|
+
|
|
8
|
+
## 2026-06-29
|
|
9
|
+
- Creation — per-folder index/log added (OKF recursive progressive disclosure; D29 reversal direction).
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Template
|
|
3
|
+
title: PRD Template
|
|
4
|
+
description: The scaffold for a Product Requirements Document instance. Copy into /planning/prd/ and fill; do not author PRDs from scratch.
|
|
5
|
+
tags: [template, prd, planning]
|
|
6
|
+
timestamp: 2026-06-28
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# PRD Template
|
|
10
|
+
|
|
11
|
+
**Situating context:** This template was authored as the canonical scaffold the
|
|
12
|
+
[prd skill](/skills/core/prd.skill) instantiates, so every PRD in PMOS has the same shape and the
|
|
13
|
+
same anchoring discipline. Copy the block below into `/planning/prd/<slug>-prd.md` and fill it; the
|
|
14
|
+
copy is an operational instance and does not live in the OKF bundle.
|
|
15
|
+
|
|
16
|
+
> Usage: replace every `<…>` placeholder. Delete guidance comments (`<!-- … -->`) once filled.
|
|
17
|
+
> Keep section order. An empty out-of-scope list or a missing parent KR means the PRD is not ready.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
# PRD: <initiative title>
|
|
23
|
+
|
|
24
|
+
## Identity
|
|
25
|
+
- initiative_id: <id>
|
|
26
|
+
- product_slug: <product_slug>
|
|
27
|
+
- pm_slug: <pm_slug>
|
|
28
|
+
- parent_KR: <objective.kr reference> <!-- REQUIRED. No parent KR = unanchored work, do not proceed. -->
|
|
29
|
+
- status: draft | approved
|
|
30
|
+
- date: <YYYY-MM-DD>
|
|
31
|
+
|
|
32
|
+
## Problem
|
|
33
|
+
<!-- Who has this problem, why it matters, and why now. Problem BEFORE solution. -->
|
|
34
|
+
|
|
35
|
+
## Goal
|
|
36
|
+
<!-- The change in the world this initiative seeks. One or two sentences. -->
|
|
37
|
+
|
|
38
|
+
## Non-goals (out of scope)
|
|
39
|
+
<!-- REQUIRED and non-empty. The primary defense against over-building. -->
|
|
40
|
+
- <out-of-scope item>
|
|
41
|
+
- <out-of-scope item>
|
|
42
|
+
|
|
43
|
+
## Requirements
|
|
44
|
+
<!-- What must be true of the solution: capabilities and constraints. Not implementation steps. -->
|
|
45
|
+
- <requirement>
|
|
46
|
+
- <requirement>
|
|
47
|
+
|
|
48
|
+
## Success criteria (outcomes, not output)
|
|
49
|
+
<!-- Tied to the parent KR. A change in the world, not a list of artifacts produced. -->
|
|
50
|
+
- <outcome criterion>
|
|
51
|
+
- <outcome criterion>
|
|
52
|
+
|
|
53
|
+
## Risks & open questions
|
|
54
|
+
<!-- Include anything to escalate to the PM. -->
|
|
55
|
+
- <risk / question>
|
|
56
|
+
|
|
57
|
+
## Eval rubric
|
|
58
|
+
<!-- The paired rubric is written BEFORE the build (eval-driven PM). -->
|
|
59
|
+
- rubric: <link to /planning/evals/<slug>-eval-rubric.md>
|
|
60
|
+
|
|
61
|
+
## Links
|
|
62
|
+
- parent KR: <link>
|
|
63
|
+
- relevant OKF concepts: <links>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Authoring checklist
|
|
69
|
+
|
|
70
|
+
- [ ] `parent_KR` present and real.
|
|
71
|
+
- [ ] Problem stated before solution.
|
|
72
|
+
- [ ] Non-goals non-empty.
|
|
73
|
+
- [ ] Success criteria are outcomes tied to the KR, not output counts.
|
|
74
|
+
- [ ] Paired eval rubric queued to be written first.
|
|
75
|
+
- [ ] Stays at control altitude — specs *what/why*, not application code or the agent's path.
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Eval Rubric: Agent-run capability baseline (kit seed — copy per initiative)
|
|
2
|
+
|
|
3
|
+
> Kit-seeded generic rubric (D54). Two purposes: (1) it is the TEMPLATE to copy to
|
|
4
|
+
> `<initiative-id>-eval-rubric.md` and specialize per initiative (rewrite the dimensions to the
|
|
5
|
+
> initiative's own outcomes; keep weights summing to 1.0); (2) it keeps the `rubrics` CI check
|
|
6
|
+
> meaningful from day one. It scores a generic agent run outcome-only (D14) with weighted partial
|
|
7
|
+
> credit (D15).
|
|
8
|
+
|
|
9
|
+
## Frontmatter
|
|
10
|
+
- type: Rubric
|
|
11
|
+
- eval_type: capability
|
|
12
|
+
- initiative_id: (set per initiative)
|
|
13
|
+
- pass_threshold: 0.80
|
|
14
|
+
- canonical_path: pmos/planning/evals/agent-run-eval-rubric.md
|
|
15
|
+
|
|
16
|
+
## Gate assignment
|
|
17
|
+
- **Quality Gate (deterministic):** repo CI green; `pmos-gate` (anchored + rubrics) green.
|
|
18
|
+
- **Review Gate (adversarial):** the weighted dimensions below — evaluator skill, default-to-refute,
|
|
19
|
+
outcome-only; verdict appended to `pmos/state/evals.jsonl`; ADVISORY until locally calibrated.
|
|
20
|
+
- **Acceptance Gate (PM):** the human PM merges and disposes — final and non-delegable (D12).
|
|
21
|
+
|
|
22
|
+
## Weighted dimensions (Review Gate)
|
|
23
|
+
Outcome-only (D14); partial credit (D15); anchors 0 / 0.5 / 1.0.
|
|
24
|
+
|
|
25
|
+
| Dimension | Weight | Score | Wtd |
|
|
26
|
+
|---|---:|---:|---:|
|
|
27
|
+
| Contract satisfaction — every done_criterion of the pre-run contract is met, verified per its test_method | 0.40 | — | — |
|
|
28
|
+
| Correctness of the produced artifact — behaves/reads as specified; no defect a reviewer can demonstrate | 0.30 | — | — |
|
|
29
|
+
| Scope discipline — nothing out of contract scope changed; state files appended, never rewritten | 0.20 | — | — |
|
|
30
|
+
| Traceability — initiative anchored; run + eval + friction logged to pmos/state/ | 0.10 | — | — |
|
|
31
|
+
| **Total** | **1.00** | | **vs 0.80** |
|
|
32
|
+
|
|
33
|
+
### Anchors (0 / 0.5 / 1)
|
|
34
|
+
- **Contract:** 0 = a criterion unmet; 0.5 = met but a test_method not actually exercised; 1 = all met and exercised.
|
|
35
|
+
- **Correctness:** 0 = demonstrable defect; 0.5 = works with a material caveat; 1 = defect-free under the rubric's probes.
|
|
36
|
+
- **Scope:** 0 = out-of-scope change or state rewrite; 0.5 = minor drift, flagged; 1 = clean.
|
|
37
|
+
- **Traceability:** 0 = unanchored or unlogged; 0.5 = partial logging; 1 = complete.
|
|
38
|
+
|
|
39
|
+
## Sprint contract (pre-run)
|
|
40
|
+
initiative_id: (set)
|
|
41
|
+
run_id: (set)
|
|
42
|
+
done_criteria:
|
|
43
|
+
1. (numbered, testable — agreed BEFORE work starts)
|
|
44
|
+
test_method:
|
|
45
|
+
1. (one per criterion; name the gate that checks it)
|
|
46
|
+
PM_approved: false <!-- flip to true only on the PM's explicit word -->
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Rubric well-formedness gate: fail CI when an eval rubric is malformed BEFORE it grades anything.
|
|
3
|
+
|
|
4
|
+
This is the deterministic, repo-only half of P6 (Review Gate as CI). The Review Gate itself is an LLM
|
|
5
|
+
judgment and cannot run reproducibly in CI — but a *malformed rubric* (weights that don't sum to 1.0, a
|
|
6
|
+
missing pass threshold, a missing eval_type) is a deterministic defect we CAN catch. This guards the
|
|
7
|
+
scaffolding the evaluator skill scores against (D14 outcome-only, D15 weighted dimensions + threshold).
|
|
8
|
+
|
|
9
|
+
Scope: every rubric in planning/evals/ — a file is a rubric iff its frontmatter declares `type: Rubric`
|
|
10
|
+
(tolerates the `- type: Rubric` markdown-list frontmatter the P0/P1 rubrics use). Calibration logs and
|
|
11
|
+
method docs are not rubrics and are skipped. Three assertions per rubric:
|
|
12
|
+
|
|
13
|
+
EVAL_TYPE — eval_type is present and is `capability` or `regression` (D15 frontmatter field).
|
|
14
|
+
THRESHOLD — a pre-committed pass threshold in (0,1] exists (`pass_threshold:` or "pass threshold = ").
|
|
15
|
+
WEIGHTS — the first Weighted-dimensions table's Weight column sums to 1.0 (±0.011), excluding the
|
|
16
|
+
explicit Total row. Partial-credit weighting is meaningless if the weights don't sum to 1.
|
|
17
|
+
|
|
18
|
+
Exit 0 = green. Exit 1 = a malformed rubric; prints which and why. No DB access, no secrets.
|
|
19
|
+
"""
|
|
20
|
+
import os, re, sys, glob
|
|
21
|
+
|
|
22
|
+
ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
23
|
+
EVALS = os.path.join(ROOT, "planning", "evals")
|
|
24
|
+
fail = []
|
|
25
|
+
checked = 0
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def read(p):
|
|
29
|
+
return open(p, encoding="utf-8").read()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def num(s):
|
|
33
|
+
"""Parse a possibly-bold/aligned numeric cell like `**0.30**` or `0.35` -> float, else None."""
|
|
34
|
+
s = s.replace("*", "").replace("`", "").strip()
|
|
35
|
+
m = re.fullmatch(r"[0-9]*\.?[0-9]+", s)
|
|
36
|
+
return float(m.group()) if m else None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def weight_sum(text):
|
|
40
|
+
"""Sum the Weight column of the FIRST markdown table that has a 'Weight' header, skipping the
|
|
41
|
+
Total row. Returns (sum, n_rows) or (None, 0) if no weighted table is found."""
|
|
42
|
+
lines = text.splitlines()
|
|
43
|
+
for i, line in enumerate(lines):
|
|
44
|
+
cells = [c.strip() for c in line.strip().strip("|").split("|")]
|
|
45
|
+
wcol = next((j for j, c in enumerate(cells) if c.lower() == "weight"), None)
|
|
46
|
+
if wcol is None:
|
|
47
|
+
continue
|
|
48
|
+
total, rows = 0.0, 0
|
|
49
|
+
for row in lines[i + 1:]:
|
|
50
|
+
if not row.lstrip().startswith("|"):
|
|
51
|
+
break # table ended
|
|
52
|
+
rc = [c.strip() for c in row.strip().strip("|").split("|")]
|
|
53
|
+
if set("".join(rc)) <= set("-: "):
|
|
54
|
+
continue # separator row |---|---|
|
|
55
|
+
if len(rc) <= wcol:
|
|
56
|
+
continue
|
|
57
|
+
# the |Total|1.00| summary row is not a dimension — the "Total" label may sit in any
|
|
58
|
+
# cell (an empty leading `#` column pushes it right), so scan every cell.
|
|
59
|
+
if any(c.replace("*", "").strip().lower().startswith("total") for c in rc):
|
|
60
|
+
continue
|
|
61
|
+
w = num(rc[wcol])
|
|
62
|
+
if w is not None:
|
|
63
|
+
total += w
|
|
64
|
+
rows += 1
|
|
65
|
+
return round(total, 4), rows
|
|
66
|
+
return None, 0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
for path in sorted(glob.glob(os.path.join(EVALS, "*.md"))):
|
|
70
|
+
rel = os.path.relpath(path, ROOT)
|
|
71
|
+
text = read(path)
|
|
72
|
+
# A rubric declares `type: Rubric` (YAML or `- ` markdown-list frontmatter). Skip everything else.
|
|
73
|
+
if not re.search(r"^[-\s]*type:\s*Rubric\b", text, re.M | re.I):
|
|
74
|
+
continue
|
|
75
|
+
checked += 1
|
|
76
|
+
|
|
77
|
+
m = re.search(r"^[-\s]*eval_type:\s*(\w+)", text, re.M | re.I)
|
|
78
|
+
if not m:
|
|
79
|
+
fail.append(f"{rel}: missing `eval_type` (must be capability|regression — D15)")
|
|
80
|
+
elif m.group(1).lower() not in ("capability", "regression"):
|
|
81
|
+
fail.append(f"{rel}: eval_type `{m.group(1)}` invalid (must be capability|regression)")
|
|
82
|
+
|
|
83
|
+
t = re.search(r"pass_threshold:\s*([0-9]*\.?[0-9]+)", text, re.I) or \
|
|
84
|
+
re.search(r"pass threshold\s*=?\s*([0-9]*\.?[0-9]+)", text, re.I)
|
|
85
|
+
if not t:
|
|
86
|
+
fail.append(f"{rel}: no pre-committed pass threshold (`pass_threshold:` or 'pass threshold = ')")
|
|
87
|
+
elif not (0 < float(t.group(1)) <= 1):
|
|
88
|
+
fail.append(f"{rel}: pass threshold {t.group(1)} out of range (0,1]")
|
|
89
|
+
|
|
90
|
+
s, rows = weight_sum(text)
|
|
91
|
+
if s is None:
|
|
92
|
+
fail.append(f"{rel}: no weighted-dimensions table with a `Weight` column (D15)")
|
|
93
|
+
elif rows < 2:
|
|
94
|
+
fail.append(f"{rel}: weighted table has {rows} dimension(s) — needs >=2 for partial credit")
|
|
95
|
+
elif abs(s - 1.0) > 0.011:
|
|
96
|
+
fail.append(f"{rel}: dimension weights sum to {s}, not 1.0 (D15 partial-credit weighting)")
|
|
97
|
+
|
|
98
|
+
print(f"Rubric gate: {checked} rubric(s) checked in planning/evals/.")
|
|
99
|
+
if fail:
|
|
100
|
+
print(f"\n✗ {len(fail)} malformed rubric issue(s):")
|
|
101
|
+
for f in fail:
|
|
102
|
+
print(" -", f)
|
|
103
|
+
print("\nFix: weights must sum to 1.0, set a pass_threshold in (0,1], and an eval_type (D15).")
|
|
104
|
+
sys.exit(1)
|
|
105
|
+
if checked == 0:
|
|
106
|
+
print("✗ no rubrics found — expected at least one `type: Rubric` doc in planning/evals/")
|
|
107
|
+
sys.exit(1)
|
|
108
|
+
print("✓ every rubric is well-formed (weights sum to 1.0, threshold + eval_type present).")
|
|
File without changes
|
|
File without changes
|