[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6X1JVS94JDJSXP71078CE5Q":3,"skill-same:01M6X1JVS94JDJSXP71078CE5Q":67},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":48,"ownerHtmlUrl":49,"ownerBlogUrl":50,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6X1JVS94JDJSXP71078CE5Q","e2e-template-testing",null,"End-to-end validation of coordinator and agent template changes","github\u002Fsquad","github","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9919?v=4","01M6AC83DS133TPXFSP1DHNCC6","GitHub","01M6X0MZ6B0WYMMDPK3Q61KER6",3377,"MIT","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Fpackages\u002Fsquad-sdk\u002Ftemplates\u002Fskills\u002Fe2e-template-testing\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37],"testing","e2e template testing","e2e","template","development","validation","end","coordinator","manual","high","changes","2026-11-10 10:12:30",false,"---\nname: \"e2e-template-testing\"\ndescription: \"End-to-end validation of coordinator and agent template changes\"\ndomain: \"development\"\nconfidence: \"high\"\nsource: \"manual\"\n---\n\n## Context\n\nSquad's coordinator prompt (`squad.agent.md`) and agent charters (e.g.\n`scribe-charter.md`) are shipped as templates in `.squad-templates\u002F`. Changes to\nthese files affect how every squad session behaves — but unit tests can't catch\nprompt-level regressions because the prompts are interpreted by an LLM at\nruntime.\n\nThis skill describes how to validate template changes end-to-end by running real\nsquad sessions against a locally-built CLI that includes your modified templates.\n\n## When To Use\n\n- You changed `.squad-templates\u002Fsquad.agent.md` (coordinator prompt)\n- You changed `.squad-templates\u002Fscribe-charter.md` or other agent charters\n- You changed `.squad-templates\u002Fnotes-protocol.md` or helper scripts\n- You added new conditional blocks (e.g. state-backend-aware spawn templates)\n- You modified the init scaffolding that writes templates to target repos\n\n## Prerequisites\n\n- **Node.js** ≥20, **npm** ≥10\n- **Git** CLI\n- **GitHub Copilot CLI** (`copilot` or `ghcs`) installed\n- A local clone of the squad repo on your feature branch\n\n## Workflow\n\n### Step 0 — Post initial tracking comment (**FIRST action — before anything else**)\n\nIf `PR_NUMBER` and `REPO` are both set, **the absolute first thing you do** — before\nfast-fail checks, before building, before creating any repos — is post the initial\ntracking comment with all steps marked as `:hourglass_flowing_sand: Pending`.\n\nThis gives reviewers immediate visibility that a run is in progress and what to expect.\n\n```powershell\n$runStart = Get-Date\n$body = @\"\n## E2E Progress - PR $env:PR_NUMBER\n\n| Step | Status | Started | Duration |\n|---|---|---|---|\n| 1. Fast-fail checks (build :cd: link :cd: ``squad version``) | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 2. Create test repo(s) | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 3. ``squad init`` + file verification | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 4. Run sessions | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 5. Verify outcomes | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 6. Record verdicts + post final comment | :hourglass_flowing_sand: Pending | --:-- | -- |\n\n| Symbol | Meaning |\n|---|---|\n| :hourglass_flowing_sand: | Not started |\n| :arrows_counterclockwise: | Running |\n| :white_check_mark: | Passed |\n| :x: | Failed |\n| :warning: | Passed with caveats |\n\n*Run started: $($runStart.ToString('HH:mm')) — all steps pending*\n\"@\n\n$tmpFile = [System.IO.Path]::GetTempFileName()\n$utf8NoBom = New-Object System.Text.UTF8Encoding $false\n[System.IO.File]::WriteAllText($tmpFile, $body, $utf8NoBom)\n$response = gh api \"repos\u002F$env:REPO\u002Fissues\u002F$env:PR_NUMBER\u002Fcomments\" --method POST --field \"body=@$tmpFile\" | ConvertFrom-Json\n$env:COMMENT_ID = $response.id\nRemove-Item $tmpFile -Force\nWrite-Host \"Progress comment posted — ID: $($response.id)\"\n```\n\nAfter posting, immediately update the comment to mark Step 1 as `:arrows_counterclockwise: Running` (do NOT wait — this is a two-step sequence: post all-pending, then immediately update to Step 1 running). Then proceed to Step 1.\n\nSee **Progress Reporting** for the full comment lifecycle and update patterns.\n\n**⚠️ STOP before continuing:** If posting the comment fails (network error, auth error), abort the run and report the failure. Do not proceed silently without a tracking comment.\n\n### Step 1 — Build the CLI from your branch\n\n```bash\ncd \u002Fpath\u002Fto\u002Fsquad          # your feature branch\nnpm install\nnpm run build -w packages\u002Fsquad-sdk && npm run build -w packages\u002Fsquad-cli\n\n# Link so `squad` command uses your local build (workspace flag — no cd required)\nnpm link -w packages\u002Fsquad-cli\n```\n\nVerify: `squad version` output includes the `-preview` suffix (e.g., `x.y.z-preview`),\nconfirming the local dev build is active. If the output shows a plain semver without\n`-preview`, the globally-installed npm package is still in use — re-check the link step.\nSee [CONTRIBUTING.md — Making the `squad` Command Use Your Local Build](..\u002F..\u002F..\u002FCONTRIBUTING.md)\nfor the full guidance on local dev versioning.\n\n### Step 2 — Create a disposable test repo\n\n```bash\nmkdir \u002Ftmp\u002Fsq-test-1 && cd \u002Ftmp\u002Fsq-test-1\ngit init\necho \"# Test Project\" > README.md\necho '{\"name\":\"test-project\",\"version\":\"1.0.0\"}' > package.json\nmkdir src\necho \"export function hello() { return 'world' }\" > src\u002Findex.ts\ngit add -- README.md package.json src\u002Findex.ts\ngit commit -m \"init: test project\"\n```\n\nKeep the project small — you only need enough for the coordinator to recognize a\ncodebase and hire a team.\n\n### Step 3 — Init a squad with your modified templates\n\n```bash\nsquad init\n# If testing a specific feature (e.g. state backends):\n# squad init --state-backend git-notes\n```\n\nVerify the init produced the expected files:\n```bash\nls -la .squad\u002F\ncat .squad\u002Fteam.md          # should have ## Members with 3+ agents\ncat .squad\u002Fconfig.json      # should reflect any CLI flags you passed\n```\n\n### Step 4 — Run a real session and capture output\n\nUse the Copilot CLI's `-p` flag with `--allow-all-tools` for non-interactive sessions.\n`--allow-all-tools` is **required** for automated\u002Fnon-interactive runs — without it,\ntool calls (including file writes) prompt for confirmation and block.\n\n```powershell\n# PowerShell (Windows)\ncopilot --agent squad --allow-all-tools -p \"Lead, decide what testing framework to use. Write your decision.\" `\n  2>&1 | Tee-Object evidence\u002Fsession-task.log\n```\n\n```bash\n# Bash (macOS\u002FLinux)\ncopilot --agent squad --allow-all-tools -p \"Lead, decide what testing framework to use. Write your decision.\" \\\n  2>&1 | tee evidence\u002Fsession-task.log\n```\n\nAlternatively, set the `COPILOT_ALLOW_ALL=1` environment variable instead of the flag.\n\nFor multi-turn workflows, run sequential sessions:\n```powershell\n# Session A: give the team a task\ncopilot --agent squad --allow-all-tools -p \"prompt A\" 2>&1 | Tee-Object evidence\u002Fsession-A.log\n\n# Session B: verify state persisted\ncopilot --agent squad --allow-all-tools -p \"What decisions has the team made?\" 2>&1 | Tee-Object evidence\u002Fsession-B.log\n```\n\n### Step 5 — Verify the outcome\n\nCheck that your template change had the expected effect. Common checks:\n\n```bash\n# State location (for state-backend changes)\ngit notes --ref=squad list              # git-notes backend\ngit ls-tree -r squad-state              # orphan backend\nls .squad\u002Fagents\u002F*\u002Fhistory.md           # worktree backend\n\n# Coordinator behavior (grep session log)\ngrep \"STATE_BACKEND\" evidence\u002Fsession-task.log\ngrep \"spawn\" evidence\u002Fsession-task.log\n\n# File tree diff\ngit diff --stat HEAD~1                  # what changed on working branch\ngit log --all --oneline                 # commits across all branches\n```\n\n### Step 6 — Record the verdict\n\nCreate an `evidence\u002Fverdict.md` in each test repo:\n\n```markdown\n## Test: [scenario name]\n**Backend:** worktree | git-notes | orphan | two-layer\n**Branch:** [your feature branch]\n**Result:** PASS | PARTIAL | FAIL\n**Duration:** Xm Ys\n\n### What was verified\n- [ ] Coordinator identified feature correctly (from session log)\n- [ ] Agent was spawned via `task` tool (not simulated)\n- [ ] team.md has ## Members with 3+ agents\n- [ ] State landed in correct location\n- [ ] No unexpected side effects\n\n### Evidence files\n- session-task.log — full session output\n- git-log.txt — `git log --all --oneline`\n\n### Notes\n[anything unusual or noteworthy]\n```\n\nRecord the wall-clock time from the start of Step 1 (fast-fail checks) to the end\nof Step 6 (verdict posted). This is the full E2E run duration for this scenario.\n\n## Progress Reporting\n\nUse this section only when you are running E2E validation for an open PR. If\n`PR_NUMBER` and `REPO` are both set, post and maintain a live tracking comment\nin the PR thread. If either value is missing (for example, a local-only run),\nskip progress reporting silently.\n\n### Start the tracking comment (Step 0 — see Workflow above)\n\nThe initial comment must be posted as **Step 0** — the absolute first action before\nanything else. See the Step 0 block in the Workflow section for the exact code.\n\nThe subsections below describe how to **update** the comment at each step boundary.\nFor reference, here is the initial all-pending comment body posted in Step 0:\n\n1. Post a PR comment before Step 1 begins:\n\n```bash\ngh pr comment \"$PR_NUMBER\" --repo \"$REPO\" --body \"## E2E Progress\\n\\n| Step | Status | Started | Duration |\n|---|---|---|---|\n| 1. Fast-fail checks (build · link · \\\\`squad version\\\\`) | ⏳ Pending | --:-- | -- |\n| 2. Create test repo(s) | ⏳ Pending | --:-- | -- |\n| 3. \\\\`squad init\\\\` + file verification | ⏳ Pending | --:-- | -- |\n| 4. Run sessions | ⏳ Pending | --:-- | -- |\n| 5. Verify outcomes | ⏳ Pending | --:-- | -- |\n| 6. Record verdicts + post final comment | ⏳ Pending | --:-- | -- |\n\\n| Symbol | Meaning |\n|---|---|\n| ⏳ | Not started |\n| ? | Running |\n| ✅ | Passed |\n| ❌ | Failed |\n| ⚠️ | Passed with caveats |\"\n```\n\n2. Capture the comment ID immediately after posting it:\n\n```bash\nCOMMENT_ID=$(gh api \"repos\u002F$REPO\u002Fissues\u002F$PR_NUMBER\u002Fcomments\" --jq '.[-1].id')\n```\n\n3. Treat Step 1 as in progress as soon as the comment exists. Update the body so\n   Step 1 shows `? Running` and every later step remains `⏳ Pending`.\n\n### Update the tracking comment after every step boundary\n\n1. When marking a step `? Running`, record `$startTime = Get-Date` and store the\n   `HH:MM` start time in that row's **Started** column.\n2. Edit the existing comment in place; do not post a new progress comment:\n\n```bash\ngh api --method PATCH \"repos\u002F$REPO\u002Fissues\u002Fcomments\u002F$COMMENT_ID\" --field body=\"...\"\n```\n\n3. When marking a step `✅`, `❌`, or `⚠️`, compute\n   `$duration = (Get-Date) - $startTime` and format it as\n   `\"{0}m {1}s\" -f [int]$duration.TotalMinutes, $duration.Seconds`.\n4. Update the completed step row to `✅`, `❌`, or `⚠️`, keep its original\n   `HH:MM` value in **Started**, and write the formatted duration in **Duration**.\n5. Keep all previously completed rows unchanged.\n6. Mark the next step as `? Running` and set its **Started** value.\n7. Leave later steps as `⏳ Pending` with `--:--` for **Started** and `--` for\n   **Duration**.\n8. If a step fails and you stop early, still update the comment so the failed step\n   shows `❌` with its original start time and computed duration, and Step 6\n   becomes `? Running` while you prepare the final verdict.\n\n### Use this status legend in the comment\n\n| Symbol | Meaning |\n|---|---|\n| ⏳ | Not started |\n| ? | Running |\n| ✅ | Passed |\n| ❌ | Failed |\n| ⚠️ | Passed with caveats |\n\n### Use exact step names and order\n\nKeep these six rows in this exact order every time you update the comment:\n\n1. Fast-fail checks (build · link · `squad version`)\n2. Create test repo(s)\n3. `squad init` + file verification\n4. Run sessions\n5. Verify outcomes\n6. Record verdicts + post final comment\n\n### Handle Windows comment bodies safely\n\nOn Windows PowerShell 5.1, use the **`--field body=@file`** pattern to post comment\nbodies. Write the content to a temp file using UTF-8 **without BOM**, then pass\n`--field \"body=@$tmpFile\"` to `gh api`. This is more reliable than piping JSON\nthrough `--input -` on PS 5.1, which can silently corrupt multi-byte characters\neven with `[Console]::OutputEncoding = UTF8`.\n\nKey rules:\n- Use `New-Object System.Text.UTF8Encoding $false` (the `$false` disables the BOM).\n  `[System.Text.Encoding]::UTF8` writes a BOM which GitHub renders as a stray\n  character (`﻿`) at the start of the comment.\n- Use `--field \"body=@$tmpFile\"`, NOT `--input -` or `--input filename`, for\n  comment body updates. The `@` prefix tells `gh` to read the field value from\n  the file rather than treating the path as a literal string.\n- Clean up the temp file after posting.\n- Scrub any local absolute paths from the body before posting (see PII Protection\n  section).\n\n```powershell\n$step1StartTime = Get-Date\n$step1Started = $step1StartTime.ToString('HH:mm')\n$step1Duration = (Get-Date) - $step1StartTime\n$step1DurationText = \"{0}m {1}s\" -f [int]$step1Duration.TotalMinutes, $step1Duration.Seconds\n$step2StartTime = Get-Date\n$step2Started = $step2StartTime.ToString('HH:mm')\n$body = @\"\n## E2E Progress\n\n| Step | Status | Started | Duration |\n|---|---|---|---|\n| 1. Fast-fail checks (build · link · `squad version`) | :white_check_mark: Passed | $step1Started | $step1DurationText |\n| 2. Create test repo(s) | :arrows_counterclockwise: Running | $step2Started | -- |\n| 3. `squad init` + file verification | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 4. Run sessions | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 5. Verify outcomes | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 6. Record verdicts + post final comment | :hourglass_flowing_sand: Pending | --:-- | -- |\n\n| Symbol | Meaning |\n|---|---|\n| :hourglass_flowing_sand: | Not started |\n| :arrows_counterclockwise: | Running |\n| :white_check_mark: | Passed |\n| :x: | Failed |\n| :warning: | Passed with caveats |\n\"@\n\n$tmpFile = \"$env:TEMP\\e2e-comment-body.md\"\n$utf8NoBom = New-Object System.Text.UTF8Encoding $false\n[System.IO.File]::WriteAllText($tmpFile, $body, $utf8NoBom)\ngh api --method PATCH \"repos\u002F$env:REPO\u002Fissues\u002Fcomments\u002F$env:COMMENT_ID\" --field \"body=@$tmpFile\"\nRemove-Item $tmpFile -Force\n```\n\n### Progressive Verdicting — Post After Each Scenario (Critical)\n\n**Do NOT batch all scenario results to the end.** This is the most common cause\nof lost verdicts. After each scenario completes, **immediately** PATCH the\ntracking comment with that scenario's result before moving to the next one.\n\nThe pattern for each scenario:\n\n```powershell\n# After scenario N completes — PATCH immediately, before starting scenario N+1\n$scenarioNDuration = \"{0}m {1}s\" -f [int]((Get-Date) - $scenarioNStartTime).TotalMinutes, ((Get-Date) - $scenarioNStartTime).Seconds\n# ...rebuild the full comment body with this scenario updated to PASS\u002FFAIL\u002FPARTIAL...\n$tmpFile = [System.IO.Path]::GetTempFileName()\n$utf8NoBom = New-Object System.Text.UTF8Encoding $false\n[System.IO.File]::WriteAllText($tmpFile, $body, $utf8NoBom)\ngh api --method PATCH \"repos\u002F$env:REPO\u002Fissues\u002Fcomments\u002F$env:COMMENT_ID\" --field \"body=@$tmpFile\"\nRemove-Item $tmpFile -Force\nWrite-Host \"Scenario N verdict posted\"\n```\n\nThis guarantees that even if the AI model connection drops mid-run, the last\nsuccessfully PATCHed state is always visible in the PR.\n\n### Agent Run Time Budget\n\n**⚠️ Critical: Background agents lose their AI model connection after ~15 minutes\nof continuous execution.** This is a platform limit, not a bug in your code.\nThe verdict stage appears to \"hang\" because the connection drops right at the end\nwhen the agent has been running too long.\n\n**Per-agent scenario budget:**\n\n| Scenario type | Estimated time | Budget |\n|---|---|---|\n| Static checks only (file existence, grep, size) | 1-3 min | 4 per agent |\n| `squad init` + file verification (no copilot session) | 3-5 min | 3 per agent |\n| `squad init` + one `copilot --agent squad` session | 8-15 min | **1 per agent** |\n| Build + link + one copilot session | 12-20 min | **1 per agent** |\n\n**Rule: Limit yourself to 1 scenario that includes a `copilot --agent squad` session\nper agent run.** For a plan with multiple copilot-session scenarios, run them in\nseparate agents — not in sequence within a single agent.\n\nIf your scenario plan has N copilot-session scenarios, request N separate test\nagents to run them in parallel (one scenario each). Static scenarios may be\nbatched up to 4 per agent.\n\n**If you are running a scenario with a `copilot --agent squad` session:**\n- Run the build and link ONCE at the start (shared across all static scenarios)\n- Run the copilot session immediately after the repo is set up\n- PATCH the comment with the result immediately after the session ends\n- Then proceed to static scenarios while you still have connection budget\n\n### Replace the tracking comment with the final verdict\n\nWhen you reach Step 6, replace the tracking comment body entirely with the final\nstructured verdict table. Do not post a separate final comment. The tracking\ncomment is the final verdict comment.\n\nInclude a summary row at the bottom of the final table showing the total elapsed\ntime for the full run:\n\n```text\n| **Total** | — | HH:MM | Xm Ys |\n```\n\n**If the connection drops before Step 6:** The last progressive verdict PATCH\nalready shows the partial state. The next agent run should read the existing\ncomment, pick up where it left off, and add remaining scenario rows rather than\nstarting fresh.\n\n## Test Matrix Template\n\nUse this matrix when planning validation for a template change. Not every change\nneeds every row — pick the scenarios relevant to your modification.\n\n| # | Scenario | What to verify | Duration |\n|---|----------|----------------|----------|\n| 1 | Basic init + task | Templates applied, agent spawned, work produced | — |\n| 2 | Cross-branch persistence | State survives `git checkout` (if state-backend) | — |\n| 3 | Scribe behavior | Scribe commits to correct target | — |\n| 4 | PR cleanliness | Feature branch PR has no leaked state files | — |\n| 5 | Migration path | Existing squad picks up new template behavior | — |\n| 6 | Edge case: empty repo | Init works in repo with single commit | — |\n| 7 | Edge case: monorepo | Init works in subdirectory of monorepo | — |\n\nNote: Keep `—` during planning, then replace it with the actual elapsed time when\nrecording the verdict for each scenario.\n\n## Tips\n\n- **Name test repos descriptively:** `sq-test-notes-crossbranch`, not `test1`.\n- **Always capture session logs.** Without logs, you can't debug failures.\n- **One scenario per repo.** Don't reuse repos across unrelated tests — state\n  leaks between tests make results unreliable.\n- **Clean up after.** Delete test repos when done. They accumulate fast.\n- **Windows users:** Use PowerShell. `Tee-Object` replaces `tee`. Paths use `\\`.\n\n## Fast-Fail Rules\n\nThese checks must pass before running any scenario. If any fail, stop\nimmediately and report the failure — do **not** attempt workarounds or mark\nscenarios as SKIPPED.\n\n0. **Clean stale SDK before building.** Before running `npm run build`, remove any\n   stale published copy of `@bradygaster\u002Fsquad-sdk` that may have been installed\n   into `packages\u002Fsquad-cli\u002Fnode_modules\u002F`. This local copy shadows the workspace\n   symlink in the root `node_modules\u002F` and causes TypeScript to see the published\n   version instead of the local source. Run from the repo root:\n   ```powershell\n   $stale = \"packages\\squad-cli\\node_modules\\@bradygaster\\squad-sdk\"\n   if (Test-Path $stale) { Remove-Item -Recurse -Force $stale; Write-Host \"Cleaned stale SDK\" }\n   ```\n   This is safe to run unconditionally — if the path doesn't exist, the command is\n   a no-op. The root `node_modules\\@bradygaster\\squad-sdk` workspace symlink remains\n   intact and npm will use it automatically.\n1. **Build must succeed.** Run `npm run build` from the repo root. A build\n   failure blocks all scenarios; report `BUILD_FAILED` and stop.\n   - If the error is `tsc: not found` or similar missing-binary errors, run\n     `npm install` first to reconcile `node_modules` with the lock file, then\n     retry. This can happen after `git checkout HEAD -- package-lock.json`\n     restores the lock file without reinstalling.\n2. **CLI must link successfully.** `cd packages\u002Fsquad-cli && npm link` must exit\n   0. If it fails, report `LINK_FAILED` and stop.\n3. **`squad version` must run.** After linking, `squad version` must output a\n   version string. If not, report `CLI_NOT_FOUND` and stop.\n\nDo **not** mark scenarios as SKIPPED due to build or environment errors —\nthat obscures real failures from reviewers. SKIPPED is only acceptable when the\nuser explicitly requests it.\n\n## PII Protection — Mandatory\n\nWhen posting evidence to PR comments, issues, or any shared document:\n\n- **Never include absolute paths** that contain a local username (e.g.,\n  `C:\\Users\\username\\...` or `\u002Fhome\u002Fusername\u002F...`).\n- **Use `~` notation** for home-relative paths: `~\u002FAppData\u002FLocal\u002FTemp\u002F...`\n  or `~\u002Ftmp\u002Fsq-test-1`.\n- **Repo-internal paths use `\u003Crepo-root>` as the prefix.** If evidence files live\n  inside the repository (e.g. `.e2e\u002F`, `tmp\u002F`, or any subdirectory of the repo),\n  write them as `\u003Crepo-root>\\.e2e\\pr-1035\\evidence` — not as `~\\..\\..\\...` backward\n  navigation. `\u003Crepo-root>` is a clear, portable placeholder for the repository root\n  that does not expose the machine's directory layout.\n- **Scrub before posting.** Replace any occurrence of the local machine path\n  prefix (everything up to and including the username segment) with `~`.\n\nExample — ❌ wrong: `C:\\Users\\johndoe\\AppData\\Local\\Temp\\sq-e2e-pr1035\\evidence`\nExample — ✅ right: `~\u002FAppData\u002FLocal\u002FTemp\u002Fsq-e2e-pr1035\u002Fevidence`\nExample — ❌ wrong: `~\\..\\..\\repos\\squad\\.e2e\\pr-1035\\evidence`\nExample — ✅ right: `\u003Crepo-root>\\.e2e\\pr-1035\\evidence`\n\nThis applies to all evidence tables, verdict files, and PR comments.\n\n## Anti-Patterns\n\n- **Skipping the local build.** If you test with the published CLI, you're\n  testing the old templates, not your changes.\n- **Posting absolute paths in PR comments.** Always scrub to `~`-relative paths\n  before sharing. See PII Protection above.\n- **Marking scenarios SKIPPED due to environment issues.** Fix the environment\n  (use fast-fail rules above) or report BUILD_FAILED — never silently skip.\n- **Testing only the happy path.** Template changes often break edge cases (empty\n  repos, monorepos, cross-branch). Test at least 2-3 scenarios.\n- **Trusting session output alone.** Always verify git state independently —\n  agents can claim they wrote something without actually doing it.\n- **Reusing test repos.** Prior state bleeds into later tests. Start fresh.\n- **Batching all scenario verdicts to the end.** The AI model connection drops\n  after ~15 minutes. Always PATCH the comment after each scenario so partial\n  results are never lost. See Progressive Verdicting above.\n- **Running multiple `copilot --agent squad` sessions in one agent.** Each\n  session takes 5-15 minutes; combined with build time, you'll hit the ~15-minute\n  connection budget. One copilot session per agent — split into parallel agents\n  if your plan has more.\n\n## Sandbox \u002F Permission Notes\n\n### Always pass `--allow-all-tools` in non-interactive mode\n\nThe Copilot CLI requires explicit permission to run tools automatically. In\ninteractive mode the user approves each tool call; in non-interactive mode (`-p`)\nthose prompts cannot be displayed and writes fail silently or with a \"Permission\ndenied and could not request permission from user\" error.\n\nFix: always include `--allow-all-tools` (or `--yolo` \u002F `--allow-all`) in Step 4\ncommands, or export `COPILOT_ALLOW_ALL=1` before running E2E sessions.\n\nThis also applies when `copilot --agent squad` is launched as a subprocess from\ninside a Copilot CLI background agent (e.g. a test engineer running via the `task` tool) —\nthe flag is still needed.\n\n### `--allow-all-paths` for repos outside the CWD\n\nBy default the CLI restricts file access to the current directory tree. If the\ncoordinator needs to read files from a parent repo while running in a disposable\ntest repo, add `--allow-all-paths`:\n\n```powershell\ncopilot --agent squad --allow-all-tools --allow-all-paths -p \"...\"\n```\n\nOr use the combined shorthand: `--allow-all` \u002F `--yolo`.\n\n## Confidence\n\nhigh — Validated through 12 real E2E test sessions during state-backend\ndevelopment (PR #1004). `--allow-all-tools` requirement confirmed in PR #1035.\n","## Context\n\nSquad's coordinator prompt (`squad.agent.md`) and agent charters (e.g.\n`scribe-charter.md`) are shipped as templates in `.squad-templates\u002F`. Changes to\nthese files affect how every squad session behaves — but unit tests can't catch\nprompt-level regressions because the prompts are interpreted by an LLM at\nruntime.\n\nThis skill describes how to validate template changes end-to-end by running real\nsquad sessions against a locally-built CLI that includes your modified templates.\n\n## When To Use\n\n- You changed `.squad-templates\u002Fsquad.agent.md` (coordinator prompt)\n- You changed `.squad-templates\u002Fscribe-charter.md` or other agent charters\n- You changed `.squad-templates\u002Fnotes-protocol.md` or helper scripts\n- You added new conditional blocks (e.g. state-backend-aware spawn templates)\n- You modified the init scaffolding that writes templates to target repos\n\n## Prerequisites\n\n- **Node.js** ≥20, **npm** ≥10\n- **Git** CLI\n- **GitHub Copilot CLI** (`copilot` or `ghcs`) installed\n- A local clone of the squad repo on your feature branch\n\n## Workflow\n\n### Step 0 — Post initial tracking comment (**FIRST action — before anything else**)\n\nIf `PR_NUMBER` and `REPO` are both set, **the absolute first thing you do** — before\nfast-fail checks, before building, before creating any repos — is post the initial\ntracking comment with all steps marked as `:hourglass_flowing_sand: Pending`.\n\nThis gives reviewers immediate visibility that a run is in progress and what to expect.\n\n```powershell\n$runStart = Get-Date\n$body = @\"\n## E2E Progress - PR $env:PR_NUMBER\n\n| Step | Status | Started | Duration |\n|---|---|---|---|\n| 1. Fast-fail checks (build :cd: link :cd: ``squad version``) | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 2. Create test repo(s) | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 3. ``squad init`` + file verification | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 4. Run sessions | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 5. Verify outcomes | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 6. Record verdicts + post final comment | :hourglass_flowing_sand: Pending | --:-- | -- |\n\n| Symbol | Meaning |\n|---|---|\n| :hourglass_flowing_sand: | Not started |\n| :arrows_counterclockwise: | Running |\n| :white_check_mark: | Passed |\n| :x: | Failed |\n| :warning: | Passed with caveats |\n\n*Run started: $($runStart.ToString('HH:mm')) — all steps pending*\n\"@\n\n$tmpFile = [System.IO.Path]::GetTempFileName()\n$utf8NoBom = New-Object System.Text.UTF8Encoding $false\n[System.IO.File]::WriteAllText($tmpFile, $body, $utf8NoBom)\n$response = gh api \"repos\u002F$env:REPO\u002Fissues\u002F$env:PR_NUMBER\u002Fcomments\" --method POST --field \"body=@$tmpFile\" | ConvertFrom-Json\n$env:COMMENT_ID = $response.id\nRemove-Item $tmpFile -Force\nWrite-Host \"Progress comment posted — ID: $($response.id)\"\n```\n\nAfter posting, immediately update the comment to mark Step 1 as `:arrows_counterclockwise: Running` (do NOT wait — this is a two-step sequence: post all-pending, then immediately update to Step 1 running). Then proceed to Step 1.\n\nSee **Progress Reporting** for the full comment lifecycle and update patterns.\n\n**⚠️ STOP before continuing:** If posting the comment fails (network error, auth error), abort the run and report the failure. Do not proceed silently without a tracking comment.\n\n### Step 1 — Build the CLI from your branch\n\n```bash\ncd \u002Fpath\u002Fto\u002Fsquad          # your feature branch\nnpm install\nnpm run build -w packages\u002Fsquad-sdk && npm run build -w packages\u002Fsquad-cli\n\n# Link so `squad` command uses your local build (workspace flag — no cd required)\nnpm link -w packages\u002Fsquad-cli\n```\n\nVerify: `squad version` output includes the `-preview` suffix (e.g., `x.y.z-preview`),\nconfirming the local dev build is active. If the output shows a plain semver without\n`-preview`, the globally-installed npm package is still in use — re-check the link step.\nSee [CONTRIBUTING.md — Making the `squad` Command Use Your Local Build](..\u002F..\u002F..\u002FCONTRIBUTING.md)\nfor the full guidance on local dev versioning.\n\n### Step 2 — Create a disposable test repo\n\n```bash\nmkdir \u002Ftmp\u002Fsq-test-1 && cd \u002Ftmp\u002Fsq-test-1\ngit init\necho \"# Test Project\" > README.md\necho '{\"name\":\"test-project\",\"version\":\"1.0.0\"}' > package.json\nmkdir src\necho \"export function hello() { return 'world' }\" > src\u002Findex.ts\ngit add -- README.md package.json src\u002Findex.ts\ngit commit -m \"init: test project\"\n```\n\nKeep the project small — you only need enough for the coordinator to recognize a\ncodebase and hire a team.\n\n### Step 3 — Init a squad with your modified templates\n\n```bash\nsquad init\n# If testing a specific feature (e.g. state backends):\n# squad init --state-backend git-notes\n```\n\nVerify the init produced the expected files:\n```bash\nls -la .squad\u002F\ncat .squad\u002Fteam.md          # should have ## Members with 3+ agents\ncat .squad\u002Fconfig.json      # should reflect any CLI flags you passed\n```\n\n### Step 4 — Run a real session and capture output\n\nUse the Copilot CLI's `-p` flag with `--allow-all-tools` for non-interactive sessions.\n`--allow-all-tools` is **required** for automated\u002Fnon-interactive runs — without it,\ntool calls (including file writes) prompt for confirmation and block.\n\n```powershell\n# PowerShell (Windows)\ncopilot --agent squad --allow-all-tools -p \"Lead, decide what testing framework to use. Write your decision.\" `\n  2>&1 | Tee-Object evidence\u002Fsession-task.log\n```\n\n```bash\n# Bash (macOS\u002FLinux)\ncopilot --agent squad --allow-all-tools -p \"Lead, decide what testing framework to use. Write your decision.\" \\\n  2>&1 | tee evidence\u002Fsession-task.log\n```\n\nAlternatively, set the `COPILOT_ALLOW_ALL=1` environment variable instead of the flag.\n\nFor multi-turn workflows, run sequential sessions:\n```powershell\n# Session A: give the team a task\ncopilot --agent squad --allow-all-tools -p \"prompt A\" 2>&1 | Tee-Object evidence\u002Fsession-A.log\n\n# Session B: verify state persisted\ncopilot --agent squad --allow-all-tools -p \"What decisions has the team made?\" 2>&1 | Tee-Object evidence\u002Fsession-B.log\n```\n\n### Step 5 — Verify the outcome\n\nCheck that your template change had the expected effect. Common checks:\n\n```bash\n# State location (for state-backend changes)\ngit notes --ref=squad list              # git-notes backend\ngit ls-tree -r squad-state              # orphan backend\nls .squad\u002Fagents\u002F*\u002Fhistory.md           # worktree backend\n\n# Coordinator behavior (grep session log)\ngrep \"STATE_BACKEND\" evidence\u002Fsession-task.log\ngrep \"spawn\" evidence\u002Fsession-task.log\n\n# File tree diff\ngit diff --stat HEAD~1                  # what changed on working branch\ngit log --all --oneline                 # commits across all branches\n```\n\n### Step 6 — Record the verdict\n\nCreate an `evidence\u002Fverdict.md` in each test repo:\n\n```markdown\n## Test: [scenario name]\n**Backend:** worktree | git-notes | orphan | two-layer\n**Branch:** [your feature branch]\n**Result:** PASS | PARTIAL | FAIL\n**Duration:** Xm Ys\n\n### What was verified\n- [ ] Coordinator identified feature correctly (from session log)\n- [ ] Agent was spawned via `task` tool (not simulated)\n- [ ] team.md has ## Members with 3+ agents\n- [ ] State landed in correct location\n- [ ] No unexpected side effects\n\n### Evidence files\n- session-task.log — full session output\n- git-log.txt — `git log --all --oneline`\n\n### Notes\n[anything unusual or noteworthy]\n```\n\nRecord the wall-clock time from the start of Step 1 (fast-fail checks) to the end\nof Step 6 (verdict posted). This is the full E2E run duration for this scenario.\n\n## Progress Reporting\n\nUse this section only when you are running E2E validation for an open PR. If\n`PR_NUMBER` and `REPO` are both set, post and maintain a live tracking comment\nin the PR thread. If either value is missing (for example, a local-only run),\nskip progress reporting silently.\n\n### Start the tracking comment (Step 0 — see Workflow above)\n\nThe initial comment must be posted as **Step 0** — the absolute first action before\nanything else. See the Step 0 block in the Workflow section for the exact code.\n\nThe subsections below describe how to **update** the comment at each step boundary.\nFor reference, here is the initial all-pending comment body posted in Step 0:\n\n1. Post a PR comment before Step 1 begins:\n\n```bash\ngh pr comment \"$PR_NUMBER\" --repo \"$REPO\" --body \"## E2E Progress\\n\\n| Step | Status | Started | Duration |\n|---|---|---|---|\n| 1. Fast-fail checks (build · link · \\\\`squad version\\\\`) | ⏳ Pending | --:-- | -- |\n| 2. Create test repo(s) | ⏳ Pending | --:-- | -- |\n| 3. \\\\`squad init\\\\` + file verification | ⏳ Pending | --:-- | -- |\n| 4. Run sessions | ⏳ Pending | --:-- | -- |\n| 5. Verify outcomes | ⏳ Pending | --:-- | -- |\n| 6. Record verdicts + post final comment | ⏳ Pending | --:-- | -- |\n\\n| Symbol | Meaning |\n|---|---|\n| ⏳ | Not started |\n| ? | Running |\n| ✅ | Passed |\n| ❌ | Failed |\n| ⚠️ | Passed with caveats |\"\n```\n\n2. Capture the comment ID immediately after posting it:\n\n```bash\nCOMMENT_ID=$(gh api \"repos\u002F$REPO\u002Fissues\u002F$PR_NUMBER\u002Fcomments\" --jq '.[-1].id')\n```\n\n3. Treat Step 1 as in progress as soon as the comment exists. Update the body so\n   Step 1 shows `? Running` and every later step remains `⏳ Pending`.\n\n### Update the tracking comment after every step boundary\n\n1. When marking a step `? Running`, record `$startTime = Get-Date` and store the\n   `HH:MM` start time in that row's **Started** column.\n2. Edit the existing comment in place; do not post a new progress comment:\n\n```bash\ngh api --method PATCH \"repos\u002F$REPO\u002Fissues\u002Fcomments\u002F$COMMENT_ID\" --field body=\"...\"\n```\n\n3. When marking a step `✅`, `❌`, or `⚠️`, compute\n   `$duration = (Get-Date) - $startTime` and format it as\n   `\"{0}m {1}s\" -f [int]$duration.TotalMinutes, $duration.Seconds`.\n4. Update the completed step row to `✅`, `❌`, or `⚠️`, keep its original\n   `HH:MM` value in **Started**, and write the formatted duration in **Duration**.\n5. Keep all previously completed rows unchanged.\n6. Mark the next step as `? Running` and set its **Started** value.\n7. Leave later steps as `⏳ Pending` with `--:--` for **Started** and `--` for\n   **Duration**.\n8. If a step fails and you stop early, still update the comment so the failed step\n   shows `❌` with its original start time and computed duration, and Step 6\n   becomes `? Running` while you prepare the final verdict.\n\n### Use this status legend in the comment\n\n| Symbol | Meaning |\n|---|---|\n| ⏳ | Not started |\n| ? | Running |\n| ✅ | Passed |\n| ❌ | Failed |\n| ⚠️ | Passed with caveats |\n\n### Use exact step names and order\n\nKeep these six rows in this exact order every time you update the comment:\n\n1. Fast-fail checks (build · link · `squad version`)\n2. Create test repo(s)\n3. `squad init` + file verification\n4. Run sessions\n5. Verify outcomes\n6. Record verdicts + post final comment\n\n### Handle Windows comment bodies safely\n\nOn Windows PowerShell 5.1, use the **`--field body=@file`** pattern to post comment\nbodies. Write the content to a temp file using UTF-8 **without BOM**, then pass\n`--field \"body=@$tmpFile\"` to `gh api`. This is more reliable than piping JSON\nthrough `--input -` on PS 5.1, which can silently corrupt multi-byte characters\neven with `[Console]::OutputEncoding = UTF8`.\n\nKey rules:\n- Use `New-Object System.Text.UTF8Encoding $false` (the `$false` disables the BOM).\n  `[System.Text.Encoding]::UTF8` writes a BOM which GitHub renders as a stray\n  character (`﻿`) at the start of the comment.\n- Use `--field \"body=@$tmpFile\"`, NOT `--input -` or `--input filename`, for\n  comment body updates. The `@` prefix tells `gh` to read the field value from\n  the file rather than treating the path as a literal string.\n- Clean up the temp file after posting.\n- Scrub any local absolute paths from the body before posting (see PII Protection\n  section).\n\n```powershell\n$step1StartTime = Get-Date\n$step1Started = $step1StartTime.ToString('HH:mm')\n$step1Duration = (Get-Date) - $step1StartTime\n$step1DurationText = \"{0}m {1}s\" -f [int]$step1Duration.TotalMinutes, $step1Duration.Seconds\n$step2StartTime = Get-Date\n$step2Started = $step2StartTime.ToString('HH:mm')\n$body = @\"\n## E2E Progress\n\n| Step | Status | Started | Duration |\n|---|---|---|---|\n| 1. Fast-fail checks (build · link · `squad version`) | :white_check_mark: Passed | $step1Started | $step1DurationText |\n| 2. Create test repo(s) | :arrows_counterclockwise: Running | $step2Started | -- |\n| 3. `squad init` + file verification | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 4. Run sessions | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 5. Verify outcomes | :hourglass_flowing_sand: Pending | --:-- | -- |\n| 6. Record verdicts + post final comment | :hourglass_flowing_sand: Pending | --:-- | -- |\n\n| Symbol | Meaning |\n|---|---|\n| :hourglass_flowing_sand: | Not started |\n| :arrows_counterclockwise: | Running |\n| :white_check_mark: | Passed |\n| :x: | Failed |\n| :warning: | Passed with caveats |\n\"@\n\n$tmpFile = \"$env:TEMP\\e2e-comment-body.md\"\n$utf8NoBom = New-Object System.Text.UTF8Encoding $false\n[System.IO.File]::WriteAllText($tmpFile, $body, $utf8NoBom)\ngh api --method PATCH \"repos\u002F$env:REPO\u002Fissues\u002Fcomments\u002F$env:COMMENT_ID\" --field \"body=@$tmpFile\"\nRemove-Item $tmpFile -Force\n```\n\n### Progressive Verdicting — Post After Each Scenario (Critical)\n\n**Do NOT batch all scenario results to the end.** This is the most common cause\nof lost verdicts. After each scenario completes, **immediately** PATCH the\ntracking comment with that scenario's result before moving to the next one.\n\nThe pattern for each scenario:\n\n```powershell\n# After scenario N completes — PATCH immediately, before starting scenario N+1\n$scenarioNDuration = \"{0}m {1}s\" -f [int]((Get-Date) - $scenarioNStartTime).TotalMinutes, ((Get-Date) - $scenarioNStartTime).Seconds\n# ...rebuild the full comment body with this scenario updated to PASS\u002FFAIL\u002FPARTIAL...\n$tmpFile = [System.IO.Path]::GetTempFileName()\n$utf8NoBom = New-Object System.Text.UTF8Encoding $false\n[System.IO.File]::WriteAllText($tmpFile, $body, $utf8NoBom)\ngh api --method PATCH \"repos\u002F$env:REPO\u002Fissues\u002Fcomments\u002F$env:COMMENT_ID\" --field \"body=@$tmpFile\"\nRemove-Item $tmpFile -Force\nWrite-Host \"Scenario N verdict posted\"\n```\n\nThis guarantees that even if the AI model connection drops mid-run, the last\nsuccessfully PATCHed state is always visible in the PR.\n\n### Agent Run Time Budget\n\n**⚠️ Critical: Background agents lose their AI model connection after ~15 minutes\nof continuous execution.** This is a platform limit, not a bug in your code.\nThe verdict stage appears to \"hang\" because the connection drops right at the end\nwhen the agent has been running too long.\n\n**Per-agent scenario budget:**\n\n| Scenario type | Estimated time | Budget |\n|---|---|---|\n| Static checks only (file existence, grep, size) | 1-3 min | 4 per agent |\n| `squad init` + file verification (no copilot session) | 3-5 min | 3 per agent |\n| `squad init` + one `copilot --agent squad` session | 8-15 min | **1 per agent** |\n| Build + link + one copilot session | 12-20 min | **1 per agent** |\n\n**Rule: Limit yourself to 1 scenario that includes a `copilot --agent squad` session\nper agent run.** For a plan with multiple copilot-session scenarios, run them in\nseparate agents — not in sequence within a single agent.\n\nIf your scenario plan has N copilot-session scenarios, request N separate test\nagents to run them in parallel (one scenario each). Static scenarios may be\nbatched up to 4 per agent.\n\n**If you are running a scenario with a `copilot --agent squad` session:**\n- Run the build and link ONCE at the start (shared across all static scenarios)\n- Run the copilot session immediately after the repo is set up\n- PATCH the comment with the result immediately after the session ends\n- Then proceed to static scenarios while you still have connection budget\n\n### Replace the tracking comment with the final verdict\n\nWhen you reach Step 6, replace the tracking comment body entirely with the final\nstructured verdict table. Do not post a separate final comment. The tracking\ncomment is the final verdict comment.\n\nInclude a summary row at the bottom of the final table showing the total elapsed\ntime for the full run:\n\n```text\n| **Total** | — | HH:MM | Xm Ys |\n```\n\n**If the connection drops before Step 6:** The last progressive verdict PATCH\nalready shows the partial state. The next agent run should read the existing\ncomment, pick up where it left off, and add remaining scenario rows rather than\nstarting fresh.\n\n## Test Matrix Template\n\nUse this matrix when planning validation for a template change. Not every change\nneeds every row — pick the scenarios relevant to your modification.\n\n| # | Scenario | What to verify | Duration |\n|---|----------|----------------|----------|\n| 1 | Basic init + task | Templates applied, agent spawned, work produced | — |\n| 2 | Cross-branch persistence | State survives `git checkout` (if state-backend) | — |\n| 3 | Scribe behavior | Scribe commits to correct target | — |\n| 4 | PR cleanliness | Feature branch PR has no leaked state files | — |\n| 5 | Migration path | Existing squad picks up new template behavior | — |\n| 6 | Edge case: empty repo | Init works in repo with single commit | — |\n| 7 | Edge case: monorepo | Init works in subdirectory of monorepo | — |\n\nNote: Keep `—` during planning, then replace it with the actual elapsed time when\nrecording the verdict for each scenario.\n\n## Tips\n\n- **Name test repos descriptively:** `sq-test-notes-crossbranch`, not `test1`.\n- **Always capture session logs.** Without logs, you can't debug failures.\n- **One scenario per repo.** Don't reuse repos across unrelated tests — state\n  leaks between tests make results unreliable.\n- **Clean up after.** Delete test repos when done. They accumulate fast.\n- **Windows users:** Use PowerShell. `Tee-Object` replaces `tee`. Paths use `\\`.\n\n## Fast-Fail Rules\n\nThese checks must pass before running any scenario. If any fail, stop\nimmediately and report the failure — do **not** attempt workarounds or mark\nscenarios as SKIPPED.\n\n0. **Clean stale SDK before building.** Before running `npm run build`, remove any\n   stale published copy of `@bradygaster\u002Fsquad-sdk` that may have been installed\n   into `packages\u002Fsquad-cli\u002Fnode_modules\u002F`. This local copy shadows the workspace\n   symlink in the root `node_modules\u002F` and causes TypeScript to see the published\n   version instead of the local source. Run from the repo root:\n   ```powershell\n   $stale = \"packages\\squad-cli\\node_modules\\@bradygaster\\squad-sdk\"\n   if (Test-Path $stale) { Remove-Item -Recurse -Force $stale; Write-Host \"Cleaned stale SDK\" }\n   ```\n   This is safe to run unconditionally — if the path doesn't exist, the command is\n   a no-op. The root `node_modules\\@bradygaster\\squad-sdk` workspace symlink remains\n   intact and npm will use it automatically.\n1. **Build must succeed.** Run `npm run build` from the repo root. A build\n   failure blocks all scenarios; report `BUILD_FAILED` and stop.\n   - If the error is `tsc: not found` or similar missing-binary errors, run\n     `npm install` first to reconcile `node_modules` with the lock file, then\n     retry. This can happen after `git checkout HEAD -- package-lock.json`\n     restores the lock file without reinstalling.\n2. **CLI must link successfully.** `cd packages\u002Fsquad-cli && npm link` must exit\n   0. If it fails, report `LINK_FAILED` and stop.\n3. **`squad version` must run.** After linking, `squad version` must output a\n   version string. If not, report `CLI_NOT_FOUND` and stop.\n\nDo **not** mark scenarios as SKIPPED due to build or environment errors —\nthat obscures real failures from reviewers. SKIPPED is only acceptable when the\nuser explicitly requests it.\n\n## PII Protection — Mandatory\n\nWhen posting evidence to PR comments, issues, or any shared document:\n\n- **Never include absolute paths** that contain a local username (e.g.,\n  `C:\\Users\\username\\...` or `\u002Fhome\u002Fusername\u002F...`).\n- **Use `~` notation** for home-relative paths: `~\u002FAppData\u002FLocal\u002FTemp\u002F...`\n  or `~\u002Ftmp\u002Fsq-test-1`.\n- **Repo-internal paths use `\u003Crepo-root>` as the prefix.** If evidence files live\n  inside the repository (e.g. `.e2e\u002F`, `tmp\u002F`, or any subdirectory of the repo),\n  write them as `\u003Crepo-root>\\.e2e\\pr-1035\\evidence` — not as `~\\..\\..\\...` backward\n  navigation. `\u003Crepo-root>` is a clear, portable placeholder for the repository root\n  that does not expose the machine's directory layout.\n- **Scrub before posting.** Replace any occurrence of the local machine path\n  prefix (everything up to and including the username segment) with `~`.\n\nExample — ❌ wrong: `C:\\Users\\johndoe\\AppData\\Local\\Temp\\sq-e2e-pr1035\\evidence`\nExample — ✅ right: `~\u002FAppData\u002FLocal\u002FTemp\u002Fsq-e2e-pr1035\u002Fevidence`\nExample — ❌ wrong: `~\\..\\..\\repos\\squad\\.e2e\\pr-1035\\evidence`\nExample — ✅ right: `\u003Crepo-root>\\.e2e\\pr-1035\\evidence`\n\nThis applies to all evidence tables, verdict files, and PR comments.\n\n## Anti-Patterns\n\n- **Skipping the local build.** If you test with the published CLI, you're\n  testing the old templates, not your changes.\n- **Posting absolute paths in PR comments.** Always scrub to `~`-relative paths\n  before sharing. See PII Protection above.\n- **Marking scenarios SKIPPED due to environment issues.** Fix the environment\n  (use fast-fail rules above) or report BUILD_FAILED — never silently skip.\n- **Testing only the happy path.** Template changes often break edge cases (empty\n  repos, monorepos, cross-branch). Test at least 2-3 scenarios.\n- **Trusting session output alone.** Always verify git state independently —\n  agents can claim they wrote something without actually doing it.\n- **Reusing test repos.** Prior state bleeds into later tests. Start fresh.\n- **Batching all scenario verdicts to the end.** The AI model connection drops\n  after ~15 minutes. Always PATCH the comment after each scenario so partial\n  results are never lost. See Progressive Verdicting above.\n- **Running multiple `copilot --agent squad` sessions in one agent.** Each\n  session takes 5-15 minutes; combined with build time, you'll hit the ~15-minute\n  connection budget. One copilot session per agent — split into parallel agents\n  if your plan has more.\n\n## Sandbox \u002F Permission Notes\n\n### Always pass `--allow-all-tools` in non-interactive mode\n\nThe Copilot CLI requires explicit permission to run tools automatically. In\ninteractive mode the user approves each tool call; in non-interactive mode (`-p`)\nthose prompts cannot be displayed and writes fail silently or with a \"Permission\ndenied and could not request permission from user\" error.\n\nFix: always include `--allow-all-tools` (or `--yolo` \u002F `--allow-all`) in Step 4\ncommands, or export `COPILOT_ALLOW_ALL=1` before running E2E sessions.\n\nThis also applies when `copilot --agent squad` is launched as a subprocess from\ninside a Copilot CLI background agent (e.g. a test engineer running via the `task` tool) —\nthe flag is still needed.\n\n### `--allow-all-paths` for repos outside the CWD\n\nBy default the CLI restricts file access to the current directory tree. If the\ncoordinator needs to read files from a parent repo while running in a disposable\ntest repo, add `--allow-all-paths`:\n\n```powershell\ncopilot --agent squad --allow-all-tools --allow-all-paths -p \"...\"\n```\n\nOr use the combined shorthand: `--allow-all` \u002F `--yolo`.\n\n## Confidence\n\nhigh — Validated through 12 real E2E test sessions during state-backend\ndevelopment (PR #1004). `--allow-all-tools` requirement confirmed in PR #1035.\n",{"name":5,"domain":31,"source":35,"confidence":36,"description":7},"dev","7b731ec97f35346bdc4fa87c3edaf16b808fc0ae","packages\u002Fsquad-sdk\u002Ftemplates\u002Fskills\u002Fe2e-template-testing",516,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad","https:\u002F\u002Fgithub.github.io\u002Fsquad\u002F","https:\u002F\u002Fgithub.com\u002Fgithub","https:\u002F\u002Fgithub.com\u002Fabout","How people build software.","2026-11-12 02:20:49",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add github\u002Fsquad --skill e2e-template-testing",{"tool":59,"command":60},"bunx","bunx skills add github\u002Fsquad --skill e2e-template-testing",{"tool":62,"command":63},"pnpm","pnpm dlx skills add github\u002Fsquad --skill e2e-template-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Fpackages\u002Fsquad-sdk\u002Ftemplates\u002Fskills\u002Fe2e-template-testing\u002FSKILL.md",true,[],[68,96,107,116,133,157],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":75,"publishedAt":38},"01M6X287DVJK1S91END9DSHETN","gh-aw-enlistment","Enlist a repository into Squad by installing the supported GitHub Agentic Workflows (gh-aw) bootstrap — with strict compilation, an explicit safe-update allowlist, and a human-reviewed bootstrap PR. Never auto-merges.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Fworkflows\u002Fskills\u002Fgh-aw-enlistment\u002FSKILL.md",[74],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95],"gh aw enlistment","gh","safe","workflows","agentic workflows","identity","squad","update","compiling","actions","ci","Safety","preflight","guide","auto","files","human","pr creation","github cli","lock",{"skillNo":97,"name":98,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":102,"publishedAt":38},"01M6X27Y5119CSRQFFJCV6432R","My Skill","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fmy-skill\u002FSKILL.md",[101],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[103,104,27,105,106],"my","my skill","vitest","tester",{"skillNo":108,"name":109,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":113,"publishedAt":38},"01M6X27RWAYB2X9ER0MVRRKXGA","bad-skill","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Ftest-fixtures\u002Fskills-test-abb30454\u002Fbad-skill\u002FSKILL.md",[112],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[114,115],"bad","bad skill",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":122,"publishedAt":38},"01M6X27HBWM6V81KXYW5XQSWFJ","windows-compatibility","Cross-platform path handling and command patterns","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fwindows-compatibility\u002FSKILL.md",[],[123,124,125,36,126,127,128,129,130,131,132],"windows compatibility","compatibility","windows","platform","path","bugs","git","command","patterns","cross-platform",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":139,"publishedAt":38},"01M6X278Z6PF2YQN406RHJJWHG","versioning-policy","SemVer rules for Squad's stable, preview, insider, and local package versions","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Fversioning-policy\u002FSKILL.md",[],[140,141,142,143,144,82,145,146,147,148,86,149,150,151,152,153,154,155,36,156],"versioning","versioning policy","policy","preview","pr","release","semver","npm","package","workspace","Rules","incident","local","resolution","channels","insider","for",{"skillNo":158,"name":159,"nameZh":6,"description":160,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":161,"categories":162,"keywords":167,"publishedAt":38},"01M6X26XS6T23E81XNP51HMQAT","tiered-memory","Three-tier agent memory model (hot\u002Fcold\u002Fwiki) for context reduction per spawn","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fsquad\u002Fblob\u002Fdev\u002Ftemplates\u002Fskills\u002Ftiered-memory\u002FSKILL.md",[163,166],{"categoryNo":164,"categoryName":165,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[168,169,170,171,172,173,174,175,156,176,177,178,179,180,181,182],"memory","tiered memory","model","wiki","agent memory","performance","cold","memory-management","runtime","three","spawn","proposal","management","design","context"]