Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
9eab7b5
docs: add issue fixer agent design spec
v1r3n Apr 24, 2026
b5562f0
docs: add issue fixer agent implementation plan
v1r3n Apr 24, 2026
6a441bb
feat(examples): add 21 tools for issue fixer agent
v1r3n Apr 24, 2026
e422152
feat(examples): add agent instructions for issue fixer
v1r3n Apr 24, 2026
71a4983
feat(examples): add issue fixer agent — autonomous issue-to-PR pipeline
v1r3n Apr 24, 2026
453207a
fix(examples): use handle.join() instead of serve() for stateful agents
v1r3n Apr 24, 2026
56c94ca
docs: update spec entry point to use join() instead of serve()
v1r3n Apr 24, 2026
e73daf9
fix(sdk): propagate domain to sub-agent worker registration
v1r3n Apr 24, 2026
fad32d1
fix(sdk): propagate domain to ALL system worker registrations
v1r3n Apr 24, 2026
c2d5c23
test(e2e): add suite 14 — stateful domain propagation
v1r3n Apr 24, 2026
dee8d9b
fix(examples): add shared working directory for all issue fixer tools
v1r3n Apr 24, 2026
78b3025
fix(examples): tighten agent instructions to prevent loops and halluc…
v1r3n Apr 24, 2026
79e495b
fix(examples): increase max_turns and add parallel tool call patterns
v1r3n Apr 24, 2026
bb5b592
feat(examples): add docs agent + fix coder handoff to DG
v1r3n Apr 24, 2026
104075f
docs: update spec with docs agent, working dir, max_turns, parallel c…
v1r3n Apr 24, 2026
4c2a262
fix(examples): prevent .contextbook from being committed
v1r3n Apr 24, 2026
5598767
feat(examples): write plans and design docs to configurable docs folders
v1r3n Apr 24, 2026
7524526
fix(examples): fetch full issue context including assignees, mileston…
v1r3n Apr 24, 2026
7640001
feat(examples): add web_fetch tool for reading external links and docs
v1r3n Apr 24, 2026
a3a9c07
feat(examples): add change_context JSON to PR descriptions
v1r3n Apr 24, 2026
a99cf93
refactor(examples): deterministic pipeline with focused review loops
v1r3n Apr 24, 2026
9698148
feat(examples): add PR feedback mode to issue fixer agent
v1r3n Apr 24, 2026
7c5999d
fix(sdk): track domain when deduplicating late-registered workers
v1r3n Apr 24, 2026
c20127e
refactor(examples): use SEQUENTIAL for code review and testing — guar…
v1r3n Apr 24, 2026
e284de3
docs: add issue fixer agent design spec
v1r3n Apr 24, 2026
1aa6a9c
docs: add issue fixer agent implementation plan
v1r3n Apr 24, 2026
22a26ee
feat(examples): add 21 tools for issue fixer agent
v1r3n Apr 24, 2026
fcb0f2e
feat(examples): add agent instructions for issue fixer
v1r3n Apr 24, 2026
c834bcb
feat(examples): add issue fixer agent — autonomous issue-to-PR pipeline
v1r3n Apr 24, 2026
125377b
fix(examples): use handle.join() instead of serve() for stateful agents
v1r3n Apr 24, 2026
0a9acdb
docs: update spec entry point to use join() instead of serve()
v1r3n Apr 24, 2026
47cd897
test(e2e): add suite 14 — stateful domain propagation
v1r3n Apr 24, 2026
5f0c723
fix(examples): add shared working directory for all issue fixer tools
v1r3n Apr 24, 2026
fe17118
fix(examples): tighten agent instructions to prevent loops and halluc…
v1r3n Apr 24, 2026
c2c215e
fix(examples): increase max_turns and add parallel tool call patterns
v1r3n Apr 24, 2026
19a64dd
feat(examples): add docs agent + fix coder handoff to DG
v1r3n Apr 24, 2026
c8348f0
docs: update spec with docs agent, working dir, max_turns, parallel c…
v1r3n Apr 24, 2026
e884d84
fix(examples): prevent .contextbook from being committed
v1r3n Apr 24, 2026
4d0c2df
feat(examples): write plans and design docs to configurable docs folders
v1r3n Apr 24, 2026
c124bf3
fix(examples): fetch full issue context including assignees, mileston…
v1r3n Apr 24, 2026
52ab2c0
feat(examples): add web_fetch tool for reading external links and docs
v1r3n Apr 24, 2026
ad12197
feat(examples): add change_context JSON to PR descriptions
v1r3n Apr 24, 2026
0a86dc1
refactor(examples): deterministic pipeline with focused review loops
v1r3n Apr 24, 2026
a421f57
feat(examples): add PR feedback mode to issue fixer agent
v1r3n Apr 24, 2026
e51aa14
refactor(examples): use SEQUENTIAL for code review and testing — guar…
v1r3n Apr 24, 2026
ce2c7cf
Merge branch 'coding_agent' of https://github.com/agentspan-ai/agents…
v1r3n Apr 26, 2026
ddc1952
chore: remove committed .contextbook artifacts
v1r3n Apr 26, 2026
b65f7ea
cleanup
v1r3n Apr 26, 2026
4c6e63a
Delete agentspan
v1r3n Apr 26, 2026
3466d4f
Update 100_issue_fixer_agent.py
v1r3n Apr 26, 2026
83678d3
fixes
v1r3n Apr 26, 2026
9c9bd43
fixes
v1r3n Apr 27, 2026
d2f515d
fixes
v1r3n Apr 27, 2026
55a767b
Update AGENTS.md
v1r3n Apr 27, 2026
163c42b
Update _issue_fixer_instructions.py
v1r3n Apr 27, 2026
bdefc9a
fixes
v1r3n Apr 27, 2026
6c9887f
fix: register handoff_check worker for SWARM parents without explicit…
v1r3n Apr 28, 2026
d69ddca
refactor: overhaul issue fixer agent — 4 agents, generic for any repo
v1r3n Apr 28, 2026
da986cf
test(ts): prove SWARM handoff_check registration works for all topolo…
v1r3n Apr 28, 2026
232fe80
fix: tech_lead agent loops forever reading — add hard turn limits
v1r3n Apr 28, 2026
12d5702
fix: coder skips contextbook_write — make it mandatory before handoff
v1r3n Apr 28, 2026
d1cd521
fix: tech_lead keeps reading forever — phase-based instructions, max_…
v1r3n Apr 28, 2026
b9a8311
fix: pr_updater loops 10 turns without pushing — simplify to 3 responses
v1r3n Apr 29, 2026
8f42884
fix: pr_updater loops 10 turns reading — rewrite as 4-step determinis…
v1r3n Apr 29, 2026
280fdf9
fix: pr_updater more deterministic — exact tool calls per response, m…
v1r3n Apr 29, 2026
1cd0055
fix: pr_updater pipeline diagram instructions + max_turns=50
v1r3n Apr 29, 2026
1cb2797
fixes
v1r3n Apr 29, 2026
094615a
more examples
v1r3n May 2, 2026
fe5293b
Merge branch 'main' into coding_agent
v1r3n May 2, 2026
913d462
deep research agent
v1r3n May 2, 2026
9f377c5
test
v1r3n May 2, 2026
0b075f8
flakey tests
v1r3n May 2, 2026
3de947a
Update test_suite15_skills.py
v1r3n May 2, 2026
a44fc0b
Merge branch 'main' into coding_agent
v1r3n May 2, 2026
c71dcea
fixes
v1r3n May 3, 2026
0a85d3f
spotless
v1r3n May 3, 2026
cf7d64b
feat: prefill_tools — pre-execute tool calls before the first LLM turn
v1r3n May 3, 2026
e596ea8
fix: stop_when fires on tool-call turns + prefill coder_planner
v1r3n May 3, 2026
bdf11cd
fix: prefill tool_call messages use camelCase matching ChatMessage model
v1r3n May 3, 2026
813ccb1
fixes
v1r3n May 3, 2026
c75fb87
feat: Strategy.PLAN_EXECUTE — compile LLM plans into deterministic Co…
v1r3n May 3, 2026
a84b692
harden: plan-execute validation, JSON retry, partial failure resilien…
v1r3n May 3, 2026
de5d829
feat: add Strategy.PLAN_EXECUTE to TypeScript and Java SDKs with e2e …
v1r3n May 4, 2026
2aa4c44
Merge remote-tracking branch 'origin/main' into coding_agent
manan164 May 4, 2026
8597089
feat: success_condition eval + parallel FORK_JOIN for plan validations
v1r3n May 5, 2026
2004791
feat: make fallback agent optional in PLAN_EXECUTE — single-agent har…
v1r3n May 5, 2026
f8a1b6f
feat: coding harness example + fix success_condition for plain-text t…
v1r3n May 5, 2026
e993c5a
feat(issue-fixer): success_condition in validation, commit moves to o…
v1r3n May 5, 2026
1fad27a
feat(issue-fixer): remove fallback agent from coder — plan must succe…
v1r3n May 6, 2026
956fdc4
docs: spec for worker liveness + idempotent auto-resume
v1r3n May 6, 2026
4ccc24c
docs: implementation plan for worker liveness + idempotent auto-resume
v1r3n May 6, 2026
212603d
docs: add stall handling policy to worker-liveness spec & plan
v1r3n May 6, 2026
7530081
feat(sdk): add liveness config fields
v1r3n May 6, 2026
2f2a07e
fix(sdk): address Task 1 review feedback
v1r3n May 6, 2026
4943f2b
feat(sdk): add WorkerStartupError, WorkerStallError, StalledTaskInfo
v1r3n May 6, 2026
fae5b41
fix(sdk): tighten Task 2 imports + stall error assertions
v1r3n May 6, 2026
a0487d2
feat(sdk): LocalLivenessCheck — assert worker subprocesses are alive
v1r3n May 6, 2026
e0231ce
feat(sdk): ServerLivenessMonitor — daemon thread detecting unpolled t…
v1r3n May 6, 2026
3d0f736
feat(sdk): WorkerRestarter — SIGKILL stuck worker subprocesses
v1r3n May 6, 2026
0ee5867
feat(sdk): _collect_registered_pairs helper for liveness check
v1r3n May 6, 2026
f2f506e
feat(sdk): call LocalLivenessCheck after worker registration
v1r3n May 6, 2026
7772549
feat(sdk): add _resolve_worker_domain + use worker_domain at 4 sites
v1r3n May 6, 2026
4c1b52b
feat(sdk): AgentHandle.is_resumed + INFO log on idempotency replay
v1r3n May 6, 2026
a96da0c
feat(sdk): AgentHandle.join() drives ServerLivenessMonitor + stall po…
v1r3n May 6, 2026
b9c699d
feat(sdk): re-export WorkerStartupError, WorkerStallError
v1r3n May 6, 2026
66d9a85
test(liveness): add Tasks 10–12 e2e suite + skip _extract_domain on f…
v1r3n May 7, 2026
cf55fb1
fix(sdk): re-register stateful workers when polling domain changes
v1r3n May 7, 2026
c4fd24c
feat(sdk,server): planSource — deterministic plan fallback for PLAN_E…
v1r3n May 7, 2026
5db0434
test(plan-execute): cross-SDK max_tokens parity for generate blocks
v1r3n May 7, 2026
ccc13c1
style(server): apply spotless formatting
v1r3n May 7, 2026
bd2a717
feat(issue-fixer): split coder agent into explorer + planner roles
v1r3n May 7, 2026
d3f3db1
docs: add coding-agent and generic-agent harness design specs
v1r3n May 7, 2026
e0d66fb
Merge remote origin/coding_agent: Java SDK Maven→Gradle, parity work,…
v1r3n May 7, 2026
6950ea4
fix(plan-execute): harden compiler, remove fail-open paths, sandbox eval
v1r3n May 7, 2026
6b7b440
docs+ts(plan-execute): TS planSource parity, spec sync, markdown_plan…
v1r3n May 7, 2026
382f8b2
test(plan-execute): add failure-mode unit tests for the new fail-clos…
v1r3n May 7, 2026
773155c
fix(plan-execute): close re-review critical findings — sandbox, gate,…
v1r3n May 7, 2026
597e18a
fix(plan-execute): close re-review important findings — markdown_plan…
v1r3n May 7, 2026
2f2e05b
fix(plan-execute): close re-review #3 — ambient input plumbing, no-va…
v1r3n May 7, 2026
9c7a36f
fix(plan-execute): close re-review #4 — sandbox ordering, JOIN aggreg…
v1r3n May 7, 2026
153019c
fix(plan-execute): close re-review #5 — terminalRef unwraps parseGate…
v1r3n May 7, 2026
ca4d15b
fix(plan-execute): conductor 3.30.0.rc12 compatibility — restore json…
v1r3n May 8, 2026
ca0f9f0
Merge branch 'main' into coding_agent
v1r3n May 13, 2026
3cfe952
Merge remote-tracking branch 'origin/main' into coding_agent
v1r3n May 13, 2026
3de0bdf
chore: split harness work to feat/coding-agent-harness branch
v1r3n May 13, 2026
be808e0
feat(pac-pae): plan-and-compile + plan-execute additions and refinements
v1r3n May 13, 2026
b7d59bc
fix(ci): restore main-side fixes lost by WIP overwrite + update stale…
v1r3n May 14, 2026
b8ea470
fix(server): restore prune API + drop obsolete PlanCompilerScriptTest
v1r3n May 14, 2026
5280e01
style(server): replace inline FQNs with imports — fixes checkNoInlineFQN
v1r3n May 14, 2026
780ed3c
style(server): apply spotless formatting
v1r3n May 14, 2026
6a34ec8
fix(sdk): restore main PR #201 — task-level failure reason in AgentRe…
v1r3n May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 226 additions & 35 deletions AGENTS.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
1. When adding e2e make sure not to use LLM for validation unless we are doing this for judging quality/output/evals
2. Write a test, then validate that the test is actually valid. make it fail, assert that it did fail so we know its corect
3. E2E tests MUST NOT run longer than 12 minutes total. If a full e2e suite takes longer, split it or run subsets. Individual test timeouts should be set accordingly.
264 changes: 264 additions & 0 deletions docs/concepts/plan-execute.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
---
title: Plan-Execute Strategy
description: PLAN_EXECUTE compiles LLM-generated (or static) plans into deterministic Conductor sub-workflows — the planner reasons, the executor runs.
---

