Skip to content

Remove the goal subsystem - #409

Merged
TheGreatAxios merged 4 commits into
mainfrom
remove-goal-subsystem
Aug 8, 2026
Merged

Remove the goal subsystem#409
TheGreatAxios merged 4 commits into
mainfrom
remove-goal-subsystem

Conversation

@TheGreatAxios

@TheGreatAxios TheGreatAxios commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Deletes the goal subsystem entirely per operator decision ("too complex, we need to rescope it"): src/agent/goal.ts, goal-evaluator.ts, manage-goal.ts, session/goal-state.ts, permission/goal-approval-timeout.ts, and their tests (~2,500 lines including tests).
  • Unwinds every consumer: the /goal slash command, director's goal-rewrite branch, tool advertisement gating (manage_goal, hasGoalAtLaunch), TUI chrome zone/palette toggle/geometry budget entry, compaction summary context, and the goal-specific arming condition on the permission-gate auto-deny timeout.
  • Kept: manage_tasks (unrelated work-list tool), and the generic approval-timeout plumbing in gate-events.ts / request-approval.ts — only the goal-specific arming condition was removed. That plumbing now has zero callers; documented explicitly rather than silently dropped or given an invented caller.
  • docs/ARCHITECTURE.md documents the interceptTerminal contract (inputs, return convention, precedence, compaction-survival requirement, token attribution, launch-ordering constraint) as the specification for the director-based replacement of the continuation capability the goal governor provided.
  • Added a regression test confirming a leftover goal.json from a pre-removal session dir doesn't break session listing (dropped on read, never fatal).
  • Net: 52 files changed, +160/-3340.

