feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(orchestration-v2): populate subagent observability from providers (2/5) - #4629

Merged
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters
Aug 1, 2026
Merged

feat(orchestration-v2): populate subagent observability from providers (2/5)#4629
shivamhwp merged 4 commits into
subagent-obs/01-contractsfrom
subagent-obs/02-adapters

Conversation

@shivamhwp

@shivamhwpshivamhwp commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Second of five stacked PRs replacing #4551. Stacked on #4779 — review that first; this diff is against it, not the base branch.

PR 1 added the schema, migration, and storage with adapters on neutral defaults. This one makes the adapters actually populate it, across Codex, Claude, Cursor, OpenCode and ACP: role provenance, token usage, recent activity, and per-activation records.

Two usage strategies, because providers differ

Codex reports cumulative usage per thread, so those snapshots merge by maximum — a duplicate or late out-of-order frame then leaves the total unchanged rather than inflating it. Claude reports per activation, so lifetime usage accumulates the delta since the previous snapshot. Using either strategy for the other provider double-counts or freezes the number, so they are separate functions with their own tests.

A subagent identity is reusable, so finishing an activation leaves it at idle rather than completed. The timeline row for that activation is still recorded as completed, via PR 1's status mapping.

Three activation-lifecycle bugs found in review

All in the Claude adapter, all fixed here:

  • A raced resume silently lost its tokens. When a resume arrives past settle, the wake buffer pre-opens the registry entry — which erased the terminal status the reopen check reads. The resume then reused the finished activation instead of starting a new one: its ordinal stopped matching reality, and its usage was measured against the previous activation's totals, clamping the delta to zero. The pre-open now records that it happened, and the reopen check honours it.
  • A replayed waiting frame could resurrect a settled subagent. Only pending/running were guarded.
  • Duplicate terminal frames re-stamped completedAt, drifting the recorded completion time. Codex already preserved it; Claude now matches.

Explicitly not here

Reuse across runs. A subagent row still carries the run it was spawned under, so a later run's update can still be dropped by routing — visible in the subagent_continue fixture. That is PR 3, deliberately kept separate because it is the subtle part.

Testing

Typecheck and lint clean. Server 1,682 passing; whole-repo run 5,460 passing (the only failures are pre-existing apps/desktop collection errors from a broken local Electron install, untouched by this PR).

Reviewed by an independent agent pass before opening; the three lifecycle bugs above came out of it and are fixed in this commit.

Note

Populate subagent observability from ACP, Claude, Codex, Cursor, and OpenCode provider adapters

  • Each provider adapter now emits subagent_activation.updated events alongside subagent.updated, carrying activation id, ordinal, status, usage, and timestamps for each discrete subagent run.
  • Adds SubagentObservability helpers: providerSubagentRole, appendSubagentActivity, mergeCumulativeSubagentUsage, and accumulateCumulativeSubagentUsage for normalizing and accumulating usage across activations.
  • Subagent tasks now track currentActivationId (nulled on settle), activationCount, recentActivity, and preserve completedAt across rebuild emits.
  • The Claude adapter gains full workflow coordinator/worker modeling: worker subagents are created under a coordinator with phase membership, parent linkage, per-attempt reopen semantics, and are settled when the coordinator terminalizes.
  • Codex adapter maps completed provider state to idle subagent status; all adapters align on idle as the terminal reusable state instead of completed.
  • Behavioral Change: subagent status for settled reusable agents is now idle (not completed); existing tests and fixtures have been updated to match.

Macroscope summarized 2038f11.


Note

Medium Risk
Touches orchestration projection for all major provider adapters and changes settled subagent status semantics (idle vs completed); Claude resume/workflow logic is intricate but heavily tested.

Overview
Provider adapters (ACP, Claude, Codex, Cursor, OpenCode) now emit subagent_activation.updated alongside subagent updates and fill roles, usage, recent activity, and activation metadata instead of neutral defaults.

SubagentObservability adds provider role provenance, bounded activity history, and two usage paths: Codex merges cumulative thread snapshots by maximum; Claude accumulates per-activation deltas into lifetime totals.

Settled reusable subagents end in idle (not completed); activations still record terminal status. currentActivationId, activationCount, and preserved completedAt on rebuild emits align across adapters.

Claude models workflow coordinators and workers from workflow_progress, settles workers when the coordinator terminalizes, and fixes resume/reopen races (resumePending, waiting reopen guards).

Codex maps collab agent states via codexCollabAgentStatus, handles token usage and thread status, and records subagent model from the turn selection. Fixtures and tests updated for idle and activation rows.

