Skip to content

Harden the harness core for rollout and bump to 0.6.0 - #131

Merged
lukebuehler merged 6 commits into
mainfrom
harness-core-hardening-squashed
Nov 4, 2026
Merged

lukebuehler merged 6 commits into
mainfrom
harness-core-hardening-squashed

Conversation

@lukebuehler

Copy link
Copy Markdown
Contributor

Hardens the harness core ahead of the first large rollout and bumps the version to 0.6.0. This is a breaking release with no compatibility layer: stored event kinds, durable state and wire values all change.

What changed

The review found the reducer and planners sound, and the failure handling around them not. This PR fixes these areas:

  • Log safety: a refused event no longer gets into the session log and poisons it.
  • Failures: permanent errors no longer retry forever, and a run that can't succeed now fails as a normal run with its real error. session/restart recovers an interrupted session on request.
  • Drive loop: it no longer loses or repeats work. Calls in a mixed tool batch are dispatched per call.
  • Provider contexts: invalid contexts are no longer sent to providers.
  • State growth: finished runs, promises and steering batches are pruned, and entry count is bounded, so long sessions stay loadable.
  • Sub-agents:
    • There is no default time limit. Long children roll over and get a liveness check.
    • Lifetime maxDescendants is gone. maxConcurrent (default 8) counts running children in the tree, and a spawn at the limit is refused, not queued.
  • Vocabulary:
    • managed splits into lifecycleControlled and declared, including session/declared/start, whose request field is now declaration.
    • native MCP execution becomes runtime.
    • workflowToolId replaces the overloaded toolId on workflow tools.

Rationale and the risky calls are in docs/roadmap/p194-harness-core-hardening.md. Start with its "Read these first" section.

Before merging or deploying

  • Fresh state required: deploying needs fresh databases and a new Temporal namespace, including on existing deployments. scripts/release/workflow-compat.sh v0.5.1 prints breaking. Runtime schema moves to revision 14 (migrations 012 to 014), and 014 fails on any mcp_servers row still holding native.
  • Old names are refused with no alias: session/managed/start, workflowTools and --execution native all fail. ls-benchmark needs a follow-up: it reads an old error kind and completedAtMs.
  • Release notes are missing: release/notes/v0.6.0.md isn't written yet and is needed before tagging.

Testing

  • Before the squash, on harness-core-hardening: Clippy clean, 3,081 workspace tests, npm run check, and 40 of 41 live suites on a reset dev database.
  • Known failure: anthropic_messages_compaction_live fails because Anthropic's classifier refuses fixtures at random. Refused compactions are a known open risk, parked for now and listed in the roadmap doc.
  • After the squash, scoped to the later changes:
    • Clippy clean, and the generated files check and web typecheck pass.
    • For the maxDescendants change: store_pg_live (44), subagents_live (13), code_capabilities_live (2) and the affected web tests (142).
    • For the declaration rename: api and api-projection tests (168), temporal-runtime unit tests (571) and SDK tests (16).
    • The sub-agent time limit change is covered by subagents_live.
  • Not rerun since the squash: the full workspace suite and the other live suites. The bot start path after the declaration rename has only been compiled and unit tested.

🤖 Generated with Claude Code

lukebuehler and others added 6 commits November 4, 2026 11:35
Drop the lifetime maxDescendants cap. maxConcurrent now counts open
descendants across the tree, defaults to 8, and a finished child frees
its slot. A spawn at the limit is refused rather than queued, because a
child waiting for a slot its parent holds could deadlock.

Regenerate the API contract and TypeScript consumers, and update the web
config editor, demo fixtures, docs and live tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
session/declared/start now takes declaration instead of workflowTools,
and its type becomes SessionDeclarationInput. The document also holds the
lifecycle controller, which is not a tool, and the new name matches
session.declaration on the read side. The old field is refused with no
alias.

Regenerate the API contract and TypeScript consumers, and update the
workflow tools guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lukebuehler
lukebuehler enabled auto-merge November 4, 2026 20:57
@lukebuehler
lukebuehler merged commit fbf012a into main Nov 4, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant