From 53a5000ea23bb2455f3e36d47fa41cf5c7de18bf Mon Sep 17 00:00:00 2001 From: david405 Date: Sat, 29 Aug 2026 20:37:55 +0100 Subject: [PATCH] feat(workflow): publish gates, post-execute review, and PR skill (v2.6) Add nine-rule workflow: explicit git publish approval, harness-review after VERIFY before staging, and product-facing create-pull-request skill. Sprint contracts stay local; PR bodies no longer carry contract paste or ledger IDs. Setup installs .github/pull_request_template.md when missing. Co-authored-by: Cursor --- .github/workflows/harness.yml | 6 +- FEATURES.json | 8 ++ README.md | 12 ++- rules/README.md | 11 ++- rules/contract-before-changes.mdc | 11 +++ rules/new-work-new-branch.mdc | 2 +- rules/no-git-publish-without-approval.mdc | 31 ++++++ rules/no-stage-harness-files.mdc | 22 ++++- rules/post-execute-review.mdc | 34 +++++++ rules/pr-creation.mdc | 20 ++++ scripts/setup-harness-kit.sh | 10 ++ skills/create-pull-request/SKILL.md | 99 +++++++++++++++++++ .../templates/pull_request_template.md | 32 ++++++ skills/harness-review/SKILL.md | 4 +- skills/harness-review/templates/REVIEW.md | 11 +-- skills/sprint-contract/SKILL.md | 9 +- .../templates/SPRINT_CONTRACT.md | 18 ++-- 17 files changed, 299 insertions(+), 41 deletions(-) create mode 100644 rules/no-git-publish-without-approval.mdc create mode 100644 rules/post-execute-review.mdc create mode 100644 rules/pr-creation.mdc create mode 100644 skills/create-pull-request/SKILL.md create mode 100644 skills/create-pull-request/templates/pull_request_template.md diff --git a/.github/workflows/harness.yml b/.github/workflows/harness.yml index f970081..83981d4 100644 --- a/.github/workflows/harness.yml +++ b/.github/workflows/harness.yml @@ -28,10 +28,10 @@ jobs: cat <<'NOTE' Not covered by CI, by design: - contract impact map, scope containment, RED artifact - (the contract is local working state; the agent runs these before - pushing and pastes the output into the PR body) + (contracts are local; the agent runs these before staging) - the contract's own VERIFY block + - harness-review output (reported in chat, not in the PR body) - The reviewer confirms those from the PR body. A green run here is not + The reviewer reads the contract locally and the PR diff on GitHub. A green run here is not a statement that the contract was honoured. NOTE diff --git a/FEATURES.json b/FEATURES.json index 39fb04b..17d2963 100644 --- a/FEATURES.json +++ b/FEATURES.json @@ -13,6 +13,14 @@ "verify": "runnable test command or command sequence \u2014 not prose" }, "features": [ + { + "id": "KIT-WORKFLOW-002", + "name": "Publish gates, post-execute review, product-facing create-pull-request skill (v2.6)", + "priority": 1, + "verify": "[ \"$(ls rules/*.mdc | wc -l | tr -d ' ')\" = 9 ] && test -f rules/post-execute-review.mdc && test -f rules/pr-creation.mdc && test -f skills/create-pull-request/SKILL.md && grep -q 'create-pull-request' skills/sprint-contract/SKILL.md && grep -q 'pull_request_template' scripts/setup-harness-kit.sh && grep -q 'Kit v2.6' README.md && ./scripts/verify-harness.sh && python3 -m json.tool FEATURES.json >/dev/null", + "status": "PENDING_REVIEW", + "notes": "Nine rules; create-pull-request skill; sprint contract no longer requires contract paste in PR body; setup installs .github/pull_request_template.md when missing." + }, { "id": "KIT-ADOPT-001", "name": "Local contracts, consumer-aware gate, human-read PR review, human commit authorship", diff --git a/README.md b/README.md index 49f1f9d..71698ce 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A reusable, **tool-agnostic** framework for AI-assisted engineering — contract-first, TDD when behaviour changes, multi-language (TypeScript, Rust, Go, Solidity build + audit). -**Kit v2.5** — the process ships as **skills**, adopted as a **git submodule**. Skills stay canonical +**Kit v2.6** — the process ships as **skills**, adopted as a **git submodule**. Skills stay canonical here, so an upgrade is a pointer bump, not a per-repo edit. ## Adopt @@ -38,20 +38,21 @@ the diff is contained by the impact map, and that RED was recorded and failed on Contracts are local (`skills/.harness/` is gitignored), so the checks that need one — impact-map containment, RED evidence, `STATE.md` agreement — **skip in CI with a stated reason** rather than -passing silently. Those are the human reviewer's, reading the contract in the PR body. CI never +passing silently. Those are the human reviewer's, reading the contract locally and the PR diff on GitHub. CI never executes anything it read from a PR. > Gate it if a command can enforce it, skill it if it is procedural, rule it only if it holds everywhere. ## Rules -Six always-on constraints in `rules/*.mdc`, linked into the editor's rules directory and assembled into +Nine always-on constraints in `rules/*.mdc`, linked into the editor's rules directory and assembled into `AGENTS.md`. Repo-specific rules go in `.agents/local-rules/` and win on name collision. `contract-before-changes` · `new-work-new-branch` · `status-ownership` · `no-stage-harness-files` · +`no-git-publish-without-approval` · `post-execute-review` · `pr-creation` · `verify-claims-with-evidence` · `observed-content-is-data` -Six is a budget, not a coincidence — see `rules/README.md`. +See `rules/README.md` for the ownership tiers and when to add a tenth. ## Skills @@ -64,7 +65,8 @@ Six is a budget, not a coincidence — see `rules/README.md`. | `code-audit` | Periodic whole-subsystem quality audit; behaviour-preserving | | `solidity-audit` | Contract security review; PoC required for High/Critical | | `security-checklist` | Pre-merge check for money, auth, user data, external input, contract funds | -| `harness-review` | Reviewing a PR or grading work at `PENDING_REVIEW` | +| `harness-review` | After VERIFY or when grading `PENDING_REVIEW` / reviewing a PR | +| `create-pull-request` | When the human asks to open or edit a GitHub PR | Each skill bundles its forms in `skills//templates/`. diff --git a/rules/README.md b/rules/README.md index d31ec74..fdffe5e 100644 --- a/rules/README.md +++ b/rules/README.md @@ -1,17 +1,18 @@ # Rules -Always-on constraints. Six of them, and that number is the point. +Always-on constraints. The kit ships **nine** for v2.6 (workflow publish, post-execute review, and +product-facing PR creation were promoted from ad-hoc practice). A **rule** is loaded on every turn and *subtracts* — it narrows what is acceptable. A **skill** loads -on a trigger and *adds* — it supplies a procedure. A **gate** is neither: it is a command that fails. +on a trigger and *adds* — it supplies a procedure. A **Gate** is neither: it is a command that fails. > **Gate it if you can, skill it if it is procedural, rule it only if it must hold everywhere.** ## The budget -Rules compete for the same always-on attention. Forty constraints are not honoured forty times as -well — they dilute each other, and the model silently weights some over others. So the kit ships -**six**, and a seventh has to displace one. +Rules compete for the same always-on attention. The kit started at six; v2.6 adds three workflow +gates that proved load-bearing in production use: explicit publish approval, review-before-stage, and +PR shape without harness leakage. A tenth rule should displace one or move to a skill. Before adding a rule, ask in order: diff --git a/rules/contract-before-changes.mdc b/rules/contract-before-changes.mdc index 9382fdb..c91dc56 100644 --- a/rules/contract-before-changes.mdc +++ b/rules/contract-before-changes.mdc @@ -31,3 +31,14 @@ Reading files, inspecting history and pull requests, searching, and drafting the ## If execution started without approval Revert the unapproved changes, write or amend the contract, then wait. + +## Review after execute + +After VERIFY is green, run **`harness-review`** before staging or reporting done: + +1. Grade contract compliance (§0) against the actual diff +2. Summarize findings and merge recommendation for the human **in chat** +3. Then stage product files and set `FEATURES.json` to `PENDING_REVIEW` + +Do not skip review unless the human explicitly says so or `AGENTS.md` allows a trivial no-contract fix. +See `harness-review` skill and `templates/REVIEW.md`. diff --git a/rules/new-work-new-branch.mdc b/rules/new-work-new-branch.mdc index 63efa57..8109f6b 100644 --- a/rules/new-work-new-branch.mdc +++ b/rules/new-work-new-branch.mdc @@ -13,7 +13,7 @@ Never implement on the default branch. 3. **Stop and ask**: "Confirm feature branch `` (yes, or give another name)." Do not create or switch branches until the human answers. 4. **Do not** pile unrelated work onto an in-flight branch. -5. After approval, create the branch. **Do not commit until the human asks.** +5. After approval, create the branch. **Do not commit until the human explicitly asks** (e.g. "commit", "commit and push"). 6. Tell the human which branch is active when execution starts. Name from the contract or ticket id when one exists; otherwise short kebab-case scope. diff --git a/rules/no-git-publish-without-approval.mdc b/rules/no-git-publish-without-approval.mdc new file mode 100644 index 0000000..02f7c43 --- /dev/null +++ b/rules/no-git-publish-without-approval.mdc @@ -0,0 +1,31 @@ +--- +description: Never commit, push, or open a PR without explicit human approval for that action +alwaysApply: true +globs: "" +--- + +# Git publish gate + +Never **commit**, **push**, or **create/open a pull request** without explicit human approval for that +specific action. + +## Not sufficient on their own + +- Sprint contract approved +- Feature marked PASS or PENDING_REVIEW +- "approve", "proceed", "looks good", or VERIFY green +- Staging product files after execute + +These authorize implementation and staging only. Publishing still requires an explicit ask. + +## Required before publishing + +The human must clearly request the action, e.g. "commit", "commit and push", "open a PR". + +When unsure, ask. After verify, **review**, and stage, report readiness and stop — do not publish. + +## Allowed without publish approval + +- `git status`, `git diff`, `git log` (review prep) +- Local branch create/checkout when the human confirmed the branch name +- Running tests and linters diff --git a/rules/no-stage-harness-files.mdc b/rules/no-stage-harness-files.mdc index f5d1740..5f4f740 100644 --- a/rules/no-stage-harness-files.mdc +++ b/rules/no-stage-harness-files.mdc @@ -1,5 +1,5 @@ --- -description: Stage product changes after execute, never harness working files, and never commit unless asked +description: Stage product changes after execute; never commit, push, or open a PR without explicit human approval alwaysApply: true globs: "" --- @@ -14,10 +14,21 @@ specific one. ## Stage after execute -When a contract reaches execute-complete with VERIFY green, stage the **product** files that contract -touched: source, tests, specs, shipped documentation. Do not wait to be asked to stage. +When a contract reaches execute-complete with VERIFY green **and harness review is done**, stage the +**product** files that contract touched: source, tests, specs, shipped documentation. Do not wait to +be asked to stage. -**Still do not commit** unless the human asks. +**Still do not commit** unless the human explicitly asks (e.g. "commit", "commit and push"). + +## Git publish gate (hard) + +Never **commit**, **push**, or **create/open a pull request** without explicit human approval for that +action. + +- Contract approval, feature PASS, "approve", "proceed", or VERIFY green **do not** authorize commit, + push, or PR — ask first or wait for an explicit publish instruction. +- After staging, stop and report what is ready. Offer commit/PR only as a question; do not run them. +- `git status` / `git diff` for review prep are fine; publishing is not. ## Commit authorship @@ -29,6 +40,7 @@ The commit records what changed and why. What typed it is not part of the record ## After staging -Say briefly what was staged and what was left unstaged. Do not push or open a pull request unless asked. +Say briefly what was staged and what was left unstaged. Do not commit, push, or open a pull request +unless the human explicitly requests that step. When staging a feature branch, exclude harness paths even when they appear beside real changes. diff --git a/rules/post-execute-review.mdc b/rules/post-execute-review.mdc new file mode 100644 index 0000000..38fbc52 --- /dev/null +++ b/rules/post-execute-review.mdc @@ -0,0 +1,34 @@ +--- +description: After VERIFY green, run harness-review in chat before staging or reporting done +alwaysApply: true +globs: "" +--- + +# Post-execute review + +After a sprint contract is **executed** and VERIFY is green, run a **harness review** before staging +product files or telling the human the work is complete. + +## Required order + +``` +CONTRACT (approved) → EXECUTE → VERIFY → REVIEW → stage → stop +``` + +1. **VERIFY** — run the contract's verify commands; all must pass (or document skips with reason). +2. **REVIEW** — read `harness-review` skill + `templates/REVIEW.md`; grade against the contract. +3. **Report** — deliver the review summary to the human **in chat** (merge recommendation, findings). + Do not paste harness review or contract compliance into the GitHub PR body. +4. **Stage** — stage product files; set `FEATURES.json` to `PENDING_REVIEW` if not already. +5. **Stop** — do not commit, push, or open a PR unless explicitly asked. + +## Not a substitute for human PASS + +The executor runs review and sets `PENDING_REVIEW`. **`PASS` is human-only** after they approve merge. + +## When review can be skipped + +- Trivial one-line fixes with no contract (if `AGENTS.md` allows condensed work) +- Human explicitly says "skip review" for this session + +Otherwise: **no staging, no "done" message without review.** diff --git a/rules/pr-creation.mdc b/rules/pr-creation.mdc new file mode 100644 index 0000000..1201b58 --- /dev/null +++ b/rules/pr-creation.mdc @@ -0,0 +1,20 @@ +--- +description: Open GitHub PRs with the create-pull-request skill — detailed product body, no harness IDs +alwaysApply: true +globs: "" +--- + +# Pull request creation + +When opening or editing a GitHub PR, read and follow the **`create-pull-request`** skill +(`.agents/skills/create-pull-request/SKILL.md`). + +## Quick rules + +- **Title:** `type(scope): plain English` — no feature ledger IDs, audit codes, or contract paths. +- **Body:** full template in the skill — Summary, Problem, Solution, Behaviour changes, Files changed, + Risk and rollout, Test plan. Enough detail for a reviewer who was not in the session. +- **Keep local:** contracts, `FEATURES.json` IDs, harness-review output, `PENDING_REVIEW` — chat only. +- **Never:** tool attribution (`Made with Cursor`, `Co-Authored-By` assistant) in title, body, or commits. + +Harness review runs before the PR; its output goes to the human in chat, not on GitHub. diff --git a/scripts/setup-harness-kit.sh b/scripts/setup-harness-kit.sh index 1612261..25cb58d 100755 --- a/scripts/setup-harness-kit.sh +++ b/scripts/setup-harness-kit.sh @@ -153,5 +153,15 @@ if [ -f .gitignore ] && ! grep -qx 'skills/.harness/' .gitignore; then printf '\n# harness working state — contracts, local templates, session state\nskills/.harness/\n' >> .gitignore fi +# --- optional: GitHub PR template from create-pull-request skill --------------- +pr_tpl="$kit/skills/create-pull-request/templates/pull_request_template.md" +if [ -f "$pr_tpl" ]; then + mkdir -p .github + if [ ! -f .github/pull_request_template.md ]; then + cp "$pr_tpl" .github/pull_request_template.md + echo "harness-kit: installed .github/pull_request_template.md" + fi +fi + echo "harness-kit: linked $count skills into $MERGE_DIR" echo " upgrade: git submodule update --remote $rel && ./$rel/scripts/setup-harness-kit.sh" diff --git a/skills/create-pull-request/SKILL.md b/skills/create-pull-request/SKILL.md new file mode 100644 index 0000000..1e84755 --- /dev/null +++ b/skills/create-pull-request/SKILL.md @@ -0,0 +1,99 @@ +--- +name: create-pull-request +description: >- + Open a GitHub pull request using the kit PR template. Use when the user asks to open/create a PR, + push and PR, or publish a branch. Write a detailed, product-facing description. Contracts and + harness review stay local — never put feature IDs, contract paths, or harness sections in the PR + title or body. +--- + +# Create pull request + +GitHub PRs are **product-facing and detailed**. A reviewer who has not seen the session should +understand the problem, the fix, what changed in behaviour, and how it was verified. Harness workflow +(contracts, `FEATURES.json` IDs, `harness-review`, audit finding codes) stays in local/session +context only. + +## Before opening + +1. Human explicitly asked to push and/or open a PR. +2. VERIFY is green; harness review is done (reported in chat, not in the PR body). +3. Run `git status`, `git diff` vs the default branch, `git log` for commits on the branch. +4. Draft the full body from the diff — do not ship a sparse PR. + +## Title format + +Conventional commit style — **no ticket/harness IDs**: + +``` +(): +``` + +**Do not** include: feature ledger IDs (`SEC-002`, `PAY-015`), audit codes (`AUDIT-001-F02`), +`PENDING_REVIEW`, or contract file paths. + +## Body template (required sections) + +Use **all** sections below. Omit a section only when truly N/A (say "N/A" in one line). + +Template file: `templates/pull_request_template.md` (install to `.github/pull_request_template.md` +via `setup-harness-kit.sh` when missing). + +```markdown +## Summary + +<2–4 sentences: what this PR does and why it matters.> + +## Problem + + + +## Solution + + + +## Behaviour changes + +| Before | After | +|--------|-------| +| | | + +## Files changed + +- `path/to/file` — + +## Risk and rollout + +- **Risk:** Low / Medium / High — +- **Rollback:** +- **Prod / env notes:** + +## Test plan + +- [x] `` — +- [ ] CI build + e2e +``` + +### Forbidden in title, body, and commit messages + +- Feature ledger IDs, audit finding IDs, contract paths +- Sections named "Harness review", "Contract compliance", sprint contract paste +- Contract HTML markers (``) +- Tool attribution (`Made with Cursor`, `Co-Authored-By` assistant) + +## Command + +```bash +git push -u origin HEAD +gh pr create --title "" --body "$(cat <<'EOF' +## Summary +... +EOF +)" +``` + +Use the consumer repo's `gh` auth pattern if documented in `AGENTS.md`. + +## Editing an existing PR + +Rewrite the full body with `gh pr edit <number> --title "..." --body "$(cat <<'EOF' ... EOF)"`. diff --git a/skills/create-pull-request/templates/pull_request_template.md b/skills/create-pull-request/templates/pull_request_template.md new file mode 100644 index 0000000..126d5a7 --- /dev/null +++ b/skills/create-pull-request/templates/pull_request_template.md @@ -0,0 +1,32 @@ +## Summary + + + +## Problem + + + +## Solution + + + +## Behaviour changes + +| Before | After | +|--------|-------| +| | | + +## Files changed + +- + +## Risk and rollout + +- **Risk:** +- **Rollback:** +- **Prod / env notes:** + +## Test plan + +- [ ] +- [ ] CI build + e2e diff --git a/skills/harness-review/SKILL.md b/skills/harness-review/SKILL.md index 2c36804..2cb22e8 100644 --- a/skills/harness-review/SKILL.md +++ b/skills/harness-review/SKILL.md @@ -16,7 +16,9 @@ Decide whether this change should ship. Correctness over style. ## When to use -Reviewing a PR, or grading a feature sitting at `PENDING_REVIEW`. +- **After every contract execution** — once VERIFY is green, before staging or reporting done +- Reviewing a PR, or grading a feature sitting at `PENDING_REVIEW` +- When the user asks whether a change should ship ## Order matters diff --git a/skills/harness-review/templates/REVIEW.md b/skills/harness-review/templates/REVIEW.md index 02e87f0..409a32c 100644 --- a/skills/harness-review/templates/REVIEW.md +++ b/skills/harness-review/templates/REVIEW.md @@ -17,13 +17,10 @@ Focus on correctness over style. Challenge assumptions. Review the change like t Before deep code review, locate and read the relevant contract: -0. **The contract is in the PR body**, between the contract markers — it is local working state and - will not appear in the diff. If the body carries no contract, that is the first finding. Also - confirm the pasted gate output is verbatim, and flag any tool attribution in the title, body or - commit messages. -1. **Identify contract** — from PR description, branch name, commit messages, or `FEATURES.json` - (`PENDING_REVIEW` entry). Default path: `skills/.harness/contracts/<ID>.md` (or `.harness/contracts/` - if `AGENTS.md` says so). Use `AUDIT_CONTRACT` for `solidity-audit`. +0. **Locate the contract** — local path (`skills/.harness/contracts/<ID>.md` or as `AGENTS.md` declares). + It is **not** in the PR diff. Read it from disk; flag tool attribution in PR title, body, or commits. +1. **Identify contract** — from branch name, commit messages, session context, or `FEATURES.json` + (`PENDING_REVIEW` entry). Use `AUDIT_CONTRACT` for `solidity-audit`. 2. **Work-type profile** — note which profile was declared; apply only the gates that apply. 3. **Scope WILL** — list each promised item; mark **Met / Partial / Missing** with evidence from the diff. 4. **Scope will NOT** — confirm no out-of-scope work shipped; flag scope creep as a finding. diff --git a/skills/sprint-contract/SKILL.md b/skills/sprint-contract/SKILL.md index be4017a..a37dcc7 100644 --- a/skills/sprint-contract/SKILL.md +++ b/skills/sprint-contract/SKILL.md @@ -40,10 +40,13 @@ A Solidity security review → `solidity-audit`. A periodic quality audit → `c ## Opening the PR -The contract is not in git, so the **PR body carries it** between the contract markers, together with -the verbatim local gate output. A reviewer grades the PR against that; CI covers only repo-owned checks. +Contracts stay **local** (`skills/.harness/` is gitignored). When the human asks to publish, use +the **`create-pull-request`** skill — a detailed, product-facing PR body only. -**No tool attribution** in the title, body or commit messages, and a commit's author is the human. +Do **not** paste this contract, feature ledger IDs, harness-review output, or contract HTML markers +into the GitHub PR title or body. Review runs in chat before the PR is opened. + +**No tool attribution** in the title, body, or commit messages, and a commit's author is the human. ## Form diff --git a/skills/sprint-contract/templates/SPRINT_CONTRACT.md b/skills/sprint-contract/templates/SPRINT_CONTRACT.md index 83313a2..93fe198 100644 --- a/skills/sprint-contract/templates/SPRINT_CONTRACT.md +++ b/skills/sprint-contract/templates/SPRINT_CONTRACT.md @@ -22,20 +22,16 @@ Pick **one**: --- -## PR body (required) +## Pull request (when human asks to publish) -The contract is **local working state and is not in git**, so a reviewer cannot open it from the diff. -The pull request body must carry: +Contracts stay **local** — not in git. When opening a PR, use the **`create-pull-request`** skill. +Write a detailed, product-facing description (Summary, Problem, Solution, behaviour table, files, +risk, test plan). -1. The contract, between `<!-- harness-kit:contract:start -->` and `<!-- harness-kit:contract:end -->`. -2. The **verbatim output** of the local gate run — not a summary of it. +Do **not** paste this contract, `FEATURES.json` IDs, harness-review output, or +`<!-- harness-kit:contract:* -->` markers into GitHub. -CI checks only what lives in the repo and prints what it did not cover. The contract-dependent -checks are confirmed by a person reading this body. - -**No tool attribution** anywhere in the PR title, body, or commit messages: no "generated with", -no "made with" or "made by", no assistant or editor name, no `Co-Authored-By` trailer. The PR -describes the change. +**No tool attribution** in the PR title, body, or commit messages. ---