Repository navigation
[Phase 1] Define held-out eval-case format + seed prompts/triage.md case set #582
Copy link
Copy link
Closed
Labels
dev-leadFor dev-lead agent pickupFor dev-lead agent pickupinitiativeEpic / initiative tracking issueEpic / initiative tracking issue
Description
Story
As a skill maintainer,
I want a versioned, documented held-out eval-case format plus a seed case set for the triage skill,
so that skill quality can be measured against a fixed, reward-hack-resistant set before any optimization loop exists.
Acceptance Criteria
- skills/evals/triage/cases.jsonl exists; each line is a JSON object pairing a triage input (a pre-fetched PR context as triage.md consumes) with the expected decision fields
escalate(bool) andrisk(LOW|MEDIUM|HIGH). - A case schema (skills/evals/case.schema.json) plus a README document the required fields, and the schema is validatable the same way scripts/initiative-planner/plan.schema.json is (python jsonschema).
- Cases cover both escalate=true and escalate=false outcomes and include at least one case for each high-risk trigger named in triage.md decision criteria (auth/secrets, DB migrations/schema, security anti-patterns).
- A CODEOWNERS entry marks skills/evals/ as separately owned so a future proposer can never edit the held-out set (reward-hacking guard).
Tasks / Subtasks
- Create skills/evals/ tree and case.schema.json mirroring the plan.schema.json JSON-Schema style (AC: Go-live improvements for PR review agent #2)
- Define required keys: input (PR context), expected.escalate, expected.risk
- additionalProperties:false like plan.schema.json
- Author skills/evals/triage/cases.jsonl grounded strictly in triage.md decision criteria (AC: test issue from agent #1, Add @claude delegation, auto-merge, and rebase handling #3)
- Include escalate=false safe cases
- Include escalate=true cases per high-risk area
- Write skills/evals/README.md documenting the case format and the separately-owned invariant (AC: Go-live improvements for PR review agent #2, Optimize review: small-PR and incremental fast paths #4)
- Add CODEOWNERS entry for skills/evals/ (AC: Optimize review: small-PR and incremental fast paths #4)
Dev Notes
- triage.md emits a deterministic JSON object (escalate, risk, signals, summary) with no tools — this is exactly why it is the right first skill: expected outputs can be fixed values. Ground each case in the numbered decision criteria, not invented behavior.
- Model the case schema on scripts/initiative-planner/plan.schema.json (draft 2020-12, additionalProperties:false) and validate with the same inline
pip install 'jsonschema>=4'pattern CI already uses. - Cases are the trust anchor of the whole initiative. They MUST live separately from any scorer/proposer and be CODEOWNER-gated; the proposer may only ever edit the skill markdown, never the test set.
- This story is data + schema + docs only — no scorer and no model invocation. Keep it reviewable in isolation.
- Directory naming follows the idea's literal
skills/evals/<skill>/cases.jsonl; flagged in open_questions since repo skills live under prompts/ and frameworks/.
Project Structure Notes
Introduces a new top-level skills/evals/ directory per Discussion #572. No existing eval/test-fixture directory covers prompt-skill quality; tests/ holds bats/python for shell + workflow contracts, not prompt evals.
References
- prompts/triage.md#Decision-criteria
- prompts/shared.md
- scripts/initiative-planner/plan.schema.json
- scripts/initiative-planner/validate-plan.py
- .github/workflows/lint.yml#bats
- AGENTS.md
Likely target surface
skills/evals/case.schema.jsonskills/evals/triage/cases.jsonlskills/evals/README.mdCODEOWNERS
Story prepared by the BMAD Scrum Master (Bob) for epic #581. Status: ready-for-dev.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
dev-leadFor dev-lead agent pickupFor dev-lead agent pickupinitiativeEpic / initiative tracking issueEpic / initiative tracking issue
Activity
don-petry commentedon Jun 12, 2026
Dev-Lead Implementation Plan
Issue: #582 — [Phase 1] Define held-out eval-case format + seed prompts/triage.md case set
Scope
Introduce a versioned, CODEOWNER-gated held-out eval-case format (
skills/evals/) with a JSON-Schema (draft 2020-12,additionalProperties:false) mirroringplan.schema.json, a pythonjsonschemavalidator, a seedtriage/cases.jsonlgrounded strictly inprompts/triage.mddecision criteria, and a README documenting the format + separately-owned invariant.Implementation Checklist
skills/evals/case.schema.json— draft 2020-12,additionalProperties:false; required keysid,input,expected(expected.escalatebool,expected.riskLOW|MEDIUM|HIGH), optionaldescription/tagsskills/evals/validate-cases.py— validate every JSONL line against the schema + enforce uniqueid(mirrorsvalidate-plan.py/ inlinepip install 'jsonschema>=4'pattern)skills/evals/triage/cases.jsonl— seed cases grounded intriage.mdnumbered criteria, covering escalate=false and escalate=true incl. one per high-risk trigger (auth/secrets, DB migrations/schema, security anti-patterns)skills/evals/README.md— document case format, validation command, and the separately-owned / reward-hacking-guard invariant.github/CODEOWNERS— add/skills/evals/entry (separately owned; proposer can never edit held-out set).github/workflows/lint.yml— add the new bats test file to thebatsjob list (per AGENTS.md repo-specific test-list note)Tests to Write
tests/test_evals_cases.bats— validator accepts realcases.jsonl; rejects missingexpected.risk, unknown property, badriskenum, duplicateid; asserts coverage of both escalate outcomes and each named high-risk trigger viatagsTest Command
bats tests/test_evals_cases.bats(full suite via thebatsjob list in.github/workflows/lint.yml); lint viabash .dev-lead/scripts/dev-lead-lint.shdon-petry commentedon Jun 12, 2026
Dev-Lead: Implementation Complete
Plan Execution
skills/evals/case.schema.json— draft 2020-12,additionalProperties:false; requiredid/input/expectedwithexpected.escalate(bool) +expected.risk(LOW|MEDIUM|HIGH), optionaldescription/tags(AC test issue from agent #1, Go-live improvements for PR review agent #2)skills/evals/validate-cases.py— validates every JSONL line against the schema and enforces uniqueid; mirrorsvalidate-plan.pyand the inlinepip install 'jsonschema>=4'CI pattern (AC Go-live improvements for PR review agent #2)skills/evals/triage/cases.jsonl— 8 seed cases grounded strictly inprompts/triage.mdnumbered criteria (AC test issue from agent #1, Add @claude delegation, auto-merge, and rebase handling #3)skills/evals/README.md— documents the case format, validation command, and the separately-owned / reward-hacking-guard invariant (AC Go-live improvements for PR review agent #2, Optimize review: small-PR and incremental fast paths #4).github/CODEOWNERS—/skills/evals/entry so the held-out set is separately owned (AC Optimize review: small-PR and incremental fast paths #4).github/workflows/lint.yml— addedtests/test_evals_cases.batsto the bats list andskills/**to the lint trigger paths so the set is validated in CItests/test_evals_cases.batswritten first (red), then implemented to greenCoverage (AC #3)
triage-docs-typo(LOW),triage-test-only(LOW),triage-clean-logic-fix(MEDIUM)triage-auth-token(HIGH, auth/secrets),triage-db-migration(HIGH, DB migration/schema),triage-sql-concat(HIGH, security anti-pattern),triage-workflow-pr-target(HIGH),triage-unresolved-thread(MEDIUM)Test Results
Full bats suite (13 files / 206 tests) passes;
bash .dev-lead/scripts/dev-lead-lint.shpasses; markdownlint and CI-config yamllint clean on the changed files.Files Changed
skills/evals/case.schema.json: new JSON-Schema for one eval caseskills/evals/validate-cases.py: new JSONL-vs-schema validator (no scorer/model)skills/evals/triage/cases.jsonl: 8 seed triage casesskills/evals/README.md: case-format + separately-owned-invariant docs.github/CODEOWNERS: separate ownership for/skills/evals/.github/workflows/lint.yml: wire the new bats test +skills/**lint triggertests/test_evals_cases.bats: schema/coverage testsNotes
skills/evals/<skill>/cases.jsonl(the open question noted that repo skills otherwise live underprompts//frameworks/). Flagging for reviewer confirmation.@petry-projects/org-leads(a known-existing team) to guarantee a valid rule; tighten to a dedicated eval-owners team if/when one exists.feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
refactor(evals): relocate held-out eval set to repo-root evals/ per m…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #583 — deterministic eval scorer (triage) over #…
14 remaining items
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…
feat: implement issue #582 — [Phase 1] Define held-out eval-case form…