create-pmos 0.4.0 → 0.6.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/README.md +149 -4
- package/bin/create-pmos.js +97 -8
- package/package.json +7 -3
- package/payload/AGENTS-HUMAN.md +6 -0
- package/payload/AGENTS.md +62 -3
- package/payload/KIT-VERSION +2 -2
- package/payload/README.md +16 -2
- package/payload/SECURITY.md +59 -0
- package/payload/okf/core/concepts/design-loop.md +6 -3
- package/payload/okf/core/concepts/frontmatter-format.md +75 -0
- package/payload/okf/core/concepts/index.md +3 -0
- package/payload/okf/core/concepts/log.md +13 -0
- package/payload/okf/core/templates/design-brief-template.md +1 -1
- package/payload/okf/core/templates/eval-rubric-template.md +12 -10
- package/payload/okf/core/templates/prd-template.md +6 -0
- package/payload/okf/core/templates/prototype-brief-template.md +45 -21
- package/payload/planning/evals/agent-run-eval-rubric.md +10 -7
- package/payload/scripts/frontier.sh +60 -0
- package/payload/scripts/metrics.py +163 -102
- package/payload/scripts/pmos-log.sh +16 -6
- package/payload/skills/SKILL-FORMAT.md +72 -9
- package/payload/skills/discovery.skill +4 -0
- package/payload/skills/eval-rubric.skill +1 -1
- package/payload/skills/evaluator.skill +65 -20
- package/payload/skills/explain-run.skill +9 -6
- package/payload/skills/explain-surface.skill +156 -0
- package/payload/skills/ingest-repo.skill +4 -3
- package/payload/skills/pmos-router.skill +25 -3
- package/payload/skills/prd.skill +8 -0
- package/payload/skills/prototype.skill +106 -41
- package/payload/skills-native/copywriting/SKILL.md +57 -0
- package/payload/skills-native/discovery/SKILL.md +75 -0
- package/payload/skills-native/eval-rubric/SKILL.md +159 -0
- package/payload/skills-native/evaluator/SKILL.md +182 -0
- package/payload/skills-native/explain-run/SKILL.md +121 -0
- package/payload/skills-native/explain-surface/SKILL.md +158 -0
- package/payload/skills-native/ingest-repo/SKILL.md +120 -0
- package/payload/skills-native/okr/SKILL.md +70 -0
- package/payload/skills-native/pmos-router/SKILL.md +81 -0
- package/payload/skills-native/prd/SKILL.md +117 -0
- package/payload/skills-native/prototype/SKILL.md +147 -0
- package/payload/state/tickets/.gitkeep +0 -0
- package/payload/templates/agent-run-eval-rubric.md +10 -7
- package/payload/templates/ticket-template.md +20 -0
- package/workspace/README.md +112 -0
- package/workspace/REMOTE.md +131 -0
- package/workspace/bin/pmos.js +206 -0
- package/workspace/doctor.js +99 -0
- package/workspace/lib/console-state.js +117 -0
- package/workspace/lib/file-mode-parse.js +58 -0
- package/workspace/lib/harness-parse.js +222 -0
- package/workspace/lib/preview-kind.js +98 -0
- package/workspace/lib/rate-limit.js +26 -0
- package/workspace/lib/remote-access.js +235 -0
- package/workspace/lib/review-gate.js +39 -0
- package/workspace/lib/schedule-logic.js +132 -0
- package/workspace/lib/skill-store.js +143 -0
- package/workspace/lib/surface-contract.js +79 -0
- package/workspace/lib/transcript-read.js +247 -0
- package/workspace/package-lock.json +94 -0
- package/workspace/package.json +23 -0
- package/workspace/public/app.js +1710 -0
- package/workspace/public/index.html +175 -0
- package/workspace/public/styles.css +766 -0
- package/workspace/server.js +1753 -0
- package/workspace/skills/backlog-triage.skill +13 -0
- package/workspace/skills/weekly-report.skill +19 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Concept
|
|
3
|
+
title: Repo-wide frontmatter format
|
|
4
|
+
description: The PMOS house convention — every tracked .md carries OKF-format YAML frontmatter with a required type + title + timestamp, so agents and the harness classify and route a file by reading it, not by guessing from its path.
|
|
5
|
+
tags: [frontmatter, okf, format, harness, aci, convention]
|
|
6
|
+
timestamp: 2026-07-24
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Repo-wide frontmatter format
|
|
10
|
+
|
|
11
|
+
**Situating context:** authored for the `repo-wide-md-frontmatter` initiative (proposed D63, amends
|
|
12
|
+
D03). The PM's framing — *"OKF is the format, not the folder"* — decouples the OKF **format** (which
|
|
13
|
+
this makes universal) from the `okf/` **bundle** (curated knowledge, unchanged) and from a file's
|
|
14
|
+
**location** (D04, unchanged). This concept is the reference for what the frontmatter lint enforces.
|
|
15
|
+
|
|
16
|
+
## The rule
|
|
17
|
+
|
|
18
|
+
Every **tracked** markdown file MUST open with a YAML frontmatter block declaring three **required**
|
|
19
|
+
keys:
|
|
20
|
+
|
|
21
|
+
| key | meaning | rule |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `type` | what the file *is* | one of the registry values (below); enforced |
|
|
24
|
+
| `title` | human-readable name | non-empty string |
|
|
25
|
+
| `timestamp` | last-modified | valid ISO 8601 date (`YYYY-MM-DD`) or datetime |
|
|
26
|
+
|
|
27
|
+
Recommended-but-optional (OKF): `description`, `tags`, `resource`. Any pre-existing producer keys
|
|
28
|
+
(`initiative_id`, `eval_type`, `parent_KR`, `pass_threshold`, …) are preserved as optional extension
|
|
29
|
+
keys — never stripped.
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
---
|
|
33
|
+
type: Concept
|
|
34
|
+
title: Repo-wide frontmatter format
|
|
35
|
+
timestamp: 2026-07-24
|
|
36
|
+
---
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Relationship to OKF and D03
|
|
40
|
+
|
|
41
|
+
OKF requires only `type`. PMOS layers `title` + `timestamp` as **required house keys**, applied
|
|
42
|
+
**repo-wide** (not just the `okf/` bundle). This is stricter than OKF's minimum but still
|
|
43
|
+
OKF-**conformant** — the spec is permissive about extra keys. It is the deliberate amendment D03
|
|
44
|
+
carries (type-only → richer set, repo-wide). The guardrail against required-key creep is this
|
|
45
|
+
registry: the enforced list of `type` values is closed and versioned.
|
|
46
|
+
|
|
47
|
+
## Reserved files (exempt)
|
|
48
|
+
|
|
49
|
+
OKF's reserved filenames carry **no** frontmatter and are skipped by both the migration and the lint:
|
|
50
|
+
|
|
51
|
+
- `index.md` — a directory listing for progressive disclosure
|
|
52
|
+
- `log.md` — a chronological update history
|
|
53
|
+
|
|
54
|
+
## The `type` registry
|
|
55
|
+
|
|
56
|
+
The enforced list lives in [`scripts/frontmatter_registry.txt`](/scripts/frontmatter_registry.txt) —
|
|
57
|
+
the single source `frontmatter_lint.py` reads. A `type:` value not in it fails CI (this catches typos).
|
|
58
|
+
|
|
59
|
+
- **OKF core:** `Concept`, `ADR`, `Template`, `Playbook`, `Reference`
|
|
60
|
+
- **Planning:** `PRD`, `Rubric`, `OKR`, `Radar`, `Checklist`, `Calibration`, `Research`, `Design`, `Prototype`
|
|
61
|
+
- **Root governance:** `Decision`, `Principle`, `Debt`, `Discovery`, `Guide`
|
|
62
|
+
|
|
63
|
+
### Extending the vocabulary
|
|
64
|
+
|
|
65
|
+
Add **one line** to `scripts/frontmatter_registry.txt` and a matching row above. A new `type` is a
|
|
66
|
+
visible, reviewable diff — never an ad-hoc value invented in a single file.
|
|
67
|
+
|
|
68
|
+
## Enforcement
|
|
69
|
+
|
|
70
|
+
- [`scripts/frontmatter_lint.py`](/scripts/frontmatter_lint.py) — deterministic, no secrets; asserts
|
|
71
|
+
the three required keys (and `type` ∈ registry) on every non-reserved tracked `.md`. Run in
|
|
72
|
+
`.github/workflows/frontmatter-ci.yml`.
|
|
73
|
+
- [`scripts/backfill_frontmatter.py`](/scripts/backfill_frontmatter.py) — the one-time migration:
|
|
74
|
+
prepend-only, idempotent; reuses a file's already-declared `type`/`date` when present, else infers
|
|
75
|
+
from path (`type`), the first H1 (`title`), and the last git-commit date (`timestamp`).
|
|
@@ -5,8 +5,10 @@ to pick concepts, then fetch the file(s) you need.
|
|
|
5
5
|
|
|
6
6
|
- [agent-harness](agent-harness.md) — Everything wrapping the model that lets it finish work — and the Summary Gate, the input gate that compresses prior-session context into essential state.
|
|
7
7
|
- [control-plane](control-plane.md) — What it means for PMOS to be a control plane — it orchestrates, specs, evaluates, and routes agent work rather than generating production code itself.
|
|
8
|
+
- [design-craft](design-craft.md) — The UI/UX practice a design agent applies: perception/cognition evidence, craft moves, accessibility floors, and recorded anti-patterns (D60).
|
|
8
9
|
- [design-loop](design-loop.md) — How PMOS makes UI/UX design a first-class, repeatable sub-flow of the Build stage — brief → design → reconcile → build → design-sync — gated by the Review Gate, presentation-only, and never a data decision.
|
|
9
10
|
- [eval-driven-pm](eval-driven-pm.md) — PMOS's core method — write the eval before the build. The rubric is the spec; the PM manages by defining what "good" means, not by inspecting work after the fact.
|
|
11
|
+
- [frontmatter-format](frontmatter-format.md) — The repo-wide house frontmatter (`type` + `title` + `timestamp` on every tracked `.md`) and the Frontmatter Gate + registry that enforce it (D63); machine-readable classification by reading, not path-guessing.
|
|
10
12
|
- [health-anchors](health-anchors.md) — The second anchor class (D59): work anchors to a KR or a declared, capped, PM-reviewed health budget, so refactor/ops/security work anchors honestly.
|
|
11
13
|
- [okf-governance](okf-governance.md) — How PMOS organizes its Open Knowledge Format bundle and the governance rules that keep it spec-conformant.
|
|
12
14
|
- [okr-anti-optimism](okr-anti-optimism.md) — Why PMOS biases status reporting toward pessimism — surfacing the red underneath green metrics — to keep KR self-reporting honest.
|
|
@@ -15,4 +17,5 @@ to pick concepts, then fetch the file(s) you need.
|
|
|
15
17
|
- [pm-identity](pm-identity.md) — How PMOS models a product manager — the pm_slug identifier, the PM's authority as the human in the loop, and PM-scoped namespaces.
|
|
16
18
|
- [product-slug-convention](product-slug-convention.md) — The rules for product_slug — the stable lowercase identifier that scopes products across OKF namespaces, planning artifacts, and agent records.
|
|
17
19
|
- [sdlc-loop](sdlc-loop.md) — The closed agent-driven software development lifecycle PMOS orchestrates — spec, contract, build, evaluate, accept, learn — and how it loops.
|
|
20
|
+
- [self-refining-harness](self-refining-harness.md) — The pattern where the harness improves from its own run evidence (evals, friction, calibration) via a detect → draft → PM-gate loop, bounded at the L3 ceiling — never L4 self-mutation.
|
|
18
21
|
- [watermelon-flag](watermelon-flag.md) — A status that reads green on automated metrics but is red underneath on strategic alignment — and silent drift, the L4 failure mode it signals.
|
|
@@ -2,5 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
OKF reserved file (no frontmatter). Change history, newest first, ISO 8601 dates.
|
|
4
4
|
|
|
5
|
+
## 2026-07-24
|
|
6
|
+
- Added [frontmatter-format](frontmatter-format.md) — the repo-wide house frontmatter (`type` + `title` + `timestamp` on every tracked `.md`) + the Frontmatter Gate and registry (D63). Indexed.
|
|
7
|
+
|
|
8
|
+
## 2026-07-21
|
|
9
|
+
- Added [design-craft](design-craft.md) — the UI/UX practice a design agent applies (perception/cognition evidence, craft moves, accessibility floors, recorded anti-patterns); promoted from `planning/design/attention-research.md` (D60). Indexed.
|
|
10
|
+
|
|
11
|
+
## 2026-07-18
|
|
12
|
+
- Added [health-anchors](health-anchors.md) — the second anchor class: work anchors to a KR or a declared, capped, PM-reviewed health budget (D59). Indexed.
|
|
13
|
+
|
|
14
|
+
## 2026-07-01
|
|
15
|
+
- Added [design-loop](design-loop.md) — UI/UX design as a Review-Gate-gated, presentation-only sub-flow of Build (brief → design → reconcile → build → design-sync); D48. Indexed.
|
|
16
|
+
- Added [self-refining-harness](self-refining-harness.md) — the harness improves from its own run evidence via detect → draft → PM-gate, bounded at L3 (D47). Indexed.
|
|
17
|
+
|
|
5
18
|
## 2026-06-29
|
|
6
19
|
- Creation — per-folder index/log added (OKF recursive progressive disclosure; D29 reversal direction).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: Template
|
|
3
3
|
title: Design Brief Template
|
|
4
|
-
description: The scaffold for a design brief instance — the context handoff from
|
|
4
|
+
description: The scaffold for a design brief instance — the context handoff from the interactive agent to an external design surface (e.g. claude.ai/design). Copy into /planning/design/ and fill; presentation-only.
|
|
5
5
|
tags: [template, design, brief, planning]
|
|
6
6
|
timestamp: 2026-07-01
|
|
7
7
|
---
|
|
@@ -20,17 +20,19 @@ OKF bundle.
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
```markdown
|
|
23
|
-
|
|
23
|
+
---
|
|
24
|
+
type: Rubric
|
|
25
|
+
title: <initiative title>
|
|
26
|
+
eval_type: capability | regression # capability = push frontier; regression = guard against backslide
|
|
27
|
+
initiative_id: <id>
|
|
28
|
+
product_slug: <product_slug>
|
|
29
|
+
pm_slug: <pm_slug>
|
|
30
|
+
parent_KR: <reference OR health:<id> (D59)>
|
|
31
|
+
pass_threshold: <0.00–1.00> # pre-committed, before output exists
|
|
32
|
+
timestamp: <YYYY-MM-DD>
|
|
33
|
+
---
|
|
24
34
|
|
|
25
|
-
|
|
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 OR health:<id> (D59)>
|
|
32
|
-
- pass_threshold: <0.00–1.00> <!-- pre-committed, before output exists -->
|
|
33
|
-
- date: <YYYY-MM-DD>
|
|
35
|
+
# Eval Rubric: <initiative title>
|
|
34
36
|
|
|
35
37
|
## Gate assignment
|
|
36
38
|
<!-- State which gate each criterion serves. Acceptance Gate is PM-only and NOT rubric-graded. -->
|
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
type: Template
|
|
3
3
|
title: Prototype Brief Template
|
|
4
|
-
description: The scaffold for a QUICK leg-A prototype brief (D60) — the idea, the user, the moment, the feel, draft copy seeds. Deliberately short; if it needs PRD-level detail the flow has failed its purpose. Copy into prototype/<initiative-id>/brief.md and set it as the initiative's prd_path.
|
|
4
|
+
description: The scaffold for a QUICK leg-A prototype brief (D60) — the idea, the judgement it exercises, the user, the moment, the feel, draft copy seeds. Works for any medium, not just UI (2026-07-24 amendment). Deliberately short; if it needs PRD-level detail the flow has failed its purpose. Copy into prototype/<initiative-id>/brief.md and set it as the initiative's prd_path.
|
|
5
5
|
tags: [template, prototype, design, lane]
|
|
6
|
-
timestamp: 2026-07-
|
|
6
|
+
timestamp: 2026-07-24
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Prototype Brief Template
|
|
10
10
|
|
|
11
11
|
**Situating context:** The [prototype lane](/okf/products/pmos/adr/d60-prototype-loop.md)'s contract
|
|
12
|
-
artifact. The PM writes THIS — quick, sketchy, incomplete is fine — and the **
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
committing to a spec. If filling it in starts to feel like writing requirements, stop — that
|
|
17
|
-
belongs in the PRD that follows a successful prototype, not here.
|
|
12
|
+
artifact. The PM writes THIS — quick, sketchy, incomplete is fine — and the **agent does the rest**:
|
|
13
|
+
picks up the artifact class's conventions (a design system for UI; SKILL-FORMAT, D19 ACI,
|
|
14
|
+
migration/RLS conventions elsewhere), applies that class's craft, drafts real content, and returns
|
|
15
|
+
divergent specimens. The brief is deliberately NOT a PRD: it exists so the PM can examine something
|
|
16
|
+
*before* committing to a spec. If filling it in starts to feel like writing requirements, stop — that
|
|
17
|
+
detail belongs in the PRD that follows a successful prototype, not here.
|
|
18
|
+
|
|
19
|
+
**Any medium** (2026-07-24 amendment to D60): the lane is not UI-gated. A specimen may be a lookable
|
|
20
|
+
screen, a worked sample output, call/response transcripts, or a schema sketch — whichever is the
|
|
21
|
+
cheapest thing that lets the PM exercise the judgement below.
|
|
18
22
|
|
|
19
23
|
> Usage: copy into `prototype/<initiative-id>/brief.md`; set it as the initiative's `prd_path`
|
|
20
24
|
> (`create_initiative`, `type: 'prototype'`). Every section may be a single sentence. Only the first
|
|
21
|
-
>
|
|
25
|
+
> three are required.
|
|
22
26
|
|
|
23
27
|
---
|
|
24
28
|
|
|
@@ -35,30 +39,50 @@ belongs in the PRD that follows a successful prototype, not here.
|
|
|
35
39
|
## Who it's for, and the moment they'd use it (required)
|
|
36
40
|
<!-- The user and the situation — "a PM opening the board on Monday morning", not a persona doc. -->
|
|
37
41
|
|
|
42
|
+
## The judgement you need to make (required)
|
|
43
|
+
<!-- One line: what you cannot decide from a description alone, and so need to SEE an instance of.
|
|
44
|
+
"Whether this actually reads as calm rather than sparse." "Whether this explainer actually
|
|
45
|
+
teaches someone who's never seen the region." "Whether this API feels right to call."
|
|
46
|
+
This is the specimen test written down — it steers the format, the grilling, and the
|
|
47
|
+
disposition. If you can't name such a judgement, this may not be a prototype (see the
|
|
48
|
+
discovery lane, whose deliverable is a learning, not a validated direction). -->
|
|
49
|
+
|
|
50
|
+
## Specimen format
|
|
51
|
+
<!-- Leave blank to let the agent propose it and say why. The principle is the CHEAPEST thing that
|
|
52
|
+
lets you exercise the judgement above: lookable HTML, a worked sample output on real input,
|
|
53
|
+
call/response transcripts, a schema sketch with example rows, the actual strings. -->
|
|
54
|
+
|
|
38
55
|
## How it should feel
|
|
39
56
|
<!-- Adjectives and references beat specification: "calm, dense, fast to scan", "more like a
|
|
40
|
-
cockpit than a report".
|
|
57
|
+
cockpit than a report". Applies beyond visuals — an API can feel obvious or fiddly, a
|
|
58
|
+
sample output can feel patronising or brisk. Leave blank to let the agent propose. -->
|
|
41
59
|
|
|
42
60
|
## Copy seeds
|
|
43
|
-
<!-- Any words you already hear: a headline, a button label, the tone. The agent
|
|
44
|
-
(D60 — copy rides the prototype, no lorem
|
|
61
|
+
<!-- Any words you already hear: a headline, a button label, an error string, the tone. The agent
|
|
62
|
+
drafts REAL content (D60 — copy rides the prototype, no lorem, and no fake inputs/outputs for
|
|
63
|
+
non-visual specimens: placeholders hide the friction the specimen exists to surface). Blank is
|
|
64
|
+
fine. -->
|
|
45
65
|
|
|
46
66
|
## What this is NOT
|
|
47
67
|
<!-- One line if you already know a direction to avoid. -->
|
|
48
68
|
|
|
49
|
-
## Existing
|
|
50
|
-
<!-- If this improves
|
|
69
|
+
## Existing thing?
|
|
70
|
+
<!-- If this improves something that already exists — a screen, a skill, an endpoint — name it.
|
|
71
|
+
Brand-new idea → leave blank. -->
|
|
51
72
|
```
|
|
52
73
|
|
|
53
74
|
---
|
|
54
75
|
|
|
55
76
|
## What the agent does with this (not the PM's job)
|
|
56
77
|
|
|
57
|
-
1. **
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
78
|
+
1. **Conventions check first (blocking, D60(c) as generalised):** the artifact class has no
|
|
79
|
+
conventions and no craft to reason from → the agent proposes a minimal set from this same brief
|
|
80
|
+
and the PM approves it *before* any prototype. For UI that is the design system; for a skill,
|
|
81
|
+
SKILL-FORMAT; for a tool or API, D19's ACI principle; for a schema, the migration/RLS conventions.
|
|
82
|
+
2. Produces **2–3 divergent low-fidelity specimens** — one safe direction is a weaker outcome than
|
|
83
|
+
three arguable ones — with **real content**, into `prototype/<initiative-id>/`.
|
|
84
|
+
3. Submits to a **craft-grade grilling** (dialogue, never a score — D60(d)): one question at a time,
|
|
85
|
+
a recommended answer with each. This holds for non-visual specimens too, where the temptation to
|
|
86
|
+
score is sharper.
|
|
63
87
|
4. The PM **disposes**: promote (→ a new feature-lane initiative; PRD + rubric derived from the
|
|
64
|
-
validated
|
|
88
|
+
validated specimen) / iterate / kill.
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Rubric
|
|
3
|
+
title: "Eval Rubric: Agent-run capability baseline (kit seed — copy per initiative)"
|
|
4
|
+
timestamp: 2026-07-19
|
|
5
|
+
eval_type: capability
|
|
6
|
+
initiative_id: (set per initiative)
|
|
7
|
+
pass_threshold: 0.80
|
|
8
|
+
canonical_path: pmos/planning/evals/agent-run-eval-rubric.md
|
|
9
|
+
---
|
|
10
|
+
|
|
1
11
|
# Eval Rubric: Agent-run capability baseline (kit seed — copy per initiative)
|
|
2
12
|
|
|
3
13
|
> Kit-seeded generic rubric (D54). Two purposes: (1) it is the TEMPLATE to copy to
|
|
@@ -6,13 +16,6 @@
|
|
|
6
16
|
> meaningful from day one. It scores a generic agent run outcome-only (D14) with weighted partial
|
|
7
17
|
> credit (D15).
|
|
8
18
|
|
|
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
19
|
## Gate assignment
|
|
17
20
|
- **Quality Gate (deterministic):** repo CI green; `pmos-gate` (anchored + rubrics) green.
|
|
18
21
|
- **Review Gate (adversarial):** the weighted dimensions below — evaluator skill, default-to-refute,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# frontier.sh — list the workable tickets in a file-mode PMOS kit (E9).
|
|
3
|
+
#
|
|
4
|
+
# "Work the frontier": a ticket is workable when it is NOT done and EVERY ticket it is blocked_by is
|
|
5
|
+
# done. This is the plain-file equivalent of a board's dependency structure — one file per ticket in
|
|
6
|
+
# state/tickets/NNN-slug.md, numbered in dependency order, blocking edges as text.
|
|
7
|
+
#
|
|
8
|
+
# scripts/frontier.sh # from the kit root; lists workable tickets
|
|
9
|
+
# scripts/frontier.sh state/tickets # explicit tickets dir
|
|
10
|
+
#
|
|
11
|
+
# Dependency-free and portable: POSIX-ish bash, no associative arrays (runs on bash 3.2, e.g. stock
|
|
12
|
+
# macOS). No network, no board. Reads only the YAML frontmatter fields id / status / blocked_by.
|
|
13
|
+
set -euo pipefail
|
|
14
|
+
|
|
15
|
+
DIR="${1:-state/tickets}"
|
|
16
|
+
[ -d "$DIR" ] || { echo "frontier: no tickets dir at '$DIR' (nothing to do)"; exit 0; }
|
|
17
|
+
|
|
18
|
+
# --- field readers (frontmatter only: stop at the closing --- fence) ----------------------------
|
|
19
|
+
fm() { awk 'NR>1 && /^---[[:space:]]*$/{exit} {print}' "$1"; } # lines between the opening and closing ---
|
|
20
|
+
field() { printf '%s\n' "$1" | sed -n "s/^$2:[[:space:]]*//p" | head -1 | sed 's/^["'\'']//;s/["'\'']$//;s/[[:space:]]*$//'; }
|
|
21
|
+
# blocked_by is an inline list "[\"002\", \"005\"]"; extract the bare ids (digits) in order.
|
|
22
|
+
blockers() { printf '%s\n' "$1" | sed -n 's/^blocked_by:[[:space:]]*//p' | head -1 | grep -oE '[0-9]+' || true; }
|
|
23
|
+
# derive an id: explicit `id:` field, else the leading NNN of the filename.
|
|
24
|
+
idof() { local i; i="$(field "$1" id)"; [ -n "$i" ] && { printf '%s' "$i"; return; }; basename "$2" | grep -oE '^[0-9]+' || basename "$2" .md; }
|
|
25
|
+
|
|
26
|
+
shopt -s nullglob
|
|
27
|
+
files=("$DIR"/*.md)
|
|
28
|
+
[ ${#files[@]} -eq 0 ] && { echo "frontier: no tickets in '$DIR' (nothing to do)"; exit 0; }
|
|
29
|
+
|
|
30
|
+
# --- pass 1: collect the done ids (newline-delimited; no associative arrays for bash-3.2 portability)
|
|
31
|
+
DONE_IDS=""
|
|
32
|
+
OPEN=0
|
|
33
|
+
for f in "${files[@]}"; do
|
|
34
|
+
meta="$(fm "$f")"; id="$(idof "$meta" "$f")"; st="$(field "$meta" status)"
|
|
35
|
+
if [ "$st" = "done" ]; then DONE_IDS="$DONE_IDS$id
|
|
36
|
+
"; else OPEN=$((OPEN+1)); fi
|
|
37
|
+
done
|
|
38
|
+
is_done() { printf '%s' "$DONE_IDS" | grep -qx "$1"; }
|
|
39
|
+
|
|
40
|
+
# --- pass 2: a ticket is on the frontier when not done and every blocker is done -----------------
|
|
41
|
+
found=0
|
|
42
|
+
for f in "${files[@]}"; do
|
|
43
|
+
meta="$(fm "$f")"; id="$(idof "$meta" "$f")"; st="$(field "$meta" status)"; st="${st:-todo}"
|
|
44
|
+
[ "$st" = "done" ] && continue
|
|
45
|
+
workable=1
|
|
46
|
+
while IFS= read -r b; do
|
|
47
|
+
[ -z "$b" ] && continue
|
|
48
|
+
is_done "$b" || workable=0
|
|
49
|
+
done < <(blockers "$meta")
|
|
50
|
+
if [ "$workable" -eq 1 ]; then
|
|
51
|
+
printf ' ▸ %-5s %-8s %s\n' "$id" "[$st]" "$(field "$meta" title)"
|
|
52
|
+
found=$((found+1))
|
|
53
|
+
fi
|
|
54
|
+
done
|
|
55
|
+
|
|
56
|
+
if [ "$found" -eq 0 ]; then
|
|
57
|
+
# distinguish "all done" from "everything is blocked" — a stuck frontier is a real signal.
|
|
58
|
+
if [ "$OPEN" -eq 0 ]; then echo "frontier: all tickets done ✓"
|
|
59
|
+
else echo "frontier: $OPEN open ticket(s), NONE workable — the frontier is blocked (check for a cycle or an undone blocker)."; fi
|
|
60
|
+
fi
|