You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My contribution adds a new instruction, prompt, agent, skill, workflow, or canvas extension file in the correct directory.
The file follows the required naming convention.
The content is clearly structured and follows the example format.
I have tested my instructions, prompt, agent, skill, workflow, or canvas extension with GitHub Copilot.
I have run npm start and verified that README.md is up to date.
I am targeting the main branch for this pull request.
Files in this PR outside the shepherd-task system
The following files are outside skills/shepherd-task* and plugins/shepherd-task:
.github/plugin/marketplace.json — generated marketplace metadata registering
the plugin.
AGENTS.md — documents the repository-wide pluginFiles composition field
and its validation requirements.
CONTRIBUTING.md — documents how plugin authors declare plugin-owned support
files and directories.
docs/README.plugins.md — generated plugin index containing the shepherd-task plugin.
docs/README.skills.md — generated skill index containing the shepherd-task-* skills.
eng/lib/plugin-files.mjs — validates repository-wide pluginFiles
declarations, including nested symlink containment.
eng/materialize-plugins.mjs — handles pluginFiles while materializing
plugin manifests.
eng/materialize-plugins.test.mjs — provides regression coverage for pluginFiles materialization.
eng/validate-plugins.mjs — integrates pluginFiles validation into the
repository-wide plugin validator.
eng/validate-plugins.test.mjs — provides regression coverage for valid,
malformed, escaping, and dangling pluginFiles references.
shepherd-task is not composed solely of reusable skills. Its installed plugin also requires plugin-owned runtime content that already lives beneath plugins/shepherd-task, including the Bash and PowerShell orchestration scripts, version metadata, installation utilities, and contract fixtures used to verify an installation. The repository’s existing composition fields could materialize shared agents, hooks, skills, and extensions, but there was no declarative way for a plugin to identify these plugin-local support files as part of its complete distributable estate.
The new repository-only pluginFiles field fills that gap. plugins/shepherd-task/plugin.json uses it to declare the local files and directories that must remain in the packaged plugin. The materializer validates those declarations and removes the repository-specific composition metadata from the served Agent Plugins manifest. Validation requires references to exist, remain within the plugin root, use normalized paths, and avoid escaping or dangling symbolic links. This prevents a malformed declaration from accidentally including content outside the plugin.
These shared eng/ changes are therefore necessary to package and validate shepherd-task correctly; they are not unrelated changes to the repository’s plugin infrastructure. The accompanying tests ensure that the new composition behavior remains deterministic and that the root-containment guarantees apply to both directly declared paths and content nested within declared directories.
Website integration
The repository’s Deploy preview website to GitHub Pages workflow passed at PR head cf2993f. This workflow runs the complete production website build, including regeneration of website data from repository plugins and skills and the Astro static-site build.
shepherd-task requires no bespoke website components. Its plugin and six skills are consumed through the website’s existing generated plugin and skill catalogs and rendered through the same generic detail-page routes used by all other repository plugins and skills. The generated plugin index, skill index, and marketplace metadata are included in this PR and pass repository validation.
Because this is a fork-based PR, the workflow intentionally skips publishing a live GitHub Pages preview, but the complete production build succeeds.
See this comment for proof that the local website generation is successful.
Description
This PR adds the shepherd-task plugin, an end-to-end system for running an ordered engineering campaign through GitHub issues and pull requests. It coordinates GitHub Copilot Coding Agent, Copilot code review, local Copilot CLI sessions, GitHub Actions, and gh while keeping GitHub state authoritative.
The campaign lifecycle is divided into explicit stages:
00: initialize durable campaign metadata and lesson state;
10: create an ignorance-reduction plan when implementation issues do not already exist;
15: derive and validate the inputs for issue creation;
20: create and order implementation issues from the resolved plan;
25: dispatch the selected issues serially;
30: assign an issue to Copilot Coding Agent and shepherd its draft PR through CI;
40: request review, resolve findings, publish lessons, and merge to the campaign base branch;
50: create an evidence-based campaign post-mortem.
The plugin includes:
six reusable shepherd-task-* skills;
Bash 3.2+ and PowerShell 7 orchestration scripts;
installers, uninstallers, version-management commands, and a versioned artifact contract;
campaign identity, resume, retry, and failure-recovery behavior;
optional campaign lesson propagation, defaulting to off;
redacted JSONL session artifacts and post-mortem inputs;
Linux, macOS, Git Bash, and PowerShell contract fixtures;
detailed operating documentation and sequence diagrams.
Task PRs target one non-main campaign base branch and run serially, so each merged task becomes the starting point for the next. The final campaign-base-to-main PR remains a separate human-controlled step.
This PR also adds the repository-side pluginFiles composition field. It allows a plugin to declare plugin-owned runtime files and directories that already live beneath the plugin root, such as scripts, tests, and version tooling. Validation rejects missing, unsorted, malformed, duplicate, or root-escaping references, and materialization strips this repository-only metadata from the served Agent Plugins manifest.
This supersedes the abandoned initial submission in #2329. The implementation has since been rebased onto current main, expanded into a complete staged campaign lifecycle, hardened through treatment/control campaigns, and validated on both Linux and Windows.
Usage notes
The system intentionally invokes copilot --yolo for bounded lifecycle stages. Users must explicitly accept that behavior and provide:
authenticated gh and Copilot CLI installations;
Copilot Coding Agent and Copilot code review enabled in the target repository;
GitHub Actions and Issues;
git, jq, uuidgen, and PowerShell 7 for PowerShell entrypoints;
a local environment capable of running the repository's real gating tests;
a checked-out non-main campaign base branch.
The full setup, installation, lifecycle, recovery, and uninstall procedures are documented in plugins/shepherd-task/README.md.
all 23 Bash contract tests passed on Linux after the Windows compatibility fixes;
all 32 PowerShell contract tests passed on Windows, including the .cmd mock-based contracts unavailable on Linux;
all shepherd-task Bash and PowerShell files passed syntax parsing;
shepherd-task JSON contracts parsed successfully;
shell executable modes and generated plugin/skill/marketplace outputs were verified.
The existing warnings for unrelated external marketplace entries with mutable source locators or non-SPDX license strings are pre-existing catalog warnings.
Type of Contribution
New instruction file.
New prompt file.
New agent file.
New plugin.
New skill file.
New agentic workflow.
New canvas extension.
Update to existing instruction, prompt, agent, plugin, skill, workflow, or canvas extension.
Other (please specify): repository build and validation support for plugin-owned pluginFiles.
Additional Notes
The contribution is intentionally technical and neutral. It documents Copilot and GitHub prerequisites because they are necessary to operate the workflow; it does not promote an unrelated paid product or direct users to marketing or signup pages.
The large test estate is included because the orchestration spans GitHub state transitions, CI approval, review convergence, cross-platform shell behavior, durable campaign artifacts, versioned installation, retries, and recovery. The fixtures provide regression coverage for those contracts without requiring reviewers to run a live multi-day campaign.
The generated plugin and skill indexes and .github/plugin/marketplace.json have been updated. plugins/external.json is unchanged.
This validates only the literal branch name main, although the plugin contract requires the campaign branch to differ from the repository's default branch. In a repository whose default is master (or any other name), initialization accepts that branch and the campaign can merge task PRs directly into it, bypassing the intended final human-controlled PR. Query defaultBranchRef for Repo and reject equality before creating campaign state; the Bash entrypoint needs the same correction.
Reject campaign branch when it matches the repository default
This validates only the literal branch name main, although the plugin contract requires the campaign branch to differ from the repository's default branch. In a repository whose default is master (or any other name), initialization accepts that branch and the campaign can merge task PRs directly into it, bypassing the intended final human-controlled PR. Query defaultBranchRef for REPO and reject equality before creating campaign state; the PowerShell entrypoint needs the same correction.
Emit raw jq output for correct file equivalence comparisons
jq is currently emitting a JSON string (for example, "body\\n") rather than normalized raw bytes. Consequently, equivalent_files appends a newline after the closing quote, so its documented one-trailing-newline tolerance can never match a newline difference inside the body. Emit raw output so the subsequent byte comparison and newline adjustment operate on the body itself.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🟡 Changes recommended
Failed sessions can expose unredacted telemetry to post-mortem processing, and Stage 30 retries can incorrectly reassign tasks with existing pull requests.
Get a fresh assessment by requesting another Copilot review.
Move final child count, identity uniqueness, and plan-order checks into a tested platform-specific helper backed by one jq contract. Wire the helper through Stage 15 and require Stage 20 to use it instead of generating ad hoc verification logic.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 0776a0ce-2054-4396-b8d0-b768262ebf03
Require generated PowerShell runners to consume the body verifier's object directly with try/catch instead of applying native-command or JSON text semantics.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 478065b5-e440-4b9d-b267-a96eb3fb2513
Hey Ed - I've been dealing w/ okta access for the last 2 weeks so I'm just going off what copilot is telling me as I can't see the actual PR. I did run an automated review of it and here are some findings. I think the biggest one is the first one. But I'm kinda flying in the dark here w/o seeing the PR itself. So anyway - does the below seem valid to you?
Finding
Impact
The published plugin’s startup breaks. Its version reader requires metadata that the publishing process deliberately removes.
The source-checkout installation works differently from the marketplace package; the published version fails before campaign initialization.
Recovery gets stuck after a PR becomes ready for review. Theorchestrator restarts stage 30, which requires a draft PR.
An interrupted stage-40 run cannot resume through the documented runner without hitting the draft-only gate.
The independent CI gate accepts pending checks. The checker only looks for failures.
The agent instructions say to wait, but the script does not independently enforce the completion guarantee it claims.
Valid plugin files are rejected through symlinked ancestors, including macOS temporary-directory paths. This affects shared repository tooling, not just Shepherd.
Add a durable runtime estate manifest for published plugins, migrate Bash and PowerShell consumers, and validate served-layout installation at version 1.0.5.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
Fix shepherd-task published estate metadata
Add a durable runtime estate manifest for published plugins, migrate Bash and PowerShell consumers, and validate served-layout installation at version 1.0.5.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
Route draft pull requests back through stage 30, but resume stage 40 for ready pull requests only when the run directory contains successful stage-30 evidence for the same task and PR.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
Treat only passing, skipped, and the named remove-before-merge failure as acceptable in the independent post-stage gate. Pending, cancelled, failed, and unknown buckets now fail closed in both Bash and PowerShell.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
| The independent CI gate accepts pending checks. The checker only looks for failures. | The agent instructions say to wait, but the script does not independently enforce the completion guarantee it claims. |
Treat only passing, skipped, and the named remove-before-merge failure as acceptable in the independent post-stage gate. Pending, cancelled, failed, and unknown buckets now fail closed in both Bash and PowerShell.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Compare lexical plugin paths against a lexical root before comparing resolved targets against the canonical root. Cover valid file and directory references through a linked ancestor while preserving top-level and nested symlink escape rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
| The new shared packaging validator mishandles symlinked paths. Itcompares a canonical root against an uncanonicalized target. | Valid plugin files are rejected through symlinked ancestors, including macOS temporary-directory paths. This affects shared repository tooling, not just Shepherd. |
Handle symlinked plugin roots
Compare lexical plugin paths against a lexical root before comparing resolved targets against the canonical root. Cover valid file and directory references through a linked ancestor while preserving top-level and nested symlink escape rejection.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
Request the documented maximum timeline page size and follow pagination links when discovering linked pull requests. Require both behaviors in the Bash and PowerShell monitor contracts.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
Request the maximum issue-timeline page size and follow pagination links for linked-PR discovery. Add Bash and PowerShell contracts covering merged PRs found only through paginated timeline output.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 292755c3-37b5-4a61-8f01-6d2d399b05cf
Require the exact Bash atomic-write helper and exercise ledger/result initialization before any GitHub mutation. Extend the Stage 20 contract to execute the documented helper under set -u.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5e90e102-df88-4229-bd33-65808fbc6a9a
Risk tier:merge-risk:high — Privileged execution, automation, or review-policy change Required to merge: passing submission-gate checks plus 2 approvals from reviewers with write access, including a maintainer with admin or maintain permission.
Why this tier
eng/lib/plugin-files.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
eng/materialize-plugins.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
eng/materialize-plugins.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
eng/validate-plugins.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
eng/validate-plugins.test.mjs is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/assert-shepherd-session-outcome.ps1 is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/assert-shepherd-session-outcome.sh is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/assert-stage20-result.ps1 is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/assert-stage20-result.sh is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/install-task-shepherd.ps1 is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/install-task-shepherd.sh is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/read-shepherd-task-version.ps1 is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/read-shepherd-task-version.sh is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/redact-secrets.ps1 is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
plugins/shepherd-task/scripts/redact-secrets.sh is a high-risk path (automation, scripts, MCP config, hooks, or review policy)
Still needed: 2 more approval(s); an approval from a maintainer with admin or maintain permission
The core-maintainers pool is not staffed yet; an approver with admin or maintain permission is required instead.
Commands
Command
Who
What it does
/rerun-checks
PR author, maintainers
Re-runs failed or incomplete checks and re-evaluates this gate
/request-review
PR author, maintainers
Asks the review rotation to assign a reviewer (adds needs-reviewer)
Updated for 13c8acb · This comment is maintained automatically — see submission gate docs.
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Files in this PR outside the
shepherd-tasksystemThe following files are outside
skills/shepherd-task*andplugins/shepherd-task:.github/plugin/marketplace.json— generated marketplace metadata registeringthe plugin.
AGENTS.md— documents the repository-widepluginFilescomposition fieldand its validation requirements.
CONTRIBUTING.md— documents how plugin authors declare plugin-owned supportfiles and directories.
docs/README.plugins.md— generated plugin index containing theshepherd-taskplugin.docs/README.skills.md— generated skill index containing theshepherd-task-*skills.eng/lib/plugin-files.mjs— validates repository-widepluginFilesdeclarations, including nested symlink containment.
eng/materialize-plugins.mjs— handlespluginFileswhile materializingplugin manifests.
eng/materialize-plugins.test.mjs— provides regression coverage forpluginFilesmaterialization.eng/validate-plugins.mjs— integratespluginFilesvalidation into therepository-wide plugin validator.
eng/validate-plugins.test.mjs— provides regression coverage for valid,malformed, escaping, and dangling
pluginFilesreferences.shepherd-taskis not composed solely of reusable skills. Its installed plugin also requires plugin-owned runtime content that already lives beneathplugins/shepherd-task, including the Bash and PowerShell orchestration scripts, version metadata, installation utilities, and contract fixtures used to verify an installation. The repository’s existing composition fields could materialize shared agents, hooks, skills, and extensions, but there was no declarative way for a plugin to identify these plugin-local support files as part of its complete distributable estate.The new repository-only
pluginFilesfield fills that gap.plugins/shepherd-task/plugin.jsonuses it to declare the local files and directories that must remain in the packaged plugin. The materializer validates those declarations and removes the repository-specific composition metadata from the served Agent Plugins manifest. Validation requires references to exist, remain within the plugin root, use normalized paths, and avoid escaping or dangling symbolic links. This prevents a malformed declaration from accidentally including content outside the plugin.These shared
eng/changes are therefore necessary to package and validateshepherd-taskcorrectly; they are not unrelated changes to the repository’s plugin infrastructure. The accompanying tests ensure that the new composition behavior remains deterministic and that the root-containment guarantees apply to both directly declared paths and content nested within declared directories.Website integration
The repository’s
Deploy preview website to GitHub Pagesworkflow passed at PR head cf2993f. This workflow runs the complete production website build, including regeneration of website data from repository plugins and skills and the Astro static-site build.shepherd-taskrequires no bespoke website components. Its plugin and six skills are consumed through the website’s existing generated plugin and skill catalogs and rendered through the same generic detail-page routes used by all other repository plugins and skills. The generated plugin index, skill index, and marketplace metadata are included in this PR and pass repository validation.Because this is a fork-based PR, the workflow intentionally skips publishing a live GitHub Pages preview, but the complete production build succeeds.
See this comment for proof that the local website generation is successful.
Description
This PR adds the
shepherd-taskplugin, an end-to-end system for running an ordered engineering campaign through GitHub issues and pull requests. It coordinates GitHub Copilot Coding Agent, Copilot code review, local Copilot CLI sessions, GitHub Actions, andghwhile keeping GitHub state authoritative.The campaign lifecycle is divided into explicit stages:
The plugin includes:
shepherd-task-*skills;Task PRs target one non-
maincampaign base branch and run serially, so each merged task becomes the starting point for the next. The final campaign-base-to-mainPR remains a separate human-controlled step.This PR also adds the repository-side
pluginFilescomposition field. It allows a plugin to declare plugin-owned runtime files and directories that already live beneath the plugin root, such as scripts, tests, and version tooling. Validation rejects missing, unsorted, malformed, duplicate, or root-escaping references, and materialization strips this repository-only metadata from the served Agent Plugins manifest.This supersedes the abandoned initial submission in #2329. The implementation has since been rebased onto current
main, expanded into a complete staged campaign lifecycle, hardened through treatment/control campaigns, and validated on both Linux and Windows.Usage notes
The system intentionally invokes
copilot --yolofor bounded lifecycle stages. Users must explicitly accept that behavior and provide:ghand Copilot CLI installations;git,jq,uuidgen, and PowerShell 7 for PowerShell entrypoints;maincampaign base branch.The full setup, installation, lifecycle, recovery, and uninstall procedures are documented in
plugins/shepherd-task/README.md.Validation
Repository validation:
npm run plugin:validatenpm run skill:validatenode --test eng/materialize-plugins.test.mjs eng/validate-plugins.test.mjsnpm startbash eng/fix-line-endings.shgit diff --check upstream/mainCross-platform contract validation:
.cmdmock-based contracts unavailable on Linux;The existing warnings for unrelated external marketplace entries with mutable source locators or non-SPDX license strings are pre-existing catalog warnings.
Type of Contribution
pluginFiles.Additional Notes
The contribution is intentionally technical and neutral. It documents Copilot and GitHub prerequisites because they are necessary to operate the workflow; it does not promote an unrelated paid product or direct users to marketing or signup pages.
The large test estate is included because the orchestration spans GitHub state transitions, CI approval, review convergence, cross-platform shell behavior, durable campaign artifacts, versioned installation, retries, and recovery. The fixtures provide regression coverage for those contracts without requiring reviewers to run a live multi-day campaign.
The generated plugin and skill indexes and
.github/plugin/marketplace.jsonhave been updated.plugins/external.jsonis unchanged.See the full documentation at README.
By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.