Skip to content

[codex] Harden PR description lint workflow - #71

Merged
hintz-openai merged 1 commit into
mainfrom
codex/harden-pr-description-lint
May 14, 2026
Merged

[codex] Harden PR description lint workflow#71
hintz-openai merged 1 commit into
mainfrom
codex/harden-pr-description-lint

Conversation

@hintz-openai

@hintz-openai hintz-openai commented May 14, 2026

Copy link
Copy Markdown
Contributor

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
  • Parsed .github/workflows/pr-description-lint.yml with PyYAML.

@hintz-openai
hintz-openai marked this pull request as ready for review May 14, 2026 03:03
@hintz-openai
hintz-openai merged commit bbef623 into main May 14, 2026
3 of 4 checks passed
@hintz-openai
hintz-openai deleted the codex/harden-pr-description-lint branch 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.
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>
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