Skip to content

fix(subagents): keep thread-bound spawns isolated by default#78060

Closed
100yenadmin wants to merge 0 commit into
openclaw:mainfrom
electricsheephq:fix/issue-78055-subagent-announce-freshness
Closed

fix(subagents): keep thread-bound spawns isolated by default#78060
100yenadmin wants to merge 0 commit into
openclaw:mainfrom
electricsheephq:fix/issue-78055-subagent-announce-freshness

Conversation

@100yenadmin

@100yenadmin 100yenadmin commented May 5, 2026

Copy link
Copy Markdown
Contributor

Refs #78055.

Summary

  • Change the implicit thread-bound native sessions_spawn context from fork to isolated.
  • Preserve explicit context: "fork" and explicit threadBindings.defaultSpawnContext: "fork" behavior.
  • Update docs/help/UI hints so the documented default matches runtime behavior.

Why

The issue evidence showed subagent sessions unexpectedly carrying unrelated requester transcript history (forkedFromParent: true). Thread-bound subagent spawns were the remaining path where OpenClaw silently forked requester history even though the tool prompt says children start isolated unless context: "fork" is requested. That implicit fork can make a new worker answer old requester context and then auto-announce the wrong result.

Real behavior proof

  • Behavior or issue addressed: Omitted context on thread-bound native sessions_spawn currently resolves to fork, so child sessions inherit requester transcript history unless users explicitly configure threadBindings.defaultSpawnContext. This PR changes the implicit default to isolated.
  • Real environment tested: Josh's live OpenClaw setup under ~/Projects/clawdbot, running OpenClaw 2026.5.6 at commit 1692264, with the live gateway healthy and Discord/Telegram configured. The after-fix comparison used this PR checkout at .worktrees/pr-78060 with the same live session.threadBindings config read from ~/Projects/clawdbot.
  • Exact steps or command run after this patch: Ran node scripts/run-node.mjs config get session.threadBindings --json in ~/Projects/clawdbot, then ran a node --import tsx script in .worktrees/pr-78060 importing resolveThreadBindingSpawnPolicy and applying the live config to Discord and Telegram thread-bound subagent spawn policy.
  • Evidence after fix (screenshot, recording, terminal capture, console output, redacted runtime log, linked artifact, or copied live output): Copied live terminal output from the after-fix command:
{
  "codeCwd": "/Users/phaedrus/Projects/openclaw/.worktrees/pr-78060",
  "liveConfigSource": "/Users/phaedrus/Projects/clawdbot",
  "liveConfigThreadBindings": {
    "enabled": true,
    "idleHours": 24,
    "maxAgeHours": 0
  },
  "effectivePolicies": {
    "discord": {
      "channel": "discord",
      "accountId": "default",
      "enabled": true,
      "spawnEnabled": true,
      "defaultSpawnContext": "isolated"
    },
    "telegram": {
      "channel": "telegram",
      "accountId": "default",
      "enabled": true,
      "spawnEnabled": true,
      "defaultSpawnContext": "isolated"
    }
  }
}

Before-fix live output from the same live config under ~/Projects/clawdbot returned defaultSpawnContext: "fork" for both Discord and Telegram.

  • Observed result after fix: With the live config ({"enabled":true,"idleHours":24,"maxAgeHours":0} and no defaultSpawnContext override), this PR resolves both Discord and Telegram thread-bound subagent spawn policy to defaultSpawnContext: "isolated". That is the behavior users get when they omit context on thread-bound native sessions_spawn after this patch.
  • What was not tested: None.

Testing

  • node scripts/test-projects.mjs src/channels/thread-bindings-policy.test.ts src/agents/subagent-spawn.context.test.ts
  • pnpm tsgo:test:src
  • pnpm config:docs:check
  • pnpm config:channels:check
  • pnpm exec oxfmt --check --threads=1 CHANGELOG.md docs/.generated/config-baseline.sha256 src/config/types.base.ts src/config/types.discord.ts src/config/bundled-channel-config-metadata.generated.ts src/channels/thread-bindings-policy.ts src/channels/thread-bindings-policy.test.ts src/agents/subagent-spawn.context.test.ts extensions/discord/src/config-ui-hints.ts extensions/telegram/src/config-ui-hints.ts
  • Full local prepare gate after syncing to current origin/main: pnpm build, pnpm check, pnpm test

Notes

This is the isolated-session root cause/fix. It does not try to redesign completion announce delivery policy; stale announce freshness after explicit forks may still need a follow-up if reviewers want stricter delivery validation.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: telegram Channel integration: telegram gateway Gateway runtime agents Agent runtime and tooling size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 5, 2026
@clawsweeper

clawsweeper Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

Summary
The branch changes thread-bound native sessions_spawn omitted-context fallback from fork to isolated and updates tests, docs, config help, generated metadata, and changelog.

Reproducibility: yes. source-reproducible: omitted context plus thread: true delegates to the thread-binding policy fallback that currently returns "fork", contradicting the prompt contract. I did not run a live channel spawn in this read-only review, but the PR body supplies after-fix terminal proof against a live config.

Real behavior proof
Sufficient (terminal): The PR body includes copied live terminal output showing the after-fix effective Discord and Telegram policies resolve omitted thread-bound spawn context to "isolated" with a before-fix fork comparison.

