Skip to content

fix(goal): Make Goal execution continuous by default / Goal 默认连续执行 - #8373

Merged
SivanCola merged 11 commits into
esengine:main-v2from
SivanCola:fix/goal-continuous-runtime
Aug 11, 2026
Merged

fix(goal): Make Goal execution continuous by default / Goal 默认连续执行#8373
SivanCola merged 11 commits into
esengine:main-v2from
SivanCola:fix/goal-continuous-runtime

Conversation

@SivanCola

@SivanCola SivanCola commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Make Goal execution continuous by default: it now runs until completion, a genuine user/external blocker, an explicit user stop, or an unrecoverable host/provider failure.
  • Remove host-owned model-round, Goal-turn, wall-time, and stall-count pause boundaries while preserving explicit goal_token_budget, max_steps, time, and cost budgets.
  • Convert repeated-error, zero-evidence, and Todo-stall thresholds into replanning redirects instead of goal_stuck, grace-round, or blocked outcomes.
  • Migrate legacy numeric-pause sidecars safely, preserve unknown fields, and expose cumulative active workDurationMs as observational runtime data across CLI, ACP, Wails, and Desktop.
  • Update Goal status UI, English/Simplified Chinese/Traditional Chinese copy, guides, specifications, enforcement documentation, examples, and the Unreleased changelog.

Issues

No linked issue.

Related and overlapping work

Compatibility and risk

  • Active Goal sidecars persist turnsLimit=-1 as the backward-compatible unlimited sentinel, while public runtime payloads expose deprecated limit fields as 0.
  • Legacy budget_turns, budget_tokens, goal_run_budget, goal_stuck, and no_progress pauses normalize to running without starting a provider request; manual and evaluator pauses remain unchanged.
  • Missing workDurationMs decodes to zero, older clients ignore the additive field, and unknown sidecar fields survive round trips.
  • Work-duration commits cover ordinary and slash-invoked runAs=subagent Goal turns and are scoped by Goal ID and continuation epoch so stale Run completions cannot update a replacement Goal.
  • No dependency, credential, permission, sandbox, or privilege boundary changes.

Verification

  • go test ./...
  • go test -race ./internal/agent ./internal/control
  • go vet ./...
  • cd desktop && go test ./...
  • cd desktop/frontend && pnpm typecheck && pnpm test:all && pnpm build
  • scripts/cache-guard.sh
  • scripts/check-cache-impact.sh
  • go run ./tools/repolint
  • git diff --check

Documentation impact

Documentation-impact: updated - documented continuous Goal execution, explicit budget semantics, legacy-state migration, and runtime statistics.

Cache impact

Cache-impact: low - cache-sensitive runtime files change, but the main provider system prompt, stable request prefix, tool schemas, and tool order remain unchanged; dynamic Goal runtime text remains turn-scoped.
Cache-guard: scripts/cache-guard.sh passed all release cases at 92-96% tail average; scripts/check-cache-impact.sh validates this declaration and the explicit system-prompt review.
System-prompt-review: Author review completed - no provider-visible system-prompt bytes changed; the boot/config edits only remove default runtime limits.

Capacity impact

  • The latest main-v2 integration adds two cohesive lines to each Goal runtime DTO owner: desktop/app.go (+2 lines, +0.0165%) and internal/acp/status.go (+2 lines, +0.2430%).
  • Both additions are the additive workDurationMs compatibility field and its boundary mapping. Splitting them would obscure the owner contract, so this PR updates only those two repolint file-size baselines.
  • The latest merged-tree frontend budgets remain within limits, including initial raw JavaScript/CSS at 2268.4 KiB / 2268.5 KiB.

Problem:
Goal mode could pause at host-owned numeric ceilings even while useful work was still progressing.

Root cause:
Default round, turn, wall-time, and stall thresholds were wired as terminal runtime boundaries and persisted as blocked Goal state.

Fix:
Remove host-owned Goal execution ceilings, preserve only user-selected resource limits, convert numeric stall guards into replanning redirects, migrate legacy numeric pauses, and expose cumulative work duration as observational runtime data.

Verification:
- go test ./...
- go test -race ./internal/agent ./internal/control
- go vet ./...
- cd desktop && go test ./...
- cd desktop/frontend && pnpm typecheck && pnpm test:all && pnpm build
- scripts/cache-guard.sh
- scripts/check-cache-impact.sh
- go run ./tools/repolint
@SivanCola
SivanCola requested a review from esengine as a code owner August 11, 2026 08:03
@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) tui Terminal UI / CLI (internal/cli, internal/control) agent Core agent loop (internal/agent, internal/control) config Configuration & setup (internal/config) and removed v2 Go rewrite (1.x) — main-v2 branch, active development labels Aug 11, 2026
Problem:
The PR lint job rejected five new regression-test loops under the intrange rule.