Reviewed by Cursor Bugbot for commit 2038f11. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitaiBot commented Jul 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 41ca544d-dcf6-4c8b-a001-f29b8fa09bfd

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch subagent-obs/02-adapters

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Jul 27, 2026
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 9296337 to 760a4c2CompareJuly 27, 2026 23:03
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from 877ef38 to 12b0111CompareJuly 28, 2026 15:31
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from 760a4c2 to f3666e9CompareJuly 28, 2026 15:31
Base automatically changed from subagent-obs/01-contracts to t3code/codex-turn-mappingJuly 28, 2026 19:27
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from f3666e9 to 2565ea0CompareJuly 28, 2026 19:27
@github-actionsgithub-actionsBot added size:XXL 1,000+ changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). labels Jul 28, 2026
@shivamhwp
shivamhwpforce-pushed the t3code/codex-turn-mapping branch from 313ae4d to f117a4aCompareJuly 28, 2026 20:12
@shivamhwp
shivamhwp changed the base branch from t3code/codex-turn-mapping to subagent-obs/01-contractsJuly 28, 2026 20:12
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch 2 times, most recently from 2567faf to dcd0319CompareJuly 30, 2026 00:00
@shivamhwp
shivamhwpforce-pushed the subagent-obs/01-contracts branch from f4037f3 to e4f6d13CompareJuly 30, 2026 00:00
Comment threadapps/server/src/orchestration-v2/testkit/fixtures/claude_workflow/output.ts Outdated
shivamhwpand others added 2 commits July 30, 2026 06:14
Fills in the data model added by the previous PR. Every adapter now
reports what its subagents are actually doing: role provenance, token
usage, recent activity, and per-activation records.
Usage needs two merge strategies because providers report it
differently. Codex sends cumulative snapshots per thread, so those merge
by maximum — duplicate and late out-of-order frames then leave the total
unchanged instead of inflating it. Claude reports per activation, so
lifetime usage accumulates only the delta since the previous snapshot.
A subagent identity is reusable, so completing an activation leaves it
at "idle" rather than "completed"; the timeline row for that activation
is still recorded as completed via the status mapping.
A Codex subAgentActivity frame carries no model of its own, so agents
registered from one were recorded with none at all — the common case for
Codex-native subagents, which then showed a role and a token count but
no model. They are recorded against the turn's model selection, which is
what they actually run on.
Three activation-lifecycle fixes in the Claude adapter, found in review:
- A resume that raced past settle was pre-opened by the wake buffer,
which erased the terminal status the reopen check reads. The resume
then reused the finished activation instead of starting a new one, so
its ordinal stopped matching reality and its usage was measured
against the previous activation's totals — clamping the delta to zero
and silently dropping the resumed run's tokens. The pre-open now
records that it happened, and the reopen check honours it.
- A replayed "waiting" frame could resurrect a settled subagent; only
pending/running were guarded before.
- A duplicate terminal frame re-stamped completedAt, drifting the
recorded completion time. Codex already preserved it; Claude now
matches.
Reuse across runs is deliberately not addressed here — a subagent row
still carries the run it was spawned under. That is the next PR.
The adapter's workflow projection was covered in isolation and the panel
derivation was covered against synthetic agents, but nothing drove real
workflow frames through the orchestrator to the projection the client
receives.
Adds a claude_workflow replay fixture: a local_workflow task with two
phases and two members, asserted on the resulting projection. Pins what
the panel groups by — that members claim declared phases, that their
membership points at the coordinator that actually reached the
projection, and that the coordinator's usage still covers its members
so subtracting theirs cannot go negative.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shivamhwp
shivamhwpforce-pushed the subagent-obs/02-adapters branch from dcd0319 to bad75abCompareJuly 30, 2026 00:45
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment threadapps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

macroscopeappBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

1 blocking correctness issue found. This PR introduces new subagent observability features across multiple provider adapters, including new event emission, status tracking, and usage accumulation logic. The scope represents significant new runtime behavior, and there is an unresolved review comment identifying a potential bug in the waiting status handling.

No code changes detected at 2038f11. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

T3 Code Testand others added 2 commits July 31, 2026 04:45
- Treat pending/waiting workflow agents as active in the session-registry
write guard and wake-buffer pre-open, so concurrent active transitions
are not dropped and wake task_started cannot force a false resume.
- Preserve the first-recorded activation completion time on duplicate
terminal frames (Claude in-place update and ACP rebuilt emits).
- Let a blocked/waiting first snapshot of a new attempt reopen a settled
workflow agent entry instead of silently dropping its status and usage.
- Settle still-active workflow members when their coordinator
terminalizes, and expect the Implementer completed in claude_workflow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

activeContext.subagentActivation === null
) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Late usage skips activation records

Medium Severity

thread/tokenUsage/updated only writes per-activation usage when the turn is still in activeTurns. Turn finalization removes that entry first, so a late usage frame updates lifetime totals but leaves the activation's usage unset.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 2038f11. Configure here.

@shivamhwp
shivamhwp merged commit 2038f11 into subagent-obs/01-contractsAug 1, 2026
16 of 17 checks passed
@shivamhwp
shivamhwp deleted the subagent-obs/02-adapters branch August 1, 2026 00:42
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL1,000+ changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@shivamhwp