# Plan-Execute Strategy

`Strategy.PLAN_EXECUTE` (also called PAE; the server-side compiler is PAC, "PLAN_AND_COMPILE") splits a task into two phases:

1. **Plan** — a planner agent emits a JSON DAG of operations.
2. **Execute** — the server compiles that JSON into a Conductor sub-workflow and runs it deterministically.

The LLM is only invoked where it adds value (planning, per-op content generation). Orchestration, retries, parallelism, and validation are pure Conductor primitives — no token cost, no nondeterminism.

## When to use it

PLAN_EXECUTE wins when the work has **fixed structure but variable content**:

- Generate a research report (3 sections, parallel writes, then assemble + validate)
- Process a batch of records with conditional branches
- Multi-stage refactor where each stage is the same shape but the inputs differ
- Anywhere you'd otherwise hand-write 20 turns of LLM tool-calling and hope it doesn't loop

If you need fully agentic exploration with no fixed shape, use `Strategy.HANDOFF` instead. If you have a fully fixed pipeline, use `Strategy.SEQUENTIAL`. PLAN_EXECUTE is the middle ground.

## The shape

```python
from agentspan.agents import Strategy, Agent, plan_execute

# One-call construction (recommended):
harness = plan_execute(
name="report_generator",
tools=[create_directory, write_file, assemble_files, check_word_count],
planner_instructions="Plan a research report on the user's topic. Use 3 sections, then assemble.",
fallback_instructions="The deterministic plan failed — recover agentically.",
)

# Or assemble manually if you need every knob:
planner = Agent(name="planner", instructions=PLANNER_INSTRUCTIONS, model=...)
fallback = Agent(name="fb", instructions=FALLBACK_INSTRUCTIONS, tools=[...], model=...)
harness = Agent(
name="report_generator",
strategy=Strategy.PLAN_EXECUTE,
planner=planner,
fallback=fallback,
tools=[...], # canonical plan-executable set; PAC validates against this
fallback_max_turns=5,
)
```

