diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 772ad6b13..f8208e5b6 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -12,7 +12,7 @@ "description": "Turn feature requests into review-ready pull requests: issue, implementation, tests, a review-and-fix loop, and docs. Runs locally or on GitHub Actions, and is built for complex brownfield repos. Each week its retrospective reads what you actually merged and proposes improvements to your skill extensions.", "author": { "name": "Daniel Radman", "email": "daniel@radman.ai" }, "homepage": "https://github.com/The01Geek/prflow", - "version": "2.37.0", + "version": "2.38.0", "license": "MIT", "keywords": [ "implement", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index df9a458d0..5b54273a1 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "prflow", "displayName": "PRFlow", - "version": "2.37.0", + "version": "2.38.0", "description": "Turn feature requests into review-ready pull requests: issue, implementation, tests, a review-and-fix loop, and docs. Runs locally or on GitHub Actions, and is built for complex brownfield repos. Each week its retrospective reads what you actually merged and proposes improvements to your skill extensions.", "author": { "name": "Daniel Radman", diff --git a/.gitattributes b/.gitattributes index 7de1adc53..35af0ebaf 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,10 +1,8 @@ -# Force LF line endings on checkout for every text file, regardless of the -# user's core.autocrlf. Without this, a Windows checkout under -# core.autocrlf=true (the Git-for-Windows installer default) rewrites LF files -# to CRLF, turning a `#!/usr/bin/env bash` shebang into `bash\r` — which fails -# with `/usr/bin/env: 'bash\r': No such file or directory`. `text=auto` lets -# git's binary detection auto-exclude binary blobs (e.g. docs/internal/ship-pr.png, the -# demo GIF), so they are never line-ending-normalized. +# Force LF line endings on checkout for every text file, regardless of the user's +# core.autocrlf. Without this, a Windows checkout under core.autocrlf=true (the +# Git-for-Windows installer default) rewrites LF files to CRLF, turning a +# `#!/usr/bin/env bash` shebang into `bash\r` — which fails with +# `/usr/bin/env: 'bash\r': No such file or directory`. * text=auto eol=lf # Execution-critical files: pin LF explicitly so a shebang or interpreter never @@ -12,42 +10,3 @@ *.sh text eol=lf *.py text eol=lf *.jq text eol=lf - -# Reserved exception (now in use): a test fixture that must keep literal CRLF or -# raw bytes would otherwise be silently normalized to LF by `* text=auto` — and a -# CRLF fixture normalized to LF makes its assertion VACUOUS rather than red, since -# the fixture then matches the LF twin it is supposed to differ from. The two -# entries below are the #664 scanner's line-ending and encoding fixtures, and each -# overrides the broader rules above, which would otherwise win. The CRLF one is -# deliberately NOT named `*.sh`: the #222 guard forbids a CR byte in the index of -# any tracked `*.sh` (a CR would break a shebang), and that guard is right — this -# fixture is read as data, never executed, so it carries a neutral suffix instead -# of being carved out of #222. Do not rename it back under `*.sh`. -lib/test/fixtures/ghapi-repo-path/adversarial-crlf.txt -text -# `-diff` as well as `-text` on the encoding fixture: its undecodable byte would -# otherwise land in `git diff` output, and the #434 stale-prose self-scan pipes that -# diff into a UTF-8 reader which fails closed on it — one fixture would silently -# disarm a blocking gate for every branch carrying it. `-diff` makes git report -# "Binary files differ" instead; the working-tree bytes the scanner reads are -# untouched, so the encoding fixture still does its job. -lib/test/fixtures/ghapi-repo-path/adversarial-nonutf8.sh -text -diff - -# issue #1072: the shipped-pruned-path lint's NUL fixture must keep its NUL byte so the -# read_source skip path is exercised — mark it binary so no text normalization strips it. -lib/test/fixtures/shipped-pruned-path/skills/nul.md -text -diff - -# Preserve issue #2097's exact captured bytes and keep frozen issue prose out of -# authored-prose diff gates; the extractor still reads the working-tree bytes. -lib/test/fixtures/issue-2097-implementation-notes.fixture -text -diff whitespace=-blank-at-eof - -# issue #1194: the coverage map stores two large string-sorted JSON objects, so two -# branches that each ADD a distinct key at an adjacent sort position conflict textually -# even though they never semantically conflict — and resolving by taking one side -# silently drops the other's entry. Route this one file through the JSON-aware merge -# driver, which unions the objects per key and conflicts only on a genuine same-key -# divergence. The attribute only NAMES the driver; git falls back silently to its -# line-based merge unless `merge.coverage-map-json.driver` is also registered locally -# (`python3 lib/test/coverage-map-merge-driver.py --register`; verify with `--check`). -# The CI-side retention check (lib/test/coverage-map-retention-check.py) covers the -# server-side/web-editor path the driver structurally cannot reach. -lib/test/modules/coverage-map.json merge=coverage-map-json diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..ccfee097f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: true +contact_links: + - name: Documentation + url: https://prflow.ai + about: Installation, configuration, workflows and troubleshooting. + - name: Report a security vulnerability + url: https://github.com/The01Geek/prflow/security/policy + about: Please do not open a public issue for a security report. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..5f007e0d6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,31 @@ + + +## Before you write anything + +**This repository is a generated release tree.** Every file in it is produced by a +deterministic exporter from a private canonical source and published as a versioned +release. Nothing is authored on this branch. + +That means **a pull request editing these files cannot be merged as-is** — the next +release would overwrite it. This is not a judgement about your change. + +**Your change is still welcome.** Describe the problem it solves below. A maintainer +will reproduce it in the canonical source, credit you, and ship it in a later release, +then close this pull request with a link to the release that carries it. Please do not +read that close as a rejection. + +If you would rather not write code, **an issue is just as useful** and is the supported +channel: + +See [CONTRIBUTING.md](../CONTRIBUTING.md) for the full picture. + +--- + +## What problem does this solve? + +## How did you verify it? diff --git a/.release/files.sha256 b/.release/files.sha256 index d613c0b3b..edeeb7d73 100644 --- a/.release/files.sha256 +++ b/.release/files.sha256 @@ -1,13 +1,15 @@ -f89b7cdabbb9f72576d450773bc341ff071484176501875f8087ae99d2516544 .claude-plugin/marketplace.json -44ab7874eee82ac691749c5c699b9312b342129bf4dde7895147a06054073c5f .claude-plugin/plugin.json -88b879c14ab7ccadf055fee3236645fe78b985f7675acf747e3220d78151b8e9 .gitattributes +80c34a89fd4644c828848c7b822386ace6ce45a4dbd6a85665157ac28bfed766 .claude-plugin/marketplace.json +92eed05492904aee543429fbd411ff6adc28a39b7fdfcd24e9a69f7ec1af8765 .claude-plugin/plugin.json +b81b9647cbf5e8fd8078f4ea5afa5ac51000687ac4586fa774b8ada97ff80b49 .gitattributes +d8cf5249d002c3686b669874fd605ee933606fd09f3e00357f2c7f48464ac78a .github/ISSUE_TEMPLATE/config.yml +76ec67640a2cf68558db8518e4b894d3f3f0abbd5e31323dce01182ad215cd20 .github/PULL_REQUEST_TEMPLATE.md 3aa581a24e94e19a450f09cf20448052b97ab6ebe9fd6f373218615b6543cc42 .github/actions/read-project-config/action.yml 2bc7a047f2c817db6aeea5c4303c1d7a894f63eb36486c8c780f83e48082b935 .github/actions/setup-project-env/action.yml facfac1900a69019debe41c71942821cef551fb8e1e25b4368fffabd3be4a7fd .github/actions/setup-project-env/provision-lint-tools.sh 738fba5b1ab2e46f2680dad5daf60ee6785c483e797cca4a827b97b8f690d31a .github/actions/setup-project-env/resolve-node-cache.sh 18ae52f7b9fe5a35b62f4025f58c9c8c1e792ed55ddd89792ec6a7f080660a17 .github/actions/vendor-plugin/action.yml 3fe54520ffe3e5e3f671bb431dc0f2ee2bff5ec1f7cae8824c570ea587c7c1bf .github/actions/vendor-plugin/vendor-slice.sh -199439577b4053425686e18d0d4365bbf93545fb83bb5628f0f2f330030efb8b .github/verify-release.py +1f557173e4642f5c42b6a58f557e2dd43baec9e76a1769649643d0a4d400c8ea .github/verify-release.py f490f1fecdf8eec6308b7cf2e34660e3889d060495a5544ce4c4221d54a122f8 .github/workflows/devflow-implement.yml 938d935591ac166850ed36b64fbbd19b178428d3079352141060cb8d2310b33c .github/workflows/devflow.yml 58502873714053155681472530c12663727136334032b59435a00738136fa435 .github/workflows/distribution-verify.yml @@ -17,8 +19,8 @@ c3bfd19a8f504f74ee75cb46a0e53c9f7572bb42b0763232632494b6b7f88692 .prflow/config 79da209590c0fedf18f3d4d4bfed66d6ecbfee9780e16dd39a5b6aef1efebe42 .prflow/install-state.json de88ef01ff25c62f1ae6b978595b98383978f9d506ec1bb0e17c375486714e69 .prflow/lint-manifest.json 80fd2b66301ff216f72292a2c45d56340ff50329a083612fdd9be9d9742fa53c .prflow/tool-presets.json -1117660af8436650d252007c3b8e38f09399d792712cdc25aaeb3217015b962a .release/source.json -73443e52f28b49e016de5c5126241f7cc138a897de414c574d7176183a944208 CITATION.cff +9e825c32fc4a9ad6866afa87fd586d5ac545b4cde529de498cb8a9b0462e7d37 .release/source.json +534b96f7fb3141f3c1d9faff5d90a4e26366d5107f601ea46bd48adb59bd7cb8 CITATION.cff 288c11f7a44605139bca53ded61ba56a1f4f9dabc53b038be4a509c2d22e93aa CODE_OF_CONDUCT.md d0ad1cce7066b03c90a6cf27aaabcb3ba8f7321683f249e038d66541e05b04f6 CONTRIBUTING.md 73f76d9d5da2bcd153813fef4b018945419a67233cf38e450afdb2761589782f LICENSE @@ -26,8 +28,8 @@ ea914a3b65b598558ebc8c0be50252fcd56bda818d4c457730cb5369eeef3ad1 LICENSES/READM cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 LICENSES/feature-dev-LICENSE cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 LICENSES/pr-review-toolkit-LICENSE a37e0e9697144819e1d965176ac4ae5bc3fa02d11e7812036bbcadf6dafe2400 LICENSES/superpowers-LICENSE -e24ac63240eecf120648cc9c2d2f0c1a445017b8a59232e8c156af8ee607833f README.md -0d86fff2241870589b964118108b0b71cf72d3bd2152eaf5c41e69b4dcf5d234 SECURITY.md +22547897d6efa508a1a1665996bfe1e6e7d4be5f1b974da1bc589cc2e5d7bff0 README.md +e3b22c1530f9a7537322b0dcbc2ade11164691ae3cc732a65c52c4a8a51c45bc SECURITY.md 8efe895eab81e5d104e995d10672a1bde5e9adc18d8be7b857b30d45e0786a61 agents/ac-claim-verifier.md 22bc78f574909072b99d28526b3b89fd7a688cf4498ea964fa59164fa94eff27 agents/ac-evidence-verifier.md cb120564f7cb0db579beb3b6ab8029d750a2c9ebbeb148b9db6d834e3c741517 agents/branch-setup.md @@ -43,7 +45,7 @@ e65890e8ec9078103e20dd364cc1530adbc11fe3139908f2b6481d9fc62216ea agents/comment 4ec3170a2e48b57218ec49b5e164c78669c376d964bd7361719fbb9e80c8b9ff agents/pr-test-analyzer.md 8202bd8287d090bdc2b9673b9c4acbc8d578ed8c97dfc627876841850d32a54d agents/silent-failure-hunter.md b2f64770a3770ba71ba945c7183437380dd2f570d10100bd209af2ce1f38ad65 agents/type-design-analyzer.md -2de5c4cdfb6ef8f71bad4329195c9d8d5eab0a60e088ae251f912dc758b28d03 docs/README.md +8f9ffdb9388c8644acda842c14bd97d7269e3e848bee6d234626927077055df7 docs/README.md aecc57e49dbe93c5c2cd602e0f697f82c96f0ee3d14f58536ea02d4b75d7b5ea docs/external/docs/concepts/human-control.md 628826ccb477c7f6ab4b0b9d1097b6a9ba2997c9e4115fa04d69cf5769939a54 docs/external/docs/concepts/index.md c2d603cdc5fb03b29f719ac09c01d97a2a54b2ff6b400f95eaed8cf23ba8cc80 docs/external/docs/concepts/lifecycle.md @@ -68,7 +70,7 @@ b6dbf359f4873650e64184c3fe5b6139b3379375ba5b0d3c2ba03fa486276032 docs/external/ 1daa3a4558ba63cb3f8ea5ce596418426fb40dc0dd4c54038599886c6c42951b docs/external/docs/getting-started/initialization.md 5698026460cd77111a208e61587dbc4180a54f8ee84f2d5170a519ebbe367fa0 docs/external/docs/getting-started/installation.md 44e7ff0be92601b9e5dbda715c41c1446a22c436b93c9d017890fa84ee3c5cbf docs/external/docs/getting-started/migrate-from-devflow.md -c43aafc48923332d4eb5b25597a4a4ac041a535f117295933d17855dd2d11e97 docs/external/docs/getting-started/requirements.md +59dd2cace7d7f992c06e1f81208db073616f17f048f92fd450380264533eb4b9 docs/external/docs/getting-started/requirements.md 065f553d791c4e2ace5631e7b87e7109f300281a6cdf902d70c0557e91bf0976 docs/external/docs/getting-started/updates.md cc5b705904aa1746d573c3f9d4fcba19859e58fca4e3d1710cc52b6c3dbbf87f docs/external/docs/index.md dc47250dc53311ccfa6ce3feed7ce5f7ccc06191a1484e8c024856bf75476fbb docs/external/docs/quickstart.md @@ -78,12 +80,12 @@ f428b17460b29e4f591f271c726315a18788fded88c4266cc68d114bc00cb75c docs/external/ 3266046bbc46dd4419d6cd3121b4165a2dab15404b1a2885e2cc0acfb0ca4345 docs/external/docs/reference/release-notes-archive-2026.md da398080f766e22f2aed0562b32343a05685368eca6ccb6b533525bf162304f4 docs/external/docs/runs/cloud/auto-review.md 27e2a313495828cbbed309ddbf283c8c4d97f88432835536327b1b570d345c6f docs/external/docs/runs/cloud/index.md -cf80f29f2bd6d6c8ad471ab44f14088324ef6922ab3ec64d8e4e2e7e01316c0f docs/external/docs/runs/cloud/installation.md +f9f3c9e3f056ea85fe7efefe2ae0eaeb505abea98f3aa911b9cecb21ff5d86c6 docs/external/docs/runs/cloud/installation.md 8f33d27592a276bce20bd22ad0ec0a858d17dc723222be9229d04e5220545a55 docs/external/docs/runs/cloud/recovery.md a8ea7f4b7f9b8dd8005530e9ccda73cb7bf2d6d1710c6072c432ffa6e4ef5757 docs/external/docs/runs/cloud/runners.md -df78e8360572cfd2ca25c8eeb3a963c76f8146f79bfff4d5f08f89ad20472d45 docs/external/docs/runs/cloud/setup.md +98c2aba17e9cb6473e747a9e997de05031a44592fd2b4f122f29550b49d6b9f3 docs/external/docs/runs/cloud/setup.md 1d3529fff694cc2f5050101cea1ded9e3bc9e5d7bc9acf60d1de4e713faf1be4 docs/external/docs/runs/cloud/triggers.md -edb11582f11bfbb36fbd84d5e1df50485ab336eff66bda07d158f26f53de512c docs/external/docs/runs/cloud/updates.md +5750700fcf3927fc9d4b6662165a8a2c9f11a21bade373537255fcb98e1256aa docs/external/docs/runs/cloud/updates.md 1081917d247cb0f70634fc08e06f3556eb5ec85b5d90bb079643016d6def5d93 docs/external/docs/runs/index.md 2fdf5aad7db89957404dbdf134afed0263dbb07fbe3e5a73cfaa90bf4d62bea9 docs/external/docs/runs/local/client-commands.md 278f9cc41cabeece613cb0b8c47ff44a899f06552d7a86eec0bf5579ae2ab8fa docs/external/docs/runs/local/index.md @@ -110,7 +112,7 @@ a446d5352123a365890aceca2d484aec79c2131b629c888195078a3a546bb263 docs/external/ ea21749d200bc56d2abc4840bcde00bf1befcd9e5e6303111494721309659f14 docs/external/images/workflow-skill-map.svg 41f0b74f88999c22c5a9e4251fcd57fb9e22abfcf6dba48d4bfc126bf84458ee docs/external/images/workpad-resume.svg eb7455d26518550f79813e873937f1cab70602c0ee7e86516bda131d4272aa33 docs/external/index.mdx -04340288a10833e59118e692fc554634217e111b8707eba05254eb3a250bff51 docs/external/release-notes.md +a8433828c1957a82a8b8bc8bff73886e7b7c6c63a2e0c204764623ad483eea21 docs/external/release-notes.md d66e62b8bf728b5f648b9a0be23f2cd0c541bdb949a07b0aad795be32da2ffd9 docs/external/style.css 5d4c888f0e8d822f00b62297010949dba765cc51fedbe0c43e8ff611241b7bec docs/ship-pr.png bd795c2b4c69558e720d59cd24b42b9b00422fb12327c891548a405a722c52e4 install.sh @@ -131,11 +133,11 @@ a1ee5306d394a4677595ca93c50e01bb9a213f3fcaf026d5737d2de9ab3a871d lib/efficiency 56cc5f3d660e2b21fca653d82a0a5b3908d583e6ee8cec8d71ebd91a3363be8b lib/fetch-pr-context.sh a5e6d6c7e9f9142c4fa0c0132ef538b701bbf9aba7365ac0b1b1dab2997c1424 lib/filing-decisions.sh d5fde1559e0ef0b32332cb4d4be9edc8c5269779a8c89775f3bca4126ba8474c lib/generate-capability-profiles.py -278fbda6c4654fb720bda3bf250989c88a1f7fc72b851cec41afd7c6ef521199 lib/generate-env-freeze-advisory.py +e258471a6df87fe06beaeb0aac96a44e3dddd6aebc78d0e57a69e10c8a9966ca lib/generate-env-freeze-advisory.py 5725ea837b253bbe8242b6135a5c22acf35c54c5ee1f46069eefc955d49d8315 lib/generate-install-state.py eb24ddb188e56d544c179fc6e6c77c7cc47cb064f910ff83224bec191c1acaa1 lib/generate-plugin-identity.py 1c216ddd4bc797200e7d1af29f375629403f18a4f49f2e0ab9e73d81dd01b774 lib/implement-stop-guard.sh -adccdb91f8015ac4f84494e334cec3d0d5d622b4a0fa50c8b031c41f04f6cedd lib/intervention-surfaces.md +17fb43d831484925b97ad0e43d5b0ec06068fd5e47133b4344103068a8aea269 lib/intervention-surfaces.md 179b7b477c4bf014f6d871e82d7c5c0ac3acec45961527d4688f275d1c112be9 lib/materialize-retrospectives.sh ddf4499fb512806fd7fc69ad26bc0650474a6b134f5a90595bc3ee321a0f782b lib/meta-issue.sh 0bff70cda583ec4dacf6514b24592bbfe535dfaf6fe27c7bbe94ebaa0c464e17 lib/migrate-config-values.py @@ -405,7 +407,7 @@ f35c3ab85dbcc5cbf9c8faa63dfffbac87832ba6dc3cb9ef80b51d0a39c46aee skills/impleme 8c99caab811587df7832ac3946660b139b91860be6c014c0594be79bcab5c8ad skills/implement/references/sweep-2-3-1-orphaned-setup.md 4cbe8d62d4e41207031ff6d52f3ba4c15237841c4f482c15cb16c3c843ab89c7 skills/implement/references/sweep-2-3-2-stranded-dependents.md 00bf3b9057a6308921db565c3d5b485430d0720c19c6decce20558838a8e16cc skills/implement/references/sweep-2-3-7-collection-cardinality.md -49be242b8f5d8c27bc373de2f5a2f83b8c29f3a7654ee8f8f5934db549020148 skills/init/SKILL.md +f0ed9a60f90a15a056d8fed37ae31c76c9ea90a0094053550e3fbea62719df57 skills/init/SKILL.md cd12d9b9257ed15ee8505e79bacd13ead098ae14ed7b716e06f99aaba5888dfe skills/pr-description/SKILL.md 6c9890b1553c6263f9441a9e048daa77eb292c2625c93a8cb059c4a80171ba22 skills/receiving-code-review/SKILL.md 8a0c484b41251c0d3e66896c1d76a496db87b2625f4dd2de78b112d1adf0c25e skills/requesting-code-review/SKILL.md diff --git a/.release/source.json b/.release/source.json index aa9960195..912682b16 100644 --- a/.release/source.json +++ b/.release/source.json @@ -1,9 +1,9 @@ { "exporter_policy_version": "1.0.0", - "payload_byte_count": 8512768, - "payload_file_count": 433, - "plugin_version": "2.37.0", + "payload_byte_count": 8514428, + "payload_file_count": 435, + "plugin_version": "2.38.0", "schema_version": 1, - "source_commit": "64dae78ee68116c8d8d6ce2d5f0ab0e4c26f89c0", - "source_commit_time": "2026-08-29T12:42:27-06:00" + "source_commit": "aeb0afc2342117ac40c153778832febf636ab8ca", + "source_commit_time": "2026-08-29T15:30:06-06:00" } diff --git a/CITATION.cff b/CITATION.cff index 5a959cae4..cbebcf419 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,7 +14,7 @@ authors: repository-code: "https://github.com/The01Geek/prflow" url: "https://github.com/The01Geek/prflow" license: MIT -version: 2.37.0 +version: 2.38.0 keywords: - claude-code - agentic-ai diff --git a/README.md b/README.md index de458fd6f..f1a2ebb41 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![PRFlow — Ship the PR, not the cleanup. A Claude Code plugin that turns one request into one merge-ready pull request across four phases: Setup (/prflow:create-issue), Implement (/prflow:implement), Review & fix (/prflow:review-and-fix), and Document (/prflow:docs).](docs/ship-pr.png)](https://prflow.ai/) -[![CI](https://github.com/The01Geek/prflow/actions/workflows/ci.yml/badge.svg)](https://github.com/The01Geek/prflow/actions/workflows/ci.yml) +[![Release verification](https://github.com/The01Geek/prflow/actions/workflows/distribution-verify.yml/badge.svg)](https://github.com/The01Geek/prflow/actions/workflows/distribution-verify.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) ![Built on Claude Code](https://img.shields.io/badge/built%20on-Claude%20Code-d97757.svg) @@ -106,7 +106,7 @@ The intended way to drive PRFlow — from a feature request to a reviewed pull r - **`git`** and **[`gh`](https://cli.github.com)** (GitHub CLI, authenticated via `gh auth login`) — you most likely already have these. - **`jq`** — JSON wrangling inside the skills. - **Python 3.11+** — the config resolver and most helper scripts are Python. Config itself is JSON, read with the standard library alone. -- **PyYAML** — `python3 -m pip install PyYAML`. **The step people miss:** `/plugin install` never runs `pip`, so install it yourself. Name the package rather than reaching for `-r requirements.txt`: that path resolves against *your* working directory, not the plugin cache, so in a Python project it installs your project's dependencies instead. On the local tier PyYAML is an **advisory** dependency — `bash lib/preflight.sh` reports a missing PyYAML and still exits 0 (see below). +- **PyYAML 6 or newer** — `python3 -m pip install 'PyYAML>=6'`. **The step people miss:** `/plugin install` never runs `pip`, so install it yourself. Name the package rather than reaching for `-r requirements.txt`: that path resolves against *your* working directory, not the plugin cache, so in a Python project it installs your project's dependencies instead. On the local tier PyYAML is an **advisory** dependency — `bash lib/preflight.sh` reports a missing PyYAML and still exits 0 (see below). `git`, `gh`, `jq` and `python3` are not optional — the core skills call them directly, and a missing one is a hard stop. Shell helpers avoid GNU-only flags, so macOS/BSD work without GNU coreutils. @@ -197,13 +197,16 @@ See [PRFlow workflows](https://prflow.ai/docs/workflows) for the supported user- ## Repository layout ```text -.claude-plugin/ # plugin.json (declares dependencies) + marketplace.json (this repo is its own marketplace) -skills/ # one SKILL.md per command (/prflow:implement, /prflow:review, /docs, …) -agents/ # 10 subagents: checklist-generator/-deduper/-verifier + code-explorer/-architect + 5 pr-review-toolkit reviewers +.claude-plugin/ # plugin.json (no companion-plugin dependencies) + marketplace.json (this repo is its own marketplace) +skills/ # one SKILL.md per command (/prflow:implement, /prflow:review, /prflow:docs, …) +agents/ # 15 subagents: the review-engine trio, the implement-phase agents, and 5 pr-review-toolkit reviewers scripts/ # Python + shell CLIs (workpad.py, config-get.sh, match-deferrals.py, …) -lib/ # retrospective-loop helpers (*.sh, *.jq), preflight.sh, test/ +lib/ # retrospective-loop helpers (*.sh, *.jq) and preflight.sh .github/ # optional cloud tier: workflows + composite actions (incl. vendor-plugin) -.prflow/ # config.example.json + config.schema.json (+ learnings/, logs/) +.prflow/ # config.example.json, config.schema.json, tool-presets.json, lint-manifest.json, install-state.json +.release/ # per-release provenance: source.json + a SHA-256 for every published file +docs/ # source for https://prflow.ai +LICENSES/ # third-party licences for the vendored skills and agents install.sh # one-command cloud-tier install/update (thin by default; DEVFLOW_VENDOR=1 to commit the plugin) ``` diff --git a/SECURITY.md b/SECURITY.md index b053d321f..35534abf6 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -29,7 +29,7 @@ workflows. A few areas warrant care: out of it — it holds only non-secret environment configuration (project/board IDs, model names). Store credentials as encrypted GitHub Actions secrets, never in `config.json`. -- **The `.prflow/learnings/` corpus is committed, not gitignored.** The +- **In a repository where PRFlow is installed, the `.prflow/learnings/` corpus is committed, not gitignored.** The retrospective loop's records (`retrospectives.jsonl`, `experiment-records.jsonl`, `overrides.json`) are tracked — re-included by the `!/.prflow/learnings/` negation in `.gitignore` past the `/.prflow/*` ignore rule — and published to diff --git a/docs/README.md b/docs/README.md index 6334a6447..226d2b543 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,10 +1,11 @@ # Documentation -PRFlow's user-facing documentation lives at ****. +This directory holds the source for **** under `external/`, plus +the note below. -## Why this directory exists +## Why this file exists -This directory is deliberately minimal, and it is not optional. +This file is not optional. Every released version of PRFlow's cloud vendoring action copies a fixed set of root members out of a clone of this repository before pruning the ones it does diff --git a/docs/external/docs/getting-started/requirements.md b/docs/external/docs/getting-started/requirements.md index cddacbcf9..c9223391e 100644 --- a/docs/external/docs/getting-started/requirements.md +++ b/docs/external/docs/getting-started/requirements.md @@ -92,7 +92,7 @@ The first line is the version that will run. The list shows every `python3` on ` PyYAML is recommended but is not a hard local prerequisite. Install it with: ```bash -python3 -m pip install PyYAML +python3 -m pip install 'PyYAML>=6' ``` Name the package rather than pointing `pip` at a requirements file. A requirements file resolves against your current working directory, so in a Python project you would install that project's dependencies by mistake. diff --git a/docs/external/docs/runs/cloud/installation.md b/docs/external/docs/runs/cloud/installation.md index ae63feabf..dca7786b8 100644 --- a/docs/external/docs/runs/cloud/installation.md +++ b/docs/external/docs/runs/cloud/installation.md @@ -20,7 +20,7 @@ Add PRFlow's optional GitHub Actions tier to a repository. Skip this page if you ```bash - curl -fsSL https://raw.githubusercontent.com/The01Geek/prflow/v2.37.0/install.sh -o devflow-install.sh + curl -fsSL https://raw.githubusercontent.com/The01Geek/prflow/v2.38.0/install.sh -o devflow-install.sh ``` @@ -30,7 +30,7 @@ Add PRFlow's optional GitHub Actions tier to a repository. Skip this page if you The URL selects the installer. `DEVFLOW_REF` selects the payload it installs. Use the same value in both places. ```bash - DEVFLOW_REF=v2.37.0 bash devflow-install.sh + DEVFLOW_REF=v2.38.0 bash devflow-install.sh ``` A first installation applies immediately. Add `--dry-run`, or set `DEVFLOW_DRY_RUN=1`, to preview instead. @@ -71,7 +71,7 @@ Add PRFlow's optional GitHub Actions tier to a repository. Skip this page if you The workflows fetch the plugin at run time into `.prflow/vendor/prflow/`, using the `prflow_version` pin in `.prflow/config.json`. The fetched tree is ignored and is not committed. ```bash - DEVFLOW_REF=v2.37.0 bash devflow-install.sh + DEVFLOW_REF=v2.38.0 bash devflow-install.sh ``` Choose this for a small install diff and a small update diff. @@ -80,7 +80,7 @@ Add PRFlow's optional GitHub Actions tier to a repository. Skip this page if you The plugin tree is committed to your repository instead. ```bash - DEVFLOW_VENDOR=1 DEVFLOW_REF=v2.37.0 bash devflow-install.sh + DEVFLOW_VENDOR=1 DEVFLOW_REF=v2.38.0 bash devflow-install.sh ``` Choose this when you want no run-time fetch and want the plugin bytes auditable in your own history. Expect a much larger install and update diff. diff --git a/docs/external/docs/runs/cloud/setup.md b/docs/external/docs/runs/cloud/setup.md index 715e17a6a..3c0aa44a0 100644 --- a/docs/external/docs/runs/cloud/setup.md +++ b/docs/external/docs/runs/cloud/setup.md @@ -107,7 +107,7 @@ renaming it actually does. If the brand inconsistency bothers you, the answer is a future PRFlow release that accepts both spellings — not a rename you perform yourself today. - +{/* prflow-env-freeze:begin freeze_version=1 sha256=83e38517a288860f4311150801dc113ad42361758a9007239d49d4bacb832314 (generated by lib/generate-env-freeze-advisory.py -- do not hand-edit; source: lib/rename-map.json frozen.env_identifiers) */} > **These names are frozen. Do not rename them.** PRFlow reads each one under its `DEVFLOW_` spelling and under no other spelling — there is no `PRFLOW_*` equivalent anywhere in the plugin. Renaming one of these does not move a setting; it removes it. **The two GitHub App pairs fail asymmetrically.** The asymmetry inverts what a careful consumer would guess. Rename the SECRET alone and the mint step fails loudly — you find out immediately. Rename the VARIABLE alone and nothing fails: the mint is gated on `vars. != ''`, an unresolvable name reads exactly like `deliberately not configured`, so every job falls back to `steps.app-token.outputs.token \|\| secrets.GITHUB_TOKEN` and the run goes GREEN under a degraded identity. Rename BOTH — the natural thing to do, since they are one setting in the consumer's head — and the variable's silent skip gates off the secret's loud guard, so the loud half never runs. The safe rename order is therefore the one nobody would guess, which is the reason this block exists. @@ -140,7 +140,7 @@ You set these in your own environment. Every one resolves through a `${NAME:-… | `DEVFLOW_APPLY` | environment variable (install-time) — the install one-liner — `DEVFLOW_APPLY=1 bash devflow-install.sh` | silent | Silent no-write on an upgrade. An existing install defaults to preview, so the upgrade you believe you applied only previewed: the repository is unchanged and keeps running the previous workflows and the previous pin. The run exits 0 and its last line is the ordinary dry-run notice. The equivalent `--apply` flag is unaffected. | Not on this list and wondering why: `DEVFLOW_PROMPT_EXTENSION_ROOT` is written by the cloud workflows that run the review engine and never set by you, and `DEVFLOW_CONFIG_FILE` is an internal seam that has never been published as a consumer setting. Both are recorded with their reasoning in `lib/rename-map.json`. - +{/* prflow-env-freeze:end */} ## Run a Smoke Test diff --git a/docs/external/docs/runs/cloud/updates.md b/docs/external/docs/runs/cloud/updates.md index c88e1cd04..461e520c2 100644 --- a/docs/external/docs/runs/cloud/updates.md +++ b/docs/external/docs/runs/cloud/updates.md @@ -18,16 +18,16 @@ The installer is review-first on an update: it previews by default, and it never Download the newer installer and pass the same new tag as the payload. ```bash - curl -fsSL https://raw.githubusercontent.com/The01Geek/prflow/v2.37.0/install.sh -o devflow-install.sh + curl -fsSL https://raw.githubusercontent.com/The01Geek/prflow/v2.38.0/install.sh -o devflow-install.sh # read devflow-install.sh, then: - DEVFLOW_REF=v2.37.0 bash devflow-install.sh + DEVFLOW_REF=v2.38.0 bash devflow-install.sh ``` On an existing installation this runs in dry-run mode. It does not intentionally change your repository, though it can create temporary files, and it does execute the script you downloaded. Read that file before you run it. ```bash - DEVFLOW_REF=v2.37.0 bash devflow-install.sh --apply + DEVFLOW_REF=v2.38.0 bash devflow-install.sh --apply ``` This refreshes the managed workflows, the composite actions and the configuration schema. It backfills newly added configuration keys and preserves the values and arrays you already set. diff --git a/docs/external/release-notes.md b/docs/external/release-notes.md index 44527191d..2ddbef565 100644 --- a/docs/external/release-notes.md +++ b/docs/external/release-notes.md @@ -29,6 +29,16 @@ This page summarizes user-visible PRFlow changes. For a complete change history, - **Installer and documentation links now point at the public documentation site.** Messages from `install.sh` and `SECURITY.md` that previously referenced maintainer-only documentation paths now link to the equivalent pages on the documentation site, so a reader can always reach them. +- **The documentation site deploys again.** The frozen-`DEVFLOW_*` advisory moved into the + published cloud-setup page, and it carried its generated region's HTML comment delimiters + with it. The documentation site parses those pages as MDX, which rejects an HTML comment + outright, so the deployment failed and the site kept serving its previous build. The + region's markers are now MDX comments and the docs build validates clean. +- **Release verification covers two surfaces it previously skipped.** SVG files are text and + can carry anything, but were absent from the scanned set, so images shipped unexamined. + The documentation navigation manifest is JSON, so the markdown link checker never read it + — a navigation entry pointing at a page that no longer ships would have published a broken + site. Both are now checked on every release, each proven against a planted defect. ## August 28, 2026 diff --git a/lib/generate-env-freeze-advisory.py b/lib/generate-env-freeze-advisory.py index 0e468aa71..4be79a034 100644 --- a/lib/generate-env-freeze-advisory.py +++ b/lib/generate-env-freeze-advisory.py @@ -62,10 +62,10 @@ MAP_REL = "lib/rename-map.json" REGION_FILE = "docs/external/docs/runs/cloud/setup.md" BEGIN_RE = re.compile( - r"^(?P\s*)" +END_TEXT = "{/* prflow-env-freeze:end */}" # The read shapes A2 accepts. A `${NAME:-...}` / `${NAME:=...}` self-default IS a read, # not an assignment -- the value still comes from the ambient environment. @@ -418,9 +418,9 @@ def region_sha(lines: list[str]) -> str: def banner(block: dict, lines: list[str]) -> str: return ( - f"" + f"source: {MAP_REL} frozen.env_identifiers) */}}" ) diff --git a/lib/intervention-surfaces.md b/lib/intervention-surfaces.md index 699a65147..23fd8e547 100644 --- a/lib/intervention-surfaces.md +++ b/lib/intervention-surfaces.md @@ -3,7 +3,7 @@ Shared prompt fragment used by the /retrospective-audit drafting brief (Stage B Stage B PROPOSES a corrective change (it files an issue spec; it does not edit). When choosing the change to propose, the agent considers — but is NOT limited to — these surfaces. Any surface is a valid proposal, because a human triages the issue and implements it through the normal -/devflow:implement -> review pipeline. +/prflow:implement -> review pipeline. --> ## Candidate intervention surfaces @@ -12,24 +12,24 @@ When the failure pattern recurs, the highest-leverage change to propose could li ### Process / workflow surfaces -- **Prompt extensions** (`.prflow/prompt-extensions/.md`) — the consumer-owned surface for a purely **additive** skill-behavior change. `scripts/load-prompt-extension.sh` prints this file and skill `` is instructed to append it verbatim to its own prompt (an absent/empty file is a silent no-op), so a "make skill X also do Y" fix can land here as an append instead of editing the shipped skill body. It is bounded: extensions are **append-only** (they cannot override or delete existing skill prose) and **consumer-local** (they don't change behavior for adopters who never pull this repo's extensions). A *structural* skill change — one that must override existing prose, or one that *must ship in the engine to take effect for adopters* — proposes a change to the engine itself instead. **Check the file's readers before estimating blast radius:** an extension is not always read by one skill. A skill that applies another skill's principles without invoking it loads that skill's extension too (issue #620), so `.prflow/prompt-extensions/receiving-code-review.md` now governs every autonomous `/devflow:review-and-fix` entry that goes through the skill preamble — the standalone loop, implement Phase 3 inline, and the Step 2.6 shadow entry — as well as direct reception passes (the documented Skill-denied Phase 3 fallback bypasses the preamble and loads neither extension). Editing it to change reception policy therefore reaches unattended loops, not only interactive ones. +- **Prompt extensions** (`.prflow/prompt-extensions/.md`) — the consumer-owned surface for a purely **additive** skill-behavior change. `scripts/load-prompt-extension.sh` prints this file and skill `` is instructed to append it verbatim to its own prompt (an absent/empty file is a silent no-op), so a "make skill X also do Y" fix can land here as an append instead of editing the shipped skill body. It is bounded: extensions are **append-only** (they cannot override or delete existing skill prose) and **consumer-local** (they don't change behavior for adopters who never pull this repo's extensions). A *structural* skill change — one that must override existing prose, or one that *must ship in the engine to take effect for adopters* — proposes a change to the engine itself instead. **Check the file's readers before estimating blast radius:** an extension is not always read by one skill. A skill that applies another skill's principles without invoking it loads that skill's extension too (issue #620), so `.prflow/prompt-extensions/receiving-code-review.md` now governs every autonomous `/prflow:review-and-fix` entry that goes through the skill preamble — the standalone loop, implement Phase 3 inline, and the Step 2.6 shadow entry — as well as direct reception passes (the documented Skill-denied Phase 3 fallback bypasses the preamble and loads neither extension). Editing it to change reception policy therefore reaches unattended loops, not only interactive ones. **Consumer-owned is a statement about who MAY write the file, not about which checkout a given tier reads it from.** On the cloud review tier those are different questions: that job checks out the pull request's head, so since issue #874 the two extensions the reviewer loads (`review` and `requesting-code-review`) are materialized from the trusted base ref and the workspace copies are truncated — a PR's edit to them does not reach its own review. This is the base-ref trust boundary. -- **`/devflow:implement` skill** (`skills/implement/SKILL.md` orchestrator + `skills/implement/phases/phase-N-*.md` reference files + `skills/implement/references/*.md` predicate-gated references) — the orchestrator drives the four-phase lifecycle; the detailed per-phase procedure you would strengthen/check/gate lives in the phase files (the orchestrator `SKILL.md` holds only thin per-phase stubs), while a procedure whose predicate is false on most runs — Phase 4.0's deferred-AC follow-up filing — lives in a `references/` file the phase file reaches only when that predicate holds. -- **`/devflow:create-issue` skill** (`skills/create-issue/SKILL.md` thin always-loaded root + `skills/create-issue/references/*.md` marker-gated step and fallback references) — the issue-quality entry point. If issues themselves are the bottleneck (vague acceptance criteria, missing repro steps, ambiguous scope), this is where to fix it; the root holds the routing pointer and load contract, the entry gate, and the non-degradable invariants, while the routing table itself (`references/degradation-routing.md`, relocated off the root in issue #1644) and the per-step procedure you would strengthen live in the reference files. -- **`/devflow:review` and `/devflow:review-and-fix` skills** — code-review discipline. If review caught a regression too late, the gap belongs here. -- **Phase sub-skills** (`pr-description`, `docs-sync-internal`, `docs-sync-external`, `docs-release-notes`) — narrower behaviors invoked by `/devflow:implement`. -- **`docs-verify` skill** (`skills/docs-verify/SKILL.md`) — invoked interactively in write mode, and dispatched in `--report-only` mode by **`/devflow:create-issue` Step 1, its only programmatic caller**. The two modes have **separate identities**: write mode is the documentation-accuracy pass; report-only is a **docs-first code explorer** whose deliverable is a map of current behavior, with documentation as its entry point and provisional evidence rather than its subject. Its report-only breadth bound (the duty floor) and its search-space operand are where to fix a Step 1 pass that surveys too much or too little; the *Who you are in report-only mode* section is where to fix one that returns the wrong **kind** of finding. The write-mode half lives in `references/write-mode.md`, loaded on the write path only and fail-closed; `/devflow:implement` does not invoke this skill. +- **`/prflow:implement` skill** (`skills/implement/SKILL.md` orchestrator + `skills/implement/phases/phase-N-*.md` reference files + `skills/implement/references/*.md` predicate-gated references) — the orchestrator drives the four-phase lifecycle; the detailed per-phase procedure you would strengthen/check/gate lives in the phase files (the orchestrator `SKILL.md` holds only thin per-phase stubs), while a procedure whose predicate is false on most runs — Phase 4.0's deferred-AC follow-up filing — lives in a `references/` file the phase file reaches only when that predicate holds. +- **`/prflow:create-issue` skill** (`skills/create-issue/SKILL.md` thin always-loaded root + `skills/create-issue/references/*.md` marker-gated step and fallback references) — the issue-quality entry point. If issues themselves are the bottleneck (vague acceptance criteria, missing repro steps, ambiguous scope), this is where to fix it; the root holds the routing pointer and load contract, the entry gate, and the non-degradable invariants, while the routing table itself (`references/degradation-routing.md`, relocated off the root in issue #1644) and the per-step procedure you would strengthen live in the reference files. +- **`/prflow:review` and `/prflow:review-and-fix` skills** — code-review discipline. If review caught a regression too late, the gap belongs here. +- **Phase sub-skills** (`pr-description`, `docs-sync-internal`, `docs-sync-external`, `docs-release-notes`) — narrower behaviors invoked by `/prflow:implement`. +- **`docs-verify` skill** (`skills/docs-verify/SKILL.md`) — invoked interactively in write mode, and dispatched in `--report-only` mode by **`/prflow:create-issue` Step 1, its only programmatic caller**. The two modes have **separate identities**: write mode is the documentation-accuracy pass; report-only is a **docs-first code explorer** whose deliverable is a map of current behavior, with documentation as its entry point and provisional evidence rather than its subject. Its report-only breadth bound (the duty floor) and its search-space operand are where to fix a Step 1 pass that surveys too much or too little; the *Who you are in report-only mode* section is where to fix one that returns the wrong **kind** of finding. The write-mode half lives in `references/write-mode.md`, loaded on the write path only and fail-closed; `/prflow:implement` does not invoke this skill. - **Issue templates** (`.github/ISSUE_TEMPLATE/`) — when the failure is structural (humans omit the same field every time), the template itself can encode the requirement. ### Knowledge / convention surfaces - **`CLAUDE.md`** at repo root — durable, agent-loaded conventions. Use sparingly: every rule here is loaded on every run. Strengthen an existing rule before adding a new one. -- **`docs/internal/.md`** — feature-specific technical context. The `/devflow:implement` skill is told to consult these first; if Claude missed one, the docs may be missing or stale. +- **`docs/internal/.md`** — feature-specific technical context. The `/prflow:implement` skill is told to consult these first; if Claude missed one, the docs may be missing or stale. - **`docs/external/`** — user-facing docs. Less common as an intervention surface but valid when the failure is documentation drift. - **Lint rules** (`phpcs.xml.dist`, ESLint configs, etc.) — encode mechanical conventions where a human-readable rule won't reliably stick. diff --git a/skills/init/SKILL.md b/skills/init/SKILL.md index 32d29bf71..7d7f10467 100644 --- a/skills/init/SKILL.md +++ b/skills/init/SKILL.md @@ -4,9 +4,9 @@ description: Use when setting up PRFlow in a repo for the first time, or after a disable-model-invocation: true --- -# DevFlow Init +# PRFlow Init -Scaffold this repo's DevFlow config files. One command does everything — do not hand-write `config.json` or guess field values. +Scaffold this repo's PRFlow config files. One command does everything — do not hand-write `config.json` or guess field values. **Portable helper anchor (single-statement).** The bundled-helper commands in this skill resolve the skill directory inline at each call site via `${CLAUDE_SKILL_DIR:-}`. When `$CLAUDE_SKILL_DIR` is set and non-empty (Claude Code), run each command exactly as written. Otherwise locate the directory yourself — this text lives in a file inside it, whose sibling `../../scripts/` directory exists — by replacing the placeholder with the skill base directory the runner reports in context (e.g. a `Base directory for this skill:` line) and accepting a candidate only once `ls /../../scripts/` succeeds in the same shell the helper commands run in. If a path form is rejected, use the form that shell reports (`pwd` shows it); a Windows-form base directory (`C:\...`) may first be converted with one standalone `wslpath -u ''` then `cygpath -u ''` command in order — no platform branch — using the output only when the command succeeded and printed a non-empty path, else falling through to the filesystem check. Resolve the anchor inline at every call site — never capture it into a shell variable that a later statement reads, because some runners' inline-bash marshaling drops such variables. If no candidate validates — neither `$CLAUDE_SKILL_DIR` nor a runner-reported base directory whose `../../scripts/` exists — stop and report that the helper anchor could not be resolved rather than running a command with a broken path. @@ -161,7 +161,7 @@ It resolves the templates from the installed plugin (`"${CLAUDE_SKILL_DIR:-}"/../../lib/preflight.sh @@ -299,7 +299,7 @@ Then branch on the preflight result — the exit code plus, on exit 0, the stabl There is no trigger label to create: in the cloud tier, `/prflow:implement` is started by commenting a bare `/prflow:implement <#>` on the issue (a native user event) — not by applying a label. The sender must be an allowed bot or an `allowed_users` collaborator with write access. -DevFlow does, however, stamp a single reserved provenance label — the literal `PRFlow` — on every issue and PR it creates, so the weekly retrospective can detect its own work independently of branch naming. Create that label now (best-effort, only here where `gh` is available) so it exists from day one: +PRFlow does, however, stamp a single reserved provenance label — the literal `PRFlow` — on every issue and PR it creates, so the weekly retrospective can detect its own work independently of branch naming. Create that label now (best-effort, only here where `gh` is available) so it exists from day one: ```bash "${CLAUDE_SKILL_DIR:-}"/../../scripts/ensure-label.sh PRFlow