Commit 38cfa89
* fix(quality-gates): cross-platform CodeRabbit CLI execution [#731]
Closes #731 (reported by @duboneh).
The CodeRabbit CLI execution paths were hardcoded to assume Windows + WSL
(`wsl bash -c '...'` wrapper, `/mnt/c/...` paths, `installation_mode: wsl`).
On macOS/Linux those commands failed silently and the Layer-2 quality-gate
automation never enforced the review. The auto-healing loop in @dev / @qa /
@devops / @architect / @data-engineer simulated success while doing nothing.
## What changed
Three patterns applied across runtime + config + agent surfaces:
### Pattern 1 — Inline cross-platform branching (runtime)
- `.aiox-core/core/orchestration/workflow-executor.js` (`runCodeRabbitAnalysis`)
- `.aiox-core/core/quality-gates/layer2-pr-automation.js` (`runCodeRabbit`)
- `.aiox-core/development/tasks/github-devops-pre-push-quality-gate.md`
(`runCodeRabbit` inline code block + error-handler messages)
Default behavior:
- `installation_mode || (process.platform === 'win32' ? 'wsl' : 'native')`.
- `cli_path` defaults to `~/.local/bin/coderabbit`.
- Explicit `installation_mode: 'wsl' | 'native'` still wins (lets ops force
WSL on macOS for testing, etc).
- Explicit raw `command:` string still wins over `cli_path` (back-compat).
Error-handler messages now switch on `process.platform`: macOS/Linux users
see native recovery commands, Windows users see WSL-wrapped ones.
### Pattern 2 — `wsl_config:` block → `cli_path:` + `platform_notes:`
DELETED `installation_mode: wsl` + `wsl_config:` blocks (no overlay; full
removal) from:
- `.aiox-core/core/quality-gates/quality-gate-config.yaml`
- `.aiox-core/development/agents/dev.md`
- `.aiox-core/development/agents/qa.md`
- `.aiox-core/development/agents/devops.md`
Replaced with:
```yaml
cli_path: ~/.local/bin/coderabbit
platform_notes:
macos_linux: "Run cli_path directly from project root (no wrapper)."
windows: "Wrap with 'wsl bash -c' and rewrite project paths to /mnt/<drive>/..."
```
### Pattern 3 — execution_guidelines rewritten neutral
Replaced "CRITICAL: CodeRabbit CLI is installed in WSL, not Windows" + the
"use 'wsl bash -c' wrapper for ALL commands" prescriptions with cross-platform
guidance in 5 agent personas (dev, qa, devops, architect, data-engineer).
`commands:` blocks now have explicit `_native` and `_wsl` template suffixes
so agents can see both shapes side-by-side.
ASCII workflow diagrams updated in:
- `.aiox-core/development/tasks/qa-review-story.md`
- `.aiox-core/development/tasks/dev-develop-story.md`
`environment-bootstrap.md` note also rewritten as cross-platform.
### Regression coverage
`tests/unit/quality-gates/cross-platform-coderabbit.test.js` — 8 tests:
- macOS (darwin) builds native command
- Linux builds native command
- Windows wraps with `wsl bash -c`
- Explicit `installation_mode: 'native'` override on Windows
- Explicit `installation_mode: 'wsl'` override on macOS
- Raw `command:` string override (back-compat)
- Custom `cli_path` honored on macOS
- Custom `cli_path` honored on Windows
Test suite: 8/8 pass.
### IDE projection sync
`npm run sync:ide` propagated the agent persona changes to:
- `.claude/skills/AIOX/agents/{...}/SKILL.md`
- `.codex/agents/*.md`
- `.gemini/rules/AIOX/agents/*.md`
- `.kimi/skills/aiox-{...}/SKILL.md`
109 files synced across 7 IDEs (claude-code, codex, gemini, github-copilot,
cursor, antigravity, kimi). Compatibility Parity Gate + IDE Command Sync
Validation should be green on this branch.
## Validation
- [x] `npm run lint` exit 0
- [x] `npx jest tests/unit/quality-gates/cross-platform-coderabbit.test.js` → 8/8 pass
- [x] `grep -rn 'installation_mode: wsl\b\|wsl_config:' .aiox-core/development/agents/*.md` → zero matches
- [x] All remaining `wsl bash -c` references are Windows-prefixed examples or `_wsl` template suffixes (verified manually)
- [x] `npm run sync:ide` clean — no projection drift
## Out of scope (separate follow-ups)
- The `Cross-Platform (${{ matrix.os }}, Node ${{ matrix.node }})` smoke
matrix check in CI is `skipping` (unexpanded YAML variable). Unrelated bug.
- `qa/MEMORY.md` mentions `installation_mode: wsl` but is a runtime memory
file, not config — intentionally left alone (per @advisor guidance).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(ids): regenerate entity-registry after [#731] agent persona changes
Pre-push hook regenerated the registry to reflect the cleanup in agent
personas (removed `installation_mode: wsl` / `wsl_config:` blocks, reworked
usedBy/dependencies for the coderabbit_integration sections). entityCount
815 → 816.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(quality-gates): address CodeRabbit feedback on PR #752 [#731]
Two real bugs CodeRabbit caught + one new regression test:
## Bug 1: ${PROJECT_ROOT} placeholder never expanded
`layer2-pr-automation.js` left `cd ${PROJECT_ROOT}` as a literal placeholder
in the WSL command string. `child_process.spawn` with `shell: true` only
expands env vars that ARE set — PROJECT_ROOT is never set at call sites,
so the cd target was empty and the command silently `cd`'d into the home
directory, then ran coderabbit there instead of in the project root.
Fix: substitute `process.cwd()` (or explicit `coderabbit.projectRoot`)
in-place and convert to `/mnt/<drive>/<path>` for the WSL host. The
resulting command now contains a real absolute path, matching what
`workflow-executor.js` already did via `this.projectRoot`.
## Bug 2: Tilde expansion not reliable in spawn contexts
Both `workflow-executor.js` (uses `child_process.exec`) and
`layer2-pr-automation.js` (uses `spawn { shell: true }`) shipped
`cli_path` literally as `~/.local/bin/coderabbit`. Shell expansion works
when the call goes through a real shell, but the `workflow-executor` path
goes through `execAsync` which is `/bin/sh -c` on POSIX (so OK) but is
host-dependent on Windows (cmd.exe does NOT expand `~`). Programmatic
expansion via `os.homedir() + path.join` removes the ambiguity.
Applied to:
- `.aiox-core/core/orchestration/workflow-executor.js`
- `.aiox-core/core/quality-gates/layer2-pr-automation.js`
- `.aiox-core/development/tasks/github-devops-pre-push-quality-gate.md`
(kept in sync — same pattern in the doc's inline JS block)
## Regression test added
`cross-platform-coderabbit.test.js`:
- "converts Windows project root to /mnt/<drive>/... inside wsl command"
- "expands tilde (~) in cli_path via os.homedir() — defensive"
Full suite: 10/10 pass (was 8 — +2 new).
## CodeRabbit feedback not addressed (with reason)
- **Helper extraction**: deferred. Two call sites + 16 lines duplicated is
cheaper to maintain than a new module + import paths + test surface.
Per advisor guidance — premature abstraction.
- **WSL availability check on Windows**: deferred to a separate issue.
If `wsl` is not installed on Windows, the user already sees a clear
`'wsl' is not recognized` error from cmd. Adding a `spawnSync('wsl',
['-l'])` probe before every CodeRabbit invocation costs latency on every
call and replaces one error message with another. Not a regression
introduced by this PR.
- **Entity-registry dependency cleanup**: the `dependencies: []` zeroed
on agent personas is a CORRECT consequence of removing `wsl_config:` +
`installation_mode: wsl` blocks. Those blocks named phantom dependencies
(Ubuntu distribution, /mnt paths) that the registry interpreted as
edges. Removing the source removed the edges. The registry is consistent
with the post-fix state.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(quality-gates): CodeRabbit round 2 — WSL tilde + lowercase drive [#731]
Two more real bugs CodeRabbit caught on the round-1 fix:
## Bug 3: Pre-expanded tilde poisons the WSL command
Round-1 expanded `~` via `os.homedir()` unconditionally — but on Windows
that yields `C:\Users\<user>` (a Windows path). Injecting that into a
`wsl bash -c '...'` command means the cd path inside WSL points at a
Windows path the WSL distribution cannot resolve. The previous round
moved the bug, didn't fix it.
Fix: split the cli_path handling by mode.
- **native mode** (macOS/Linux): expand `~` via `os.homedir() +
path.join(...)`. The resolved absolute path is shell-agnostic.
- **WSL mode** (Windows or explicit override): keep the literal `~`.
The WSL distribution's own bash expands it to the WSL user's HOME
(`/home/<wsl-user>`) — the only correct expansion in that context.
## Bug 4: Drive-letter regex only matched uppercase
`/^([A-Z]):/` rejects `c:\path` (lowercase drive letter from
`process.cwd()` on some configurations / npm test environments).
Changed to `/^([A-Za-z]):/`. Replacement still lowercases the captured
drive (per WSL convention `/mnt/c/...`).
Applied to all three call sites.
## Regression coverage
`cross-platform-coderabbit.test.js` — 2 new tests + 1 reshape:
- "handles lowercase drive letters when converting to /mnt/<drive>/..."
- "keeps tilde (~) literal in cli_path in WSL mode — bash expands it inside WSL"
- "wraps the command... (win32)" now asserts the host's homedir-prefixed
cli_path does NOT appear in the WSL command (more precise than the
previous "no homedir" check which was incidentally tripped by cwd).
Full suite: 12/12 pass (was 10 — +2 new).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(manifest): regenerate install-manifest hash for entity-registry [#731]
CI's Install Manifest Validation step failed because the IDS-Hook
regenerated `entity-registry.yaml` in the pre-push (after the round-2
commit) but the matching hash in `install-manifest.yaml` was not
updated. `npm run generate:manifest` corrects the drift.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 536bda9 commit 38cfa89
35 files changed
Lines changed: 1058 additions & 828 deletions
File tree
- .aiox-core
- core
- orchestration
- quality-gates
- data
- development
- agents
- tasks
- .claude/skills/AIOX/agents
- architect
- data-engineer
- devops
- dev
- qa
- .codex/agents
- .gemini/rules/AIOX/agents
- .kimi/skills
- aiox-architect
- aiox-data-engineer
- aiox-devops
- aiox-dev
- aiox-qa
- tests/unit/quality-gates
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
778 | 779 | | |
779 | 780 | | |
780 | 781 | | |
781 | | - | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
782 | 794 | | |
783 | | - | |
784 | | - | |
785 | | - | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
786 | 801 | | |
787 | | - | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
788 | 806 | | |
789 | 807 | | |
790 | 808 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| |||
96 | 97 | | |
97 | 98 | | |
98 | 99 | | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
103 | 133 | | |
104 | 134 | | |
105 | 135 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
38 | 47 | | |
39 | 48 | | |
40 | 49 | | |
| |||
0 commit comments