fix(installer): isolate Pro install from ancestor workspaces/package.json - #742
Conversation
…json Cohort students hit "Pro activation failed: Installed Pro artifact did not create node_modules/@aiox-squads/pro" even though npm install exits 0 and the upstream Pro license activation completes successfully. Root cause: installProArtifactIntoTarget runs `npm install <tgz>` in targetDir without --prefix or --workspaces=false. npm 10+ walks the directory tree, finds the first ancestor with a package.json (or one declaring workspaces), and installs node_modules there instead of in the target. The post-install integrity check then fails because the artifact is in the wrong place, not because it never downloaded. This was reproduced locally in 4 install topologies before patching, then proved by running the new test suite against pre-fix code — the two ancestor-hijack scenarios fail cleanly without the fix: 1. workspace declared in ancestor → npm installs at workspace root (FAILS pre-fix) 2. plain package.json in ancestor → npm installs at ancestor (FAILS pre-fix) 3. empty targetDir, clean ancestor → works (current happy path) 4. targetDir with own package.json → works (current happy path) Fixes applied: * installProArtifactIntoTarget: pass --prefix=targetDir + --workspaces=false + --include-workspace-root=false; create a synthetic anchor package.json if targetDir is empty, then clean it up after. * extractProArtifactToTemp: mirror the same flags to harden the temp extraction (it never failed in practice because os.tmpdir() has no ancestors with package.json, but the asymmetry was fragile). * acquireProArtifactSourceDir: when the target install fails, fall back to the extracted (sha256-verified) Pro source from tempRoot and emit a warning instead of bricking the wizard. The scaffolder copies files from the source dir, so the target install is a convenience, not a requirement. The warning is explicit that subsequent `aiox install` calls in the same directory will re-download Pro until the user runs from a fresh empty directory. * New diagnostic helper findAncestorNodeModulesPro walks up to 8 levels looking for a stray install, included in the user-facing error so students can see where npm actually put the package. Tests added: tests/installer/pro-setup-target-install.test.js — 8 regression tests covering all four install topologies, the synthetic anchor cleanup, the diagnostic helper (positive + negative cases), and the graceful fallback contract in acquireProArtifactSourceDir. Integration-style: builds a minimal fixture tarball at runtime via `npm pack`, no external dependencies, no Supabase credentials needed. CI added: .github/workflows/installer-smoke-matrix.yml — runs the regression suite + three end-to-end smoke installs (empty target, nested in workspace, nested under plain package.json) on Ubuntu/macOS/ Windows with Node 18/20/22 and npm 8/10/11. Triggers on packages/installer/** and tests/installer/** changes, breaking the "11 fixes to pro-setup.js in 30 days, each catching a new edge case" pattern by validating the install surface itself before publish. Cleared the dead fallback path in acquireProArtifactSourceDir that was already wired (`installedProSourceDir || extractedProSourceDir`) but unreachable because the throw in installProArtifactIntoTarget short- circuited it. Affected story: PRO-13.6 (signed artifact pipeline) Builds on: #735 (Windows npm spawn), PRO-13.5 (private distribution) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughPrevents npm from escaping target installs by adding explicit --prefix and workspace flags, detects ancestor-installed Pro and throws PRO_INSTALL_TARGET_HIJACKED, falls back to a verified temp source with a user warning, and adds regression tests plus a cross‑platform smoke workflow. ChangesPro Artifact Installation Safeguards
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
📊 Coverage ReportCoverage report not available
Generated by PR Automation (Story 6.1) |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/installer/pro-setup-target-install.test.js (1)
34-34: ⚡ Quick winUse an absolute import for
pro-setupin this test.Line 34 uses a relative path import; switch this to the repository’s absolute import convention.
As per coding guidelines, "**/*.{js,jsx,ts,tsx}: Use absolute imports instead of relative imports in all code".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/installer/pro-setup-target-install.test.js` at line 34, The test imports pro-setup using a relative path; replace the relative require for pro-setup (the line using "const proSetup = require('../../packages/installer/src/wizard/pro-setup');") with the repository's absolute import style—use the absolute module path for the installer wizard (e.g. require('packages/installer/src/wizard/pro-setup') or your repo's configured absolute alias) so the test follows the project's absolute-import convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/installer-smoke-matrix.yml:
- Around line 116-130: The inline Node scripts call execFileSync('npm', ...)
which breaks on Windows (npm is npm.cmd); update each script to resolve the npm
executable using platform detection (e.g., choose 'npm.cmd' when
process.platform === 'win32' and 'npm' otherwise) and pass that resolved name
into execFileSync instead of the hardcoded 'npm' (update the occurrences around
execFileSync('npm', ['pack', ...], { encoding: 'utf8' }) in the inline scripts
and the other two similar blocks mentioned).
In `@tests/installer/pro-setup-target-install.test.js`:
- Around line 89-93: The execFileSync call that sets packOutput uses a hardcoded
'npm' which fails on Windows; change it to select the platform-aware binary
(like const npmBin = process.platform === 'win32' ? 'npm.cmd' : 'npm') and call
execFileSync(npmBin, ['pack', '--json'], { cwd: buildDir, timeout:
NPM_INSTALL_TIMEOUT_MS, encoding: 'utf8' }); update the reference in this test
(the packOutput/execFileSync invocation) so Windows runners use npm.cmd the same
way other code (e.g., pro-setup.js) does.
---
Nitpick comments:
In `@tests/installer/pro-setup-target-install.test.js`:
- Line 34: The test imports pro-setup using a relative path; replace the
relative require for pro-setup (the line using "const proSetup =
require('../../packages/installer/src/wizard/pro-setup');") with the
repository's absolute import style—use the absolute module path for the
installer wizard (e.g. require('packages/installer/src/wizard/pro-setup') or
your repo's configured absolute alias) so the test follows the project's
absolute-import convention.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e33a22ec-e463-4e56-ba8f-3c29b025abd0
📒 Files selected for processing (3)
.github/workflows/installer-smoke-matrix.ymlpackages/installer/src/wizard/pro-setup.jstests/installer/pro-setup-target-install.test.js
* Use platform-aware npm binary (npm.cmd on Windows) in the test fixture
tarball builder and the 3 inline smoke install scripts in
installer-smoke-matrix.yml. Mirrors the pattern in pro-setup.js'
resolveNpmInvocation. Without this, the Windows job fixed below would
fail at the `execFileSync('npm', ...)` call.
* Replace the cross-product matrix with an explicit `include:` list and
drop combos that are structurally invalid (and were failing CI on the
first run): Node 18 + npm 11 (npm 11 requires Node >= 20.17), Node 20
+ npm 8 (npm 8 too old to honor --workspaces=false reliably), and the
redundant npm 11 re-pin on Node 22 (already ships with npm 11; the
re-pin via `npm install --global` conflicts with the bundled install
on GitHub-hosted runners). Added a new `bundled` mode that skips the
pin step entirely.
* Coverage retained: Ubuntu (Node 18/20/22 × npm 10/11/bundled),
macOS (Node 20/22), Windows (Node 20/22). 8 combos total, all valid.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addressed in 6bd1c3c — platform-aware npm bin in test fixture + smoke workflow inline scripts; matrix combos invalid in npm 8/11 vs Node 18/22 dropped. Nitpick on relative import is project convention (all other tests/installer/* use the same).
…#743) Hotfix release for #742 (already merged). Bumps: * @aiox-squads/core: 5.2.5 → 5.2.6 * aiox-core (compat wrapper): 5.2.5 → 5.2.6 + dependency @aiox-squads/core: 5.2.5 → 5.2.6 * @aiox-squads/installer: 3.3.4 → 3.3.5 Pushing tag v5.2.6 triggers .github/workflows/npm-publish.yml which publishes to npmjs.org using NPM_TOKEN_AIOX_SQUADS. After publish, students hit by "Installed Pro artifact did not create node_modules/@aiox-squads/pro" can update via: npx -y -p @aiox-squads/core@latest aiox install without the previously recommended fresh-directory workaround. Includes: - package-lock.json refreshed to 5.2.6 - CHANGELOG.md entry under [5.2.6] - 2026-05-17 - .aiox-core/data/entity-registry.yaml regenerated by pre-commit hook (757 → 815 entities — incidental sync, not caused by this release) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…leshooting (#745) * docs: align ecosystem with release-procedure SOP + Issue 10 troubleshooting Cross-cutting cleanup so the operator/student/agent ecosystem references the canonical release SOP (introduced in PR #744) consistently and exposes the npm-hijack troubleshooting path to students. ## docs/guides/installation-troubleshooting.md Added Issue 10: "Pro activation failed: Installed Pro artifact did not create node_modules/@aiox-squads/pro" — the exact error that affected cohorts for 30 days before PR #742 shipped. Documents symptom, root cause (npm hijack into ancestor with package.json/workspaces), fix (5.2.6+), and a two-tier recovery procedure (simple retry first, then cache cleanup + residual-install removal if state is fouled). ## docs/guides/aiox-pro-access.md "Erros comuns" section gains an explicit entry for the install failure with a direct link to Issue 10 above. Previously the guide only covered auth-side errors; students hitting the install-side error googled into silence. ## .aiox-core/development/tasks/publish-npm.md ## .aiox-core/development/tasks/release-management.md Both converted to slim wrappers that delegate to docs/guides/release-procedure.md as the authoritative source. The full procedures previously inlined here (757 and 257 lines respectively) were missing the gotchas paid for in 11 patches across 30 days: two- system branch protection bypass, publish race conditions, Windows path escape in node -e, npm CDN propagation budget, payload sanitization for ruleset PUT, trap EXIT for atomic restore. Maintaining the full content in two files would have drifted immediately; the wrappers keep the task IDs that agent workflows reference while pointing at the one source of truth. ## .aiox-core/development/agents/devops.md Added a "Release Procedure (NON-NEGOTIABLE Reference)" section to the DevOps Guide. When @devops is invoked for a release, push, or publish that ends with a tag push to @aiox-squads/*, the agent now has explicit instruction to load and follow the SOP. Captures the institutional memory items most likely to bite (two-system protection, 4-site version bump, publish_legacy race, smoke timeout, Windows path escape) so the agent does not re-discover them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address CodeRabbit feedback on PR #745 Four real issues caught: 1. devops.md L584 referenced `*publish` which is not in the agent's declared commands list. Replaced with `*push` followed by version-bump intent, which matches the actual command surface. 2. release-management.md L43 + publish-npm.md L32 + release-procedure.md L170 had `git tag -a vX.Y.Z origin/main -m "<notes>"` — options mixed with positional args. Reordered to `git tag -a -m "<notes>" vX.Y.Z origin/main` (options before tag name, ref last) as the idiomatic form. Both forms work in modern git, but the linted form is more robust against argument parsing edge cases. 3. installation-troubleshooting.md L260: fenced output block was missing language tag — failing MD040 linter. Added `text`. 4. installation-troubleshooting.md L276 (CodeRabbit nitpick, addressed in full): the cleanup snippets were bash-only and assumed macOS/Linux. Students hitting the original error on Windows had no recovery path. Added labelled PowerShell and Command Prompt variants alongside the bash version, all three with equivalent behavior: purge stray `node_modules/@aiox-squads/pro` directories + clear the npx cache + retry the install with `-p @aiox-squads/core@latest`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(release): bump to 5.2.7 — consolidate PRs #744-#750 from 5.2.6 Consolidates 7 PRs merged after the 5.2.6 release. None of them required an immediate hotfix on their own, but together they unblock cohort students from a real CI/CD failure mode (#739 Bug 1) and remove three sources of registry drift. ## What ships in 5.2.7 - **#744** (66b302a) — Pipeline hardening: `publish_legacy_aiox_core` race fix, smoke timeout 90s→240s with dual visibility check, structured notify summary, Windows path escape fix via WORKSPACE_DIR env var. Plus the canonical `docs/guides/release-procedure.md` SOP. - **#745** (342ef63) — Ecosystem alignment: `installation-troubleshooting.md` Issue 10 (install-side recovery for the npm-hijack symptom), aiox-pro-access.md link, slim wrappers for publish-npm.md/release-management.md tasks pointing at the SOP, devops.md Release Procedure section. - **#746** (ef7a352) — Internal `.aiox-core/package.json` rebranded `@aiox-fullstack/core@4.31.1` → `@aiox-squads/core-internal@5.2.7` (private, no phantom peerDeps). New `scripts/validate-aiox-core-namespace.js` (5-rule gate) wired into `validate:publish`. Closes #739 Bug 2. - **#747** (e5cd355) — 70 substitutions across 17 files realigning legacy `aiox-core/{templates,checklists,agents,tasks,workflows,agent-teams}/<X>` references to current `.aiox-core/...` layout. Unblocks `@po *validate-story-draft`. Closes #741. - **#748** (1f97f6f) — IDS `extractPurpose()` rewritten as strict priority chain (frontmatter → ## Purpose → ## Overview → # Title → fallback). Removed body-level regex that picked up example transcripts as purposes. New `syncSelfRegistryEntry()` writes sentinel `sha256:<self-reference>` checksum for the registry's own record. - **#749** (70fa5e2) — `looksLikePlaceholder()` filter excludes 16 garbage purposes (`{Brief...}`, `{{TASK_TITLE}}`, `${context.componentName}`). - **#750** (21782cc) — Installer honors `--ci` / `--yes` / `--skipPrompts` flags at the CLAUDE.md merge prompt. Non-interactive runs no longer block waiting for keyboard input. Closes #739 Bug 1. ## Version sites bumped (5 — up from 4 in the previous SOP) - `package.json` (root): 5.2.6 → 5.2.7 - `compat/aiox-core/package.json`: version + dep["@aiox-squads/core"] 5.2.6 → 5.2.7 - `packages/installer/package.json`: 3.3.5 → 3.3.6 (#750 touched installer src) - `.aiox-core/package.json` (internal): 5.2.6 → 5.2.7 (validate-aiox-core-namespace enforces lockstep with root — new in 5.2.7, first release under the gate) - `package-lock.json` refresh - `CHANGELOG.md`: new [5.2.7] entry - `docs/guides/release-procedure.md`: bump the "4 sites" rule to "5 sites" reflecting the validate-aiox-core-namespace gate added in PR #746 ## Validation - `npm run lint` → exit 0 - `npm run test:ci` → 8510 passed (151 skipped), 344/355 suites, 229s - `npx jest tests/installer/ --no-coverage` → 276/276 pass - `npm run validate:publish` → PASS (12911 files; namespace sync verified) Pro install hijack fix (#742) shipped in 5.2.6 and remains in production — this release does not re-iterate it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: address CodeRabbit nitpick on release-procedure.md lockstep wording PR #751 CodeRabbit review flagged that the "Bump all five version sites in lockstep" wording was ambiguous — the table below explicitly treats `packages/installer/package.json` as conditional ("patch bump if installer changed; otherwise leave"). Operators reading only line 36 could over-bump the installer. Reworded to distinguish: - Root + internal manifest + compat: MUST stay in lockstep at same version - packages/installer: bumped ONLY when installer source changed (not every release) Also explicit on the two failure-mode detection layers: - Smoke tests (catch silent publish mismatches) - validate-aiox-core-namespace.js wired into validate:publish (rule 4 enforces lockstep) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…json (SynkraAI#742) * fix(installer): isolate Pro install from ancestor workspaces/package.json Cohort students hit "Pro activation failed: Installed Pro artifact did not create node_modules/@aiox-squads/pro" even though npm install exits 0 and the upstream Pro license activation completes successfully. Root cause: installProArtifactIntoTarget runs `npm install <tgz>` in targetDir without --prefix or --workspaces=false. npm 10+ walks the directory tree, finds the first ancestor with a package.json (or one declaring workspaces), and installs node_modules there instead of in the target. The post-install integrity check then fails because the artifact is in the wrong place, not because it never downloaded. This was reproduced locally in 4 install topologies before patching, then proved by running the new test suite against pre-fix code — the two ancestor-hijack scenarios fail cleanly without the fix: 1. workspace declared in ancestor → npm installs at workspace root (FAILS pre-fix) 2. plain package.json in ancestor → npm installs at ancestor (FAILS pre-fix) 3. empty targetDir, clean ancestor → works (current happy path) 4. targetDir with own package.json → works (current happy path) Fixes applied: * installProArtifactIntoTarget: pass --prefix=targetDir + --workspaces=false + --include-workspace-root=false; create a synthetic anchor package.json if targetDir is empty, then clean it up after. * extractProArtifactToTemp: mirror the same flags to harden the temp extraction (it never failed in practice because os.tmpdir() has no ancestors with package.json, but the asymmetry was fragile). * acquireProArtifactSourceDir: when the target install fails, fall back to the extracted (sha256-verified) Pro source from tempRoot and emit a warning instead of bricking the wizard. The scaffolder copies files from the source dir, so the target install is a convenience, not a requirement. The warning is explicit that subsequent `aiox install` calls in the same directory will re-download Pro until the user runs from a fresh empty directory. * New diagnostic helper findAncestorNodeModulesPro walks up to 8 levels looking for a stray install, included in the user-facing error so students can see where npm actually put the package. Tests added: tests/installer/pro-setup-target-install.test.js — 8 regression tests covering all four install topologies, the synthetic anchor cleanup, the diagnostic helper (positive + negative cases), and the graceful fallback contract in acquireProArtifactSourceDir. Integration-style: builds a minimal fixture tarball at runtime via `npm pack`, no external dependencies, no Supabase credentials needed. CI added: .github/workflows/installer-smoke-matrix.yml — runs the regression suite + three end-to-end smoke installs (empty target, nested in workspace, nested under plain package.json) on Ubuntu/macOS/ Windows with Node 18/20/22 and npm 8/10/11. Triggers on packages/installer/** and tests/installer/** changes, breaking the "11 fixes to pro-setup.js in 30 days, each catching a new edge case" pattern by validating the install surface itself before publish. Cleared the dead fallback path in acquireProArtifactSourceDir that was already wired (`installedProSourceDir || extractedProSourceDir`) but unreachable because the throw in installProArtifactIntoTarget short- circuited it. Affected story: PRO-13.6 (signed artifact pipeline) Builds on: SynkraAI#735 (Windows npm spawn), PRO-13.5 (private distribution) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(installer-smoke): address CodeRabbit feedback on PR SynkraAI#742 * Use platform-aware npm binary (npm.cmd on Windows) in the test fixture tarball builder and the 3 inline smoke install scripts in installer-smoke-matrix.yml. Mirrors the pattern in pro-setup.js' resolveNpmInvocation. Without this, the Windows job fixed below would fail at the `execFileSync('npm', ...)` call. * Replace the cross-product matrix with an explicit `include:` list and drop combos that are structurally invalid (and were failing CI on the first run): Node 18 + npm 11 (npm 11 requires Node >= 20.17), Node 20 + npm 8 (npm 8 too old to honor --workspaces=false reliably), and the redundant npm 11 re-pin on Node 22 (already ships with npm 11; the re-pin via `npm install --global` conflicts with the bundled install on GitHub-hosted runners). Added a new `bundled` mode that skips the pin step entirely. * Coverage retained: Ubuntu (Node 18/20/22 × npm 10/11/bundled), macOS (Node 20/22), Windows (Node 20/22). 8 combos total, all valid. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…SynkraAI#743) Hotfix release for SynkraAI#742 (already merged). Bumps: * @aiox-squads/core: 5.2.5 → 5.2.6 * aiox-core (compat wrapper): 5.2.5 → 5.2.6 + dependency @aiox-squads/core: 5.2.5 → 5.2.6 * @aiox-squads/installer: 3.3.4 → 3.3.5 Pushing tag v5.2.6 triggers .github/workflows/npm-publish.yml which publishes to npmjs.org using NPM_TOKEN_AIOX_SQUADS. After publish, students hit by "Installed Pro artifact did not create node_modules/@aiox-squads/pro" can update via: npx -y -p @aiox-squads/core@latest aiox install without the previously recommended fresh-directory workaround. Includes: - package-lock.json refreshed to 5.2.6 - CHANGELOG.md entry under [5.2.6] - 2026-05-17 - .aiox-core/data/entity-registry.yaml regenerated by pre-commit hook (757 → 815 entities — incidental sync, not caused by this release) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…leshooting (SynkraAI#745) * docs: align ecosystem with release-procedure SOP + Issue 10 troubleshooting Cross-cutting cleanup so the operator/student/agent ecosystem references the canonical release SOP (introduced in PR SynkraAI#744) consistently and exposes the npm-hijack troubleshooting path to students. ## docs/guides/installation-troubleshooting.md Added Issue 10: "Pro activation failed: Installed Pro artifact did not create node_modules/@aiox-squads/pro" — the exact error that affected cohorts for 30 days before PR SynkraAI#742 shipped. Documents symptom, root cause (npm hijack into ancestor with package.json/workspaces), fix (5.2.6+), and a two-tier recovery procedure (simple retry first, then cache cleanup + residual-install removal if state is fouled). ## docs/guides/aiox-pro-access.md "Erros comuns" section gains an explicit entry for the install failure with a direct link to Issue 10 above. Previously the guide only covered auth-side errors; students hitting the install-side error googled into silence. ## .aiox-core/development/tasks/publish-npm.md ## .aiox-core/development/tasks/release-management.md Both converted to slim wrappers that delegate to docs/guides/release-procedure.md as the authoritative source. The full procedures previously inlined here (757 and 257 lines respectively) were missing the gotchas paid for in 11 patches across 30 days: two- system branch protection bypass, publish race conditions, Windows path escape in node -e, npm CDN propagation budget, payload sanitization for ruleset PUT, trap EXIT for atomic restore. Maintaining the full content in two files would have drifted immediately; the wrappers keep the task IDs that agent workflows reference while pointing at the one source of truth. ## .aiox-core/development/agents/devops.md Added a "Release Procedure (NON-NEGOTIABLE Reference)" section to the DevOps Guide. When @devops is invoked for a release, push, or publish that ends with a tag push to @aiox-squads/*, the agent now has explicit instruction to load and follow the SOP. Captures the institutional memory items most likely to bite (two-system protection, 4-site version bump, publish_legacy race, smoke timeout, Windows path escape) so the agent does not re-discover them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: address CodeRabbit feedback on PR SynkraAI#745 Four real issues caught: 1. devops.md L584 referenced `*publish` which is not in the agent's declared commands list. Replaced with `*push` followed by version-bump intent, which matches the actual command surface. 2. release-management.md L43 + publish-npm.md L32 + release-procedure.md L170 had `git tag -a vX.Y.Z origin/main -m "<notes>"` — options mixed with positional args. Reordered to `git tag -a -m "<notes>" vX.Y.Z origin/main` (options before tag name, ref last) as the idiomatic form. Both forms work in modern git, but the linted form is more robust against argument parsing edge cases. 3. installation-troubleshooting.md L260: fenced output block was missing language tag — failing MD040 linter. Added `text`. 4. installation-troubleshooting.md L276 (CodeRabbit nitpick, addressed in full): the cleanup snippets were bash-only and assumed macOS/Linux. Students hitting the original error on Windows had no recovery path. Added labelled PowerShell and Command Prompt variants alongside the bash version, all three with equivalent behavior: purge stray `node_modules/@aiox-squads/pro` directories + clear the npx cache + retry the install with `-p @aiox-squads/core@latest`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…m 5.2.6 (SynkraAI#751) * chore(release): bump to 5.2.7 — consolidate PRs SynkraAI#744-SynkraAI#750 from 5.2.6 Consolidates 7 PRs merged after the 5.2.6 release. None of them required an immediate hotfix on their own, but together they unblock cohort students from a real CI/CD failure mode (SynkraAI#739 Bug 1) and remove three sources of registry drift. ## What ships in 5.2.7 - **SynkraAI#744** (d949918) — Pipeline hardening: `publish_legacy_aiox_core` race fix, smoke timeout 90s→240s with dual visibility check, structured notify summary, Windows path escape fix via WORKSPACE_DIR env var. Plus the canonical `docs/guides/release-procedure.md` SOP. - **SynkraAI#745** (b728a39) — Ecosystem alignment: `installation-troubleshooting.md` Issue 10 (install-side recovery for the npm-hijack symptom), aiox-pro-access.md link, slim wrappers for publish-npm.md/release-management.md tasks pointing at the SOP, devops.md Release Procedure section. - **SynkraAI#746** (dea939e) — Internal `.aiox-core/package.json` rebranded `@aiox-fullstack/core@4.31.1` → `@aiox-squads/core-internal@5.2.7` (private, no phantom peerDeps). New `scripts/validate-aiox-core-namespace.js` (5-rule gate) wired into `validate:publish`. Closes SynkraAI#739 Bug 2. - **SynkraAI#747** (e874103) — 70 substitutions across 17 files realigning legacy `aiox-core/{templates,checklists,agents,tasks,workflows,agent-teams}/<X>` references to current `.aiox-core/...` layout. Unblocks `@po *validate-story-draft`. Closes SynkraAI#741. - **SynkraAI#748** (e8f8761) — IDS `extractPurpose()` rewritten as strict priority chain (frontmatter → ## Purpose → ## Overview → # Title → fallback). Removed body-level regex that picked up example transcripts as purposes. New `syncSelfRegistryEntry()` writes sentinel `sha256:<self-reference>` checksum for the registry's own record. - **SynkraAI#749** (6113083) — `looksLikePlaceholder()` filter excludes 16 garbage purposes (`{Brief...}`, `{{TASK_TITLE}}`, `${context.componentName}`). - **SynkraAI#750** (1d16b51) — Installer honors `--ci` / `--yes` / `--skipPrompts` flags at the CLAUDE.md merge prompt. Non-interactive runs no longer block waiting for keyboard input. Closes SynkraAI#739 Bug 1. ## Version sites bumped (5 — up from 4 in the previous SOP) - `package.json` (root): 5.2.6 → 5.2.7 - `compat/aiox-core/package.json`: version + dep["@aiox-squads/core"] 5.2.6 → 5.2.7 - `packages/installer/package.json`: 3.3.5 → 3.3.6 (SynkraAI#750 touched installer src) - `.aiox-core/package.json` (internal): 5.2.6 → 5.2.7 (validate-aiox-core-namespace enforces lockstep with root — new in 5.2.7, first release under the gate) - `package-lock.json` refresh - `CHANGELOG.md`: new [5.2.7] entry - `docs/guides/release-procedure.md`: bump the "4 sites" rule to "5 sites" reflecting the validate-aiox-core-namespace gate added in PR SynkraAI#746 ## Validation - `npm run lint` → exit 0 - `npm run test:ci` → 8510 passed (151 skipped), 344/355 suites, 229s - `npx jest tests/installer/ --no-coverage` → 276/276 pass - `npm run validate:publish` → PASS (12911 files; namespace sync verified) Pro install hijack fix (SynkraAI#742) shipped in 5.2.6 and remains in production — this release does not re-iterate it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: address CodeRabbit nitpick on release-procedure.md lockstep wording PR SynkraAI#751 CodeRabbit review flagged that the "Bump all five version sites in lockstep" wording was ambiguous — the table below explicitly treats `packages/installer/package.json` as conditional ("patch bump if installer changed; otherwise leave"). Operators reading only line 36 could over-bump the installer. Reworded to distinguish: - Root + internal manifest + compat: MUST stay in lockstep at same version - packages/installer: bumped ONLY when installer source changed (not every release) Also explicit on the two failure-mode detection layers: - Smoke tests (catch silent publish mismatches) - validate-aiox-core-namespace.js wired into validate:publish (rule 4 enforces lockstep) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Hotfix para o erro recorrente que vem travando alunos das cohorts no
aiox install(Pro flow):A licença ativa, o sha256 bate, o
npm installretorna exit 0 — e mesmo assim o check de integridade do post-install falha.Root cause
installProArtifactIntoTarget(packages/installer/src/wizard/pro-setup.js:814) rodanpm install <tgz>sem--prefixnem--workspaces=false. npm 10+/11 sobe a árvore de diretórios procurando o primeiropackage.jsonancestral (ouworkspaces:declarado) e instalanode_moduleslá em vez dotargetDir. O check pós-install emtargetDir/node_modules/@aiox-squads/pro/package.jsonfalha porque o artefato foi parar em outro lugar.Reproduzido localmente em 4 topologias de install antes do fix, depois provado rodando a nova suite de tests contra o código pre-fix — os dois cenários de hijack falham cleanly sem o fix:
What changed
installProArtifactIntoTarget: passa--prefix=targetDir+--workspaces=false+--include-workspace-root=false. Cria umpackage.jsonanchor sintético se otargetDirestiver vazio e remove nofinally.extractProArtifactToTemp: mesmos flags por simetria — nunca falhou em prática porqueos.tmpdir()não tem ancestrais compackage.json, mas a assimetria era frágil.acquireProArtifactSourceDir: quando o install no target falha, faz fallback graceful ao Pro source já extraído e sha256-verificado notempRoot, emitindo warning explícito em vez de bloquear o wizard. O scaffolder copia arquivos do source dir, então o install no target é conveniência, não pré-requisito. A warning é explícita sobre re-download em chamadas futuras.findAncestorNodeModulesPropercorre até 8 níveis pra cima procurando install perdido — incluído na mensagem de erro pra que o aluno veja onde npm realmente colocou o pacote.Tests
tests/installer/pro-setup-target-install.test.js— 8 regression tests:acquireProArtifactSourceDirIntegration-style: builda um tarball fixture mínimo em runtime via
npm pack, sem dependências externas, sem credenciais Supabase.Validação: rodei a suite contra o pro-setup.js pre-fix (
git checkout f949b42d -- pro-setup.js) e os 2 tests de hijack falharam conforme esperado. Provei que os tests pegam o bug que dizem pegar.CI
.github/workflows/installer-smoke-matrix.yml— matrix:Roda regression suite + 3 smoke installs end-to-end (empty target, nested em workspace, nested sob plain package.json) ANTES de qualquer publish. Trigger em
packages/installer/**etests/installer/**.Existe pra quebrar o padrão "11 fixes em
pro-setup.jsem 30 dias, cada um pegando um edge case novo" — agora a superfície de install é validada antes do release.Test plan
npx jest tests/installer/ --no-coverage→ 259/259 verdenpx eslint packages/installer/src/wizard/pro-setup.js tests/installer/pro-setup-target-install.test.js→ cleaninstaller-smoke-matrix.ymldeve validar em Ubuntu/macOS/Windows × Node 18/20/22 × npm 8/10/11 quando este PR rodar CIImpact
5.2.5→5.2.6) — fix only, no behavior change for happy pathaiox installem diretório fresh sem ancestrais (mkdir ~/aiox-pro && cd ~/aiox-pro && npx -y -p @aiox-squads/core@latest aiox install)🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests