Skip to content

fix: accept empty Pi completions and stabilize CI - #32

Merged
RobertTLange merged 5 commits into
mainfrom
fix/pi-empty-completion
Sep 9, 2026
Merged

fix: accept empty Pi completions and stabilize CI#32
RobertTLange merged 5 commits into
mainfrom
fix/pi-empty-completion

Conversation

@RobertTLange

@RobertTLange RobertTLange commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Pi can finish artifact-producing work successfully with an empty final assistant message. Headless treated this as could not extract final message and returned exit 1. This stopped learned-optimizer job 79706 during task design, although Pi exited 0 after writing task_design.json.

This change observes bounded native Pi JSONL output before capture truncation. An explicit normal terminal completion preserves an empty final answer across plain, debug, raw JSON, SDK, session persistence, and run coordination. Usage remains available; SDK results contain finalMessage: "". Native errors, nonzero exits, and incomplete lifecycles still fail, even when earlier progress text exists. Empty replies also clear stale messages on reused run nodes. Artifact validation and any subsequent repair remain the caller's responsibility.

The failing main CI run (34347389524, Node 24) was a test ordering race: an already-running has-session probe could log after successful kill-session cleanup. The fixture now deterministically exercises that ordering and checks the targeted cleanup and SIGTERM outcome. A separate test fix isolates the stuck-server fixture from host Codex history; a real-home scan took 20 seconds before its deadline began. Neither fix relaxes the cleanup timeout.

Validation:

  • Regression tests cover explicit empty completion, errors, truncated/incomplete output, usage, SDK formats, session resume, reused run nodes, Docker transport, and Modal capture truncation.
  • Replayed job 79706's recorded native trace: exit 0, exactly one usage report, no extraction error; no live API request.
  • npm run check: 705 passed, 3 skipped; npm run pack:check passed.
  • Node 22 focused completion and SIGTERM tests.
  • Python SDK: 67 tests passed, including packaging.
  • GitHub CI run 34349246703: all six jobs passed (Linux Node 22/24, Windows run storage Node 22/24, Python 3.10/3.14).

Three logical commits separate the CI ordering fix, test environment isolation, and Pi completion fix. The saved design still requires normal structural validation; this change makes that workflow reachable rather than declaring the artifact valid.

@RobertTLange

Copy link
Copy Markdown
Owner Author

Implemented both review findings in separate commits:

  • 8c90750 — Preserve the terminal answer through threshold compaction (src/pi-completion.ts:103). Restore it only after a matching successful compaction_end with willRetry: false; aborted, interrupted, malformed, and retrying sequences cannot revive completion.
  • 7b006e9 — Handle cumulative agent_end.messages history above 4 MiB (src/pi-terminal-json.ts, src/pi-completion.ts:86). The fallback parser validates the entire JSON record while retaining only the last message and bounded envelope fields. Ordinary records retain the existing parsing path; no new dependencies.

Validation:

  • npm run check with umask 0022: 725 passed, 3 skipped.
  • npm run pack:check: passed.
  • 73 focused observer, parser, and CLI tests: passed. Covers empty/nonempty answers, plain/SDK output, session persistence, malformed skipped history, native errors/retries, duplicate and escaped keys, chunk boundaries, and UTF-8 limits.
  • Changed completion code: 100% line/function coverage, 98.03% branch coverage.
  • Independent security, reliability, and contract review: no outstanding findings; differential JSON mutation and chunk-split checks passed.

Both findings addressed; none deferred. Retained projection remains limited to 4 MiB and parser nesting to 256 levels. Oversized final messages and malformed records remain failures.

CI run 34350476692 passed all six jobs: Linux Node 22/24, Windows run storage Node 22/24, and Python 3.10/3.14.

@RobertTLange
RobertTLange merged commit b89c5d1 into main Sep 9, 2026
6 checks passed
@RobertTLange
RobertTLange deleted the fix/pi-empty-completion branch September 9, 2026 12:23
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.

1 participant