Repository navigation
fix(cli): 2.0.0-preview.2 upgrade/health fixes from dogfooding - #2303
Conversation
🟠 Impact Analysis — PR #2303Risk tier: 🟠 HIGH 📊 Summary
🎯 Risk Factors
📦 Modules Affectedci-workflows (2 files)
docs (3 files)
root (7 files)
scripts (1 file)
squad-cli (13 files)
squad-sdk (8 files)
templates (2 files)
tests (9 files)
|
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 5 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ❌ | Copilot threads resolved | 8 unresolved Copilot thread(s) — fix and resolve before merging |
| ❌ | CI passing | 4 check(s) failing: test, sdk-exports-validation, samples-build, Verify exact SHA and build evidence |
Files Changed (45 files, +3112 −351)
| File | +/− |
|---|---|
.changeset/health-legacy-and-roster.md |
+6 −0 |
.changeset/preview2-command-fixes.md |
+6 −0 |
.changeset/self-upgrade-dry-run-channel.md |
+5 −0 |
.changeset/upgrade-idempotent-backups.md |
+5 −0 |
.github/agents/squad.agent.md |
+2 −2 |
.github/workflows/squad-release-verify.yml |
+6 −2 |
.squad-templates/README.md |
+2 −2 |
.squad-templates/squad.agent.md |
+2 −2 |
README.md |
+3 −2 |
docs/src/content/docs/features/self-upgrade.md |
+41 −30 |
docs/src/content/docs/reference/cli.md |
+2 −0 |
docs/src/content/docs/scenarios/upgrading.md |
+27 −1 |
packages/squad-cli/src/cli-entry.ts |
+47 −19 |
packages/squad-cli/src/cli/commands/client.ts |
+159 −0 |
packages/squad-cli/src/cli/commands/doctor.ts |
+20 −5 |
packages/squad-cli/src/cli/commands/health.ts |
+74 −4 |
packages/squad-cli/src/cli/commands/roster.ts |
+323 −0 |
packages/squad-cli/src/cli/commands/update-check.ts |
+17 −3 |
packages/squad-cli/src/cli/core/command-help.ts |
+40 −8 |
packages/squad-cli/src/cli/core/init.ts |
+5 −3 |
packages/squad-cli/src/cli/core/squad-owned-files.ts |
+368 −0 |
packages/squad-cli/src/cli/core/team-md.ts |
+87 −0 |
packages/squad-cli/src/cli/core/upgrade.ts |
+439 −212 |
packages/squad-cli/templates/README.md |
+2 −2 |
packages/squad-cli/templates/squad.agent.md.template |
+2 −2 |
packages/squad-sdk/src/agents/charter-markdown.ts |
+21 −8 |
packages/squad-sdk/src/agents/onboarding.ts |
+1 −1 |
packages/squad-sdk/src/config/init.ts |
+5 −0 |
packages/squad-sdk/src/config/markdown-migration.ts |
+28 −7 |
packages/squad-sdk/src/ralph/triage.ts |
+3 −1 |
packages/squad-sdk/src/tools/index.ts |
+50 −4 |
packages/squad-sdk/templates/README.md |
+2 −2 |
packages/squad-sdk/templates/squad.agent.md.template |
+2 −2 |
scripts/release/policy-gates.mjs |
+55 −5 |
templates/README.md |
+2 −2 |
templates/squad.agent.md.template |
+2 −2 |
test/cli/command-help.test.ts |
+2 −0 |
test/cli/health-legacy.test.ts |
+204 −0 |
test/cli/preview2-cli-fixes.test.ts |
+174 −0 |
test/cli/rai-rename-git.test.ts |
+90 −0 |
test/cli/roster.test.ts |
+157 −0 |
test/cli/upgrade-idempotent.test.ts |
+427 −0 |
test/cli/upgrade.test.ts |
+22 −18 |
test/release-policy-changeset-drain.test.ts |
+91 −0 |
test/sdk/squad-decide-inbox.test.ts |
+84 −0 |
Total: +3112 −351
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
🏗️ Architectural Review
Automated architectural review — informational only. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved deletion and migration data-loss risks, incomplete downgrade protection, and a Linux-failing test assertion block approval.
10 open issues
Restrict manifest deletions to authorized managed paths · New Preserve interrupted migration state before scaffolding · New Use platform path utilities for cross-platform path tests · New Fail when client projection errors prevent persistence · New Do not whitelist routing destinations excluded by the contract · New Repair Git case drift even when the legacy directory is absent · New Resolve and install the exact version from the effective registry · New Compare prerelease SemVer identifiers numerically · New Reject dot path segments as workstream slugs · New Use the project activation path for linked-team stream lookup · New
What changed in this PR
This PR addresses preview-release dogfooding issues across Squad’s CLI upgrade flow, health checks, and SDK decision routing. It also adjusts release verification so pull requests can retain valid pending changesets.
Changes:
- Adds content-aware upgrade planning, verified backups, retired-file cleanup, and channel-aware self-upgrade safeguards.
- Improves legacy charter handling, built-in roster migration, client commands, diagnostics, and workstream inbox selection.
- Adds regression coverage, updates upgrade documentation, and synchronizes lowercase Rai paths across templates.
| File | Description |
|---|---|
test/sdk/squad-decide-inbox.test.ts |
Tests workstream inbox routing and filename handling. |
test/release-policy-changeset-drain.test.ts |
Tests event-aware changeset policy. |
test/cli/upgrade.test.ts |
Updates upgrade and Rai migration expectations. |
test/cli/upgrade-idempotent.test.ts |
Covers backups, idempotence, dry runs, and self-upgrade. |
test/cli/rai-rename-git.test.ts |
Tests Git-recorded Rai directory renames. |
test/cli/preview2-cli-fixes.test.ts |
Covers roster, client, diagnostic, and header fixes. |
test/cli/health-legacy.test.ts |
Covers legacy health checks and roster drift. |
test/cli/command-help.test.ts |
Adds client command help coverage. |
templates/squad.agent.md.template |
Updates documented Rai paths. |
templates/README.md |
Documents lowercase Rai destinations. |
scripts/release/policy-gates.mjs |
Validates pending changesets in CI mode. |
README.md |
Describes upgrade safeguards and client commands. |
packages/squad-sdk/templates/squad.agent.md.template |
Synchronizes SDK coordinator Rai references. |
packages/squad-sdk/templates/README.md |
Synchronizes SDK Rai path documentation. |
packages/squad-sdk/src/tools/index.ts |
Adds workstream-aware decision inbox selection. |
packages/squad-sdk/src/ralph/triage.ts |
Excludes built-in support agents from triage. |
packages/squad-sdk/src/config/markdown-migration.ts |
Filters routing headers and placeholders. |
packages/squad-sdk/src/config/init.ts |
Recognizes the lowercase Rai role. |
packages/squad-sdk/src/agents/onboarding.ts |
Uses the lowercase Rai template key. |
packages/squad-sdk/src/agents/charter-markdown.ts |
Parses BOM-prefixed and compact legacy charters. |
packages/squad-cli/templates/squad.agent.md.template |
Synchronizes CLI coordinator Rai references. |
packages/squad-cli/templates/README.md |
Synchronizes CLI Rai path documentation. |
packages/squad-cli/src/cli/core/upgrade.ts |
Integrates upgrade planning, migrations, and downgrade checks. |
packages/squad-cli/src/cli/core/team-md.ts |
Adds missing built-in roster rows. |
packages/squad-cli/src/cli/core/squad-owned-files.ts |
Implements managed-file planning, backups, and retirement. |
packages/squad-cli/src/cli/core/init.ts |
Seeds lowercase Rai and records shipped-file hashes. |
packages/squad-cli/src/cli/core/command-help.ts |
Expands upgrade and client help. |
packages/squad-cli/src/cli/commands/update-check.ts |
Flags stale cached update results. |
packages/squad-cli/src/cli/commands/health.ts |
Adds warnings and built-in recognition. |
packages/squad-cli/src/cli/commands/doctor.ts |
Corrects local-mode detection and subprocess usage. |
packages/squad-cli/src/cli/commands/client.ts |
Adds client listing and projection commands. |
packages/squad-cli/src/cli-entry.ts |
Wires client commands and dry-run handling. |
docs/src/content/docs/features/self-upgrade.md |
Documents revised upgrade behavior. |
.squad-templates/squad.agent.md |
Updates canonical coordinator Rai references. |
.squad-templates/README.md |
Updates canonical Rai path documentation. |
.github/workflows/squad-release-verify.yml |
Selects policy mode from the triggering event. |
.github/agents/squad.agent.md |
Synchronizes active coordinator Rai references. |
.changeset/upgrade-idempotent-backups.md |
Records managed-file upgrade changes. |
.changeset/self-upgrade-dry-run-channel.md |
Records self-upgrade safety changes. |
.changeset/preview2-command-fixes.md |
Records CLI and SDK command fixes. |
.changeset/health-legacy-and-roster.md |
Records health and roster changes. |
Review effort: Balanced
| const absPath = path.join(dest, ...relPath.split('/')); | ||
| const existing = readExistingText(absPath); | ||
| if (existing === undefined) continue; | ||
| retired.push({ relPath, absPath, customized: contentHash(existing) !== hash }); |
| if (hasCanonical) { | ||
| storage.deleteDirSync(tempDir); |
| }); | ||
|
|
||
| it('uses the project name from config or the repository directory name, never "undefined"', async () => { | ||
| expect(readProjectLabel('C:\\repos\\my-squad', {})).toBe('my-squad'); |
| reportClientResults(synced.results); | ||
| console.log(`${GREEN}✓${RESET} clients configured: ${synced.clients.join(', ')}`); | ||
| return 0; |
| // Built-in support agents are legitimate routing targets even though they are not cast (#1785). | ||
| for (const { id, name } of BUILTIN_AGENTS) { | ||
| keys.add(normalizeAgentRef(id)); | ||
| keys.add(normalizeAgentRef(name)); |
| } | ||
| } | ||
|
|
||
| if (!hasLegacy) return { migrated, tombstoned, recordedInGit }; |
| const res = await fetch('https://registry.npmjs.org/-/package/@bradygaster%2Fsquad-cli/dist-tags', { signal: controller.signal }); | ||
| clearTimeout(timer); | ||
| if (!res.ok) return null; | ||
| const tags = await res.json() as Record<string, string>; | ||
| return typeof tags[tag] === 'string' ? tags[tag]! : null; |
| const resolve = options.resolveTagVersion ?? resolveSelfUpgradeTagVersion; | ||
| const targetVersion = await resolve(tag); | ||
|
|
||
| if (targetVersion && safeCompareVersions(targetVersion, currentVersion) < 0) { |
| { root: 'identity', kind: 'dir' }, | ||
| ]; | ||
|
|
||
| const WORKSTREAM_SLUG = /^[A-Za-z0-9._-]+$/; |
| const activationFile = path.join(path.dirname(squadRoot), '.squad-workstream'); | ||
| if (storage.existsSync(activationFile)) { | ||
| const fromFile = (storage.readSync(activationFile) ?? '').split(/\r?\n/)[0]?.trim(); | ||
| if (isActive(fromFile)) return inboxFor(fromFile); |
- upgrade --self: honor --dry-run (zero exec), follow the installed channel (prerelease -> @insider, stable -> @latest), refuse downgrades without --force (#2295) - upgrade: one content-compared plan for every squad-owned file; verified <file>.local-backup before overwrite; shipped-files manifest distinguishes user edits from template revisions; dry-run writes nothing and reports nothing right after an upgrade (also on CRLF checkouts); .gitignore/.gitattributes appended in the file's own EOL; retired files removed when unmodified; provably Squad-shipped stale .copilot/skills copies cleaned (#2297, #2266, #2047, #2232) - health: table headers/placeholders never parsed as agents, built-ins are valid routing targets, BOM/pipe-joined legacy charters parse, missing identity is a warn with a hint, roster drift warns; upgrade adds built-in rows to team.md (#2298, #2234, #1785) - Rai -> rai: two-step rename recorded with git mv; templates reference agents/rai/; init scaffolds rai/ (#2299) - squad client list|add, dry-run header shows project name, update-check stale cache, squad_decide workstream inbox + 80-char slug, doctor Mode: local for same-project teamRoot and no DEP0190 (#2299, #2174) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
squad-release-verify.yml ran policy-gates.mjs --mode=release on pull_request too, so every PR carrying a changeset failed the gate (#2283, #2301). The workflow now passes --mode=ci on pull_request and --mode=release only on the release path (workflow_call from squad-release.yml). In ci mode the gate still runs: pending fragments are allowed but must be well-formed (allowlisted package, patch|minor|major bump, non-empty summary); malformed ones fail. Release mode keeps enforcing the drain unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
…ade and lowercase rai init - upgrade.test: customized-skill expectations now assert the .local-backup message; Rai migration test recreates the legacy mixed-case layout (init scaffolds rai/) - command-help.test: 'client' has a dedicated help block - cli-entry: --self --dry-run returns through the single success branch (performed=false) - team-md: never invent a roster table in a team.md without one - .github/agents/squad.agent.md: agents/rai/ (template-sync parity) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
Keep team.md byte-stable during upgrade, report unconfigured optional built-ins as informational, and add a provenance-backed roster command with exact restore semantics. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
Treat compound .example templates as text for EOL-normalized planning and distinguish unproven first-upgrade provenance from confirmed customization in backup output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 995eea17-c356-4912-90ea-5e5b144e7ba9
ca77de6 to
7e422a5
Compare
|
Revision pushed at Commits on rebased
This addresses review findings CL-1..CL-4; roster additions are now explicit opt-in per reviewer contract. Plain upgrade/dry-run and projection uninstall preserve Validation: build + TypeScript lint pass; mandated focused suites 58/58; upgrade suites 139 pass / 1 platform skip; health/doctor/init/template suites 726 pass after isolated timeout rerun; CI policy gates pass; release mode fails closed on 9 pending changesets as expected; 21 release scripts clean. Local Windows Upgrade Matrix for 0.13.1 |
|
Final CI update:
|


Summary
Dogfooding
2.0.0-preview.1found CLI upgrade, health, self-update, client, and migration defects. This branch is rebased ontodevatde1c4e66and now includes an independent post-review revision addressing Worf findings CL-1 through CL-4.Fixes #2295, Fixes #2297, Fixes #2298, Fixes #2299
Fixes #2047, Fixes #2174
Refs #2266, #2232, #2234, #1785, #2283, #2301
Reviewer revision
The rejected head
ca77de68automatically added Rai and Fact Checker to user-owned.squad/team.md. That behavior has been removed.squad upgrade,--dry-run, client projection, and projection uninstall preserveteam.mdbyte-for-byte.squad roster add <rai|fact-checker|all> [--dry-run]squad roster remove <rai|fact-checker|all> [--dry-run]disableanduninstallare remove aliases.mesh.json.examplenow use EOL-normalized comparison, eliminating CRLF false overwrites.Bug → fix → test
insider; stable stays onlatest; downgrade refusal unless forcedupgrade-idempotent.test.ts.local-backup, shipped manifest, retired-file cleanup, EOL-preserving no-op upgradesupgrade-idempotent, upgrade/template suitesroster.test.ts,health-legacy.test.ts, Upgrade MatrixRai→rairename with restart-safe fallbackrai-rename-git.test.tspreview2-cli-fixes, doctor suitessquad-decide-inbox.test.tsrelease-policy-changeset-drain.test.tsRelationship to #2269
Compatible, not superseding. #2269 owns casting JSON normalization and its
.gitattributesrule. This PR now handles compound textual.exampletemplates in the squad-owned file planner; it still does not normalize or rewrite the casting registry/history pair.Commits after rebase
65245d4c— dogfood upgrade/health fixes84839419— event-aware changeset drain8df2b794— legacy upgrade/help test alignment0e58cd07— explicit optional built-in roster contract7e422a5e— compound text-template CRLF idempotence and provenance-neutral backup wordingValidation
SKIP_BUILD_BUMP=1 npm run build— passnpm run lint— passrai-rename-git,health-legacy,preview2-cli-fixes,squad-decide-inbox,release-policy-changeset-drain,command-help, roster) — 58/58 passpolicy-gates --mode=ci— pass with 9 valid pending changesetspolicy-gates --mode=release— expected fail-closed on those pending changesetscheck-release-scripts— 21 scripts clean0.13.1, shapesdefault+ai-team— 2/2 rows pass;user-state-preservedandprojection-uninstall-byte-exactboth pass for both shapesLeftovers / not in this PR
.squad/casting-*.jsoncompatibility copies remain; coordinated removal is separate work..local-backupfiles, but the wording no longer claims customization was proven.mcp-root-writeskip; this PR does not touch the bridge test or reconciliation policy.