The **planner**, **fallback**, and **tools** slots are the three first-class fields. `agents=[...]` is **not** valid for PLAN_EXECUTE — set the named slots.

## Plan schema

The server auto-appends a `## Plan schema` block to the planner's user prompt (along with `## Available tools` derived from `harness.tools`). Your `planner_instructions` only needs to cover **domain-level guidance** — what to plan, not how to format JSON.

The schema PAC consumes:

```json
{
"steps": [
{
"id": "<unique step id>",
"depends_on": ["<other step id>"],
"parallel": false,
"operations": [
{"tool": "<tool>", "args": {<literal arg map>}},
{"tool": "<tool>", "generate": {
"instructions": "<what the LLM should produce>",
"output_schema": "<JSON shape that becomes the tool's args>",
"max_tokens": 4096
}}
]
}
],
"validation": [
{"tool": "<validator>", "args": {...},
"success_condition": "$.passed === true"}
],
"on_success": [{"tool": "<tool>", "args": {...}}],
"on_failure": [{"tool": "<tool>", "args": {...}}]
}
```

**Key concepts:**

- **`args` vs `generate`** — `args` runs the tool with literal values you decide at plan time. `generate` defers arg construction to a per-op LLM call at run time.
- **`depends_on`** — cross-step concurrency. A step starts when *all* listed deps complete. Defaults to the previous step.
- **`parallel`** — when true, the step's own `operations` run concurrently (FORK_JOIN). Without it, operations run in order within the step.
- **`success_condition`** — JS expression evaluated against the validator's output (`$` = parsed output map). Returns truthy on pass.
- **`on_success` / `on_failure`** — tools to run after validation. Optional.

