Repository navigation
fix(release): musl activation node + Codex MCP adapter env — replay-proven green - #2691
Conversation
fix(release): musl adapter host-uid execution (dev twin)
…usl adapter v5.260726.11 got further than any release yet: only 'candidate real-PTY setup exited 1' on musl remains, and the harness's error surfaced nothing (empty stderr, echoed 'yes' on stdout). Mirror capturePtySetup's Linux path in the smoke — script(1) PTY, stdin confirmation, CI emptied — with both streams captured to files so the actual container error is visible in PR checks instead of costing a release cycle to observe.
…R checks The N-based PTY leg passes, so the v5.260726.11 failure needs the real candidate and harness state. Replay the exact entry-runner invocation with the failed run's own artifact set (previous release, signed musl candidate, manifests, descriptors, endorsement) on ubuntu-latest, mirroring the dogfood job's environment step for step — the real error surfaces in this PR's checks instead of costing a release cycle.
The real-PTY stage merges child stderr into the transcript and an early spawn-chain death produces almost nothing, so the truncated one-line error (historically just the echoed 'yes') hid which link failed across two release cycles. Include exe, argv, and both streams with byte counts.
…ion H3 smoke requires v5.260726.11's last failure, made visible by the replay + stage-error instrumentation: the candidate's real-PTY setup reached activation and died at 'no Node executable found for the H3 smoke'. The H3 smoke resolves node from PATH (Bun.which) and the Alpine container had none — host runners have node preinstalled, which is why every host-native platform passed. Install nodejs in the bootstrap: every real Codex host has node (codex-cli is a Node program), so this is environmental fidelity, not a shim.
… adapter platforms
Codex spawns MCP servers with a sanitized environment; the thread/start
config declared command+args only, so DOGFOOD_ROOT never reached the
launcher and the musl execution adapter silently fell into probe mode —
read-only /candidate mount, no workdir, cwd=/ in the container — and
genie_board reported project-context-unavailable ('no Git worktree
contains /') where the stage expected project-database-unavailable.
Host-native platforms never noticed: they need no adapter environment.
The replay reproduced the v5.260726.11 musl failure at PR speed and validated both fixes (nodejs for the H3 smoke, DOGFOOD_ROOT in the MCP server config) against the run's real artifacts — green at run 30223292592. Its pinned artifacts expire within days, so it must not stay as a permanent check; the pattern lives in this branch's history for the next investigation. The self-sufficient probe/seeding/PTY legs remain.
|
Caution The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased. |
📝 WalkthroughWalkthroughThe PR aligns Genie plugin versions at ChangesPlugin release metadata
Musl adapter PTY smoke coverage
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant SmokeWorkflow
participant MuslAdapter
participant PTY
SmokeWorkflow->>MuslAdapter: invoke setup --codex
MuslAdapter->>PTY: run interactive command with confirmation
PTY-->>SmokeWorkflow: return exit status and captured stdout/stderr
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@tests/support/codex-dogfood-harness.ts`:
- Around line 899-908: Update CapturedCommand to retain the raw
stdout.byteLength and stderr.byteLength values before string conversion, then
use those byte-length fields in the diagnostic Error message instead of the
converted string lengths. Preserve the existing trimmed stream content and
invocation details.
🪄 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: ASSERTIVE
Plan: Pro Plus
Run ID: fbdf4bc5-da57-4fce-a3f3-af86dd665bb3
📒 Files selected for processing (10)
.claude-plugin/marketplace.json.github/workflows/musl-adapter-smoke.ymlpackage.jsonplugins/genie/.claude-plugin/plugin.jsonplugins/genie/.codex-plugin/plugin.jsonplugins/genie/package.jsonplugins/hermes-genie/plugin.yamlscripts/run-musl-dogfood.shtests/support/codex-dogfood-harness.tstests/support/codex-native-mcp-evidence.ts
| // Both complete streams, with byte counts: a PTY stage merges the child's | ||
| // stderr into the transcript and an early spawn-chain death can produce | ||
| // almost nothing, so a truncated one-liner (historically just the echoed | ||
| // "yes") hides which link failed. exe/argv identify the exact invocation. | ||
| throw new Error( | ||
| `${label} exited ${observation.exit}, expected ${expected}: ${observation.stderr.trim() || observation.stdout.trim()}`, | ||
| `${label} exited ${observation.exit}, expected ${expected}\n` + | ||
| ` exe: ${observation.executable}\n` + | ||
| ` argv: ${JSON.stringify(observation.argv)}\n` + | ||
| ` stderr[${observation.stderr.length}B]: ${observation.stderr.trim() || '<empty>'}\n` + | ||
| ` stdout[${observation.stdout.length}B]: ${observation.stdout.trim() || '<empty>'}`, |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
bun -e 'const value = "é"; console.log({ codeUnits: value.length, utf8Bytes: Buffer.byteLength(value, "utf8") })'Repository: automagik-dev/genie
Length of output: 198
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== locate file =="
fd -a 'codex-dogfood-harness\.ts$' . || true
echo "== relevant captures and error output =="
file="$(fd 'codex-dogfood-harness\.ts$' . | head -n1)"
if [ -n "${file:-}" ]; then
wc -l "$file"
sed -n '1,160p' "$file"
sed -n '820,930p' "$file"
fi
echo "== JS string length vs UTF-8 bytes probe =="
node - <<'JS'
const examples = ['é', '\ud800\udd00', 'éx: 8894\n'];
for (const s of examples) {
console.log(JSON.stringify({ s, codeUnits: s.length, utf8Bytes: Buffer.byteLength(s, 'utf8') }));
}
JSRepository: automagik-dev/genie
Length of output: 9361
Report actual stream byte lengths.
stdout and stderr are converted to strings before this comparison, so .length reports UTF-16 code units and can label non-ASCII or invalid UTF-8 as the wrong byte count. Keep the raw stdout.byteLength / stderr.byteLength values on CapturedCommand and use those in the error message.
🤖 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/support/codex-dogfood-harness.ts` around lines 899 - 908, Update
CapturedCommand to retain the raw stdout.byteLength and stderr.byteLength values
before string conversion, then use those byte-length fields in the diagnostic
Error message instead of the converted string lengths. Preserve the existing
trimmed stream content and invocation details.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 019917d6b4
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| DOGFOOD_ROOT="$ROOT" HOME="$ROOT/home" GENIE_HOME="$ROOT/genie-home" \ | ||
| CODEX_HOME="$ROOT/codex-home" TMPDIR="$ROOT/tmp" \ | ||
| GENIE_RELEASE_DOGFOOD=1 TERM=xterm CI= CODEX_THREAD_ID= \ | ||
| script -qec "'$ADAPTER' '$ROOT/genie-home/bin/genie' setup --codex" /dev/null \ |
There was a problem hiding this comment.
Seed delivery state before running the PTY setup smoke
Once .well-known/latest.json advances to a release containing the current delivery-gated setup, this invocation will exit before reaching the H3 smoke: the fixture only copies the binary and VERSION into GENIE_HOME (lines 49–53), while setup --codex requires both the canonical plugin payload and a matching authenticated delivery record (src/genie-commands/setup.ts:515-532). Consequently, future adapter-touching PRs will fail with payload-missing or delivery-incomplete rather than test Node availability; seed the full delivered generation and its authenticated record before invoking setup.
Useful? React with 👍 / 👎.
The last two musl defects, found and fixed at PR speed
A full-fidelity replay job (temporarily part of this branch) ran the real dogfood entry-runner with run 30220567504's own artifacts on ubuntu-latest, reproducing the v5.260726.11 failure exactly and validating each fix without a release cycle:
no Node executable found for the H3 smoke— the candidate's PTY activation resolves node from PATH (Bun.which); the Alpine container had none while host runners have it preinstalled. Fix:apk add nodejsin the adapter bootstrap (every real Codex host has node — codex-cli is a Node program).project-context-unavailable: no Git worktree contains /— codex spawns MCP servers with a sanitized environment; thethread/startconfig declared command+args only, soDOGFOOD_ROOTnever reached the launcher and the adapter silently fell into probe mode (cwd=/ in the container). Fix: declareDOGFOOD_ROOTin the MCP server config for adapter platforms.Plus: captured-stage failures now report exe, argv, and both complete streams with byte counts — the old truncated one-liner (literally just the echoed "yes") hid these defects across two release cycles.
Evidence
Replay run 30223292592: SUCCESS — the complete real musl entry (N verification, update lifecycle, PTY activation, all codex-native MCP evidence stages, evidence emission) with the real signed v5.260726.11 candidate. The pinned replay job is retired in the final commit (its artifacts expire); the self-sufficient probe/seeding/PTY smoke legs remain as permanent PR checks.
darwin/glibc/arm64 already pass in production (runs 30218355227, 30220567504). This is the last platform.
Sequencing
Main-first (harness + adapter execute from main). After this merges and main's CI push run completes, I merge the dev twin — that ordering avoids the bind-guard race that burned v5.260726.10.
Summary by CodeRabbit
New Features
Bug Fixes
Tests