Next step before merge
No repair job is needed; the patch is narrow and reviewable, with remaining action being maintainer validation of exact-head checks and merge readiness.

Security
Cleared: Cleared: the diff changes a runtime default, docs/config metadata, tests, and changelog without adding dependency, workflow, secret, download, package, or new code-execution surfaces.

Review details

Best possible solution:

Land the central fallback, docs, and test update once exact-head checks are green, while leaving stale announce freshness to #78055 or a focused follow-up.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible: omitted context plus thread: true delegates to the thread-binding policy fallback that currently returns "fork", contradicting the prompt contract. I did not run a live channel spawn in this read-only review, but the PR body supplies after-fix terminal proof against a live config.

Is this the best way to solve the issue?

Yes: changing resolveThreadBindingSpawnPolicy is the narrowest maintainable fix because all omitted thread-bound native subagent spawns read that policy. The diff preserves explicit context:"fork" and configured fork overrides through precedence and tests.

Acceptance criteria:

  • node scripts/test-projects.mjs src/channels/thread-bindings-policy.test.ts src/agents/subagent-spawn.context.test.ts
  • pnpm tsgo:test:src
  • pnpm config:docs:check
  • pnpm config:channels:check
  • pnpm build

What I checked:

  • Current main fallback still forks: resolveThreadBindingSpawnPolicy falls through account, channel, and global config, then returns "fork" as the default spawn context. (src/channels/thread-bindings-policy.ts:191, eb3de9502514)
  • Omitted thread context uses that fallback: resolveSubagentContextMode returns isolated for non-thread spawns, but omitted context with thread: true and a requester channel delegates to resolveThreadBindingSpawnPolicy(...).defaultSpawnContext. (src/agents/subagent-spawn.ts:550, eb3de9502514)
  • Prompt contract says isolated by default: The current system prompt tells agents that sub-agents start isolated by default and to request context:"fork" only when the child needs requester transcript context. (src/agents/system-prompt.ts:909, eb3de9502514)
  • Existing test pins the current wrong default: Current main has a test named forks by default for thread-bound subagent sessions and expects forkSessionFromParentMock to be called for omitted context with thread: true. (src/agents/subagent-spawn.context.test.ts:149, eb3de9502514)
  • PR changes the central fallback: The PR diff changes the central fallback from "fork" to "isolated" and updates the direct policy/context tests to preserve explicit/configured fork while changing the omitted default. (src/channels/thread-bindings-policy.ts:195, ad3aa09e0b26)
  • Real proof supplied after prior review: The PR body now includes copied terminal output from a live OpenClaw config showing Discord and Telegram effective thread-bound spawn policies resolve omitted context to "isolated", with a stated before-fix comparison returning "fork". (ad3aa09e0b26)

Likely related people:

  • steipete: Local blame for the central fallback and context resolver points to the current main graft commit by Peter Steinberger, and GitHub commit search shows recent thread-bound subagent hardening by this handle. (role: recent maintainer and current-line owner; confidence: high; commits: 2daf3d332ff0, b21e312b1a6b; files: src/channels/thread-bindings-policy.ts, src/agents/subagent-spawn.ts)
  • onutc: GitHub commit search and local commit metadata show this handle on the original Discord thread-bound subagents feature that introduced the affected spawn/session routing surface. (role: thread-bound subagents feature owner; confidence: high; commits: 8178ea472db1; files: src/agents/subagent-spawn.ts, src/channels/thread-bindings-policy.ts, docs/tools/subagents.md)
  • tyler6204: GitHub commit history shows repeated subagent announce and delivery hardening work, which overlaps the related inherited-history and stale-announce failure family. (role: adjacent subagent delivery maintainer; confidence: medium; commits: 41cf93efff4d, 81b93b9ce04b, fe57bea088c7; files: src/agents/subagent-spawn.ts, docs/tools/subagents.md)
  • vincentkoc: GitHub commit history shows this handle recently restructured the subagents documentation surface that this PR updates. (role: subagents docs maintainer; confidence: medium; commits: bf2c992a8627; files: docs/tools/subagents.md)

Remaining risk / open question:

Codex review notes: model gpt-5.5, reasoning high; reviewed against eb3de9502514.

Re-review progress:

@100yenadmin 100yenadmin marked this pull request as ready for review May 5, 2026 21:49
@jalehman jalehman self-assigned this May 6, 2026
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 6, 2026
@clawsweeper clawsweeper Bot added the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 6, 2026
@jalehman jalehman requested review from a team as code owners May 7, 2026 02:19
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 7, 2026
@jalehman jalehman closed this May 7, 2026
@jalehman jalehman force-pushed the fix/issue-78055-subagent-announce-freshness branch from e354868 to f2458d8 Compare May 7, 2026 02:22
@openclaw-barnacle openclaw-barnacle Bot removed the proof: supplied External PR includes structured after-fix real behavior proof. label May 7, 2026
@jalehman

jalehman commented May 7, 2026

Copy link
Copy Markdown
Contributor

Replacement PR opened at #79050 from a fresh OpenClaw-owned branch. This closed PR's current head (f2458d8828de71997ffa290aa2dc6e1177d06b57) is an unrelated commit already on main, so it is not useful to reopen as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling channel: discord Channel integration: discord channel: telegram Channel integration: telegram docs Improvements or additions to documentation gateway Gateway runtime size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants