Skip to content

fix(automation): region-aware run-history compaction keeps loop containers + early failures (#3234) - #3240

Merged
os-zhuang merged 2 commits into
mainfrom
claude/step-logs-run-observability-plxc2p
Jul 18, 2026
Merged

fix(automation): region-aware run-history compaction keeps loop containers + early failures (#3234)#3240
os-zhuang merged 2 commits into
mainfrom
claude/step-logs-run-observability-plxc2p

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1505 (region step logs). AutomationEngine.compactStepsForHistory() bounded a terminal run's persisted step log to the lastMAX_PERSISTED_HISTORY_STEPS entries with a plain tail-slice. With the ADR-0031 structured-region step logs, a single loop can now emit iterations × body-steps entries, so the tail-slice:

  • dropped the loop/parallel/try_catchcontainer step (it precedes all its body steps), leaving getRun/listRuns — served from durable history after a restart or ring-buffer eviction — with body steps the Runs surface (objectui FlowRunsPanel) could no longer nest; and
  • silently hid an early failure (e.g. iteration 2 of 500), the single most useful thing about a failed run.

The fix

New exported, region-aware compactStepLogForHistory (the private method delegates to it). Under budget the log is kept whole (stacks stripped) — unchanged. Over budget it selects a bounded, order-preserving subset that keeps the run's structural backbone:

  1. every top-level step (parentNodeId === undefined) — start/end, main-graph nodes, and the region container steps (bounded by the flow's static node count, not by loop iterations);
  2. every failure, wherever it occurred, each pulled in with its ancestor container chain for context;
  3. the most recent body steps (what the run was doing when it ended), each also with its ancestor chain.

Every retained body step therefore keeps its enclosing container(s) — so the compacted log never contains an orphan and the observability surface's per-iteration / per-region nesting still reconstructs — and the result is hard-capped at max, so steps_json stays bounded (#2585). Parent lookup is O(n) via a running last-seen-index map (the same "nearest preceding container instance" that FlowRunsPanel.buildStepTree nests under).

Verification

  • run-history.test.ts14/14 pass (7 new: cap, container/backbone retention, recent-iteration tail, early-failure retention, order preservation, nested-container no-orphan).
  • Full @objectstack/service-automation suite — 326/326 pass (no regression).
  • tsup build incl. DTS typecheck — pass. ESLint — clean.
  • Changeset: @objectstack/service-automation minor.

Closes#3234.

🤖 Generated with Claude Code


Generated by Claude Code

…iners + early failures (#3234)
`compactStepsForHistory` bounded a terminal run's persisted step log to the last
`MAX_PERSISTED_HISTORY_STEPS` entries with a plain tail-slice. With the ADR-0031
structured-region step logs (#1505) a single `loop` can emit
`iterations × body-steps` entries, so the tail-slice dropped the
`loop`/`parallel`/`try_catch` container step (it precedes all its body steps) and
every early iteration — leaving `getRun`/`listRuns` (after a restart or
ring-buffer eviction) with body steps the Runs surface could no longer nest, and
silently hiding an early failure.
Introduce an exported, region-aware `compactStepLogForHistory`; the private
method now delegates to it. Over budget it keeps the run's structural backbone —
every top-level step (including the region container steps) and every failure,
each pulled in with its ancestor container chain — plus the most recent body
steps, order-preserving and hard-capped at `max` so `steps_json` stays bounded
(#2585). Every retained body step keeps its enclosing container(s), so the
compacted log never contains an orphan and the observability surface's
per-iteration / per-region nesting still reconstructs. Under budget behavior is
unchanged (whole log, stacks stripped).
Adds 7 unit tests (cap, container/backbone retention, recent-iteration tail,
early-failure retention, order preservation, nested-container no-orphan).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VuvxWgoadqryqBcjs7TpVi
@vercel

vercelBot commented Jul 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specCanceledCanceledJul 18, 2026 5:15pm

Request Review

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tests tooling size/m labels Jul 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): packages/services.

6 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/automation/webhooks.mdx(via packages/services)
  • content/docs/kernel/runtime-services/audit-service.mdx(via packages/services)
  • content/docs/kernel/runtime-services/index.mdx(via packages/services)
  • content/docs/kernel/runtime-services/settings-service.mdx(via packages/services)
  • content/docs/plugins/packages.mdx(via packages/services)
  • content/docs/protocol/kernel/i18n-standard.mdx(via packages/services)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

…g in flows.mdx
The "Runs" section still described run history as an in-memory ring buffer whose
`sys_automation_run` rows "hold only live pauses", so "history starts fresh on
each boot". That predates the durable terminal run history (#2585): terminal
runs (completed / failed) are mirrored to `sys_automation_run` with a bounded
step log, and `listRuns` / `getRun` merge it so a run's status / steps / failure
reason survive a restart or ring-buffer eviction. Also note the Studio Runs
panel now nests body steps by iteration / branch / handler (#1505, objectui
#2667). Surfaced by the docs-drift check on #3240.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VuvxWgoadqryqBcjs7TpVi
@os-zhuang
os-zhuang marked this pull request as ready for review July 18, 2026 20:43
@os-zhuang
os-zhuang merged commit 1e145eb into mainJul 18, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/step-logs-run-observability-plxc2p branch July 18, 2026 20:43
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Long-loop run history truncation drops container + early-iteration step logs (compactStepsForHistory)

2 participants

@os-zhuang@claude