fix(tools/git/pr-ci-wait): stdin collision in python3 here-doc caused wrapper to always return unknown #513
Closed
jason.woltje
wants to merge 0 commits from
fix/pr-ci-wait-stdin-collision into main
pull from: fix/pr-ci-wait-stdin-collision
merge into: mosaicstack:main
mosaicstack:main
mosaicstack:mos-comms-live
mosaicstack:mos-comms
mosaicstack:feat/tess-interaction-agent
mosaicstack:fix/tess-docs-format
mosaicstack:next
mosaicstack:draft/mosaic-platform-prd
mosaicstack:enhance/tmux-send-buffer-race
mosaicstack:enhance/561-python-is-python3
mosaicstack:feat/federation-m3-verb-list
mosaicstack:fix/fleet-restart-tightloop-guard
mosaicstack:feat/federation-m3-scope-service
mosaicstack:feat/installer-dev-build-from-source
mosaicstack:fix/federation-tasks-prettier
mosaicstack:fix/installer-provider-gate-and-local-gateway-redis
mosaicstack:chore/fed-m3-dag-fix
mosaicstack:feat/federation-m3-verb-capabilities
mosaicstack:feat/federation-m3-query-source
mosaicstack:chore/fed-m3-backlog-sync
mosaicstack:release/mosaic-0.0.48
mosaicstack:fix/persona-class-pane-export
mosaicstack:feat/h3-fleet-provision
mosaicstack:fix/db-republish-backlog
mosaicstack:docs/north-star-per-agent-model-switch
mosaicstack:release/mosaic-0.0.46
mosaicstack:feat/a3a-agent-class-env
mosaicstack:feat/a3b-persona-contract
mosaicstack:feat/orchestrator-persona
mosaicstack:feat/h4-persona-overrides
mosaicstack:feat/h2-system-profiles
mosaicstack:feat/h1-persona-library
mosaicstack:feat/h-northstar-personas
mosaicstack:feat/a4-mosaic-backlog
mosaicstack:feat/a1-north-star
mosaicstack:feat/a2-role-registry
mosaicstack:release/mosaic-cli-0.0.45
mosaicstack:fix/h2-readiness-available
mosaicstack:release/mosaic-cli-0.0.44
mosaicstack:fix/fleet-pane-idle-activity
mosaicstack:release/mosaic-cli-0.0.43
mosaicstack:feat/h1-heartbeat-readiness
mosaicstack:release/mosaic-cli-0.0.42
mosaicstack:fix/fleet-claude-trust-gate-644
mosaicstack:fix/db-pglite-test-flake
mosaicstack:fix/framework-drift-reseed-642
mosaicstack:release/mosaic-cli-0.0.41
mosaicstack:chore/ci-base-node-24-alpine
mosaicstack:chore/ci-cache-phase1-prebaked-image
mosaicstack:feat/633-comms-block-runbook
mosaicstack:chore/ci-base-image
mosaicstack:feat/f3-m3-update-reseed
mosaicstack:feat/p6-docs-compliance-alpha
mosaicstack:release/mosaic-0.0.39
mosaicstack:feat/p5-overlay-composer
mosaicstack:release/mosaic-0.0.38
mosaicstack:feat/f3-m2-pi-harness
mosaicstack:feat/f3-watch-workdir
mosaicstack:feat/f3-hb-consistency
mosaicstack:release/mosaic-0.0.37b
mosaicstack:feat/fleet-mutable-add-remove
mosaicstack:feat/f3-pi-harness-hb
mosaicstack:feat/p4-1-comment-cleanup
mosaicstack:feat/fleet-presets-init
mosaicstack:feat/p4-upgrade-safe-migration
mosaicstack:feat/fleet-suite-prd
mosaicstack:release/mosaic-cli-0.0.37
mosaicstack:feat/fleet-ps-show-unmanaged
mosaicstack:release/mosaic-cli-0.0.36
mosaicstack:feat/fleet-heartbeat-sidecar
mosaicstack:feat/fleet-phase3-enablement
mosaicstack:release/mosaic-cli-0.0.35
mosaicstack:feat/fleet-launch-path
mosaicstack:feat/fleet-observability
mosaicstack:feat/p3-1-governance-gate-hardening
mosaicstack:feat/p3-constitution-extraction
mosaicstack:feat/p1p2-sanitization-gate
mosaicstack:feat/framework-constitution-alpha
mosaicstack:feat/p0-license-leak-sanitize
mosaicstack:docs/framework-agency-patterns
mosaicstack:fix/fleet-install-script-perms
mosaicstack:fix/fleet-preserve-agent-env
mosaicstack:release/mosaic-cli-0.0.32
mosaicstack:fix/fleet-release-hardening
mosaicstack:feat/fleet-cli-local-canary
mosaicstack:plan/tmux-fleet-durable-install
mosaicstack:fix/pi-skill-args-all-discover
mosaicstack:feat/pi-mosaic-tools-skill
mosaicstack:feat/tools-cheatsheet-salience
mosaicstack:fix/tooling-eval-injection-jq-json
mosaicstack:feat/us007-agent-registration
mosaicstack:docs/merge-authority-rule
mosaicstack:feat/mosaic-as-provisioning
mosaicstack:fix/t_301e4e3b-pr-merge-gitea-empty-uid
mosaicstack:ci/publish-appservice-image
mosaicstack:feat/mosaic-as-daemon
mosaicstack:feat/mosaic-as-m4a
mosaicstack:fix/pi-token-lean-skills
mosaicstack:fix/git-wrapper-rollup-20260526
mosaicstack:fix/git-wrapper-repo-detection
mosaicstack:fix/woodpecker-wrapper-legacy-mosaic
mosaicstack:fix/t-a292e96f-gitea-pr-metadata
mosaicstack:fix/gitea-pr-metadata-login-t-a292e96f
mosaicstack:fix/t_a292e96f-pr-metadata-gitea
mosaicstack:fix/t_3a368a52-gitea-usc-login
mosaicstack:fix/bootstrap-hotfix
mosaicstack:fix/populate-known-packages-list
mosaicstack:fix/idempotent-init
No Reviewers
No Label
Milestone
No items
No Milestone
Projects
Clear projects
No project
Assignees
jason.woltje
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mosaicstack/stack#513
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Delete Branch "fix/pr-ci-wait-stdin-collision"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
See commit
a4cbd4bfor full diagnosis. Heredoc-bound stdin consumed Python program text; json.load(sys.stdin) then saw EOF and bailed to unknown. Fix: capture stdin to local var before heredoc; pass via PR_CI_STATUS_JSON env. Same fix applied to both extract_state_from_status_json and print_status_summary.When the wrapper invoked `python3 - <<'PY' ... PY` inside a function that was being fed JSON via a pipe (`printf '%s' "$STATUS_JSON" | extract_state_from_status_json`), the heredoc bound stdin to the Python program text. The `-` argument tells Python to read its program from stdin, so the program consumed stdin before json.load(sys.stdin) ran — which then saw EOF and bailed to the "unknown" branch every time. Result: pr-ci-wait.sh hung the full timeout (default 30 min) even when the upstream Gitea status was already 'success', because every poll returned 'unknown' and the loop kept retrying. Fix: capture the piped JSON into a local variable with `payload=$(cat)` BEFORE invoking python, then pass it via env (PR_CI_STATUS_JSON). The heredoc still drives the Python program, but the payload is now read from the environment instead of a stdin that's already been consumed. Same fix applied to print_status_summary() which has the identical pattern. Verified locally: $ echo '{"state":"success"}' | extract_state_from_status_json → success $ echo '' | extract_state_from_status_json → unknown $ echo '{"state":null,"statuses":[{"state":"success"}]}' | … → success $ echo '{"state":"pending"}' | extract_state_from_status_json → pending $ echo '{"state":"failure"}' | extract_state_from_status_json → failure Reported in screenshot from operator session 2026-05-13 — wrapper was stuck waiting on a PR whose underlying Gitea status was already success. Operator workaround was to bypass the wrapper and use the raw Gitea API. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>a4cbd4be51to59b611ba8aClosing as superseded by #524 (rollup, merged 2026-05-26 as
821e19d). Verified during orchestration rebase: the pr-ci-wait.sh stdin-collision fix is already present on current main in both extract_state_from_status_json() and print_status_summary(); rebasing this branch drops its commit as already-upstream (net-zero diff vs main). The underlying bug is fixed in main — no code action needed. — orchestrator (mos)Pull request closed