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,56 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PMOS portable kit — file-backed Initiative Gate (D54). Fail-closed enforcement of the loop,
|
|
3
|
+
# same contract as the hosted gate but reading pmos/state/ instead of a database. A PR is
|
|
4
|
+
# "anchored" only when:
|
|
5
|
+
# 1. the branch is initiative/<id> (or the PR body declares 'Initiative: <id>'), and
|
|
6
|
+
# 2. pmos/state/initiatives/<id>.md EXISTS in the checkout, and
|
|
7
|
+
# 3. its prd_path is set and that file exists, and
|
|
8
|
+
# 4. its rubric_path is set and that file exists.
|
|
9
|
+
# Escape hatch (explicit, logged): the `no-initiative` label skips the gate.
|
|
10
|
+
# Inputs via env: HEAD_REF, PR_BODY, PR_LABELS. Optional: KIT_ROOT (default: pmos).
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
KIT_ROOT="${KIT_ROOT:-pmos}"
|
|
14
|
+
fail() { echo "::error::initiative-gate: $*"; echo "❌ initiative gate FAILED — $*"; exit 1; }
|
|
15
|
+
note() { echo "::notice::initiative-gate: $*"; echo "ℹ️ $*"; }
|
|
16
|
+
|
|
17
|
+
# ---- escape hatch (genuine chores) — exact label, space-bounded ------------
|
|
18
|
+
case " ${PR_LABELS:-} " in
|
|
19
|
+
*" no-initiative "*) note "PR labelled 'no-initiative' — gate skipped (sanctioned chore path)."; exit 0 ;;
|
|
20
|
+
esac
|
|
21
|
+
|
|
22
|
+
# ---- fail closed if the state layer is missing ------------------------------
|
|
23
|
+
[ -d "$KIT_ROOT/state/initiatives" ] || fail "$KIT_ROOT/state/initiatives/ not found — the kit state layer is required and the gate fails closed (a hard gate must not be silently disableable)."
|
|
24
|
+
|
|
25
|
+
# ---- derive the initiative id ----------------------------------------------
|
|
26
|
+
id=""
|
|
27
|
+
case "${HEAD_REF:-}" in
|
|
28
|
+
initiative/*) id="${HEAD_REF#initiative/}" ;;
|
|
29
|
+
esac
|
|
30
|
+
if [ -z "$id" ]; then
|
|
31
|
+
# `|| true`: a no-match grep exits 1, which under set -e would abort BEFORE the fail() guidance
|
|
32
|
+
# below ever prints (silent exit 1 on the most common failure path).
|
|
33
|
+
id="$(printf '%s' "${PR_BODY:-}" | { grep -ioE 'Initiative:[[:space:]]*[A-Za-z0-9._-]+' || true; } | head -1 | sed -E 's/.*:[[:space:]]*//')"
|
|
34
|
+
fi
|
|
35
|
+
[ -n "$id" ] || fail "Not anchored. Name the branch 'initiative/<id>' or add 'Initiative: <id>' to the PR body, or label the PR 'no-initiative' for a genuine chore. See $KIT_ROOT/AGENTS.md."
|
|
36
|
+
|
|
37
|
+
# ---- validate the id (also guards the path interpolation below) -------------
|
|
38
|
+
printf '%s' "$id" | grep -qE '^[a-z0-9][a-z0-9._-]*$' || fail "Initiative id '$id' is malformed (expected ^[a-z0-9][a-z0-9._-]*$)."
|
|
39
|
+
|
|
40
|
+
# ---- read the initiative file ------------------------------------------------
|
|
41
|
+
init_file="$KIT_ROOT/state/initiatives/$id.md"
|
|
42
|
+
[ -f "$init_file" ] || fail "No initiative file at $init_file. Create it first — an initiative must exist before its PR. This is the loop rule the gate enforces."
|
|
43
|
+
|
|
44
|
+
frontval() { # frontval <key> — first 'key: value' line in the file, value trimmed.
|
|
45
|
+
# `|| true`: an absent key must fall through to the explicit fail() below, not abort silently.
|
|
46
|
+
{ grep -m1 -E "^$1:[[:space:]]*" "$init_file" || true; } | sed -E "s/^$1:[[:space:]]*//" | tr -d '\r' | sed -E 's/[[:space:]]+$//'
|
|
47
|
+
}
|
|
48
|
+
prd="$(frontval prd_path)"
|
|
49
|
+
rubric="$(frontval rubric_path)"
|
|
50
|
+
|
|
51
|
+
[ -n "$prd" ] || fail "initiative '$id' has no prd_path in $init_file. Author a PRD and set prd_path (eval-first: PRD + rubric before build)."
|
|
52
|
+
[ -f "$prd" ] || fail "prd_path '$prd' (from $init_file) does not exist in the repo."
|
|
53
|
+
[ -n "$rubric" ] || fail "initiative '$id' has no rubric_path in $init_file. Author an eval rubric and set rubric_path."
|
|
54
|
+
[ -f "$rubric" ] || fail "rubric_path '$rubric' (from $init_file) does not exist in the repo."
|
|
55
|
+
|
|
56
|
+
echo "✅ initiative gate PASSED — '$id' is anchored: $init_file exists, PRD ($prd) and rubric ($rubric) present."
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# PMOS portable kit — kernel update (D54). Runs FROM the vendored kit inside a target repo:
|
|
3
|
+
#
|
|
4
|
+
# pmos/scripts/kit-update.sh <path-to-pmos-checkout>
|
|
5
|
+
#
|
|
6
|
+
# Re-vendors ONLY the kernel (skills/, okf/core/, scripts/, check_rubrics.py, AGENTS.md, README.md,
|
|
7
|
+
# templates/) from the given PMOS checkout, stamps KIT-VERSION, and never touches state/,
|
|
8
|
+
# planning/ (beyond check_rubrics.py), or okf/product/. Updates flow one-way, PMOS -> kit.
|
|
9
|
+
# Review the resulting diff as a normal PR.
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
[ -n "${1:-}" ] || { echo "usage: kit-update.sh <path-to-pmos-checkout>" >&2; exit 1; }
|
|
13
|
+
SRC="$1"
|
|
14
|
+
KIT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
15
|
+
[ -x "$SRC/kit/build-kit.sh" ] || { echo "kit-update: ERROR — $SRC is not a PMOS checkout (no kit/build-kit.sh)" >&2; exit 1; }
|
|
16
|
+
exec "$SRC/kit/build-kit.sh" --update "$KIT"
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""PMOS portable kit — balanced metrics over the file-mode state layer (D54, D39).
|
|
3
|
+
|
|
4
|
+
Reads pmos/state/{runs,evals,acceptances}.jsonl and prints:
|
|
5
|
+
B1 north star — human corrections per ACCEPTED run (lower is better; D10, counted over
|
|
6
|
+
accepted runs only so leniency can't deflate it)
|
|
7
|
+
B2 throughput — accepted runs (guards against winning B1 by doing less)
|
|
8
|
+
-- eval pass rate — share of evals with verdict PASS / PASS-WITH-FINDINGS
|
|
9
|
+
B4 calibration — evaluator verdict vs PM label, joined by run_id: raw agreement, TPR, TNR,
|
|
10
|
+
Cohen's kappa (the D40 classifier method, computed locally)
|
|
11
|
+
-- Goodhart tripwire — fires when eval_pass_rate >= 0.8 while avg corrections >= 1.5 (the
|
|
12
|
+
pass-happy-judge signal; anti-optimism: read the red first)
|
|
13
|
+
|
|
14
|
+
No network, no secrets. Exit 0 always (a reporting tool, not a gate). Anti-optimism: reds print first.
|
|
15
|
+
"""
|
|
16
|
+
import json, os, sys
|
|
17
|
+
|
|
18
|
+
KIT = os.environ.get("KIT_ROOT") or os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
19
|
+
STATE = os.path.join(KIT, "state")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def load(name):
|
|
23
|
+
path = os.path.join(STATE, name)
|
|
24
|
+
rows = []
|
|
25
|
+
if os.path.exists(path):
|
|
26
|
+
for i, line in enumerate(open(path, encoding="utf-8"), 1):
|
|
27
|
+
line = line.strip()
|
|
28
|
+
if not line:
|
|
29
|
+
continue
|
|
30
|
+
try:
|
|
31
|
+
rows.append(json.loads(line))
|
|
32
|
+
except json.JSONDecodeError:
|
|
33
|
+
print(f"⚠ {name}:{i} is not valid JSON — skipped (append-only files must hold one JSON object per line)")
|
|
34
|
+
return rows
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
runs = load("runs.jsonl")
|
|
38
|
+
evals = load("evals.jsonl")
|
|
39
|
+
acc = load("acceptances.jsonl")
|
|
40
|
+
|
|
41
|
+
accepted = [a for a in acc if a.get("accepted") is True]
|
|
42
|
+
corrections_by_run = {r.get("run_id"): int(r.get("human_corrections") or 0) for r in runs}
|
|
43
|
+
acc_corr = [corrections_by_run.get(a.get("run_id"), 0) for a in accepted]
|
|
44
|
+
|
|
45
|
+
passing = ("PASS", "PASS-WITH-FINDINGS")
|
|
46
|
+
n_pass = sum(1 for e in evals if str(e.get("verdict", "")).upper() in passing)
|
|
47
|
+
pass_rate = (n_pass / len(evals)) if evals else None
|
|
48
|
+
|
|
49
|
+
# --- B4: verdict-vs-PM-label confusion matrix, joined by run_id (D40) ---
|
|
50
|
+
label_by_run = {a.get("run_id"): str(a.get("pm_label", "")).lower() for a in acc if a.get("pm_label")}
|
|
51
|
+
tp = tn = fp = fn = 0
|
|
52
|
+
for e in evals:
|
|
53
|
+
lab = label_by_run.get(e.get("run_id"))
|
|
54
|
+
if lab not in ("pass", "fail"):
|
|
55
|
+
continue
|
|
56
|
+
pred_pass = str(e.get("verdict", "")).upper() in passing
|
|
57
|
+
if pred_pass and lab == "pass":
|
|
58
|
+
tp += 1
|
|
59
|
+
elif pred_pass and lab == "fail":
|
|
60
|
+
fp += 1
|
|
61
|
+
elif not pred_pass and lab == "fail":
|
|
62
|
+
tn += 1
|
|
63
|
+
else:
|
|
64
|
+
fn += 1
|
|
65
|
+
n = tp + tn + fp + fn
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def kappa():
|
|
69
|
+
if n == 0:
|
|
70
|
+
return None
|
|
71
|
+
po = (tp + tn) / n
|
|
72
|
+
pe = (((tp + fp) * (tp + fn)) + ((fn + tn) * (fp + tn))) / (n * n)
|
|
73
|
+
return None if pe == 1 else (po - pe) / (1 - pe)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
avg_corr = (sum(corrections_by_run.values()) / len(corrections_by_run)) if corrections_by_run else None
|
|
77
|
+
tripwire = pass_rate is not None and avg_corr is not None and pass_rate >= 0.8 and avg_corr >= 1.5
|
|
78
|
+
|
|
79
|
+
print(f"PMOS kit metrics — {len(runs)} run(s), {len(evals)} eval(s), {len(acc)} acceptance record(s)\n")
|
|
80
|
+
if tripwire:
|
|
81
|
+
print("🔴 GOODHART TRIPWIRE FIRED — evaluator passes >=80% while humans average >=1.5 corrections/run.")
|
|
82
|
+
print(" The north star is being gamed; treat the Review Gate as NOT calibrated (D40).\n")
|
|
83
|
+
if not accepted:
|
|
84
|
+
print("🔴 B1 north star: UNMEASURABLE — no accepted runs yet (record acceptances to pmos/state/acceptances.jsonl).")
|
|
85
|
+
else:
|
|
86
|
+
ns = sum(acc_corr) / len(accepted)
|
|
87
|
+
print(f"B1 north star: {ns:.2f} human corrections per accepted run (over {len(accepted)} accepted run(s); lower is better)")
|
|
88
|
+
print(f"B2 throughput: {len(accepted)} accepted run(s)")
|
|
89
|
+
print(f" eval pass rate: {'n/a — no evals yet' if pass_rate is None else f'{pass_rate:.0%} ({n_pass}/{len(evals)})'}")
|
|
90
|
+
k = kappa()
|
|
91
|
+
if n == 0:
|
|
92
|
+
print("🔴 B4 calibration: UNMEASURABLE — no eval joined to a PM-labelled acceptance yet; the Review Gate is uncalibrated.")
|
|
93
|
+
else:
|
|
94
|
+
tpr = tp / (tp + fn) if (tp + fn) else None
|
|
95
|
+
tnr = tn / (tn + fp) if (tn + fp) else None
|
|
96
|
+
print(f"B4 calibration (n={n}): raw agreement {(tp + tn) / n:.0%}, "
|
|
97
|
+
f"TPR {'n/a' if tpr is None else f'{tpr:.0%}'}, "
|
|
98
|
+
f"TNR {'n/a — no PM fails seen (leniency blind spot)' if tnr is None else f'{tnr:.0%}'}, "
|
|
99
|
+
f"kappa {'undefined' if k is None else f'{k:.2f}'} (target >= 0.60 — verdict ADVISORY below it, D40)")
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# SKILL-FORMAT.md — Required Format for PMOS Skills
|
|
2
|
+
|
|
3
|
+
This document defines the **required** structure for every `.skill` file in PMOS. It is the
|
|
4
|
+
authority that all seed skills (`prd`, `eval-rubric`, `okr`, `strategic-brief`, `source-to-concept`)
|
|
5
|
+
and every future skill must conform to.
|
|
6
|
+
|
|
7
|
+
## Why a fixed format
|
|
8
|
+
|
|
9
|
+
Skills are how PMOS gives an agent procedural competence on demand without flooding its context.
|
|
10
|
+
The format exists to make that economical: cheap to keep many skills available, expensive to load
|
|
11
|
+
only the one in use. The mechanism is **three-level progressive disclosure**.
|
|
12
|
+
|
|
13
|
+
## The three levels
|
|
14
|
+
|
|
15
|
+
### Level 1 — Frontmatter (always loaded)
|
|
16
|
+
|
|
17
|
+
YAML frontmatter containing **only `name` and `description`**. This is pre-loaded for **all** skills
|
|
18
|
+
at agent startup, so it must stay small — it is the *trigger signal* the agent uses to decide
|
|
19
|
+
whether the skill is relevant.
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
---
|
|
23
|
+
name: prd
|
|
24
|
+
description: Write a Product Requirements Document for an initiative. Use when an initiative needs a spec before build work begins.
|
|
25
|
+
---
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Rules:
|
|
29
|
+
- `name` — lowercase, matches the filename stem (`prd` → `prd.skill`). **Required.**
|
|
30
|
+
- `description` — one or two sentences. State **what** the skill does and **when** to use it.
|
|
31
|
+
This is the only text the agent sees for an unloaded skill, so the "when" is what makes it fire.
|
|
32
|
+
**Required.**
|
|
33
|
+
- `maturity_mode` — **optional**. Present **only** on skills that are not yet active (e.g. `bootstrap`);
|
|
34
|
+
omit it entirely on active skills. It lives at L1 because "is this skill executable yet?" is an
|
|
35
|
+
execution-gating signal a loader/CI must be able to read without parsing the body. Values: `bootstrap`
|
|
36
|
+
(specified, non-executable) → graduates to active (key removed) by a PM decision in `DECISIONS.md`.
|
|
37
|
+
- **Optional Phase-B registry metadata (D49)** — a skill may also carry `version`, `owner`, `risk`,
|
|
38
|
+
`category`, and `scope`. These are **optional**, producer-defined registry fields that
|
|
39
|
+
[`gen_skills_seed.sh`](/supabase/seed/gen_skills_seed.sh) sources into the `skills` table so the skill
|
|
40
|
+
library can group/version/scope skills. A skill with only `name` + `description` is still fully
|
|
41
|
+
conformant (e.g. `build-skills/evaluator.skill`); carry the registry keys on durable `skills/core/`
|
|
42
|
+
entries for consistency with their siblings.
|
|
43
|
+
- **No other L1 keys.** Beyond the required `name` + `description`, the optional `maturity_mode`, and the
|
|
44
|
+
optional Phase-B registry keys above, procedural detail does not belong in L1 — it lives in the body.
|
|
45
|
+
|
|
46
|
+
### Level 2 — SKILL.md body (loaded when relevant)
|
|
47
|
+
|
|
48
|
+
The body below the frontmatter holds the **full procedural detail**: steps, heuristics, required
|
|
49
|
+
fields, gate criteria, examples. The agent reads this only after Level 1 has signalled relevance.
|
|
50
|
+
|
|
51
|
+
This is where the actual "how to do the task" lives. Write it at optimal altitude — concrete
|
|
52
|
+
heuristics that guide judgment, not a brittle decision tree and not a vague mandate.
|
|
53
|
+
|
|
54
|
+
### Level 3 — Linked sub-files (loaded on demand)
|
|
55
|
+
|
|
56
|
+
Rare sub-cases, long reference tables, or edge-case procedures live in **separate files**,
|
|
57
|
+
referenced **by filename** from the Level 2 body. The agent reads them only when the body points it
|
|
58
|
+
there for the specific case in hand.
|
|
59
|
+
|
|
60
|
+
Example reference from a body: *"For multi-product PRDs, follow `prd-multiproduct.md`."*
|
|
61
|
+
|
|
62
|
+
Use Level 3 to keep Level 2 focused. If a section applies to <20% of runs, it is a Level 3
|
|
63
|
+
candidate.
|
|
64
|
+
|
|
65
|
+
## File naming
|
|
66
|
+
|
|
67
|
+
- Skill files use the `.skill` extension: `prd.skill`, `eval-rubric.skill`.
|
|
68
|
+
- Level 3 sub-files are plain `.md` and live alongside the skill or in a named subfolder.
|
|
69
|
+
|
|
70
|
+
## Skill namespaces
|
|
71
|
+
|
|
72
|
+
- `/skills/core/` — seed skills, canonical across PMOS.
|
|
73
|
+
- `/skills/domains/` — domain-specific variants (P1).
|
|
74
|
+
- `/skills/pm/<pm_slug>/` — PM-specific variants (e.g. `/skills/pm/wawan/`).
|
|
75
|
+
- `/build-skills/` — skills for the coding agents that build PMOS itself (distinct from PM skills).
|
|
76
|
+
|
|
77
|
+
## Conformance checklist
|
|
78
|
+
|
|
79
|
+
A skill is well-formed when:
|
|
80
|
+
|
|
81
|
+
1. Level 1 frontmatter has `name` + `description` (both required), plus optionally `maturity_mode` (on
|
|
82
|
+
non-active skills) and the Phase-B registry keys `version`/`owner`/`risk`/`category`/`scope` (D49);
|
|
83
|
+
no other L1 keys.
|
|
84
|
+
2. `name` matches the filename stem.
|
|
85
|
+
3. `description` states both what the skill does and when to use it.
|
|
86
|
+
4. The body (Level 2) carries the full procedure and is self-sufficient for the common case.
|
|
87
|
+
5. Edge cases are pushed to Level 3 sub-files and referenced by filename.
|
|
88
|
+
|
|
89
|
+
All five seed skills are authored against this checklist.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: eval-rubric
|
|
3
|
+
description: Author an evaluation rubric for an initiative — the measurable definition of "good" used to judge agent output. Use before any build starts; the eval is written first, paired with the PRD.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
owner: wawan
|
|
6
|
+
risk: low
|
|
7
|
+
category: eval
|
|
8
|
+
scope: read:okf, write:planning/evals
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# eval-rubric — Author an Evaluation Rubric
|
|
12
|
+
|
|
13
|
+
This skill produces an eval rubric instance for one initiative. In eval-driven PM the rubric **is the
|
|
14
|
+
spec made measurable** ([eval-driven-pm](/okf/core/concepts/eval-driven-pm.md)): it is authored
|
|
15
|
+
*before* the build, alongside the [PRD](/skills/core/prd.skill), and it defines how output will pass
|
|
16
|
+
through the [three-tier gate](/okf/core/concepts/output-eval.md).
|
|
17
|
+
|
|
18
|
+
> **Format note:** three-level progressive disclosure
|
|
19
|
+
> ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1 frontmatter above is the trigger and
|
|
20
|
+
> carries only `name` + `description`. Note: the *rubric instances* this skill produces carry their
|
|
21
|
+
> own frontmatter (including `eval_type`, below) — that is the rubric's frontmatter, not this skill
|
|
22
|
+
> file's.
|
|
23
|
+
|
|
24
|
+
## The three-tier gate vocabulary
|
|
25
|
+
|
|
26
|
+
A rubric is written with the gate it serves in mind. Name the tiers explicitly; they are not
|
|
27
|
+
interchangeable:
|
|
28
|
+
|
|
29
|
+
- **Quality Gate** — *deterministic, automated.* Compile, lint, unit tests. Toolchain-enforced
|
|
30
|
+
pass/fail. No human judgment. A rubric's Quality-Gate criteria must be machine-checkable.
|
|
31
|
+
- **Review Gate** — *probabilistic, adversarial.* Does the output satisfy the rubric's criteria?
|
|
32
|
+
Applied by a separate evaluator agent or by the PM as critic. This is where the weighted dimensions
|
|
33
|
+
below are scored. Treat its verdict as **uncalibrated** until validated
|
|
34
|
+
([evaluator leniency](/okf/core/concepts/output-eval.md)).
|
|
35
|
+
- **Acceptance Gate** — *subjective, strategic.* Is this the **right** thing? Human PM only. **This
|
|
36
|
+
is NOT a re-check of the rubric.** The PM's role at the end of every agent run **is** the
|
|
37
|
+
Acceptance Gate — a strategic-fit decision, not a re-scoring of dimensions.
|
|
38
|
+
|
|
39
|
+
Make this explicit in every rubric: state which criteria belong to which gate, and state that the
|
|
40
|
+
Acceptance Gate is the PM's and is not graded by the rubric.
|
|
41
|
+
|
|
42
|
+
## Required frontmatter on the rubric instance
|
|
43
|
+
|
|
44
|
+
Every rubric document carries, at minimum:
|
|
45
|
+
|
|
46
|
+
- `type: Rubric` (or as the bundle/planning convention requires)
|
|
47
|
+
- **`eval_type: capability | regression`** —
|
|
48
|
+
- `capability` — tests whether the agent can do something new / harder. Used to push the frontier.
|
|
49
|
+
- `regression` — guards an already-passing capability against backsliding. Saturated capability
|
|
50
|
+
rubrics retire into the regression suite.
|
|
51
|
+
- `initiative_id`, `product_slug`, `pm_slug`, parent `KR`.
|
|
52
|
+
|
|
53
|
+
## Grading rules
|
|
54
|
+
|
|
55
|
+
1. **Outcome-only grading.** Criteria check **what the agent produced**, not the path it took. **Do
|
|
56
|
+
not grade tool call sequences**, intermediate reasoning, or how many steps were taken. A correct
|
|
57
|
+
outcome by an unexpected route still passes.
|
|
58
|
+
2. **Weighted dimensions with partial credit.** Each rubric dimension gets a **weight**. Each is
|
|
59
|
+
scored (not just pass/fail), the weighted scores are **summed to a total**, and the total is
|
|
60
|
+
compared against a **pass threshold**. **Partial credit is required** — a rubric that is
|
|
61
|
+
all-or-nothing per dimension is malformed. See
|
|
62
|
+
[eval-rubric-template](/okf/core/templates/eval-rubric-template.md) for the scoring math.
|
|
63
|
+
3. **Pre-commit the threshold.** The pass threshold is set when the rubric is written, before output
|
|
64
|
+
exists — not tuned afterward to match what came back.
|
|
65
|
+
|
|
66
|
+
### Worked shape
|
|
67
|
+
|
|
68
|
+
| Dimension | Weight | Score (0–1) | Weighted |
|
|
69
|
+
|-----------|-------:|------------:|---------:|
|
|
70
|
+
| Correctness | 0.40 | … | … |
|
|
71
|
+
| Completeness vs PRD | 0.30 | … | … |
|
|
72
|
+
| Conformance (format/spec) | 0.20 | … | … |
|
|
73
|
+
| Clarity | 0.10 | … | … |
|
|
74
|
+
| **Total** | **1.00** | | **vs threshold** |
|
|
75
|
+
|
|
76
|
+
## Sprint contract (pre-run contract)
|
|
77
|
+
|
|
78
|
+
Before any work begins, the generator and evaluator **agree on done-criteria** — this is the
|
|
79
|
+
contract stage of the [SDLC loop](/okf/core/concepts/sdlc-loop.md). A rubric is incomplete without
|
|
80
|
+
one.
|
|
81
|
+
|
|
82
|
+
**Format:**
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
initiative_id: <id>
|
|
86
|
+
run_id: <id>
|
|
87
|
+
done_criteria:
|
|
88
|
+
1. <testable criterion>
|
|
89
|
+
2. <testable criterion>
|
|
90
|
+
...
|
|
91
|
+
test_method:
|
|
92
|
+
1. <how criterion 1 is verified>
|
|
93
|
+
2. <how criterion 2 is verified>
|
|
94
|
+
...
|
|
95
|
+
PM_approved: true | false
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- **P0 (manual):** write the contract to a temp file and get explicit **PM approval** before work
|
|
99
|
+
starts. `PM_approved` must be `true` to proceed.
|
|
100
|
+
- **P1+:** the contract is stored in `agent_runs.pre_run_contract`.
|
|
101
|
+
|
|
102
|
+
The contract and the rubric are consistent by construction: every `done_criterion` maps to rubric
|
|
103
|
+
dimensions, and `test_method` states the gate (Quality/Review) that checks it.
|
|
104
|
+
|
|
105
|
+
## Output and placement
|
|
106
|
+
|
|
107
|
+
- Rubric instances are **operational** — they live under `/planning/evals/`, not in the OKF bundle.
|
|
108
|
+
- Filename: slugged to the initiative, e.g. `p0-eval-rubric.md`.
|
|
109
|
+
|
|
110
|
+
## Quality bar
|
|
111
|
+
|
|
112
|
+
Before handoff: `eval_type` set; every dimension weighted; weights sum to 1.0; partial credit
|
|
113
|
+
possible; threshold pre-committed; gate assignment stated per criterion; Acceptance Gate marked as
|
|
114
|
+
PM-owned and not rubric-graded; sprint contract present with `PM_approved`.
|
|
115
|
+
|
|
116
|
+
## Level 3 sub-cases
|
|
117
|
+
|
|
118
|
+
- Calibrating a leniency-prone evaluator against
|
|
119
|
+
[eval-calibration.md](/planning/evals/eval-calibration.md): see `eval-calibration-procedure.md`
|
|
120
|
+
(author on first need).
|
|
121
|
+
- Rubrics for non-code deliverables (docs, strategy): see `eval-rubric-nontext.md`
|
|
122
|
+
(author on first need).
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: evaluator
|
|
3
|
+
description: Adversarially evaluate an agent run's output against its rubric and persist the verdict (the self-hosted Review Gate). Use after any build run, before the PM Acceptance Gate.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# evaluator — The Self-Hosted Review Gate
|
|
7
|
+
|
|
8
|
+
This skill is PMOS's **Review Gate** made a first-class, repeatable capability (P4). It formalizes the
|
|
9
|
+
adversarial independent evaluator run by hand through P1–P3: judge what an agent run produced against a
|
|
10
|
+
rubric, write a structured verdict to the `evals` table, and surface it on the radar/board. It runs in
|
|
11
|
+
**Claude Code** (heavy judgment), not an Edge Function ([D34](/DECISIONS.md)).
|
|
12
|
+
|
|
13
|
+
> **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1
|
|
14
|
+
> frontmatter above is the trigger. This Level 2 body is the full procedure.
|
|
15
|
+
|
|
16
|
+
## Non-negotiable stance
|
|
17
|
+
|
|
18
|
+
- **Independent.** Evaluate in a fresh context, separate from the builder. Never rubber-stamp.
|
|
19
|
+
- **Adversarial / default-to-refute.** For each claimed property, try to *refute* it. Assume a defect
|
|
20
|
+
exists until you've looked. The builder's self-eval is **lenient** by default
|
|
21
|
+
([evaluator leniency](/okf/core/concepts/output-eval.md), [D20](/DECISIONS.md)) — your job is to catch
|
|
22
|
+
what it overstated.
|
|
23
|
+
- **Outcome-only ([D14](/DECISIONS.md)).** Grade what the run *produced* — the artifact, the diff, the
|
|
24
|
+
live behavior — **not** the tool-call sequence or the path taken. A right answer reached "the wrong
|
|
25
|
+
way" still passes; a wrong answer reached tidily still fails.
|
|
26
|
+
- **Self-preference bias — distrust your own praise.** You are a **Claude evaluator judging
|
|
27
|
+
Claude-built work**, so you carry a built-in bias to over-reward outputs in your own family's style
|
|
28
|
+
([D40](/DECISIONS.md)). Counter it: **default to skeptical**, and when a pass feels easy or you are
|
|
29
|
+
uncertain, **say so explicitly** and flag the run for the cross-family spot-check / minority-veto jury
|
|
30
|
+
([calibration-method](/planning/evals/calibration-method.md)). Do not let stylistic familiarity read as
|
|
31
|
+
quality.
|
|
32
|
+
- **Advisory, not final.** Your verdict informs; it does not decide. The human PM **Acceptance Gate**
|
|
33
|
+
([D12](/DECISIONS.md)) is the final authority, and this gate is **uncalibrated** until it clears the
|
|
34
|
+
calibration threshold. Calibration is now measured like a classifier — **Cohen's kappa ≥ 0.60 against
|
|
35
|
+
PM labels** (TPR/TNR, not a streak) per [D40](/DECISIONS.md), which **supersedes** D20's "3 consecutive
|
|
36
|
+
agreements" standard. Say in the verdict that the gate is advisory until that kappa threshold is met.
|
|
37
|
+
|
|
38
|
+
## Procedure
|
|
39
|
+
|
|
40
|
+
1. **Read [AGENTS.md](/AGENTS.md)** and the run's `pre_run_contract` (the agreed done-criteria).
|
|
41
|
+
2. **Get the rubric** — `get_eval_rubric` (or the `rubric_path`). If none fits, use the reusable
|
|
42
|
+
[agent-run rubric](/planning/evals/agent-run-eval-rubric.md). Note its weighted dimensions + pass
|
|
43
|
+
threshold ([D15](/DECISIONS.md)).
|
|
44
|
+
3. **Read the actual output** — the committed diff, the migration/function/UI, and where possible the
|
|
45
|
+
**live behavior** (run the query, hit the endpoint, read the CI result). Verify, don't trust the
|
|
46
|
+
summary. The highest-value findings come from checking claims against reality. Three probes catch the
|
|
47
|
+
defect classes builder self-eval reliably misses (from `eval-calibration.md`):
|
|
48
|
+
- **Does the gate actually gate?** Check the enforcement's own teeth — a *required*-check /
|
|
49
|
+
branch-protection / applied config, not just the script logic. A gate that isn't a required check
|
|
50
|
+
doesn't gate. *(workflow-enforcement-gate.)*
|
|
51
|
+
- **Does defensive code HIDE a failure?** A blank/empty/`allSettled`/error-swallowing fallback that
|
|
52
|
+
renders green instead of surfacing red is a false-confidence defect. *(p2-monitoring blank north-star
|
|
53
|
+
tile / radar-blanking throw.)*
|
|
54
|
+
- **Documented ≠ in-effect.** A criterion written down but not actually applied live (a raised TTL, a
|
|
55
|
+
revoked grant) is a FAIL. *(p1-mcp-connect JWT-TTL.)*
|
|
56
|
+
4. **Grade each contract criterion reference-guided BINARY pass/fail** — not vibes. The **reference** is
|
|
57
|
+
the run's `pre_run_contract` ([D16](/DECISIONS.md)): for each `done_criteria` item, did the produced
|
|
58
|
+
outcome satisfy it, judged against its `test_method` and **outcome-only** (D14)? Emit a crisp PASS or
|
|
59
|
+
FAIL per criterion (no "mostly met"). These binary verdicts are what feed the PM-label confusion matrix
|
|
60
|
+
(D40); be conservative — an unverified criterion is a FAIL, not a pass.
|
|
61
|
+
5. **Score each weighted dimension** 0..1 with a one-line justification grounded in what you observed.
|
|
62
|
+
Compute the weighted total (partial credit, D15) and compare to the pass threshold. The dimension score
|
|
63
|
+
is the numeric aggregate; the per-criterion binary grades above are the honest pass/fail backbone.
|
|
64
|
+
6. **Enumerate defects** — each with `severity` (critical / must-fix / should-fix / low / nit), the
|
|
65
|
+
specific file+line or behavior, why it's a problem, and a concrete fix. Lead with the single most
|
|
66
|
+
important finding.
|
|
67
|
+
7. **Decide a verdict**: `PASS` / `PASS-WITH-FINDINGS` / `FAIL`. PASS-WITH-FINDINGS is correct when the
|
|
68
|
+
work is acceptable but carries non-blocking defects.
|
|
69
|
+
8. **Persist it** — `save_eval({ initiative_id, run_id, rubric_path, score, verdict, dimensions })`,
|
|
70
|
+
where `dimensions` is `{ <name>: { score, weight, note } }`. This is what makes the gate self-hosting
|
|
71
|
+
— the verdict lands in `evals` and surfaces on `v_eval_gate_status` (radar/board).
|
|
72
|
+
9. **Hand to the PM.** The Acceptance Gate is theirs, and the PM records the ground-truth `pm_label` to
|
|
73
|
+
`acceptances` — paired against your verdict by `v_calibration` to compute the kappa that calibrates this
|
|
74
|
+
gate ([D40](/DECISIONS.md), [calibration-method](/planning/evals/calibration-method.md)). If the PM
|
|
75
|
+
overrides your verdict, that override is logged to
|
|
76
|
+
[eval-calibration.md](/planning/evals/eval-calibration.md) and the calibration loop patches this skill.
|
|
77
|
+
|
|
78
|
+
## Output shape
|
|
79
|
+
|
|
80
|
+
A short report: **most important finding first**, then VERDICT (score vs threshold), the numbered
|
|
81
|
+
defects, and the per-dimension scores — followed by the `save_eval` call. Be concrete; cite specifics;
|
|
82
|
+
if it is genuinely solid, say so — but only after a real refutation attempt.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ingest-repo
|
|
3
|
+
description: Scan an existing product repository read-only and emit a DRAFT OKF reference layer (architecture, per-table, capability ledger, integrations, conventions, ADR seeds) + register the repo, so a build agent starts warm. Use when a PM brings a product that already ships and has a repo. Never writes the tenant repo; never emits secrets.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
owner: wawan
|
|
6
|
+
risk: medium
|
|
7
|
+
category: onboarding
|
|
8
|
+
scope: read:tenant-repo, write:tenant-okf-drafts, write:product_repos
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ingest-repo — Warm-start an existing product from its code
|
|
12
|
+
|
|
13
|
+
This skill is the **existing-repo on-ramp**: a PM arrives with a product that already ships and already
|
|
14
|
+
has a repo, and PMOS needs knowledge of it so a build agent doesn't cold-start on every run (re-deriving
|
|
15
|
+
the stack, assuming wrong, producing work the PM must heavily correct — the north-star cost). It is the
|
|
16
|
+
**inverse of [analyze-product-infra](/build-skills/analyze-product-infra.skill)** (which goes PRD →
|
|
17
|
+
what the product *needs*): ingest-repo goes **code → what the product *is***. It emits a **draft** OKF
|
|
18
|
+
reference layer + a repo registration and then **stops for PM approval**.
|
|
19
|
+
|
|
20
|
+
> **Format:** three-level progressive disclosure ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). L1
|
|
21
|
+
> frontmatter above is the trigger; this L2 body is the full procedure.
|
|
22
|
+
> **Where it runs:** in **Claude Code**, in the tenant's own conversation, read-only — never a
|
|
23
|
+
> server-side scanner ([D51](/okf/products/pmos/adr/d51-scan-location.md); heavy reasoning runs in Code
|
|
24
|
+
> per [D09](/okf/products/pmos/adr/d09-skills-execute-in-claude-code.md)).
|
|
25
|
+
|
|
26
|
+
## Non-negotiable stance
|
|
27
|
+
|
|
28
|
+
- **Read-only, at control altitude ([D01](/okf/products/pmos/adr/d01-control-plane.md)).** Zero writes
|
|
29
|
+
to the tenant repo — no files, no branches, no commits. If `git status` is not clean after the run,
|
|
30
|
+
that is a defect.
|
|
31
|
+
- **No secrets, ever ([D08](/okf/products/pmos/adr/d08-never-log-request-headers.md)).** Read only env
|
|
32
|
+
var *names* (`.env.example`, config keys). **Secret-scan the repo content AND git history** (real
|
|
33
|
+
repos leak keys in committed code/history); if a secret value is found, **never** place it in a doc,
|
|
34
|
+
a log, or the registry — note only that a leak exists and where, by path, so the PM can rotate it.
|
|
35
|
+
- **Default-to-refute on capability** (the [design-reconcile](/skills/core/design-reconcile.skill)
|
|
36
|
+
stance applied to code): a control/route is **watermelon** until a concrete backend read/write path
|
|
37
|
+
is found in the code. Unbacked controls land in **§D**, not invented as capability.
|
|
38
|
+
- **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)).**
|
|
39
|
+
`save_okf_doc(... status:'draft')`. The agent proposes; the **PM approves in-app**. Retrieval note:
|
|
40
|
+
a PM's own build agent *can* read its own tenant drafts (get_okf_concepts returns owner-scoped drafts,
|
|
41
|
+
the ratified 2026-07-02 draft-visible-to-own-agent stance), so warm-start works immediately; approval
|
|
42
|
+
governs promotion/trust, not visibility to the owner's own agent.
|
|
43
|
+
- **Tenant-only.** `save_okf_doc` rejects `pmos`; this never writes the PMOS-self git bundle.
|
|
44
|
+
- **Idempotent.** Re-running upserts docs (on `id`) and reconciles the registry (on `product_slug`) —
|
|
45
|
+
no duplicates.
|
|
46
|
+
|
|
47
|
+
## Procedure
|
|
48
|
+
|
|
49
|
+
1. **Read [AGENTS.md](/AGENTS.md)** and confirm the target `product_slug` (owner-scoped; one product).
|
|
50
|
+
2. **Read-only scan** of the tenant repo, gathering *cited* evidence (every claim will carry the repo
|
|
51
|
+
path it came from):
|
|
52
|
+
- **Stack & app surface** — manifests/lockfiles (`package.json`, `pyproject.toml`, `go.mod`, …),
|
|
53
|
+
framework config, entrypoints.
|
|
54
|
+
- **Architecture** — directory tree, entrypoints, module boundaries.
|
|
55
|
+
- **Data model** — migrations / schema / ORM models: one asset per table/model (columns + RLS/perm
|
|
56
|
+
shape where expressed).
|
|
57
|
+
- **Capability map** — trace **routes ↔ handlers ↔ queries**: which UI control/route reaches which
|
|
58
|
+
backend read/write. This is the raw material for the ledger.
|
|
59
|
+
- **Integrations** — config + SDK imports + `.env.example` **names only** (maps, transcription,
|
|
60
|
+
push, payments, storage, …).
|
|
61
|
+
- **Decisions & conventions** — README / ADRs / CHANGELOG / commit history (existing decisions);
|
|
62
|
+
CI config, lint rules, observed patterns (conventions).
|
|
63
|
+
3. **Secret-scan** repo content + git history (e.g. high-entropy strings, known key prefixes). Emit
|
|
64
|
+
**no** value; record only "possible secret at `<path>`" for the PM.
|
|
65
|
+
4. **Emit the reference layer** — via `save_okf_doc(..., status:'draft', product_slug:<slug>)`,
|
|
66
|
+
namespaced `products/<slug>/...`, **each body carrying situating context + the exact repo path(s)**
|
|
67
|
+
it was derived from (the [source-to-concept](/skills/core/source-to-concept.skill) rule + the
|
|
68
|
+
analyze-product-infra cited-line bar, applied to code). Minimum six kinds:
|
|
69
|
+
|
|
70
|
+
| Doc | OKF `type` | id (under `products/<slug>/`) | derived from |
|
|
71
|
+
|---|---|---|---|
|
|
72
|
+
| Architecture / stack overview | `Concept` | `concepts/architecture` | manifests + tree + entrypoints |
|
|
73
|
+
| Per-table/model schema (one each) | `Reference` | `data-model/<table>` | migrations / ORM models |
|
|
74
|
+
| **Capability ledger** | `Reference` | `references/capability-ledger` | routes ↔ handlers ↔ queries |
|
|
75
|
+
| Integration map | `Reference` | `references/integrations` | config + SDK imports + .env.example names |
|
|
76
|
+
| Conventions | `Concept` | `concepts/conventions` | CI/lint config + observed patterns |
|
|
77
|
+
| ADR seed(s) | `ADR` | `adr/<slug>-<n>-<topic>` | README / ADRs / commit history |
|
|
78
|
+
|
|
79
|
+
5. **Bootstrap the per-tenant capability ledger** (the artifact
|
|
80
|
+
[design-reconcile](/skills/core/design-reconcile.skill) consumes, [D50](/okf/products/pmos/adr/d50-design-loop-product-scoped.md)
|
|
81
|
+
pattern — generic method, per-tenant instance). Classify **every** user-facing control/route into
|
|
82
|
+
exactly one bucket; each §A/§B entry **names the concrete read/write path** in the code:
|
|
83
|
+
- **§A — read-backed:** maps to a real backend read (query/endpoint) — cite it.
|
|
84
|
+
- **§B — write-backed:** maps to a real backend write (mutation/endpoint) — cite it.
|
|
85
|
+
- **§C — data-exists-unsurfaced:** the data exists but no control surfaces it (opt-in opportunity).
|
|
86
|
+
- **§D — no-backing (watermelon):** a control with no backend path found — flagged, not invented.
|
|
87
|
+
6. **Register the repo** — `register_product_repo({ product_slug, repo:'owner/name',
|
|
88
|
+
app_surface:<observed>, backend_model:<observed>, status:'active', irs_ref:<repo-profile doc id>,
|
|
89
|
+
webhook_secret_ref: <name-or-null> })`. Fields are **observed** here (not IRS-derived); pass **no
|
|
90
|
+
secret value**. Add an "observed, not IRS-derived" provenance note.
|
|
91
|
+
7. **STOP for PM approval.** Present the drafted layer + the ledger's §D watermelon list + any secret
|
|
92
|
+
findings. The PM approves docs in-app; you do not self-approve. Log the run + friction.
|
|
93
|
+
|
|
94
|
+
## Guardrails
|
|
95
|
+
|
|
96
|
+
- **Provenance is a hard gate.** An emitted doc with an un-sourced assertion is a defect — the
|
|
97
|
+
evaluator's provenance dimension hunts for exactly this ([rubric](/planning/evals/ingest-repo-eval-rubric.md)).
|
|
98
|
+
- **Large/polyglot monorepos:** flag scope to the PM and do a per-package pass; do **not** emit a
|
|
99
|
+
shallow single profile.
|
|
100
|
+
- **`register_product_repo` semantics:** designed for provisioning output — here `app_surface`/
|
|
101
|
+
`backend_model` are *observed*, a usage-only difference (no schema change); note it.
|
|
102
|
+
- **B5 measurability:** the value thesis is "warm start → fewer corrections"; the first post-ingest
|
|
103
|
+
build run should retrieve these concepts (B5 > 0 for the tenant, via
|
|
104
|
+
[v_knowledge_reuse](/okf/products/pmos/references/metrics/v_knowledge_reuse.md) — now written by
|
|
105
|
+
get_okf_concepts FETCH). That real correction-delta, not the doc count, is the win.
|
|
106
|
+
|
|
107
|
+
## Level 3 — references
|
|
108
|
+
|
|
109
|
+
- The write path + PM gate: [okf-author](/build-skills/okf-author.skill) Mode B, [D37](/okf/products/pmos/adr/d37-tenant-okf-db-native.md).
|
|
110
|
+
- The ledger method: [design-loop concept](/okf/core/concepts/design-loop.md),
|
|
111
|
+
[design-reconcile](/skills/core/design-reconcile.skill), [watermelon-flag](/okf/core/concepts/watermelon-flag.md).
|
|
112
|
+
- Extraction discipline: [source-to-concept](/skills/core/source-to-concept.skill).
|
|
113
|
+
- Scan location: [D51](/okf/products/pmos/adr/d51-scan-location.md). Registry:
|
|
114
|
+
[register_product_repo](/okf/products/pmos/references/mcp-tools/register_product_repo.md),
|
|
115
|
+
[product_repos](/okf/products/pmos/data-model/product_repos.md).
|
|
116
|
+
- Sibling on-ramps: [analyze-product-infra](/build-skills/analyze-product-infra.skill),
|
|
117
|
+
[product-onboarding playbook](/okf/core/playbooks/product-onboarding.md).
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: okr
|
|
3
|
+
description: Draft or revise an OKR set for a planning period — objectives with measurable key results that initiatives ladder up to. Use when setting quarterly strategy or re-anchoring drifting work.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
owner: wawan
|
|
6
|
+
risk: low
|
|
7
|
+
category: planning
|
|
8
|
+
scope: read:okf, write:planning/okrs
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# okr — Draft or Revise an OKR Set
|
|
12
|
+
|
|
13
|
+
This skill produces an OKR instance for a planning period: a small set of objectives, each with
|
|
14
|
+
measurable key results, structured as a tree that initiatives and agent runs ladder up to. It
|
|
15
|
+
operationalizes the [okr-tree](/okf/core/concepts/okr-tree.md) concept.
|
|
16
|
+
|
|
17
|
+
> **Format note:** three-level progressive disclosure
|
|
18
|
+
> ([SKILL-FORMAT](/skills/core/SKILL-FORMAT.md)). Level 1 above is the trigger; this body is the
|
|
19
|
+
> procedure; rare variants go to Level 3 sub-files.
|
|
20
|
+
|
|
21
|
+
## When to use vs. not
|
|
22
|
+
|
|
23
|
+
- **Use** to set strategy for a planning period, or to re-anchor an initiative that has drifted from
|
|
24
|
+
its parent KR.
|
|
25
|
+
- **Do not use** to spec a single piece of work — that is the [PRD skill](/skills/core/prd.skill).
|
|
26
|
+
OKRs sit one level above initiatives.
|
|
27
|
+
|
|
28
|
+
## Procedure
|
|
29
|
+
|
|
30
|
+
1. **Objectives: qualitative and few.** 2–4 objectives for the period. Each is directional and
|
|
31
|
+
inspirational, carries no number itself, and states a "what we want to be true."
|
|
32
|
+
2. **Key results: measurable outcomes.** 2–5 KRs per objective. Each is a **change in the world**,
|
|
33
|
+
not a count of work done — "reduce human correction rate to < 0.5", not "ship 5 features". KRs
|
|
34
|
+
that measure output invite the [watermelon flag](/okf/core/concepts/watermelon-flag.md).
|
|
35
|
+
3. **Ladder to the north star.** Every KR should move, directly or indirectly, the north-star metric
|
|
36
|
+
— **human correction rate per agent run** (lower is better). If a KR ladders to nothing, cut it.
|
|
37
|
+
4. **Baseline and target.** Each KR states current baseline, target, and the measurement source.
|
|
38
|
+
"From X to Y, measured by Z."
|
|
39
|
+
5. **Leave room for initiatives.** OKRs are parents; do not pre-assign every initiative. The tree is
|
|
40
|
+
filled in as work is chosen.
|
|
41
|
+
6. **Set the review cadence.** State when KRs are checked and that reporting follows
|
|
42
|
+
[anti-optimism](/okf/core/concepts/okr-anti-optimism.md): report the red, separate confidence
|
|
43
|
+
from status.
|
|
44
|
+
|
|
45
|
+
## Required content
|
|
46
|
+
|
|
47
|
+
- **Period & identity** — planning period, `product_slug`, `pm_slug`.
|
|
48
|
+
- **Objectives** — numbered, qualitative.
|
|
49
|
+
- **Key results** — per objective: baseline → target, measurement source, confidence.
|
|
50
|
+
- **North-star linkage** — how the set ladders to human correction rate.
|
|
51
|
+
- **Cadence** — review rhythm and reporting stance.
|
|
52
|
+
|
|
53
|
+
## Output and placement
|
|
54
|
+
|
|
55
|
+
- OKR instances are **operational** — under `/planning/okrs/`, not in the OKF bundle.
|
|
56
|
+
- Filename: period-slugged, e.g. `okrs-q3-2026.md`.
|
|
57
|
+
|
|
58
|
+
## Quality bar
|
|
59
|
+
|
|
60
|
+
Before handoff: objectives are qualitative; KRs are outcomes with baseline+target+source; every KR
|
|
61
|
+
ladders toward the north star; reporting stance is anti-optimist; no initiative is smuggled in as a
|
|
62
|
+
KR.
|
|
63
|
+
|
|
64
|
+
## Level 3 sub-cases
|
|
65
|
+
|
|
66
|
+
- Mid-period KR revision / re-baselining without resetting objectives: see `okr-rebaseline.md`
|
|
67
|
+
(author on first need).
|
|
68
|
+
- Multi-product objective rollups: see `okr-rollup.md` (author on first need).
|