## Typed plans (no JSON soup)

For static plans (or plans you build programmatically), import the typed builders:

```python
from agentspan.agents import Plan, Step, Op, Generate, Validation, Action

plan = Plan(
steps=[
Step("setup", operations=[Op("create_directory", args={"path": "out"})]),
Step(
"write",
depends_on=["setup"],
parallel=True,
operations=[
Op("write_file", generate=Generate(
instructions="Write the introduction.",
output_schema='{"path": "out/intro.md", "content": "..."}',
)),
],
),
],
validation=[
Validation("check_word_count", args={"path": "out/intro.md", "min_words": 200}),
],
)
```

IDE autocomplete, Pylance type-checks, no escaping nightmares.

## Static plans — skip the planner LLM

Pass a `Plan` (or a raw dict in the same shape) to `runtime.run` and PAC uses it directly:

```python
result = runtime.run(harness, "anything", plan=plan, cwd=work_dir)
```

The planner LLM still runs (the workflow shape is fixed at compile time) but its output is discarded — PAC's `extract_json` reads `workflow.input.static_plan` as Case 0, which wins over planner output. Use this for:

- Tests (deterministic plan, no LLM nondeterminism)
- Replays of a previously-emitted plan
- Pipelines where planning lives outside the agent (a separate service or a code path that builds the `Plan` object)

