[codex] Harden PR description lint workflow - #71
Merged
Conversation
hintz-openai
marked this pull request as ready for review
May 14, 2026 03:03
chihsuan
referenced
this pull request
in Automattic/symphony
May 15, 2026
…andbox-allowlist feat(sandbox): drop api.github.com and api.linear.app from default allowlist
kimjj81
pushed a commit
to kimjj81/symphony
that referenced
this pull request
May 24, 2026
#### Context Restrict the PR description lint workflow so forked PR checks run with the least token access needed. #### TL;DR *Set read-only workflow permissions and stop checkout from storing credentials.* #### Summary - Add explicit contents read permission to the PR description lint workflow. - Set checkout persist-credentials to false for the lint job. #### Alternatives - Leave defaults unchanged, but explicit permissions make the token scope easier to review. #### Test Plan - [ ] `make -C elixir all` - [x] Parsed `.github/workflows/pr-description-lint.yml` with PyYAML.
1 task
hniska-identione
referenced
this pull request
in Identione/symphony
May 26, 2026
) (#25) Port upstream's "Surface input-blocked Symphony sessions" (3365695, #66). When Codex reports it needs operator input — a turn/* input request, an approval prompt, or an MCP elicitation — the orchestrator keeps the issue claimed and parks it as `blocked` instead of retrying until exhausted. Blocked issues are re-checked against Linear each tick and released when the issue goes terminal, non-active, re-routed, or vanishes. Surfaced in runtime state, the JSON API (`status: "blocked"`), and the dashboard. Blocked state is in-memory only and clears on restart. Codex-adapter-only by design: the Claude SDK sidecar runs unattended (permission_mode: dontAsk, can_use_tool unwired) and emits none of the input-required signals the detector keys off, so a claude session never blocks. Adapter scope is documented in elixir/README.md and SPEC.md §4.1.8 rather than forcing a synthetic blocker into claude's unattended posture. The other two upstream commits we were behind are intentionally skipped: #71 (pr-description-lint hardening) — GitHub Actions is disabled on this fork; the README Vimeo-link swap — cosmetic. Co-authored-by: hniska <hakan@niska.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CryptoJym
added a commit
to CryptoJym/symphony
that referenced
this pull request
May 29, 2026
* Add SSH worker support to Symphony Elixir #### Context Symphony needs to run tickets on SSH workers, keep the live E2E reliable, and preserve correct remote path semantics. #### TL;DR *Add SSH workers, Docker-backed SSH live E2E coverage, per-host caps, and correct worker-side `~` resolution.* #### Summary - Add SSH worker execution, remote workspace handling, and SSH app-server launch support in Elixir. - Add live E2E coverage for both local workers and SSH workers, with Docker-backed SSH workers by default. - Add an optional shared `worker.max_concurrent_agents_per_host` cap and document the SSH extension. - Keep `workspace.root` raw so SSH workers resolve `~` on the worker, while local paths expand at local use sites. #### Alternatives - Keep expanding `workspace.root` in config and carry duplicate raw path state, but that complicates the config model. - Require only absolute remote workspace roots, but that makes real worker setup less ergonomic and less representative. #### Test Plan - [x] `make -C elixir all` - [x] `cd elixir && env -u SYMPHONY_LIVE_SSH_WORKER_HOSTS LINEAR_API_KEY="$(tr -d '\r\n' < ~/.linear_api_key)" SYMPHONY_RUN_LIVE_E2E=1 mix test test/symphony_elixir/live_e2e_test.exs:128` * fix(elixir): fix malformed JSON event form codex message (openai#50) #### Context The Codex app-server merges stderr into stdout (`stderr_to_stdout`). Non-JSON diagnostic lines written by Codex during healthy turns were incorrectly emitted as `:malformed` protocol events in the Symphony UI. <img width="2496" height="446" alt="Screenshot 2026-03-12 at 4 27 20 PM" src="https://github.com/user-attachments/assets/3d85fa5b-c0d9-4079-87c6-850c7ccf7ee2" /> #### TL;DR *Only emit `:malformed` events for JSON-like protocol frames (lines starting with `{`); silently log all other non-JSON stream output.* #### Summary - Gate `:malformed` event emission on a new `protocol_message_candidate?/1` check — only lines starting with `{` - Preserve full logging of all non-JSON stderr noise via `log_non_json_stream_line` - Fix existing "Capture stderr log" test to assert no `:malformed` event is emitted for stderr noise - Add regression test verifying truncated JSON-like frames still surface as `:malformed` #### Alternatives - Separate stderr from stdout with a dedicated pipe: more invasive change, unnecessary given the simple heuristic - Suppress all non-JSON output silently: would lose valuable diagnostic logging #### Test Plan - [x] `make -C elixir all` - [x] `mise exec -- mix format lib/symphony_elixir/codex/app_server.ex test/symphony_elixir/app_server_test.exs` - [x] Additional: `MIX_ENV=test mise exec -- mix run --no-start -e 'Application.put_env(:symphony_elixir, :workflow_file_path, System.fetch_env!("SYMPHONY_TEST_WORKFLOW")); Mix.Task.run("test", ["test/symphony_elixir/app_server_test.exs"])'` Co-authored-by: Codex <noreply@openai.com> * fix(elixir): keep ssh retries in orchestrator (openai#54) #### Context SSH failover currently happens inside `AgentRunner`, which can bypass per-host caps and rerun a ticket on a second host after the first host already started setup. #### TL;DR *Keep each worker run on one SSH host and let the orchestrator own retries.* #### Summary - Remove `AgentRunner`'s internal cross-host failover loop - Keep a worker lifetime pinned to one selected SSH host - Add a regression test proving startup failure on one host does not fall through to another #### Alternatives - Keep internal failover and classify retryable errors, but that duplicates orchestrator scheduling logic - Only patch per-host cap enforcement, but invisible cross-host reruns would still risk duplicate side effects #### Test Plan - [x] `make -C elixir all` - [x] `cd elixir && mise exec -- mix test test/symphony_elixir/core_test.exs:1167 test/symphony_elixir/core_test.exs:1237 test/symphony_elixir/core_test.exs:1337 --seed 0` * [codex] Pin GitHub Actions workflow references (openai#57) ## Summary Pin floating external GitHub Actions workflow refs to immutable SHAs. ## Why See the rationale doc: https://docs.google.com/document/d/1qOURCNx2zszQ0uWx7Fj5ERu4jpiYjxLVWBWgKa2wTsA/edit?tab=t.0 ## Validation - `rg -n --pcre2 "uses:\s*(?!\./)(?!docker://)[^#\n]+@(?![0-9a-f]{40}(?:\s+#.*)?$)\S+" .github/workflows` - `git diff --check` - `git diff --stat -- .github/workflows` * Clarify Symphony service specification (openai#61) #### Context SPEC.md had ambiguous conformance language and implementation details that made the service contract harder to port. #### TL;DR *Clarify SPEC.md and normalize RFC-style requirement wording.* #### Summary - Add normative language and tighten config, workspace, reload, restart, and user-input wording. - Move extension config ownership to extension sections. - Point Codex protocol details at the targeted app-server spec instead of duplicating payloads. - Run a careful RFC 2119 terminology pass after mechanical normalization. #### Alternatives - Left attempt/retry redesign and broader safety issues for follow-up spec changes. #### Test Plan - [x] `make -C elixir all` - [x] `git diff --check HEAD~1..HEAD` - [x] RFC keyword scan outside code fences --------- Co-authored-by: Codex <codex@openai.com> * fix(elixir): configure Codex app-server model via config Summary: - Update the default Symphony Codex command to select gpt-5.5 via --config model instead of the root --model flag. - Refresh README and tests so examples and argv assertions match the app-server-compatible command shape. Rationale: - Codex app-server ignores the root --model flag, so the previous command could silently use the default model instead of the intended one. - Passing model through --config keeps the workflow aligned with Codex app-server behavior and the verified gpt-5.5 setup. Tests: - mise exec -- mix format --check-formatted - mise exec -- mix test - mise exec -- mix lint - Isolated app-server smoke test with the updated command Co-authored-by: Codex <codex@openai.com> * Add GitHub label gate for Linear dispatch * [codex] Harden PR description lint workflow (openai#71) #### Context Restrict the PR description lint workflow so forked PR checks run with the least token access needed. #### TL;DR *Set read-only workflow permissions and stop checkout from storing credentials.* #### Summary - Add explicit contents read permission to the PR description lint workflow. - Set checkout persist-credentials to false for the lint job. #### Alternatives - Leave defaults unchanged, but explicit permissions make the token scope easier to review. #### Test Plan - [ ] `make -C elixir all` - [x] Parsed `.github/workflows/pr-description-lint.yml` with PyYAML. * Surface input-blocked Symphony sessions (openai#66) #### Context Codex app-server sessions can request operator input or MCP elicitation. These should pause visibly instead of retrying until exhausted. #### TL;DR *Show input-blocked Symphony sessions in state, API, and dashboard.* #### Summary - Treat Codex input-required and MCP elicitation events as blocked sessions. - Keep blocked issues claimed until Linear state/routing changes. - Add blocked counts and per-issue blocked details to presenter payloads. - Render blocked sessions in the dashboard. - Add regression coverage for app-server and orchestrator blocked flows. #### Alternatives - Retrying was rejected because human-input blockers are not transient failures. - Moving Linear to Done was rejected because Done is post-merge terminal state. #### Test Plan - [ ] `make -C elixir all` - [x] `mise exec -- mix format` - [x] `mise exec -- mix test test/symphony_elixir/app_server_test.exs test/symphony_elixir/extensions_test.exs test/symphony_elixir/orchestrator_status_test.exs` --------- Co-authored-by: Codex <codex@openai.com> * Update README.md * Harden GitHub dispatch gate * Prefer explicit GitHub source links * docs: add SD-4 Symphony smoke-test note #### Context Smoke-test ticket SD-4 asks for an isolated doc proving Symphony picked up and handled the issue. #### TL;DR *Adds the SD-4 Symphony smoke-test note.* #### Summary - Adds `docs/symphony-smoke-test-one.md`. - Keeps the change docs-only and limited to the smoke-test note. - Mentions Jira issue key `SD-4`. #### Alternatives - Leave no repo artifact; rejected because the ticket asks for a committed smoke-test doc. #### Test Plan - [x] `make -C elixir all` via GitHub Actions `make-all` - [x] `test -f docs/symphony-smoke-test-one.md && rg "SD-4|Symphony" docs/symphony-smoke-test-one.md && git diff --check` - [x] `mix pr_body.check --file <process-substitution>` * Add state prompts and issue manifests * Add Linear issue identifier dispatch filter --------- Co-authored-by: Alex Kotliarskyi <frantic@openai.com> Co-authored-by: Kevin Wang <kevin.kx.wang@gmail.com> Co-authored-by: Codex <noreply@openai.com> Co-authored-by: mstrautmann-oai <mstrautmann@openai.com> Co-authored-by: Drew Hintz <hintz@openai.com> Co-authored-by: Codex <codex@openai.com> Co-authored-by: Danial Mirza <danial@openai.com> Co-authored-by: poon-oai <poon@openai.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.
Context
Restrict the PR description lint workflow so forked PR checks run with the least token access needed.
TL;DR
Set read-only workflow permissions and stop checkout from storing credentials.
Summary
Alternatives
Test Plan
make -C elixir all.github/workflows/pr-description-lint.ymlwith PyYAML.