feat(goals): keep active session goals in per-turn context + continuance QA scenarios#100468
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed July 5, 2026, 10:49 PM ET / 02:49 UTC. Summary PR surface: Source +151, Tests +310, Docs +13, Other +435. Total +909 across 17 files. Reproducibility: yes. for the review blockers by source inspection. The active-goal line is generated into currentInboundContext, the default steer path sends only prompt text, and room-event wrapping places the same line into ambient room context. Review metrics: 2 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review findings
Review detailsBest possible solution: Land bounded active-goal context only after steering delivery, room-event gating, and generated maturity docs are fixed, then have maintainers confirm the every-turn goal prompt contract. Do we have a high-confidence way to reproduce the issue? Yes for the review blockers by source inspection. The active-goal line is generated into currentInboundContext, the default steer path sends only prompt text, and room-event wrapping places the same line into ambient room context. Is this the best way to solve the issue? No as written. The per-turn active-goal design is plausible, but it must cover steering, avoid ambient room-event nudges, refresh generated maturity docs, and receive product confirmation before merge. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 75c8753a2cb5. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +151, Tests +310, Docs +13, Other +435. Total +909 across 17 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (3 earlier review cycles)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5fc6155837
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| baseBody: baseBodyFinal, | ||
| hasUserBody, | ||
| inboundUserContext, | ||
| activeGoalContext, |
There was a problem hiding this comment.
Include goal context in steered turns
When a session is already active and queue mode stays at its default steer (resolveQueueSettings defaults to "steer"), runReplyAgent injects only followupRun.prompt through queueEmbeddedAgentMessageWithOutcomeAsync (src/auto-reply/reply/agent-runner.ts:1288-1294) and does not apply followupRun.currentInboundContext. Since the new active-goal line is carried only via activeGoalContext/currentInboundContext here, any turn sent while a run is streaming is steered without the active goal context, contradicting the new docs/QA claim that every user/chat turn with an active goal includes it. Please fold the current inbound context into the steer prompt or extend the steering path to accept it.
Useful? React with 👍 / 👎.
Active goals now inject one bounded user-role context line on every non-heartbeat turn, refreshed at queued/interrupt admission via provenance-tracked generated lines so operator stops take effect immediately. Adds qa/scenarios/goals continuance scenarios and goals.* coverage IDs.
c0731c3 to
ae10620
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ae10620c40
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const activeGoalContext = formatActiveGoalContext(sessionEntry); | ||
| if (activeGoalContext) { | ||
| blocks.push(activeGoalContext); |
There was a problem hiding this comment.
Skip goal nudges for ambient room events
When ctx.InboundEventKind === "room_event", this block still lands in the Room context because buildReplyPromptEnvelopeBase wraps inboundUserContext with buildRoomEventContext. Room events include ambient/unmentioned Slack and Discord messages and the room-event directive says the default is no reply, but this new line tells the model to advance the active goal, so an unrelated channel message in a session with an active goal can start goal work without a user request. Gate this injection to actual user-request turns or explicitly suppress it for room_event.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 818dd18ded
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - name: Goal continuance | ||
| coverageIds: [goals.context-injection, goals.continuance] | ||
| description: Active session goals remain visible in current-turn context and drive concrete followthrough across later turns and compaction. |
There was a problem hiding this comment.
Regenerate maturity docs for the taxonomy addition
Adding this third Context Engine feature changes the taxonomy inputs, but the generated docs/maturity/** projections were not refreshed: docs/maturity/taxonomy.md still reports Context Engine as 2 capabilities and omits docs/tools/goal.md, and repo-wide search only finds goals.context-injection / goals.continuance in taxonomy.yaml plus the new scenarios. The scoped docs guide says docs/maturity/** is generated from taxonomy.yaml via pnpm maturity:render, so leaving it stale will make the maturity check fail once dependencies are present and will publish an outdated scorecard.
Useful? React with 👍 / 👎.
…nce QA scenarios (openclaw#100468) * feat(goals): keep active session goals in per-turn context (openclaw#100409) Active goals now inject one bounded user-role context line on every non-heartbeat turn, refreshed at queued/interrupt admission via provenance-tracked generated lines so operator stops take effect immediately. Adds qa/scenarios/goals continuance scenarios and goals.* coverage IDs. * docs: regenerate docs map for goal context section * fix(qa): use requiredChannelDriver instead of execution.channel pin in goal scenarios
…nce QA scenarios (openclaw#100468) * feat(goals): keep active session goals in per-turn context (openclaw#100409) Active goals now inject one bounded user-role context line on every non-heartbeat turn, refreshed at queued/interrupt admission via provenance-tracked generated lines so operator stops take effect immediately. Adds qa/scenarios/goals continuance scenarios and goals.* coverage IDs. * docs: regenerate docs map for goal context section * fix(qa): use requiredChannelDriver instead of execution.channel pin in goal scenarios
What Problem This Solves
A session goal (docs/tools/goal.md) persists as session state, but nothing surfaces it to the model on later turns: after a few turns or a compaction, the agent only rediscovers the objective if it happens to call
get_goal. Persistence of the goal record is not persistence of pursuit — long-form work silently stalls and operators end up re-prompting "continue". There was also zero QA coverage proving multi-turn goal followthrough, so continuance regressions were invisible.Closes #100409.
Why This Change Was Made
Per-turn goal context (active goals only).
buildInboundUserContextPrefix(src/auto-reply/reply/inbound-meta.ts) now appends one bounded line when the session goal isactive:paused/blocked/budget_limited/usage_limited/completeinject nothing: an operator stop stays stopped. Heartbeat turns are excluded.Staleness across queueing/interrupts. Queued turns build their context early; a goal can complete/pause/start while they wait. Admission (
reply-turn-admission.ts) already loads the latest session entry under the lifecycle fence, so it now exposes that entry, and queued/interrupt-delayed turns refresh only the previously injected goal line at admission (refreshActiveGoalContext, provenance-tracked viainjectedGoalContextsso only generated lines are ever touched — never user text). Interrupt-race path inget-reply-run.tsre-resolves after an actual admission wait.QA continuance scenarios (
qa/scenarios/goals/, new theme +goals.context-injection/goals.continuancecoverage IDs intaxonomy.yaml):goal-context-next-turn—/goal start, then an unrelated turn; asserts the exact goal line in the captured mock-provider request payload.goal-context-survives-compaction— goal line still present on the post-compaction turn.goal-followthrough-live(live-only tier) — with an active multi-step goal, a bare "continue" turn must advance the next concrete step instead of re-planning, mirroring the instruction-followthrough contract.User Impact
Sessions with an active
/goalkeep pursuing it: the objective is visible to the model on every turn and survives compaction, queueing, and interruptions. Operator semantics unchanged — pausing/completing a goal immediately stops injection. Documented in the new "Goal context on every turn" section of goal docs.Evidence
git diff --checkclean.inbound-meta.test.ts,followup-runner.test.ts,get-reply-run.media-only.test.ts(active/inactive/no-goal/truncation, queued-refresh staleness, heartbeat exclusion, interrupt-race regression).feat— active session goals now stay in per-turn context and are covered by continuance QA scenarios.