Root cause:
The tests used classic counted for loops even though the repository targets Go 1.22 integer ranges.

Fix:
Rewrite the five bounded test loops with integer range syntax without changing their iteration counts or assertions.

Verification:
- golangci-lint run --timeout=5m
- go test ./internal/agent ./internal/control
- go run ./tools/repolint
- git diff --check
Problem:
Slash-invoked runAs=subagent Goal turns counted provider requests and tokens but left cumulative workDurationMs at zero.

Root cause:
The isolated answer was copied into the parent session without its turn duration, and this controller path bypassed the existing Goal duration capture.

Fix:
Stamp returned subagent answers with cumulative turn work time and commit the new-message maximum through the existing scope/epoch recorder. Add success and deterministic Goal-replacement regression coverage.

Verification:
- go test ./...
- go test -race ./internal/control
- go vet ./...
- scripts/cache-guard.sh
- scripts/check-cache-impact.sh
- go run ./tools/repolint
Integrate the newly landed no-Todo-stall and no-Goal-round-ceiling changes from esengine#8347 and esengine#8357 without rewriting the published PR history.

Preserve this PR's broader continuous-runtime behavior: Goal Todo stalls still trigger a second-stage replan and epoch reset, while goal_stuck finalization remains removed.

Verified with full Go tests, agent/control race tests, go vet, repolint, Desktop tests, frontend typecheck/test/build, and cache guards.
Preserve continuous Goal semantics and cumulative runtime statistics while accepting the newly merged, user-configured token budget. Keep structural no-progress guards corrective-only and retain downgrade-safe sidecar migration.
Extract the spend-slice helper and move newly added compatibility coverage out of historical oversized test files without changing behavior.
Problem:
The PR head predates newly merged main-v2 changes, so its previous green checks do not cover the current integration tree.

Root cause:
main-v2 advanced in overlapping Desktop runtime DTO, frontend, and capacity budget surfaces after the last PR update.

Fix:
Merge the latest main-v2 history while preserving continuous Goal semantics and the newly landed UI and bundle-budget changes.

Verification:
The merged tree is verified by the focused Goal, race, vet, Desktop, frontend, cache, and repository lint gates before push.
Problem:
The latest main-v2 merge tree adds two cohesive lines to each of the Desktop and ACP Goal runtime DTO owners, exceeding their existing file-size ratchets.

Root cause:
workDurationMs requires one additive compatibility field and one boundary mapping at each owner; splitting these contracts would reduce clarity.

Fix:
Raise only the two affected repolint file-size baselines by two lines. The increases are 0.0163% for desktop/app.go and 0.2478% for internal/acp/status.go.

Verification:
- go run ./tools/repolint
- git diff --check
Problem:
main-v2 advanced with the SQLite catalog integration while this PR's final CI was running, leaving the continuous Goal branch conflicting and unmergeable.

Root cause:
Both branches update Desktop runtime DTO owners and the repolint baseline; the catalog merge also extracts substantial Desktop code.

Fix:
Merge the latest main-v2 catalog stack, preserve the Goal workDurationMs contract, and carry forward only its two-line file-size delta on top of the reduced Desktop app baseline.

Verification:
The updated integration tree is rerun through Goal, catalog, race, Desktop, frontend, cache, and repository lint gates before push.
Problem: main-v2 advanced with the execution-role and completion-summary stack while PR esengine#8373 was in CI, leaving the Goal runtime branch conflicted.

Root cause: both changes touch the Desktop and ACP runtime DTO owners and their repolint baselines.

Fix: merge main-v2, preserve the upstream execution-role behavior, retain the additive Goal workDurationMs mappings, and combine the exact repolint baselines.

Verification: git diff --check; go run ./tools/repolint
@SivanCola
SivanCola enabled auto-merge August 11, 2026 13:44
@SivanCola
SivanCola disabled auto-merge August 11, 2026 13:49
@SivanCola
SivanCola merged commit 2043834 into esengine:main-v2 Aug 11, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Core agent loop (internal/agent, internal/control) config Configuration & setup (internal/config) desktop Wails desktop app (desktop/**) tui Terminal UI / CLI (internal/cli, internal/control) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant