Conversation
…igration * ts(slice-17, wip 1/N): port peer-call/codex (.sh→.ts) Third sibling of the peer-call cluster (after grok #896 and gemini #898). Wraps 'codex exec -s read-only --skip-git-repo-check' (default) or 'codex review' (with --review). --model is ignored in --review mode with a warning to stderr. Bakes in all the round-2 + round-3 fixes from the gemini.ts review cycle: - exit codes 0/1/2 uniform per tools/peer-call/README.md (NOT 64) - commandAvailable via /bin/sh -c 'command -v <cmd>' (PATH check, not --version) - /bin/bash -c (not /bin/sh -c) for context-cmd to preserve bash-only feature support (Codex P2) - ReadHeadResult { ok, content, error } so file-read failures surface to stderr instead of silently dropping context - classifySpawnFailure 4-case helper (status / ENOENT → 127 / signal / other) reused from PR #887 + slice-16 #898 - Concat stdout + stderr from runContextCmd to preserve shell parse errors that fall outside the inner ( ) 2>&1 redirect Lint-clean: bun --bun tsc --noEmit + eslint strictTypeChecked + sonarjs all pass. Argument-validation byte-equivalent. Note: same CodeQL js/indirect-command-line-injection alert will fire here as on grok.ts and gemini.ts. Per B-0107 (filed in PR #897) the per-PR dismissal pattern applies until B-0107 implements the structural fix.
There was a problem hiding this comment.
Pull request overview
Ports the codex peer-call wrapper from bash to TypeScript/Bun, aligning it with the existing grok.ts and gemini.ts sibling scripts in tools/peer-call/ as part of the ongoing TS/Bun migration.
Changes:
- Add
tools/peer-call/codex.tsimplementing the Codex peer-call wrapper viacodex exec(default) andcodex review(via--review). - Reuse the shared peer-call patterns: uniform exit codes (0/1/2),
command -vavailability check,ReadHeadResultfor file context reads, and spawn failure classification.
AceHack
added a commit
that referenced
this pull request
Apr 30, 2026
…ull-stream guards + header phrasing Three Copilot findings on #901: P0 — spawnSync launch failures collapsed into exitCode 1: Added classifySpawnFailure helper (4-case: status set / ENOENT → 127 / signal / other) reused from PRs #887, #898, #900. Both runSnapshotBurn and runProjectRunway now report a contextual note when the child can't start (e.g., 'snapshot-burn.sh: command not found on PATH (ENOENT)'). P0 — null stdout/stderr could yield 'nullnull': When a child fails to start, result.stdout / result.stderr can be null even with encoding: 'utf8'. Guarded with `?? ''` in runProjectRunway so the projection block doesn't end up as the literal string 'nullnull'. P2 — Header comment phrasing: Reworded 'snapshot-burn.sh ported in #894' to 'TS port snapshot-burn.ts landed in #894 but this wrapper still spawns the .sh during the soak period' to avoid implying the .sh file itself is the ported artifact.
AceHack
added a commit
that referenced
this pull request
Apr 30, 2026
…tion (#901) * ts(B-0086): port 1 budget script (.sh→.ts) — slice 18 of TS/Bun migration * ts(slice-18, wip 1/N): port budget/daily-cost-report (.sh→.ts) Daily cost-monitoring entry point. Wraps snapshot-burn.sh + project-runway.sh and writes human-readable projection to docs/budget-history/latest-report.md (visibility surface for Aaron's #287 deadline). Note: this wrapper still spawns the bash siblings (snapshot-burn.sh + project-runway.sh), NOT the TS port — the bash versions are the soak-period reference until they retire. Once project-runway is also TS-ported, this wrapper can switch to spawning the .ts versions. Mechanical changes: - bash arg-parse → parseArgs with ParsedArgs | ArgError | help - bash 'cat > "$report_path" <<EOF...EOF' heredoc → buildReport() template literal returning the markdown string - bash subshell command capture ($(...)) → spawnSync with stdio ['inherit', 'pipe', 'pipe'] for project-runway combined output - bash heredoc concat across multi-line → resolved via separate argsSuffix variable (sonarjs no-nested-template-literals) - exit codes 0/1/2 preserved verbatim per bash original Lint-clean: tsc --noEmit + eslint strictTypeChecked + sonarjs all pass. Argument-validation byte-equivalent. Trajectory: 39 ports total after merge, 4 Bucket B files remain (1 budget project-runway + 1 git/batch-resolve + 1 pr-preservation + 1 in-flight = 4 remaining). * review(slice-18): use statSync.isFile() instead of existsSync per Codex P2 Codex P2: existsSync returns true for directories and other non-regular paths; the bash original uses -f which checks regular-file existence. If snapshots.jsonl were ever a directory, existsSync would skip the bootstrap branch and the wrapper would try to spawn project-runway.sh against a non-file. Switched to statSync.isFile() with try/catch fallback to false. * review(slice-18): address Copilot P0+P0+P2 — spawn classification + null-stream guards + header phrasing Three Copilot findings on #901: P0 — spawnSync launch failures collapsed into exitCode 1: Added classifySpawnFailure helper (4-case: status set / ENOENT → 127 / signal / other) reused from PRs #887, #898, #900. Both runSnapshotBurn and runProjectRunway now report a contextual note when the child can't start (e.g., 'snapshot-burn.sh: command not found on PATH (ENOENT)'). P0 — null stdout/stderr could yield 'nullnull': When a child fails to start, result.stdout / result.stderr can be null even with encoding: 'utf8'. Guarded with `?? ''` in runProjectRunway so the projection block doesn't end up as the literal string 'nullnull'. P2 — Header comment phrasing: Reworded 'snapshot-burn.sh ported in #894' to 'TS port snapshot-burn.ts landed in #894 but this wrapper still spawns the .sh during the soak period' to avoid implying the .sh file itself is the ported artifact. * review(slice-18) round-2: extract step-helpers + suppress no-unnecessary-condition - Extracted runSnapshotStep + runProjectionStep helpers to drop main() under cognitive-complexity 15. - Added eslint-disable on stdout/stderr ?? '' guards (typings claim string when encoding is set, but the runtime can return null when spawn fails — same pattern as #898). Lint clean: tsc + eslint strictTypeChecked + sonarjs all pass. * review(slice-18): preserve stdout/stderr ordering via shell-side 2>&1 per Copilot P1 Copilot caught: concatenating result.stdout + result.stderr does NOT preserve the original chronological ordering of merged streams. The bash original $(... 2>&1) merges at the kernel pipe level — if project-runway.sh emits warnings on stderr while writing success output to stdout, the messages interleave correctly. Switched to /bin/bash -c 'path 2>&1' so the merge happens shell-side (matches bash original semantics). Single stdout pipe = correct ordering. result.stderr is now unused (the inherit pipe still receives nothing).
4 tasks
AceHack
added a commit
that referenced
this pull request
Apr 30, 2026
…sure (#903) Per the consolidated-row-pattern (rows from 03:41Z + 05:01Z arc closures): when a session lands many small commits across multiple ticks, a single consolidated row summarizing the arc is more signal-dense than N minimal rows. Covers the slices 15-19 arc that landed after the 05:43Z slice-14 row: - #896 slice 15 (grok.ts) — peer-call cluster opens - #898 slice 16 (gemini.ts) — peer-call sibling - #899 backport to grok from #898 review-cycle findings - #900 slice 17 (codex.ts) — peer-call cluster closes - #897 B-0107 row — CodeQL dismissal pattern - #901 slice 18 (daily-cost-report.ts) — budget wrapper - #902 slice 19 (project-runway.ts) — budget cluster closes (in flight) Three new substrate observations recorded for future-Otto: - sibling-port-cost decreases monotonically (round-2/3 fixes bake into later siblings proactively) - kernel-pipe vs JS-space stream interleaving distinction (bash `2>&1` merges shell-side; `result.stdout + result.stderr` in JS does not preserve chronological ordering) - fix-the-bug + file-the-row + implement-the-row + closeout pattern is the durable shape (B-0106 + B-0107 are both worked examples) Cron 98fc7424 still armed. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2 tasks
AceHack
added a commit
that referenced
this pull request
Apr 30, 2026
…s updates (#904) * docs(ts-bun-migration): backfill slice-16/17/18 audit entries + status updates Backfills the slice-audits.md gap surfaced during the slice-19 close: slices 16, 17, 18 had merged but their audit entries were missing. Also flips slice 15 + slice 19 entries from "PR pending" to merged status (PR # + commit SHA). Slice 16 (peer-call/gemini, #898): three rounds of review-cycle fixes documented (round 1 exit-code 1 + commandAvailable PATH check; round 2 /bin/bash -c + shell-side truncation + ReadHeadResult; round 3 stderr concat for parse-error preservation). Slice 17 (peer-call/codex, #900): closes peer-call cluster. Documents the sibling-port-cost-decreases-monotonically pattern — slice 17 shipped 357 lines in a single commit with all known fixes pre-baked. Slice 18 (budget/daily-cost-report, #901): first wrapper-class port. Documents the kernel-pipe vs JS-space stream-ordering distinction that became substrate observation in the 07:21Z tick row. No code changes. Doc-only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(ts-bun-audits): address #904 review threads — MD038, persona attribution, monotonic deltas Round-1 fixes for PR #904: - MD038 markdownlint failure (line 451) — slice-18 entry had nested backticks (` "${path}" 2>&1 ` inside an outer code span) that confused markdown's parser. Rephrased prose to avoid embedding backticks inside backticks. - Persona-name attribution in current-state doc (Copilot P1, twice) — slice-16 + slice-17 file descriptions used "Otto's harness-side caller for invoking ..." Per the .github/copilot-instructions.md no-name-attribution rule for current-state docs, switched to role-ref "the harness-side caller for invoking ...". Slice-15 pre-existing wording on main left alone (separate commit if needed). - Non-monotonic Bucket B deltas (Codex P2) — backfilled rows for slices 16/17/18 had stale numbers (9→8, 8→7, 7→6) that were inconsistent with the pre-existing slice-15 row's "8 → 7". Recomputed to monotonic sequence: slice 16 = 7→6, slice 17 = 6→5, slice 18 = 5→4. - Slice-19 outcome wording (Copilot) — "Once this lands" → "Now that this has landed" since slice 19 already merged at commit bfdadd9. Doc-only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Slice 17 — third peer-call sibling (after grok #896 and gemini #898):
tools/peer-call/codex.{sh→ts}(Codex peer-caller via codex CLI; defaultcodex exec -s read-only --skip-git-repo-check,--reviewroutes throughcodex review)Bakes in all the round-2 + round-3 fixes from the gemini.ts review cycle:
tools/peer-call/README.md(NOT 64).commandAvailablevia/bin/sh -c 'command -v <cmd>'(PATH check, not--version)./bin/bash -c(not/bin/sh -c) for context-cmd to preserve bash-only feature support.ReadHeadResult { ok, content, error }so file-read failures surface to stderr instead of silently dropping context.classifySpawnFailure4-case helper (status / ENOENT → 127 / signal / other) reused from fix(ts): tsc TS2322 in audit-agencysignature-main-tip — narrow ArgStep.key #887 + ts(B-0086): port 1 peer-call sibling (.sh→.ts) — slice 16 of TS/Bun migration #898.stdout + stderrfromrunContextCmdto preserve shell parse errors that fall outside the inner( ) 2>&1redirect.Test plan
bun --bun tsc --noEmitclean (lint-tsc-tools gate from ci(B-0106): add lint-tsc-tools gate job — tsc --noEmit on tsconfig.json #890 will validate this in CI).eslintclean.--modelwithout value → exit 1; no prompt → exit 1;--bogus→ exit 1.Note on CodeQL alert
Same
js/indirect-command-line-injectionwill fire onrunContextCmd. Per B-0107 the per-PR dismissal pattern applies until the structural fix lands.Trajectory
After-merge: 38 ports total, 5 Bucket B files remain (2 budget + 1 git/batch-resolve + 1 pr-preservation/archive + 0 peer-call — cluster complete!).
🤖 Generated with Claude Code