## Tool guardrails propagate

`@tool(guardrails=[...])` works inside PLAN_EXECUTE the same way it works in the LLM-loop:

```python
no_pii = RegexGuardrail(patterns=[r"\b\d{16}\b"], on_fail=OnFail.RAISE, ...)

@tool(guardrails=[no_pii])
def send_email(to: str, body: str) -> str: ...
```

PAC wraps every emitted SIMPLE for `send_email` in a guardrail SWITCH gate. The bare SIMPLE only runs from the gate's `pass` branch. If the guardrail trips:

- `on_fail=raise` — TERMINATE the dynamic plan; harness's `fallback` agent recovers
- `on_fail=retry` / `fix` / `human` — collapse to TERMINATE in plan mode; same fallback path. (See `OnFail` docstring for full semantics — there's no LLM loop in plan mode to feed retry feedback into; the fallback IS the retry loop.)

The compiler emits **only the SWITCH cases that are reachable** for the configured `on_fail`. An `on_fail=raise` guardrail produces one `raise` case, not four dead branches.

## Fallback — the recovery agent

Configure `fallback=<Agent>` on the harness for adaptive recovery when:

- The planner emits a malformed plan (PAC validation fails)
- A guardrail trips on a deterministic step
- A plan step itself fails at run time

The fallback runs as a normal LLM-loop agent with the harness's `tools`. It receives the original prompt + the failure context (planner output, error message). `fallback_max_turns` caps its turn count during recovery.

Without a fallback, any failure terminates the workflow. Acceptable for fail-loud pipelines; surprising otherwise — the SDK warns at compile time when guardrails with `on_fail≠raise` are configured but no fallback exists.

## What PAC actually emits

For a plan with N parallel steps + 1 validator, the compiled WorkflowDef looks roughly like:

```
SET_VARIABLE _ctx_init
FORK_JOIN (per-step branches)
LLM_CHAT_COMPLETE (per generate op)
INLINE (parse LLM JSON output)
SWITCH (parse-error gate)
SIMPLE (the tool call)
JOIN
INLINE (aggregate parallel branch results — only if downstream reads it)
SIMPLE (validator)
INLINE (val_eval — emits "passed"/"failed")
SWITCH vsw ("passed" → on_success, default → TERMINATE/on_failure)
```

The `## Available tools` block in the planner prompt and PAC's validator share the same source: `harness.tools`. A planner can't emit a tool name that PAC will reject (and PAC will reject anything not in the harness's set — closes the hallucinated-tool-name bug).

## Common patterns

### Research report (LLM-driven planning)

```python
harness = plan_execute(
name="report",
tools=[create_directory, write_file, assemble_files, check_word_count],
planner_instructions="Plan a research report on the user's topic. Use 3 sections.",
fallback_instructions="Fix what the deterministic plan couldn't.",
)
result = runtime.run(harness, "AI agents in 2025")
```

### Static pipeline (no planner reasoning needed)

```python
harness = plan_execute(name="ingest", tools=[fetch, transform, store])
plan = Plan(steps=[
Step("fetch", operations=[Op("fetch", args={"url": url})]),
Step("transform", depends_on=["fetch"], operations=[Op("transform", args={"path": "raw.json"})]),
Step("store", depends_on=["transform"], operations=[Op("store", args={"key": "result"})]),
])
result = runtime.run(harness, "ingest job", plan=plan)
```

### Parallel work + validation

```python
plan = Plan(
steps=[
Step("setup", operations=[Op("create_directory", args={"path": "out"})]),
Step("write_all", depends_on=["setup"], parallel=True, operations=[
Op("write_file", generate=Generate(
instructions=f"Write section {i}.",
output_schema=f'{{"path": "out/{i}.md", "content": "..."}}',
))
for i in range(5)
]),
Step("assemble", depends_on=["write_all"], operations=[
Op("assemble_files", args={"output_path": "report.md", "input_paths": "..."})
]),
],
validation=[Validation("check_word_count", args={"path": "report.md", "min_words": 1000})],
)
```

## Knobs reference

| Field | Purpose |
|---|---|
| `planner=` | Required. The agent that emits the JSON plan. |
| `fallback=` | Optional. Agentic recovery when a plan can't compile/exec. |
| `tools=` | Required. Plan-executable tool set. PAC validates `op.tool` names against this list and propagates each tool's guardrails. |
| `fallback_max_turns=` | Caps the fallback agent's turn count during recovery. |
| `plan_source=` | Compile-time deterministic plan via a tool call. (Use `plan=` at run time instead — same effect, simpler.) |

| Run-time kwarg | Purpose |
|---|---|
| `plan=` | Skip the planner LLM's output; use this `Plan`/dict directly. |
| `cwd=` | Working directory for filesystem-bound tools. |

## Examples

- `examples/85_plan_execute_harness.py` — research report with LLM planner + fallback recovery
- `examples/103_plan_and_compile.py` — minimal PAC demo with `args` + `generate` ops + validation
- `examples/104_plan_execute_guardrails.py` — guardrail propagation in plan mode
- `examples/100_issue_fixer_agent.py` — production-shape pipeline with PLAN_EXECUTE coder + agentic fallback

## Failure modes

| Symptom | Cause | Fix |
|---|---|---|
| Workflow FAILED with "uses unknown tool" in PAC error | Planner emitted a tool name not in `harness.tools` | Add the tool, or fix the planner prompt; the auto-injected `## Available tools` block already constrains the planner — check it appears in your prompt |
| Workflow FAILED, no fallback ran | `plan_exec` SUB_WORKFLOW failure not caught | Confirm `harness.fallback` is set; failures route through `exec_route` SWITCH to fallback |
| Guardrail tripped, workflow terminated | No fallback configured for `on_fail=retry/fix/human` | Configure a fallback or set `on_fail=raise` to acknowledge fail-closed semantics |
| Plan compiled but did wrong thing | Planner LLM produced a syntactically-valid but semantically-wrong plan | Improve `planner_instructions`; consider switching to `plan=` static plan for deterministic flows |
Loading
Loading