Goals, Tasks and Success Conditions¶
A loop must know what it is trying to achieve¶
In agentic execution, it is dangerous to pass a vague user request to the model and keep running until the model says it is done.
For example:
"Fix the payment bug."
This is broad even for a human. For a loop it is especially problematic because it does not define:
- the concrete target,
- allowed scope,
- what counts as success,
- what evidence is required for completion,
- what may remain unresolved.
A useful separation is:
User request
↓
Execution goal
↓
Subtasks / subgoals
↓
Success conditions
↓
Completion evidence
User request vs execution goal¶
The user request can be natural-language and ambiguous:
"Find out why checkout is slow and fix it."
The runtime can turn this into a more explicit execution goal:
Goal:
Identify the primary cause of checkout latency regression and produce a verified remediation within the allowed repository scope.
With constraints such as:
- read production telemetry
- modify current repository only
- do not deploy automatically
- maximum 25 iterations
The goal does not have to be generated by the model. Often the application layer derives it from user intent and system policy.
Goal as a contract¶
Useful mental model:
Goal
├── desired outcome
├── scope
├── constraints
├── required evidence
├── allowed side effects
└── termination semantics
Example coding task:
desired_outcome: PaymentRetryTest and related retry tests pass without duplicate charge behavior
scope:
repository: payment-service
constraints:
- no production deploy
- no API contract changes without approval
required_evidence:
- target test passes
- regression tests pass
- patch explains root cause
Make success conditions explicit¶
Weak:
Stop when you think the issue is fixed.
Better:
Success requires:
1. failing test passes
2. related regression suite passes
3. implementation no longer performs duplicate non-idempotent charge
Completion should not be only model intuition.
Completion evidence¶
The runtime should ask:
What evidence proves that the goal has been achieved?
Examples:
Coding¶
- tests passed
- static checks passed
- expected file changed
- no forbidden files changed
Incident diagnosis¶
- root-cause hypothesis supported by metric/log/deployment evidence
- alternative major hypotheses ruled out or marked unresolved
Data extraction¶
- all required fields extracted
- schema valid
- source location recorded for each critical value
Deployment validation¶
- deployment reached desired version
- readiness healthy
- error rate below threshold
Deterministic vs semantic success checks¶
Not every condition is the same.
Deterministic¶
exit_code == 0
all_required_fields_present
http_status == 200
version == expected_version
Do not delegate these to the LLM.
Semantic¶
Does the proposed root cause explain the observed symptoms?
Does the patch preserve the intended architecture?
Is the support response actually helpful and policy-consistent?
These may need a model, human, or evaluator.
A strong design often combines:
Hard deterministic gates
+
Semantic evaluation
Goal decomposition¶
Complex goals can be split into subtasks.
For example:
Goal: fix checkout latency regression
Subgoals:
1. establish baseline and affected endpoint
2. correlate regression with recent changes
3. identify root cause
4. implement remediation
5. verify latency and regressions
Benefits:
- visible progress,
- measurable partial completion,
- localized failure,
- explicit state,
- easier resume.
Do not decompose for its own sake¶
Not every task needs twenty subtasks.
Weak:
1. Think about problem
2. Read file
3. Think again
4. Decide whether to inspect another file
5. Think more
...
This is artificial complexity.
Better rule:
Decompose when subtasks have distinct completion state, dependencies, or failure modes.
Static vs dynamic decomposition¶
Static decomposition¶
The workflow already knows:
collect evidence
→ analyze
→ propose remediation
→ verify
This can be deterministic orchestration.
Dynamic decomposition¶
The runtime discovers new subgoals during execution:
Need to inspect DB latency
↓
DB healthy
↓
Need to inspect downstream payment provider
Here subgoals are created at runtime.
Goal tree / task graph mental model¶
Complex execution may use state such as:
Root goal
├── [done] reproduce failure
├── [done] identify duplicate charge path
├── [active] implement idempotency fix
└── [pending] run regression suite
Or a dependency graph:
A: fetch telemetry
B: inspect deploy
C: compare before/after
D: propose cause
E: verify cause
A ─┐
B ─┼→ C → D → E
Not every agent needs a DAG engine. The point is to keep task state explicit.
Partial success¶
Not every run is binary success/failure.
For example:
Goal: diagnose incident and propose safe remediation
A valid outcome may be:
PARTIAL_SUCCESS
- probable root cause identified
- evidence strong
- remediation not verified because staging unavailable
This is better than falsely reporting SUCCESS.
Useful outcome taxonomy:
SUCCESS
PARTIAL_SUCCESS
BLOCKED
NEEDS_HUMAN
FAILED
CANCELLED
BUDGET_EXCEEDED
Blocked goals¶
The runtime should support legitimate blocked state:
BLOCKED
reason: required production metric unavailable
The model does not need to “somehow continue”.
This reduces hallucination pressure.
User intent vs policy conflicts¶
Suppose the user asks:
"Deploy the fix automatically to production."
while application policy says:
production deployment requires human approval
Then the execution goal can be:
Prepare verified production-ready change and request approval for deployment.
The runtime does not simply copy the user's request. The goal is derived from user intent plus system policy.
Goal drift¶
During a loop, the model may drift away from the original task.
For example:
Goal: fix one retry bug
↓
model notices old code
↓
starts refactoring entire payment module
This is goal drift.
Mitigations include:
- explicit scope,
- current goal included in decisions,
- allowed files/tools,
- progress state,
- change budgets,
- rejection of out-of-scope actions.
Success-condition drift¶
Another danger:
Original success:
all retry tests pass
Model later:
"The code looks correct now, so we are done."
The runtime should not let the model rewrite hard completion criteria.
Model can propose completion
↓
Runtime verifies required conditions
↓
COMPLETED or continue
Example: PR repair loop¶
User:
Fix review comments on PR 184.
Execution goal:
Resolve all actionable review findings in PR 184 without introducing test regressions.
Subtasks:
1. load unresolved review findings
2. classify actionable vs non-actionable
3. fix actionable findings
4. run relevant tests
5. verify findings are addressed
Success:
- no unresolved actionable finding remains
- required tests pass
- only permitted repository changed
The model may say:
"I believe all comments are addressed."
but the runtime can re-fetch review state and test results.
Example: support agent¶
Goal:
Resolve customer's invoice rejection question using current account/invoice data and approved policy.
Success condition:
- correct invoice identified
- rejection reason grounded in current billing data
- explanation matches policy
- if account data unavailable → BLOCKED, not guessed answer
Goal progress¶
An explicit representation can help:
{
"goal": "Fix retry bug",
"progress": [
{"task": "reproduce failure", "status": "DONE"},
{"task": "identify cause", "status": "DONE"},
{"task": "implement fix", "status": "IN_PROGRESS"},
{"task": "verify regression suite", "status": "PENDING"}
]
}
Only a relevant projection needs to enter model context.
Anti-pattern: “done” as free text¶
Weak:
Model: "Looks good, we're done."
Runtime: stop
Better:
Model proposes STOP_SUCCESS
↓
Runtime checks:
- required tasks complete?
- deterministic gates pass?
- required evidence exists?
↓
yes → complete
no → continue / fail
Anti-pattern: hidden goal mutation¶
Do not allow the model to silently change:
Goal A
into:
Goal B, because A is inconvenient
Replanning may be allowed, but as an explicit state transition:
REPLAN_REQUESTED
reason: staging unavailable
proposed_new_subgoal: verify with unit/integration evidence instead
Hard top-level goals and policies must not change without control.
Takeaways¶
- The user request and execution goal are not always identical.
- A good goal includes outcome, scope, constraints, and completion evidence.
- Make success conditions explicit; do not rely on the model's feeling that the task is complete.
- Deterministic conditions should be checked by code.
- Decompose into subtasks when they have separate state, dependencies, or failure modes.
PARTIAL_SUCCESS,BLOCKED, andNEEDS_HUMANare legitimate outcomes.- The runtime should protect against goal drift and success-condition drift.
- The model may propose
STOP; the runtime decides whether the completion contract is actually satisfied.