Skip to content

fix: capture child and descriptor stdout in JSON envelopes - #420

Merged
codeforester merged 77 commits into
mainfrom
bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr
Oct 5, 2026
Merged

codeforester merged 77 commits into
mainfrom
bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr

Conversation

@codeforester

@codeforester codeforester commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

JSON invocations now capture process descriptor 1 as well as Python stdout, so inherited subprocess output remains inside the single envelope. A concurrent drain avoids pipe deadlocks, the native path enforces the JSON capture limit, and descriptor restoration precedes envelope emission.

The guides state the boundaries: wait for children, flush native stdio before returning, and use NDJSON for large output. A child retaining stdout causes a bounded capture error.

Fixes #379.

Branch maintenance

Refs #426. Targets the branch for #419. Retarget and refresh after that parent is squash-merged; preserve the ordered stack.

The branch was refreshed without rewriting history to include main at a576cc279739eae5e4cfc33ffab2a7fb56de24de.

Current-head validation

At 0441cec3b3098425d8c87aa9c8eaeee6e5496969: uv lock freshness and baseline, runtime, strict typing, style, and contracts passed locally with all declared extras. Runtime result: 629 passed, 1 warning, 262 subtests passed in 9.37s.

Hosted checks: 7/7 required checks passed; 0 checks pending; 0 unsuccessful checks at 2026-10-04T14:19:40.760978+00:00. See the PR Checks tab and #426 for subsequent results.

…07-us-record-about-20x-stdlib' into bug/378-20261003-bug-run-bundle-retention-is-inoperative-on-native-windows
…e-on-native-windows' into enhancement/386-20261003-perf-retention-serializes-concurrent-invocations-on-an-untim
…urrent-invocations-on-an-untim' into security/385-20261003-security-validate-trust-of-ancestor-discovered-project-confi
…or-discovered-project-confi' into bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr
…ff-check-and-mypy-do-not-cover-the-compatibility-consum
…-compatibility-consum' into bug/387-20261003-bug-configure-logger-closes-consumer-owned-handlers-and-forc
…wned-handlers-and-forc' into enhancement/381-20261003-perf-lifecycle-logging-costs-107-us-record-about-20x-stdlib
…07-us-record-about-20x-stdlib' into bug/378-20261003-bug-run-bundle-retention-is-inoperative-on-native-windows
…e-on-native-windows' into enhancement/386-20261003-perf-retention-serializes-concurrent-invocations-on-an-untim
…urrent-invocations-on-an-untim' into security/385-20261003-security-validate-trust-of-ancestor-discovered-project-confi
…or-discovered-project-confi' into bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr
…07-us-record-about-20x-stdlib' into bug/378-20261003-bug-run-bundle-retention-is-inoperative-on-native-windows
…e-on-native-windows' into enhancement/386-20261003-perf-retention-serializes-concurrent-invocations-on-an-untim
…urrent-invocations-on-an-untim' into security/385-20261003-security-validate-trust-of-ancestor-discovered-project-confi
…or-discovered-project-confi' into bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr
…-compatibility-consum' into bug/387-20261003-bug-configure-logger-closes-consumer-owned-handlers-and-forc
…fecycle-logging-costs-107-us-record-about-20x-stdlib' into bug/378-20261003-bug-run-bundle-retention-is-inoperative-on-native-windows
…ff-check-and-mypy-do-not-cover-the-compatibility-consum
…d-mypy-do-not-cover-the-compatibility-consum' into bug/387-20261003-bug-configure-logger-closes-consumer-owned-handlers-and-forc

# Conflicts:
#	docs/integrations.md
…ogger-closes-consumer-owned-handlers-and-forc' into enhancement/381-20261003-perf-lifecycle-logging-costs-107-us-record-about-20x-stdlib
…fecycle-logging-costs-107-us-record-about-20x-stdlib' into bug/378-20261003-bug-run-bundle-retention-is-inoperative-on-native-windows
…retention-is-inoperative-on-native-windows' into enhancement/386-20261003-perf-retention-serializes-concurrent-invocations-on-an-untim
…tention-serializes-concurrent-invocations-on-an-untim' into security/385-20261003-security-validate-trust-of-ancestor-discovered-project-confi
…alidate-trust-of-ancestor-discovered-project-confi' into bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr
@codeforester

Copy link
Copy Markdown
Contributor Author

Re-verified at 40d9e2a: addressed ✅. A detached child that still holds stdout is still an error, but it is now an explicit, typed capture_incomplete (StdoutCaptureIncompleteError) with everything drained before the timeout preserved in the single envelope, plus DEVNULL/start_new_session guidance. That meets #379's 'do not silently truncate or discard child-process output' non-goal, and keeping the error rather than returning success is a reasonable contract choice. The process-wide fd-1 note is documented. Full suite passes at the tip. The threads can be resolved.

Base automatically changed from security/385-20261003-security-validate-trust-of-ancestor-discovered-project-confi to main October 5, 2026 15:45
@codeforester

Copy link
Copy Markdown
Contributor Author

Resolved the merge conflicts by merging current main, including merged PRs #418 and #419, into this branch in commit b94249c. Preserved the #379 JSON descriptor-capture implementation and documentation, current main logging sidecar recovery, and the combined hot-path tests. Local validation passed: descriptor/JSON focused tests, full pytest, Ruff check and format, strict mypy, and documentation validation. GitHub reports the PR as conflict-free; hosted checks are running on the new head. The PR remains open and unmerged.

@codeforester
codeforester merged commit 77cf717 into main Oct 5, 2026
117 checks passed
@codeforester
codeforester deleted the bug/379-20261003-bug-json-single-envelope-stdout-contract-is-broken-by-any-wr branch October 5, 2026 15:58
codeforester added a commit that referenced this pull request Oct 5, 2026
Project Intake now uses REST for issue and Project reconciliation,
preserves active statuses and existing planning fields, batches
missing-field updates, and independently verifies every managed field.
It no longer depends on GraphQL owner discovery.

Quota exhaustion and long Retry-After/reset windows report a deferred
reconciliation; an hourly full issue sweep retries events even if no
card was created. Authentication failures remain explicit. Workflow logs
redact credentials and report API usage.

Fixes #311.

## Branch maintenance

Refs #426. Targets the branch for #420. Retarget and refresh after that
parent is squash-merged; preserve the ordered stack.

The branch was refreshed without rewriting history to include `main` at
`a576cc279739eae5e4cfc33ffab2a7fb56de24de`.

## Current-head validation

At `f5330b22446191532fb9c518c1f8f06522d777d7`: uv lock freshness and
baseline, runtime, strict typing, style, and contracts passed locally
with all declared extras. Runtime result: 658 passed, 1 warning, 282
subtests passed in 10.05s.

Hosted checks: 7/7 required checks passed; 0 checks pending; 0
unsuccessful checks at 2026-10-04T14:19:40.760978+00:00. See the PR
Checks tab and #426 for subsequent results.
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.

bug: --json single-envelope stdout contract is broken by any writer to fd 1

1 participant