CDX-301h · Module 2
Partial Completion & Graceful Degradation
3 min read
Not every pipeline failure requires a full abort. Graceful degradation means accepting partial results when some agents succeed and others fail. If three out of five agents complete their tasks successfully, the pipeline delivers 60% of the value rather than 0%. This requires that the decomposition produces independently valuable units — each agent's output must be usable on its own, not just as input to the next agent.
Implementing graceful degradation requires three design decisions. First, which tasks are mandatory (pipeline aborts if they fail) and which are optional (pipeline continues without them)? A core implementation is mandatory; documentation is optional. Second, what is the minimum viable output? If the test writer fails but the implementer succeeds, is untested code acceptable as a partial result? Third, how does the pipeline report partial completion — which deliverables were produced and which were skipped?
from dataclasses import dataclass
from enum import Enum
class TaskPriority(Enum):
MANDATORY = "mandatory" # Pipeline fails without this
IMPORTANT = "important" # Degrades quality if missing
OPTIONAL = "optional" # Nice-to-have, skip if failed
@dataclass
class TaskResult:
agent: str
priority: TaskPriority
succeeded: bool
output: str
def evaluate_pipeline(results: list[TaskResult]) -> dict:
"""Determine if partial results are acceptable."""
mandatory_failures = [
r for r in results
if r.priority == TaskPriority.MANDATORY and not r.succeeded
]
if mandatory_failures:
return {
"status": "abort",
"reason": f"Mandatory tasks failed: "
f"{[r.agent for r in mandatory_failures]}",
}
succeeded = [r for r in results if r.succeeded]
skipped = [r for r in results if not r.succeeded]
return {
"status": "partial" if skipped else "complete",
"delivered": [r.agent for r in succeeded],
"skipped": [r.agent for r in skipped],
}
Do This
- Classify every task as mandatory, important, or optional before the pipeline runs
- Design decompositions that produce independently valuable units — not just inputs to the next step
- Report partial completion clearly — list what was delivered and what was skipped
- Accept partial results as progress — 60% delivered is better than 0% from a full abort
Avoid This
- Treat all tasks as mandatory — this makes the pipeline fragile and all-or-nothing
- Accept partial results that are internally inconsistent — partial output must still compile and pass checks
- Hide skipped tasks from the final report — the user needs to know what is missing
- Design pipelines where every task depends on every other task — this eliminates any possibility of graceful degradation