Rebase onto main (#407 and others merged mid-review)

This branch was rebased onto current origin/main after #407 (CL-5664: queued-gate timers arm at display not emit, onOperator gained an abort/timeout safety net, a shared attachApprovalBudget helper landed in request-approval.ts, operator-gate teardowns are now tracked and drained on dispose) merged, along with several other same-day PRs. Two real conflicts, both in the timeout-arming plumbing this branch touches:

  • src/tui/request-approval.ts — composed the new attachApprovalBudget helper (from Arm queued gates' display-dependent timers only once shown #407) with this branch's goalTimeoutapprovalTimeout rename. Resolved by keeping Arm queued gates' display-dependent timers only once shown #407's helper and calling args.approvalTimeout() instead of the old args.goalTimeout().
  • src/tui/runner.tsArm queued gates' display-dependent timers only once shown #407 turned out to have built a shared goalTimeout() closure used at three call sites, not one: the permission gate, onOperatorGate, and requestMcpTrust (TOFU). My original diff only touched the permission-gate call site because that's all that existed when this branch was cut. Resolved by generalizing the shared closure itself to approvalTimeout: () => undefined and updating all three call sites to use it, so the "no caller arms this, plumbing kept for a future generalized mechanism" story holds consistently everywhere, not just where I originally happened to look.

A third, non-conflicting but real issue: gate-wire.ts's rewrite from #407 added two new comments ("goal-mode timeout", "the goal-mode timeout") and gate-wire.test.ts added a new timeout fixture string ("goal mode: no answer in time") for the new onOperator timeout test — none of these existed when this branch was cut, so the rebase silently reintroduced stale wording that a plain conflict-resolution pass wouldn't have caught. Fixed by wording only (no logic touched) in a dedicated follow-up commit.

Invariant re-verification against the new base (not assumed to carry over)

  • CL-5644 / CL-4995 (every gate settles exactly once, one transcript row)gate-wire.ts's settle-once architecture (the permission queue as the single settle guard, openedGeneration vs overlayGeneration for the operator gate, recordDecision as the sole transcript-row writer) is structurally unchanged by this branch; my edits there are two comment lines. Read the full onPermission/onOperator bodies post-rebase to confirm no dangling reference to the deleted timeout source disturbs settlement.
  • CL-5664 (timers arm at display not emit; onOperator abort/timeout/auto-cancel; teardown drains on dispose) — this is the invariant most directly under my feet, since I generalized the exact closure Arm queued gates' display-dependent timers only once shown #407 built this feature on top of. Verified: approvalTimeout() now returns undefined unconditionally at all three call sites (permission gate, onOperatorGate, requestMcpTrust), so the display-gated arm-on-open logic in gate-wire.ts simply never receives a timeoutMs to schedule — it degrades to "abort-only" safety net exactly as intended, not silently broken. operatorTeardowns drain-on-dispose is untouched code.
  • CL-5641 / CL-5642 (stall exemption: tool calls outstanding OR gate open)turn-state.ts diff against the new base is still comment-only.
  • CL-5646 (agents panel degrades one row at a time; budgets measured not guessed) — re-checked geometry/zones.ts/geometry/resolve.ts/shell.ts diffs against the new base: identical shape to the pre-rebase diff (goal dropped from ZONE_IDS/ZONE_REGISTRY/COLLAPSE_ORDER/PAINT_ORDER/ZoneVisibility, promptTop arithmetic dropped only goalH). No other zone changed today collided with this.

Capability lost, replacement needed

Deciding whether to re-enter inference after a clean yield (wait/replyinfer rewrite) is no longer implemented anywhere — it moves to the director later, generalized beyond a single-goal acceptance checklist. See docs/ARCHITECTURE.md's "Removed: goal subsystem" section for the full contract, including the compaction-survival trap (continuation state living only in turn history dies at the first compaction) that the deleted SummaryContext.goal field existed specifically to avoid.

The approval-timeout auto-deny/auto-cancel mechanism (timeoutMs/timeoutMessage) is kept but currently has no caller at any of its three sites (permission gate, operator gate, MCP TOFU) — a future generalized auto-continue mechanism owns re-arming approvalTimeout() in runner.ts.

Test plan

  • bun run typecheck — clean (post-rebase)
  • bun run build — clean (post-rebase)
  • bun run test4131 pass, 0 fail (post-rebase; main gained tests via Arm queued gates' display-dependent timers only once shown #407 and others since this branch was cut, so this number is not directly comparable to the earlier 4122/0)
  • Regression test for stale goal.json session-dir compatibility
  • Five-reviewer bar (greybeard, CTO, critique, neckbeard, karen) — findings addressed; do not merge, read-first gate per operator

@TheGreatAxios
TheGreatAxios force-pushed the remove-goal-subsystem branch from bab4202 to bc10f7f Compare August 8, 2026 20:12
Too complex, being rescoped. Deletes the goal governor, evaluator,
manage_goal tool, and their persisted session state, plus every TUI
surface that wired into it: the /goal command, chrome zone, palette
toggle, geometry budget entry, and the goal-specific approval-timeout
arming condition.

Kept: manage_tasks (unrelated work list), the generic approval-timeout
plumbing in gate-events.ts/request-approval.ts (now with no caller —
a future generalized auto-continue mechanism owns re-arming it), and
the turn-state settle-on-inference.done invariant (comment reworded,
the self-continuing-cycle case it guards is no longer goal-specific).

The continuation capability the goal governor provided — deciding
whether to re-enter inference after a clean yield — moves to the
director later; docs/ARCHITECTURE.md documents the interceptTerminal
contract the replacement must satisfy.

A stray goal.json left over in a session dir from before this change
is inert (nothing reads it) — regression test covers that sessions
still list cleanly.
Reviewer pass (greybeard, CTO, neckbeard) surfaced doc drift the
removal commit missed: docs/TUI.md's chrome-zone description and
collapse order still listed goal alongside task/agents; the
tui-opentui README's worked example passed a goal field that no
longer type-checks against ChromeLiveState; docs/PRODUCT.md still
called out "no goal governor" as an exec-runner delta that no longer
exists to be absent; docs/ARCHITECTURE.md's compaction section still
described injecting goal state into the summary; director.ts's
ensureCycleSettlesWithReply comment still enumerated a goal rewrite
path that's gone.

Also expands the interceptTerminal replacement contract in
ARCHITECTURE.md with the parts a from-scratch implementation would
otherwise rediscover as bugs: the compaction-survival requirement
(continuation state that lives only in turn history dies at the
first compaction), token attribution, and the launch-ordering
constraint on persisted state gating tool advertisement. Trims the
"Known live gap" callout since the auto-deny half is now dormant
with no caller.
Critique's sweep found one comment survivor in
tests/integration/vendored-carry.test.ts referencing "the chat
director and goal governor" as the shape an ephemeral nudge takes.
Reworded to the chat director's terminal rewrites generally, since
that's what the test actually exercises now.
Rebasing onto main picked up #407's rewrite of gate-wire.ts (display-
gated timers, onOperator safety net, attachApprovalBudget). Two of
its new comments and one test fixture still said "goal-mode timeout"
/ "goal mode" — composed correctly with this branch's removal in
substance (the timeout is generic plumbing either way) but stale in
wording now that there's no goal subsystem to name. Reworded only;
no logic changed.
@TheGreatAxios
TheGreatAxios force-pushed the remove-goal-subsystem branch from bc10f7f to 3df306c Compare August 8, 2026 21:31
@TheGreatAxios
TheGreatAxios merged commit 3b6cf52 into main Aug 8, 2026
3 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