feat(util): allowlisted env reader (B5) + test(integration): cross-family handoff matrix (B4) + 08-pi-mono comparison#26
Conversation
…odifications) COMPARISON.md, CODEX_BRIEFING.md, CODEX_RESPONSE.md, SYNTHESIS.md. Codex thread 019e12f0; verdict accept-with-modifications. Locked borrow set: B1 (renamed requestedModel/responseId), B2a/B2b split, B3 hardened to observer-only + wrapper-owned redactor, B4 12-pair offline matrix, B5 allowlisted env reader (not whole-env Map), B6 reframed as code-oz-original typed ProviderDiagnostic, B7 deferred behind compiled-binary keepalive test, B8 downgraded to model lifecycle guard. S1 catalog -> docs only; R1-R5 unchanged with R1 annotated demand-gated for meta-providers.
…tests (MR-1) Closes the block-push miss surfaced by Codex during the pi-mono comparison. Line 9 had drifted four milestones behind: it still described v0.13.0-alpha.0 / PE-1 closed / 1983 tests. Actual state is M16 production CLI completion (per-task cursor, dispatch build/verify/review under M14 + M15 authorities), W3-lite tarballs shipped at v0.14.0-alpha.0, and the package.json version is 0.17.0-alpha.0. Test count now reflects the bun test baseline (3108 pass / 1 skip). PE-1 trust-boundary discipline and live xAI gating language preserved.
…ck (B5)
Closes pi-mono borrow B5 with the synthesis MR-3 hardening (locked
in docs/comparison/08-pi-mono/SYNTHESIS.md). Pi-mono's getProcEnv
parses the entire /proc/self/environ into a Map and caches it; that
violates rule 13 by capturing every env var indefinitely.
This implementation:
- readEnv(allowedKeys: readonly string[]) -> Record<string,string>
- Reads process.env first.
- On Linux + Bun + Object.keys(process.env).length === 0 (the
oven-sh/bun#27802 empty-env signal), falls back to a one-shot,
allowlist-filtered read of /proc/self/environ for ONLY the
requested keys.
- No module-level cache.
- No log/serialize of unrelated vars.
- Never throws on /proc read failure.
7 Bun tests cover the API + the platform-skip fallback path.
…nt (B4)
Closes pi-mono borrow B4 (synthesis LD-2). Code-oz already runs
cross-family handoff in production at every M14 Reviewer panel
call and M10 Debate runtime round, but had no explicit test for
the round-trip. A future change to artifact projection, the M11
capability-routed wrapper, or the M14 panel fan-out could break
the property silently.
Implementation:
- tests/cross-family-handoff.test.ts uses a tiny in-test
FamilyAlias wrapper around a single shared FakeProvider so
each of {claude, codex, gemini, xai} reports its own (id,
family) without modifying src/providers/fake.ts.
- test.each parametrizes over the 12 directional family pairs
(4 ids x 3 not-self).
- For each pair: invoke source -> serialize assistant content +
tool_calls to an explicit artifact path -> invoke target with
only that path in req.files. Assert source family != target
family, byte-identical content survives, agent_invoked carries
the source provider id, target manifest contains only the
passed-in path (rule 13 + rule 18).
Test count: 3108 -> 3127 (12 new test.each cases + 7 from B5
util-env tests; full suite passes 3127 / 1 skip / 0 fail).
# Conflicts: # CLAUDE.md
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
✨ Finishing Touches🧪 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.
Code Review
This pull request adds a detailed comparison between code-oz and pi-mono, including synthesis documentation for future feature 'borrows'. It also introduces a new environment variable utility with a Linux-specific fallback for Bun and a cross-family handoff integration test. Feedback identifies an outdated test count in CLAUDE.md and suggests a more efficient single-pass implementation for reading the Linux environment buffer.
| `code-oz` is a standalone Bun + TypeScript CLI that boots an adaptive multi-agent software-company simulation over a hybrid phase-graph + agentic sub-orchestration spine. Hard SDLC gates between phases (file-based, schema-validated). Cross-family adversarial review. Non-technical-user intent elicitation at the front. Multi-provider via `IAgentProvider` (Claude / Codex / Gemini SDKs reading CLI OAuth tokens). | ||
|
|
||
| Status: **v0.17.0-alpha.0 — M16 closed.** Production CLI completion (per-task cursor, dispatch infra, milestone-level e2e through the binary): `code-oz run`, `approve`, and `doctor` are wired end-to-end across DEFINE → REVIEW; full `resume` command remains M17. 3108 offline tests pass (+402 across M16); live xAI gated behind `CODE_OZ_LIVE_PROVIDER_TESTS=xai` + `CODE_OZ_LIVE_XAI_MODEL=<grok-variant>`. M16 R0/R1/R2 closed (8 production bugs caught by C12 e2e + 4 by Codex R1; per-commit cross-model peer review pattern validated for shared infra). Latest tag pushed: `v0.17.0-alpha.0` (2026-05-10). | ||
| Status: **v0.17.0-alpha.0 — M16 closed and pushed.** Production CLI completion: per-task cursor (`bun run dev run`), build/verify/review dispatch under M14 Reviewer panel + M15 debate-policy scheduler authorities, exit-code discipline, prod seams, phase-locks, validators. M13 (role-cost policy under `budgets.global`) shipped alongside W3-lite tarballs at v0.14.0-alpha.0 (Mach-O `code-oz` darwin tarball; smoke 5/5; ralph-loop overnight closure 2026-05-02). PE-1 (xAI direct HTTP, OpenAI-compatible subset, strict request-body allowlist; trust-boundary discipline in `docs/references/provider-contract.md` § "Auth model — subprocess delegation + API-key transmission (v0.1)") shipped at v0.13.0-alpha.0; review trail in `docs/research/CODEX_REVIEW_PE1.md`. **3108 offline tests pass** (1 skip is the live xAI integration gated behind `CODE_OZ_LIVE_PROVIDER_TESTS=xai` + `CODE_OZ_LIVE_XAI_MODEL=<grok-variant>`). PE-2 demand-gated; M17+ pending milestone planning. |
| function readAllowedProcEnv(allowedKeys: readonly string[]): Record<string, string> { | ||
| let environ: Buffer | ||
| try { | ||
| environ = readFileSync(PROC_SELF_ENVIRON) | ||
| } catch { | ||
| return {} | ||
| } | ||
|
|
||
| const values: Record<string, string> = {} | ||
| const seen = new Set<string>() | ||
| for (const key of allowedKeys) { | ||
| if (seen.has(key)) { | ||
| continue | ||
| } | ||
| seen.add(key) | ||
|
|
||
| const value = findProcEnvValue(environ, key) | ||
| if (value !== undefined) { | ||
| values[key] = value | ||
| } | ||
| } | ||
| return values | ||
| } | ||
|
|
||
| function findProcEnvValue(environ: Buffer, key: string): string | undefined { | ||
| if (key === '' || key.includes('=')) { | ||
| return undefined | ||
| } | ||
|
|
||
| const needle = Buffer.from(`${key}=`, 'utf8') | ||
| let offset = 0 | ||
|
|
||
| while (offset < environ.length) { | ||
| const match = environ.indexOf(needle, offset) | ||
| if (match === -1) { | ||
| return undefined | ||
| } | ||
|
|
||
| if (match === 0 || environ[match - 1] === 0) { | ||
| const valueStart = match + needle.length | ||
| const nul = environ.indexOf(0, valueStart) | ||
| const valueEnd = nul === -1 ? environ.length : nul | ||
| return environ.subarray(valueStart, valueEnd).toString('utf8') | ||
| } | ||
|
|
||
| offset = match + 1 | ||
| } | ||
|
|
||
| return undefined | ||
| } |
There was a problem hiding this comment.
The current implementation of readAllowedProcEnv is inefficient as it performs a full buffer scan for every key in allowedKeys (O(K * E)). A single-pass approach iterating through the null-terminated records in /proc/self/environ is more efficient and simplifies the logic by removing the need for findProcEnvValue.
function readAllowedProcEnv(allowedKeys: readonly string[]): Record<string, string> {
let environ: Buffer
try {
environ = readFileSync(PROC_SELF_ENVIRON)
} catch {
return {}
}
const allowedSet = new Set(allowedKeys)
const values: Record<string, string> = {}
let start = 0
while (start < environ.length) {
const end = environ.indexOf(0, start)
const limit = end === -1 ? environ.length : end
const entry = environ.subarray(start, limit)
const eqIdx = entry.indexOf(61) // '='
if (eqIdx !== -1) {
const key = entry.subarray(0, eqIdx).toString('utf8')
if (allowedSet.has(key)) {
values[key] = entry.subarray(eqIdx + 1).toString('utf8')
}
}
if (end === -1) break
start = end + 1
}
return values
}There was a problem hiding this comment.
Pull request overview
Adds an allowlisted environment-variable reader (with a Linux Bun /proc/self/environ fallback) and expands offline test coverage around cross-family REVIEW handoffs, alongside documentation updates capturing the “08 pi-mono” comparison packet and updating project status/index docs.
Changes:
- Introduce
readEnv(allowedKeys)insrc/util/env.ts, including a Bun-on-Linux/proc/self/environfallback that only decodes allowlisted keys. - Add offline tests: env allowlist behavior and a 12-direction cross-family assistant-message handoff matrix using
FakeProvider. - Update comparison index/docs for the new “08 pi-mono” session and refresh
CLAUDE.mdstatus text.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/util-env.test.ts | New unit tests for allowlisted env reads via readEnv. |
| tests/cross-family-handoff.test.ts | New offline matrix test asserting cross-family REVIEW handoff invariants + byte-preserving file manifest handoff. |
| src/util/env.ts | New allowlisted env reader with /proc/self/environ fallback under Bun/Linux empty-env condition. |
| docs/comparison/README.md | Adds row for 08 pi-mono and removes pi-mono from backlog list. |
| docs/comparison/08-pi-mono/SYNTHESIS.md | Adds the pi-mono synthesis/decision record. |
| docs/comparison/08-pi-mono/COMPARISON.md | Adds the pi-mono comparison writeup (initial analysis). |
| docs/comparison/08-pi-mono/CODEX_BRIEFING.md | Adds the debate prompt captured for Codex. |
| docs/comparison/08-pi-mono/CODEX_RESPONSE.md | Adds the verbatim Codex response captured for the session. |
| CLAUDE.md | Updates the project status line/details. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function shouldReadProcEnv(): boolean { | ||
| return process.platform === 'linux' | ||
| && process.versions?.bun !== undefined | ||
| && Object.keys(process.env).length === 0 | ||
| } |
| const fake = new FakeProvider({ strict: true }) | ||
| const aliases = makeAliases(fake) | ||
| const registry = new ProviderRegistry({ providers: aliases }) | ||
| const aliasById = new Map(aliases.map((alias) => [alias.id, alias])) | ||
|
|
| --- | ||
| template: pi-mono | ||
| template-path: ~/Projects/agents/templates/pi-mono | ||
| template-status: audited (CLAUDE.md influence library row "pi-mono → Streaming event model + multi-provider abstraction") | ||
| session: 2026-05-10 |
| ## What ships from this comparison (acceptance gates per item) | ||
|
|
||
| Nothing ships from the comparison itself — this is research, not implementation. Locked decisions become inputs to: | ||
|
|
||
| - **Next M13 follow-up commit** picks up B2a + the `cacheSessionId` privacy invariant test. |
| `code-oz` is a standalone Bun + TypeScript CLI that boots an adaptive multi-agent software-company simulation over a hybrid phase-graph + agentic sub-orchestration spine. Hard SDLC gates between phases (file-based, schema-validated). Cross-family adversarial review. Non-technical-user intent elicitation at the front. Multi-provider via `IAgentProvider` (Claude / Codex / Gemini SDKs reading CLI OAuth tokens). | ||
|
|
||
| Status: **v0.17.0-alpha.0 — M16 closed.** Production CLI completion (per-task cursor, dispatch infra, milestone-level e2e through the binary): `code-oz run`, `approve`, and `doctor` are wired end-to-end across DEFINE → REVIEW; full `resume` command remains M17. 3108 offline tests pass (+402 across M16); live xAI gated behind `CODE_OZ_LIVE_PROVIDER_TESTS=xai` + `CODE_OZ_LIVE_XAI_MODEL=<grok-variant>`. M16 R0/R1/R2 closed (8 production bugs caught by C12 e2e + 4 by Codex R1; per-commit cross-model peer review pattern validated for shared infra). Latest tag pushed: `v0.17.0-alpha.0` (2026-05-10). | ||
| Status: **v0.17.0-alpha.0 — M16 closed and pushed.** Production CLI completion: per-task cursor (`bun run dev run`), build/verify/review dispatch under M14 Reviewer panel + M15 debate-policy scheduler authorities, exit-code discipline, prod seams, phase-locks, validators. M13 (role-cost policy under `budgets.global`) shipped alongside W3-lite tarballs at v0.14.0-alpha.0 (Mach-O `code-oz` darwin tarball; smoke 5/5; ralph-loop overnight closure 2026-05-02). PE-1 (xAI direct HTTP, OpenAI-compatible subset, strict request-body allowlist; trust-boundary discipline in `docs/references/provider-contract.md` § "Auth model — subprocess delegation + API-key transmission (v0.1)") shipped at v0.13.0-alpha.0; review trail in `docs/research/CODEX_REVIEW_PE1.md`. **3108 offline tests pass** (1 skip is the live xAI integration gated behind `CODE_OZ_LIVE_PROVIDER_TESTS=xai` + `CODE_OZ_LIVE_XAI_MODEL=<grok-variant>`). PE-2 demand-gated; M17+ pending milestone planning. |
Summary
Doc + targeted-code subset of the pi-mono comparison borrow set landed under the Codex
accept-with-modificationsverdict (thread019e12f0). Four commits + merge from origin/main:claude/codex/gemini/xai, using thebuildProviderRegistry({ providerOverride: 'fake' })family-aliasing seam.src/util/env.ts) with Bun/proc/self/environfallback. Reads only declared keys, never the whole environment as a Map (rule-13 privacy-by-default).v0.17.0-alpha.0 / M16 / 3108 tests.COMPARISON.md,CODEX_BRIEFING.md,CODEX_RESPONSE.md,SYNTHESIS.mdcapturing the seven accepted modifications (B2 split, B3 hardening, B5 allowlist, B6 reframe, B7 deferral, B8 downgrade, S1 deferral) and demand-gated R1 annotation.Merged origin/main on top to absorb 11 PRs that landed earlier today (#12-#22). Conflicts resolved: CLAUDE.md status line (kept this branch's pi-mono-era line; rule-1 expansion and rule-16 persona paragraph from main preserved);
docs/comparison/README.md(new file from main, appended 08-pi-mono row, removed pi-mono from backlog).Verification
bun test-> 3196 pass / 2 skip / 0 fail (was 3108 before merge; +88 from the new B4 matrix + B5 fallback tests plus the union of origin/main's new suites).CODE_OZ_LIVE_PROVIDER_TESTS=xai+CODE_OZ_LIVE_XAI_MODEL).Test plan
bun testpasses offlinedocs/comparison/README.mdhas the 08-pi-mono row and removes pi-mono from the backlog list