Add failure-isolation catch gate and cause-chain classification primitive (0074)#174
Merged
Merged
Conversation
Advance the spec submodule pin v0.64.0 -> v0.65.0 for accepted proposal 0074 (failure-isolation catch gate + §6.4 cause-chain classification primitive). Updates __spec_version__, the pyproject spec_version, the smoke assertion, the conformance.toml spec_pin, and regenerates the bundled AGENTS.md. conformance.toml records 0074 as implemented.
FailureIsolationMiddleware gains an optional `catch` set of error categories: an exception is caught only if the derived category of its cause chain (resolved through node_exception carriers) is in the set, conjoined with `predicate` (catch checked first, short-circuiting). The carrier-skipping walk behind `catch` and `caught_exception` becomes a public primitive, classify_cause_chain(exc) -> CaughtException. The cause-chain types (CauseLink, CaughtException) move into the new cause_chain module alongside it, so the concept has one home and events consumes it; the public openarmature.graph paths are unchanged. The default retry classifier's single-level depth is documented as deliberate (no behavior change). Unit tests cover the gate, the short-circuit, and the primitive.
Parse the `catch` directive on the failure_isolation fixture middleware config and add fixture 072 to the failure-isolation fixture set. 072 (two cases) drives the catch gate matching through a §9.7 instance node_exception carrier (degrade) and a non-matching catch (propagate).
Document the `catch` category gate and the public classify_cause_chain primitive in the middleware concepts page, and add the 0.15.0 changelog entry (advancing the spec-pin bullet to v0.65.0).
There was a problem hiding this comment.
Pull request overview
Implements spec proposal 0074 (spec v0.65.0) by adding a failure-isolation catch category gate and promoting the carrier-skipping cause-chain walk to a public classify_cause_chain primitive, plus related documentation and spec pin/version updates.
Changes:
- Add
catch(category-set gate) toFailureIsolationMiddleware, using cause-chain derived category to match throughnode_exceptioncarriers. - Introduce
graph/cause_chain.pywithCauseLink,CaughtException, andclassify_cause_chain, and re-export viaopenarmature.graph. - Bump spec pin/version to v0.65.0 and update docs, changelog, and conformance runner for fixture 072.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_failure_isolation_middleware.py | Adds unit tests for catch gating behavior and classify_cause_chain. |
| tests/test_smoke.py | Updates __spec_version__ assertion to 0.65.0. |
| tests/conformance/test_pipeline_utilities.py | Adds fixture 072 and wires catch from conformance configs. |
| src/openarmature/graph/middleware/retry.py | Documents deliberate single-level retry classification depth. |
| src/openarmature/graph/middleware/failure_isolation.py | Implements catch gate and uses classify_cause_chain for gating + event payload. |
| src/openarmature/graph/events.py | Moves CaughtException type usage to new cause-chain module import. |
| src/openarmature/graph/cause_chain.py | New public cause-chain types + classification primitive. |
| src/openarmature/graph/init.py | Re-exports cause-chain types/primitive from openarmature.graph. |
| src/openarmature/AGENTS.md | Updates bundled agent guide spec version to v0.65.0. |
| src/openarmature/init.py | Updates __spec_version__ to 0.65.0. |
| pyproject.toml | Updates tool.openarmature.spec_version to 0.65.0. |
| docs/concepts/middleware.md | Documents catch gate and the new classify_cause_chain primitive. |
| conformance.toml | Pins spec to v0.65.0 and records proposal 0074 as implemented. |
| CHANGELOG.md | Adds entry for proposal 0074 and updates spec pin narrative. |
Comments suppressed due to low confidence (1)
src/openarmature/graph/events.py:782
openarmature.graph.eventspreviously exportedCaughtException/CauseLink(via__all__). Removing them is an observable API change; consider continuing to re-export them from this module for backward compatibility (even if the canonical home moved tocause_chain).
__all__ = [
"FailureIsolatedEvent",
"FanOutEventConfig",
"InvocationCompletedEvent",
"InvocationStartedEvent",
"LlmCompletionEvent",
"LlmFailedEvent",
"LlmRetryAttemptEvent",
"MetadataAugmentationEvent",
"NodeEvent",
"ParallelBranchesEventConfig",
]
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
PR #174 review: reject a bare str for FailureIsolationMiddleware.catch (a str is a Collection[str], so it would substring-match and silently mis-gate) and normalize to a frozenset. Tighten the derived-category wording in the docstring, the concepts page, and the classify example to the outermost non-carrier link with a category (an uncategorized surface link resolves to the deeper categorized cause). Fix the stale events/errors import comment now that cause_chain imports only errors.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements proposal 0074 (spec v0.65.0): the failure-isolation
catchcause-chain category gate (§6.3) and the public cause-chain classification primitive (§6.4), plus the §6.1 retry-classifier-depth documentation. Pins the spec submodule v0.64.0 -> v0.65.0.What changed
catchgate (§6.3).FailureIsolationMiddlewaregains an optionalcatch: a set of error categories. An exception is caught only if the derived category of its cause chain (the outermost non-carrier link's category, resolved through the engine'snode_exceptioncarriers, the same value reported ascaught_exception.category) is in the set. This closes a degrade-into-crash footgun: at a wrapping placement (subgraph, fan-out instance, branch) the engine wraps the originating failure in a carrier, so apredicateinspecting the surface exception sees only the carrier and misses it, whereascatchclassifies through it.catchcomposes withpredicateas a conjunction (catch checked first, short-circuiting); both default permissive, so the both-unset default stays catch-all, and a null derived category never matches a non-empty set.catchandcaught_exceptionis promoted to a publicclassify_cause_chain(exc) -> CaughtException. The cause-chain types (CauseLink,CaughtException) move into a newgraph/cause_chain.pyalongside the primitive, so the concept has one cohesive home andeventsconsumes it; the publicopenarmature.graph.*import paths are unchanged via the re-export.catchform (spec MAY); the normative contract is the category set.Testing
Notes
0.15.0changelog date is tentative pending the release tag.