Skip to content

ts(B-0086): port 1 peer-call sibling (.sh→.ts) — slice 17 of TS/Bun migration#900

Merged
AceHack merged 1 commit intomainfrom
lane-b/ts-bun-slice-17-peer-call-codex-2026-04-30
Apr 30, 2026
Merged

ts(B-0086): port 1 peer-call sibling (.sh→.ts) — slice 17 of TS/Bun migration#900
AceHack merged 1 commit intomainfrom
lane-b/ts-bun-slice-17-peer-call-codex-2026-04-30

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 30, 2026

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; default codex exec -s read-only --skip-git-repo-check, --review routes through codex review)

Bakes in all the round-2 + round-3 fixes from the gemini.ts review cycle:

Test plan

Note on CodeQL alert

Same js/indirect-command-line-injection will fire on runContextCmd. 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

…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.
Copilot AI review requested due to automatic review settings April 30, 2026 06:46
@AceHack AceHack enabled auto-merge (squash) April 30, 2026 06:46
Comment thread tools/peer-call/codex.ts Dismissed
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.ts implementing the Codex peer-call wrapper via codex exec (default) and codex review (via --review).
  • Reuse the shared peer-call patterns: uniform exit codes (0/1/2), command -v availability check, ReadHeadResult for file context reads, and spawn failure classification.

Comment thread tools/peer-call/codex.ts
Comment thread tools/peer-call/codex.ts
@AceHack AceHack merged commit 10c3418 into main Apr 30, 2026
28 checks passed
@AceHack AceHack deleted the lane-b/ts-bun-slice-17-peer-call-codex-2026-04-30 branch April 30, 2026 06:52
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).
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>
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants