Skip to content

fix(harness-server): export SLACK_CHANNEL/SLACK_THREAD_TS for codex tools#531

Open
cjustice wants to merge 1 commit into
paradigmxyz:mainfrom
cjustice:fix/harness-server-slack-thread-env
Open

fix(harness-server): export SLACK_CHANNEL/SLACK_THREAD_TS for codex tools#531
cjustice wants to merge 1 commit into
paradigmxyz:mainfrom
cjustice:fix/harness-server-slack-thread-env

Conversation

@cjustice

@cjustice cjustice commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Problem

harness-server codex (blocks mode, the default) never sets SLACK_CHANNEL/SLACK_THREAD_TS, so slack-upload aborts with SLACK_CHANNEL not set and the agent can't deliver files back into the Slack thread.

The Python codex-app-wrapper derived these from the per-turn thread_key before starting the app server (export_slack_thread_env). That was dropped when the Rust harness replaced the wrapper in #344. The Rust bridge also spawns codex app-server eagerly, before reading any input — so the child (and the tools it spawns, which inherit its env) can't pick up vars set mid-stream.

Fix (crates/harness-server/src/codex.rs)

  • Defer the codex app-server spawn + initialize to the first user turn.
  • Before that spawn, parse thread_key from the blocks line and export SLACK_CHANNEL/SLACK_THREAD_TS so the child and its tool subprocesses inherit them. Mirrors export_slack_thread_env; supports slack:<channel>:<thread_ts> (api-rs) and legacy slack:<team>:<channel>:<thread_ts>; no-op for non-Slack threads.

env::set_var runs before the child/reader threads exist (single-threaded), so it's sound. Deferring initialize matches the wrapper's original ordering and is invisible to api-rs — no harness output flows until the first turn.

Scope

Only the codex blocks path. The claude-code path (run_blocks_app_server) has the same gap — separate generic codepath, left for follow-up.

Testing

  • Unit tests for slack_channel_and_thread / thread_key_from_blocks_line (arity, legacy 4-part keys, non-Slack, empty/blank/absent/invalid).
  • Integration test: a fake codex app-server records its inherited env; asserts SLACK_CHANNEL/SLACK_THREAD_TS are set from thread_key "slack:C123:123.456". Confirmed to fail without the fix.
  • cargo test (37 lib + 8 integration), cargo fmt --check, cargo clippy all clean. K8s E2E not run — change is confined to the harness binary.

🤖 Generated with Claude Code

@cjustice cjustice force-pushed the fix/harness-server-slack-thread-env branch from 02729f2 to c3804ea Compare June 12, 2026 15:34
…ools

The Rust codex blocks bridge spawned `codex app-server` before reading any
input, so the per-turn `thread_key` never reached the agent's tool
subprocesses as SLACK_CHANNEL/SLACK_THREAD_TS. `slack-upload` therefore
aborted with "SLACK_CHANNEL not set" and the agent could not deliver files
back into the originating Slack thread.

The Python codex-app-wrapper derived these vars from the thread_key "before
the app server first starts" (export_slack_thread_env); that behavior was
dropped when the Rust harness replaced the wrapper in paradigmxyz#344.

Restore it for the codex blocks path: defer the codex app-server spawn until
the first user turn and, before spawning, parse the thread_key out of the
blocks line and export SLACK_CHANNEL/SLACK_THREAD_TS so the child — and the
tool subprocesses it runs — inherit them. Supports both `slack:<channel>:<ts>`
(api-rs) and legacy `slack:<team>:<channel>:<ts>` shapes; no-op for non-Slack
threads.

The claude-code blocks path (run_blocks_app_server) has the same gap but is a
separate generic codepath; left out of this focused fix.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cjustice cjustice force-pushed the fix/harness-server-slack-thread-env branch from c3804ea to 93f9734 Compare June 13, 2026 01:49
@cjustice

Copy link
Copy Markdown
Contributor Author

@akshaan — mind taking a look when convenient? Small harness-server fix to export SLACK_CHANNEL/SLACK_THREAD_TS for codex tools, in your Slack-thread area and rebased on latest main. Thanks!

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