@homericintelligence/athena-opencode 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -17
- package/package.json +2 -2
- package/plugin.js +20 -5
- package/skills/TECHNICAL_ENGLISH.md +78 -0
- package/skills/_cli.py +26 -18
- package/skills/_support/docs/dependency-resolution.md +192 -0
- package/skills/_support/docs/policies/development.md +117 -0
- package/skills/_support/docs/policies/evidence-integrity.md +40 -0
- package/skills/_support/docs/principles/README.md +542 -0
- package/skills/_support/docs/principles/details/p001-kiss.md +114 -0
- package/skills/_support/docs/principles/details/p002-yagni.md +109 -0
- package/skills/_support/docs/principles/details/p003-dry.md +126 -0
- package/skills/_support/docs/principles/details/p004-solid.md +165 -0
- package/skills/_support/docs/principles/details/p005-modularity.md +123 -0
- package/skills/_support/docs/principles/details/p006-principle-of-least-astonishment.md +115 -0
- package/skills/_support/docs/principles/details/p007-subtraction-over-addition.md +113 -0
- package/skills/_support/docs/principles/details/p008-understand-before-subtracting.md +115 -0
- package/skills/_support/docs/principles/details/p009-general-mechanisms-over-special-cases.md +108 -0
- package/skills/_support/docs/principles/details/p010-scope-fidelity.md +117 -0
- package/skills/_support/docs/principles/details/p011-minimal-coherent-change.md +128 -0
- package/skills/_support/docs/principles/details/p012-evidence-before-modification.md +115 -0
- package/skills/_support/docs/principles/details/p013-avoid-hasty-abstractions.md +112 -0
- package/skills/_support/docs/principles/details/p014-preserve-unrequested-behavior.md +110 -0
- package/skills/_support/docs/principles/details/p015-architecture-conformance.md +124 -0
- package/skills/_support/docs/principles/details/p016-separation-of-concerns.md +125 -0
- package/skills/_support/docs/principles/details/p017-high-cohesion-low-coupling.md +130 -0
- package/skills/_support/docs/principles/details/p018-information-hiding.md +128 -0
- package/skills/_support/docs/principles/details/p019-explicit-contracts.md +134 -0
- package/skills/_support/docs/principles/details/p020-executable-architecture.md +130 -0
- package/skills/_support/docs/principles/details/p021-evolutionary-and-reversible-design.md +126 -0
- package/skills/_support/docs/principles/details/p022-test-behavior-not-implementation.md +129 -0
- package/skills/_support/docs/principles/details/p023-parameterized-table-driven-testing.md +129 -0
- package/skills/_support/docs/principles/details/p024-boundary-value-testing.md +128 -0
- package/skills/_support/docs/principles/details/p025-property-based-testing-for-invariants.md +133 -0
- package/skills/_support/docs/principles/details/p026-regression-before-repair.md +134 -0
- package/skills/_support/docs/principles/details/p027-deterministic-and-hermetic-tests.md +128 -0
- package/skills/_support/docs/principles/details/p028-test-failure-paths.md +133 -0
- package/skills/_support/docs/principles/details/p029-generalize-error-policy-preserve-specific-cause.md +131 -0
- package/skills/_support/docs/principles/details/p030-nearest-responsible-error-boundary.md +133 -0
- package/skills/_support/docs/principles/details/p031-propagate-rather-than-swallow.md +131 -0
- package/skills/_support/docs/principles/details/p032-handle-once-preserve-causality.md +137 -0
- package/skills/_support/docs/principles/details/p033-state-safe-failure-semantics.md +140 -0
- package/skills/_support/docs/principles/details/p034-fail-fast.md +132 -0
- package/skills/_support/docs/principles/details/p035-fail-secure-fail-closed.md +137 -0
- package/skills/_support/docs/principles/details/p036-graceful-degradation.md +137 -0
- package/skills/_support/docs/principles/details/p037-idempotency-before-retry.md +139 -0
- package/skills/_support/docs/principles/details/p038-bounded-retry.md +145 -0
- package/skills/_support/docs/principles/details/p039-bounded-waiting.md +151 -0
- package/skills/_support/docs/principles/details/p040-bounded-resources.md +138 -0
- package/skills/_support/docs/principles/details/p041-backpressure-and-load-shedding.md +141 -0
- package/skills/_support/docs/principles/details/p042-fault-isolation-bulkheads.md +140 -0
- package/skills/_support/docs/principles/details/p043-circuit-breakers.md +148 -0
- package/skills/_support/docs/principles/details/p044-atomicity-where-possible.md +141 -0
- package/skills/_support/docs/principles/details/p045-compensation-where-atomicity-is-impossible.md +163 -0
- package/skills/_support/docs/principles/details/p046-resumability.md +138 -0
- package/skills/_support/docs/principles/details/p047-observability-is-part-of-correctness.md +134 -0
- package/skills/_support/docs/principles/details/p048-secure-by-design.md +132 -0
- package/skills/_support/docs/principles/details/p049-secure-by-default.md +126 -0
- package/skills/_support/docs/principles/details/p050-least-privilege.md +123 -0
- package/skills/_support/docs/principles/details/p051-complete-mediation.md +124 -0
- package/skills/_support/docs/principles/details/p052-separation-of-duties.md +129 -0
- package/skills/_support/docs/principles/details/p053-validate-at-trust-boundaries.md +126 -0
- package/skills/_support/docs/principles/details/p054-defense-in-depth.md +135 -0
- package/skills/_support/docs/principles/details/p055-minimize-attack-surface.md +133 -0
- package/skills/_support/docs/principles/details/p056-secrets-stay-out-of-code-and-context.md +137 -0
- package/skills/_support/docs/principles/details/p057-supply-chain-integrity.md +135 -0
- package/skills/_support/docs/principles/details/p058-bounded-agent-authority.md +137 -0
- package/skills/_support/docs/principles/details/p059-data-is-not-instruction.md +130 -0
- package/skills/_support/docs/principles/details/p060-constrain-sub-agents.md +136 -0
- package/skills/_support/docs/principles/details/p061-separate-decision-from-high-impact-execution.md +131 -0
- package/skills/_support/docs/principles/details/p062-human-approval-for-irreversible-or-high-risk-actions.md +129 -0
- package/skills/_support/docs/principles/details/p063-requirement-to-code-traceability.md +116 -0
- package/skills/_support/docs/principles/details/p064-requirement-to-test-traceability.md +116 -0
- package/skills/_support/docs/principles/details/p065-verify-before-claiming-completion.md +129 -0
- package/skills/_support/docs/principles/details/p066-preserve-existing-work.md +114 -0
- package/skills/_support/docs/principles/details/p067-no-test-cheating.md +126 -0
- package/skills/_support/docs/principles/details/p068-no-validation-bypass.md +119 -0
- package/skills/_support/docs/principles/details/p069-independent-review-for-high-risk-changes.md +129 -0
- package/skills/_support/docs/principles/details/p070-code-health-must-not-regress.md +116 -0
- package/skills/_support/docs/principles/details/p071-consistency-over-personal-preference.md +117 -0
- package/skills/_support/docs/principles/details/p072-technical-evidence-over-preference.md +122 -0
- package/skills/_support/docs/principles/details/p073-optimize-only-with-evidence.md +123 -0
- package/skills/_support/docs/principles/details/p074-prefer-existing-mechanisms.md +121 -0
- package/skills/_support/docs/principles/details/p075-make-invalid-states-hard-to-represent.md +128 -0
- package/skills/_support/docs/principles/details/p076-parse-then-validate-then-operate.md +133 -0
- package/skills/_support/docs/principles/details/p077-separate-policy-from-mechanism.md +112 -0
- package/skills/_support/docs/principles/details/p078-single-source-of-truth.md +131 -0
- package/skills/_support/docs/principles/details/p079-explicit-ownership-and-lifetimes.md +124 -0
- package/skills/_support/docs/principles/details/p080-make-concurrency-deliberate.md +122 -0
- package/skills/_support/docs/principles/details/p081-forward-progress-with-safety.md +125 -0
- package/skills/_support/docs/principles/details/p082-design-for-cancellation.md +133 -0
- package/skills/_support/docs/principles/details/p083-irreversible-actions-last.md +124 -0
- package/skills/_support/docs/principles/details/p084-prefer-local-reasoning.md +131 -0
- package/skills/_support/docs/principles/details/p085-explicit-is-better-than-implicit.md +123 -0
- package/skills/_support/docs/principles/details/p086-readability-counts.md +113 -0
- package/skills/_support/docs/principles/details/p087-comments-explain-why-code-explains-what.md +120 -0
- package/skills/_support/docs/principles/details/p088-delete-dead-code.md +125 -0
- package/skills/_support/docs/principles/details/p089-delete-obsolete-configuration-and-dependencies.md +125 -0
- package/skills/_support/docs/principles/details/p090-prefer-negative-code.md +134 -0
- package/skills/_support/docs/principles/details/p091-test-driven-development.md +149 -0
- package/skills/_support/docs/review/README.md +59 -0
- package/skills/_support/docs/review/behavior-first-testing.md +73 -0
- package/skills/_support/docs/review/common.md +365 -0
- package/skills/_support/docs/review/design-docs.md +74 -0
- package/skills/_support/docs/review/issue-planning.md +220 -0
- package/skills/_support/docs/review/language-routing.md +141 -0
- package/skills/_support/docs/review/repository-scorecard.md +170 -0
- package/skills/advise/SKILL.md +93 -67
- package/skills/advise/scripts/list_retrievable_skills.py +3 -3
- package/skills/brainstorm/SKILL.md +160 -127
- package/skills/change-review/SKILL.md +91 -71
- package/skills/change-review/references/scope-resolution.md +69 -46
- package/skills/change-review/scripts/resolve_scope.py +119 -73
- package/skills/finalize-plan/SKILL.md +198 -139
- package/skills/git-worktrees/SKILL.md +100 -80
- package/skills/git-worktrees/scripts/prepare_worktree.py +16 -10
- package/skills/issue-review/SKILL.md +136 -79
- package/skills/learn/SKILL.md +276 -186
- package/skills/myrmidon-swarm/SKILL.md +126 -86
- package/skills/plan-issue/SKILL.md +122 -81
- package/skills/pr-review/SKILL.md +164 -114
- package/skills/pr-review/references/criteria.md +58 -37
- package/skills/pr-review/references/delivery.md +156 -98
- package/skills/pr-review/references/evidence.md +265 -148
- package/skills/pr-review/references/prevalidated.md +93 -61
- package/skills/pr-review/scripts/collect_evidence.py +211 -140
- package/skills/pr-review/scripts/diff_context.py +6 -4
- package/skills/pr-review/scripts/materialize_snapshot.py +112 -120
- package/skills/pr-review/scripts/pr_identity.py +27 -15
- package/skills/pr-review/scripts/resolve_pr.py +53 -31
- package/skills/repo-review/SKILL.md +202 -131
- package/skills/systematic-debugging/SKILL.md +210 -192
- package/skills/systematic-debugging/scripts/repository_evidence.py +9 -4
- package/skills/test-driven-development/SKILL.md +126 -96
- package/skills/tidy/SKILL.md +92 -59
- package/skills/tidy/scripts/run_tidy.py +3 -3
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# P032 — Handle Once; Preserve Causality
|
|
2
|
+
|
|
3
|
+
## Definition
|
|
4
|
+
|
|
5
|
+
One boundary must have responsibility for the outcome policy for a failure. Other layers can add safe
|
|
6
|
+
context or telemetry. They must record only one incident for the failure.
|
|
7
|
+
|
|
8
|
+
Each error translation must keep the causal chain, stack data, and structured context. These data
|
|
9
|
+
help engineers find the initial failure cause.
|
|
10
|
+
|
|
11
|
+
**Aliases:** single-owner error handling, log-or-propagate, exception chaining
|
|
12
|
+
|
|
13
|
+
## Provenance
|
|
14
|
+
|
|
15
|
+
**Classification:** practitioner heuristic.
|
|
16
|
+
|
|
17
|
+
Many languages include exception chaining. The full “handle once” rule is a cross-language
|
|
18
|
+
engineering synthesis. Athena cannot identify one source for this rule.
|
|
19
|
+
|
|
20
|
+
## Decision rule
|
|
21
|
+
|
|
22
|
+
For each failure, find the boundary that selects the outcome. Other layers must propagate the
|
|
23
|
+
failure. They can add context that is available only at their layer.
|
|
24
|
+
|
|
25
|
+
## How to apply
|
|
26
|
+
|
|
27
|
+
- Give ownership of recovery, user output, and error-level records to a clear API, process, job, or
|
|
28
|
+
workflow boundary.
|
|
29
|
+
- Use native cause links or structured error wrappers. Do not replace an error with a message that
|
|
30
|
+
has no relation.
|
|
31
|
+
- Add an operation, safe identifier, or dependency name only at the layer that knows it.
|
|
32
|
+
- Correlate retry telemetry with the last outcome. Do not record each try as a different,
|
|
33
|
+
uncorrelated incident.
|
|
34
|
+
- Keep stack and cause fields in structured telemetry. Remove sensitive data from those fields.
|
|
35
|
+
- Make sure that each translated error has the stable public category and internal cause.
|
|
36
|
+
|
|
37
|
+
## Diagram
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
flowchart TD
|
|
41
|
+
A["A layer receives a failure"] --> B{"Does this layer have responsibility for outcome policy?"}
|
|
42
|
+
B -- "Yes" --> C["Select the outcome and record one incident"]
|
|
43
|
+
B -- "No" --> D{"Does this layer have safe context available only here?"}
|
|
44
|
+
D -- "Yes" --> E["Add context and keep the cause"]
|
|
45
|
+
D -- "No" --> F["Keep the failure unchanged"]
|
|
46
|
+
E --> G["Propagate to the responsible boundary"]
|
|
47
|
+
F --> G
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Language examples
|
|
51
|
+
|
|
52
|
+
Each example adds one artifact identifier and keeps the initial storage error as the cause.
|
|
53
|
+
|
|
54
|
+
### Python
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
def load_artifact(store, key):
|
|
58
|
+
try:
|
|
59
|
+
return store.read(key)
|
|
60
|
+
except StorageError as error:
|
|
61
|
+
raise ArtifactLoadError(key) from error
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Rust
|
|
65
|
+
|
|
66
|
+
```rust
|
|
67
|
+
fn load_artifact(store: &Store, key: &str) -> Result<Artifact, ArtifactLoadError> {
|
|
68
|
+
store.read(key).map_err(|source| ArtifactLoadError {
|
|
69
|
+
key: key.to_owned(),
|
|
70
|
+
source,
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Boundaries and tensions
|
|
76
|
+
|
|
77
|
+
“Handle once” lets teams record metrics or low-severity tries at more than one layer. It does not
|
|
78
|
+
let them record one failure as more than one incident. A library can record
|
|
79
|
+
diagnostic events if its observability contract includes them. Ownership and correlation must
|
|
80
|
+
stay clearly specified.
|
|
81
|
+
|
|
82
|
+
Use this rule with [P031](p031-propagate-rather-than-swallow.md). Propagation keeps the failure available.
|
|
83
|
+
Cause preservation gives the responsible boundary sufficient diagnostic data. Security and privacy
|
|
84
|
+
controls can prevent public access to some information. These controls must keep the protected internal chain.
|
|
85
|
+
|
|
86
|
+
## Examples
|
|
87
|
+
|
|
88
|
+
### Positive application
|
|
89
|
+
|
|
90
|
+
A storage client returns a timeout with endpoint metadata. The repository wrapper links that cause
|
|
91
|
+
to `ArtifactLoadFailed` with an artifact identifier. The request boundary records one correlated
|
|
92
|
+
error event and returns the stable public code.
|
|
93
|
+
|
|
94
|
+
### Misuse or counterexample
|
|
95
|
+
|
|
96
|
+
Four nested functions each record the same exception at error level. Each function throws a new
|
|
97
|
+
exception without its cause. One incident causes four alerts. Engineers cannot get the initial
|
|
98
|
+
stack.
|
|
99
|
+
|
|
100
|
+
### Athena or agent workflow
|
|
101
|
+
|
|
102
|
+
A delegated reviewer records a tool failure with its command and exit status. The coordinator adds
|
|
103
|
+
the inspection phase. It records one failure for the user.
|
|
104
|
+
|
|
105
|
+
## Related principles
|
|
106
|
+
|
|
107
|
+
- [P031 — Propagate Rather Than Swallow](p031-propagate-rather-than-swallow.md)
|
|
108
|
+
- [P033 — State-Safe Failure Semantics](p033-state-safe-failure-semantics.md)
|
|
109
|
+
- [P038 — Bounded Retry](p038-bounded-retry.md)
|
|
110
|
+
- [P047 — Observability Is Part of Correctness](p047-observability-is-part-of-correctness.md)
|
|
111
|
+
|
|
112
|
+
## References
|
|
113
|
+
|
|
114
|
+
### Source information
|
|
115
|
+
|
|
116
|
+
- [PEP 3134 — Exception Chaining and Embedded Tracebacks](https://peps.python.org/pep-3134/)
|
|
117
|
+
— records information about automatic and specified cause retention during Python exception
|
|
118
|
+
translation.
|
|
119
|
+
- [John B. Goodenough, “Structured Exception Handling” (1975)](https://doi.org/10.1145/512976.512997)
|
|
120
|
+
— a 1975 analysis of structured exception handling. It does not give Athena's specified
|
|
121
|
+
record policy.
|
|
122
|
+
|
|
123
|
+
### Applicable information
|
|
124
|
+
|
|
125
|
+
- [OpenTelemetry Semantic Conventions 1.44.0: exceptions in logs](https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-logs/)
|
|
126
|
+
— applicable conventions for correlated exception records, stack traces, and duplicate prevention
|
|
127
|
+
in instrumentation.
|
|
128
|
+
- [C++ Core Guidelines E.17 and E.18](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#e17-dont-try-to-catch-every-exception-in-every-function)
|
|
129
|
+
— recommends no catch operation in each function and recommends a small number of specified
|
|
130
|
+
handlers.
|
|
131
|
+
|
|
132
|
+
### More information
|
|
133
|
+
|
|
134
|
+
- [P029 — Generalize Error Policy; Preserve Specific Cause](../README.md#p029) — shows stable
|
|
135
|
+
boundary taxonomies and internal diagnostics that keep the cause.
|
|
136
|
+
|
|
137
|
+
[Back to the engineering principles catalog](../README.md#p032)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# P033 — State-Safe Failure Semantics
|
|
2
|
+
|
|
3
|
+
## Definition
|
|
4
|
+
|
|
5
|
+
After failure, each applicable resource and state holder must stay unchanged or change to a
|
|
6
|
+
specified recoverable state. This state must be correct. The failure path must keep invariants and
|
|
7
|
+
use a deterministic procedure to release resources. Work after the failure must not read state that can be incorrect.
|
|
8
|
+
|
|
9
|
+
This postcondition does not include reversal of all effects.
|
|
10
|
+
|
|
11
|
+
**Aliases:** exception safety, valid-state guarantee
|
|
12
|
+
|
|
13
|
+
## Provenance
|
|
14
|
+
|
|
15
|
+
**Classification:** Athena synthesis.
|
|
16
|
+
|
|
17
|
+
Exception-safety guarantees and transaction theory contain types of this rule. Athena cannot
|
|
18
|
+
identify one source for this language-neutral rule.
|
|
19
|
+
|
|
20
|
+
## Decision rule
|
|
21
|
+
|
|
22
|
+
Before a new mutation, record the correct states after each possible failure point. If only some
|
|
23
|
+
effects can occur, record those effects in durable data. Make sure that the system can find them
|
|
24
|
+
and recover from them.
|
|
25
|
+
|
|
26
|
+
## How to apply
|
|
27
|
+
|
|
28
|
+
- Before implementation of a multistep mutation, record invariants and failure postconditions.
|
|
29
|
+
- Before a state change, validate inputs and prerequisites.
|
|
30
|
+
- Put output in temporary state. After all necessary work succeeds, publish it.
|
|
31
|
+
- Use scoped resource ownership to release locks, files, connections, and temporary resources on
|
|
32
|
+
each exit path.
|
|
33
|
+
- Use one transaction for changes in one transactional boundary. If one transaction cannot contain
|
|
34
|
+
all changes, record durable completed-step data and compensation data.
|
|
35
|
+
- In tests, put failures between steps. Make sure that the state, resource release, and recovery path are correct.
|
|
36
|
+
|
|
37
|
+
## Diagram
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
flowchart TD
|
|
41
|
+
A["Record invariants and failure postconditions"] --> B["Validate inputs and prerequisites"]
|
|
42
|
+
B --> C{"Can one transaction contain all effects?"}
|
|
43
|
+
C -- "Yes" --> D["Prepare effects and commit in one operation"]
|
|
44
|
+
C -- "No" --> E["Record durable completed-step data and compensation data"]
|
|
45
|
+
D --> F{"Did the operation fail?"}
|
|
46
|
+
E --> F
|
|
47
|
+
F -- "No" --> G["Publish the correct result"]
|
|
48
|
+
F -- "Yes" --> H["Put the system in the specified recoverable state"]
|
|
49
|
+
H --> I["Release resources and propagate the failure"]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Language examples
|
|
53
|
+
|
|
54
|
+
Each example commits the source and target account changes or keeps the previous state.
|
|
55
|
+
|
|
56
|
+
### Python
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
def transfer(db, source, target, amount):
|
|
60
|
+
with db.transaction():
|
|
61
|
+
db.debit(source, amount)
|
|
62
|
+
db.credit(target, amount)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Rust
|
|
66
|
+
|
|
67
|
+
```rust
|
|
68
|
+
fn transfer(db: &mut Db, source: Id, target: Id, amount: Money) -> Result<(), Error> {
|
|
69
|
+
let mut transaction = db.transaction()?;
|
|
70
|
+
transaction.debit(source, amount)?;
|
|
71
|
+
transaction.credit(target, amount)?;
|
|
72
|
+
transaction.commit()
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Boundaries and tensions
|
|
77
|
+
|
|
78
|
+
Failure atomicity is a stronger related guarantee, not an alias. If an operation fails, it must keep
|
|
79
|
+
the initial state unchanged for failure atomicity. State-safe failure semantics can have a specified
|
|
80
|
+
recoverable state as their result. This state must be correct.
|
|
81
|
+
|
|
82
|
+
When one transaction can contain the logical operation, use
|
|
83
|
+
[P044](p044-atomicity-where-possible.md) first. When effects occur in different systems or include
|
|
84
|
+
work with a long time, use [P045](p045-compensation-where-atomicity-is-impossible.md). Compensation
|
|
85
|
+
can give a correct business state that does not have all previous bytes.
|
|
86
|
+
|
|
87
|
+
[P034](p034-fail-fast.md) stops dangerous continuation. Termination does not correct a resource leak
|
|
88
|
+
or an effect that is not clear from only some steps. State preservation does not include failure suppression.
|
|
89
|
+
Use [P031](p031-propagate-rather-than-swallow.md) to propagate the failure.
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
### Positive application
|
|
94
|
+
|
|
95
|
+
A file generator writes and validates a temporary file. It flushes the file and uses an atomic
|
|
96
|
+
replacement for the destination. If generation fails, it removes the temporary file. The previous
|
|
97
|
+
artifact stays unchanged.
|
|
98
|
+
|
|
99
|
+
### Misuse or counterexample
|
|
100
|
+
|
|
101
|
+
A migration updates some table rows and catches an error after the update of only some rows. It returns
|
|
102
|
+
success. No rollback or durable checkpoint records the changed rows.
|
|
103
|
+
|
|
104
|
+
### Athena or agent workflow
|
|
105
|
+
|
|
106
|
+
An Athena workflow validates all of a proposed issue body before issue creation. If creation
|
|
107
|
+
fails, the workflow gives a failure result. It does not give a success result or edit paths not in task scope.
|
|
108
|
+
|
|
109
|
+
## Related principles
|
|
110
|
+
|
|
111
|
+
- [P031 — Propagate Rather Than Swallow](p031-propagate-rather-than-swallow.md)
|
|
112
|
+
- [P034 — Fail Fast](p034-fail-fast.md)
|
|
113
|
+
- [P044 — Atomicity Where Possible](p044-atomicity-where-possible.md)
|
|
114
|
+
- [P045 — Compensation Where Atomicity Is Impossible](p045-compensation-where-atomicity-is-impossible.md)
|
|
115
|
+
|
|
116
|
+
## References
|
|
117
|
+
|
|
118
|
+
### Source information
|
|
119
|
+
|
|
120
|
+
- [Härder and Reuter, “Principles of Transaction-Oriented Database Recovery” (1983)](https://doi.org/10.1145/289.291)
|
|
121
|
+
— an analysis of transaction recovery and the ACID terms for all-or-nothing state
|
|
122
|
+
changes.
|
|
123
|
+
- [Boost, Exception Safety](https://www.boost.org/doc/user-guide/exception-safety.html) — records
|
|
124
|
+
the basic and strong exception-safety guarantees for correct state and rollback behavior. These
|
|
125
|
+
guarantees have a smaller scope. Athena's rule also includes system-level effects.
|
|
126
|
+
|
|
127
|
+
### Applicable information
|
|
128
|
+
|
|
129
|
+
- [C++ Core Guidelines E.4 and E.6](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#e4-design-your-error-handling-strategy-around-invariants)
|
|
130
|
+
— applicable guidance for an error strategy that uses invariants. It recommends automatic resource
|
|
131
|
+
management to prevent leaks.
|
|
132
|
+
- [Microsoft Azure, Compensating Transaction pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/compensating-transaction)
|
|
133
|
+
— applicable guidance for recoverability when a multistep operation cannot use one atomic operation.
|
|
134
|
+
|
|
135
|
+
### More information
|
|
136
|
+
|
|
137
|
+
- [PostgreSQL 18 transaction tutorial](https://www.postgresql.org/docs/18/tutorial-transactions.html)
|
|
138
|
+
— information about all-or-nothing transaction behavior and rollback.
|
|
139
|
+
|
|
140
|
+
[Back to the engineering principles catalog](../README.md#p033)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# P034 — Fail Fast
|
|
2
|
+
|
|
3
|
+
## Definition
|
|
4
|
+
|
|
5
|
+
When a necessary invariant, configuration, dependency, or precondition is missing or incorrect, stop
|
|
6
|
+
the applicable operation near the detection point. Before incorrect state causes corruption, incorrect
|
|
7
|
+
output, or a symptom far from the defect, give a clear failure.
|
|
8
|
+
|
|
9
|
+
**Aliases:** early failure, immediate visible failure, detect invalid state near its source
|
|
10
|
+
|
|
11
|
+
## Provenance
|
|
12
|
+
|
|
13
|
+
**Classification:** practitioner heuristic.
|
|
14
|
+
|
|
15
|
+
Jim Shore gives information about the rule in IEEE Software (2004). That source is not the source
|
|
16
|
+
of the phrase or rule.
|
|
17
|
+
|
|
18
|
+
## Decision rule
|
|
19
|
+
|
|
20
|
+
If continuation cannot satisfy the correctness and safety contract, fail at the nearest applicable
|
|
21
|
+
boundary. That boundary must identify the defect and keep safe state.
|
|
22
|
+
|
|
23
|
+
## How to apply
|
|
24
|
+
|
|
25
|
+
- During startup or at the applicable entry boundary, validate necessary configuration and schemas.
|
|
26
|
+
- Before the operation uses state, examine invariants. Record the violated condition with safe context.
|
|
27
|
+
- Before irreversible work or work with high cost, reject malformed inputs and inputs that cannot be correct.
|
|
28
|
+
- Select specified result types and error statuses that identify the defect. Use assertions only for
|
|
29
|
+
programmer invariants. Do not use sentinel defaults. They prevent detection near the source.
|
|
30
|
+
- Make sure that termination releases resources. Give one diagnostic that tells the user how to
|
|
31
|
+
correct the defect.
|
|
32
|
+
- Do tests of startup, boundary, and invariant failures. Do not limit tests to correct
|
|
33
|
+
execution.
|
|
34
|
+
|
|
35
|
+
## Diagram
|
|
36
|
+
|
|
37
|
+
```mermaid
|
|
38
|
+
flowchart TD
|
|
39
|
+
A["Examine a necessary condition"] --> B{"Is the condition correct?"}
|
|
40
|
+
B -- "Yes" --> C["Continue the operation"]
|
|
41
|
+
B -- "No" --> D["Find the smallest applicable scope"]
|
|
42
|
+
D --> E["Keep correct state and release resources"]
|
|
43
|
+
E --> F["Show the defect clearly"]
|
|
44
|
+
F --> G["Stop the operation"]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Language examples
|
|
48
|
+
|
|
49
|
+
Each example rejects a missing endpoint before client creation.
|
|
50
|
+
|
|
51
|
+
### Python
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
def connect(config):
|
|
55
|
+
if not config.endpoint:
|
|
56
|
+
raise ConfigError("endpoint is required")
|
|
57
|
+
return Client(config.endpoint)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Rust
|
|
61
|
+
|
|
62
|
+
```rust
|
|
63
|
+
fn connect(config: &Config) -> Result<Client, ConfigError> {
|
|
64
|
+
let endpoint = config
|
|
65
|
+
.endpoint
|
|
66
|
+
.as_ref()
|
|
67
|
+
.filter(|endpoint| !endpoint.is_empty())
|
|
68
|
+
.ok_or(ConfigError::MissingEndpoint)?;
|
|
69
|
+
Ok(Client::new(endpoint))
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Boundaries and tensions
|
|
74
|
+
|
|
75
|
+
This principle gives the conditions and location for a stop.
|
|
76
|
+
[P035](p035-fail-secure-fail-closed.md) gives the safe authorization or security state after
|
|
77
|
+
uncertainty. [P036](p036-graceful-degradation.md) gives reduced service for a noncritical
|
|
78
|
+
capability with a specified safe fallback.
|
|
79
|
+
|
|
80
|
+
A necessary capability must not become “optional” only to keep a process active.
|
|
81
|
+
|
|
82
|
+
Use this principle only for the applicable scope. Isolate the operation with
|
|
83
|
+
[P042](p042-fault-isolation-bulkheads.md). Use [P033](p033-state-safe-failure-semantics.md) to
|
|
84
|
+
keep state. Stop only the scope that cannot operate correctly.
|
|
85
|
+
|
|
86
|
+
## Examples
|
|
87
|
+
|
|
88
|
+
### Positive application
|
|
89
|
+
|
|
90
|
+
Before a service accepts traffic, it validates its necessary signing key. A missing key causes
|
|
91
|
+
startup to fail with the configuration field name. Requests do not cause a signature error that
|
|
92
|
+
fails to identify the source.
|
|
93
|
+
|
|
94
|
+
### Misuse or counterexample
|
|
95
|
+
|
|
96
|
+
A parser replaces a missing necessary identifier with an empty string. A database constraint fails
|
|
97
|
+
after many layers. The result does not show the input defect.
|
|
98
|
+
|
|
99
|
+
### Athena or agent workflow
|
|
100
|
+
|
|
101
|
+
An Athena skill examines its declared hard dependency before it plans external steps. If the
|
|
102
|
+
skill cannot use or get the dependency, it immediately gives a prerequisite-failure result. It does
|
|
103
|
+
not give results that it did not receive. It does not give an incorrect success report.
|
|
104
|
+
|
|
105
|
+
## Related principles
|
|
106
|
+
|
|
107
|
+
- [P033 — State-Safe Failure Semantics](p033-state-safe-failure-semantics.md)
|
|
108
|
+
- [P035 — Fail Secure / Fail Closed](p035-fail-secure-fail-closed.md)
|
|
109
|
+
- [P036 — Graceful Degradation](p036-graceful-degradation.md)
|
|
110
|
+
- [P042 — Fault Isolation / Bulkheads](p042-fault-isolation-bulkheads.md)
|
|
111
|
+
|
|
112
|
+
## References
|
|
113
|
+
|
|
114
|
+
### Source information
|
|
115
|
+
|
|
116
|
+
- [Jim Shore, “Fail Fast,” IEEE Software (2004)](https://martinfowler.com/ieeeSoftware/failFast.pdf)
|
|
117
|
+
— a 2004 source that shows how failure at the detection point helps diagnostics.
|
|
118
|
+
|
|
119
|
+
### Applicable information
|
|
120
|
+
|
|
121
|
+
- [C++ Core Guidelines P.7](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#p7-catch-run-time-errors-early)
|
|
122
|
+
— applicable language guidance that recommends runtime-error detection near the source.
|
|
123
|
+
- [Microsoft Azure, Design for self-healing](https://learn.microsoft.com/en-us/azure/architecture/guide/design-principles/self-healing)
|
|
124
|
+
— applies circuit breakers to remote dependencies with continuous failures.
|
|
125
|
+
|
|
126
|
+
### More information
|
|
127
|
+
|
|
128
|
+
- [Microsoft Azure, Circuit Breaker pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)
|
|
129
|
+
— shows how rejection at the caller boundary can prevent damage to the caller and dependency during continuous
|
|
130
|
+
failure.
|
|
131
|
+
|
|
132
|
+
[Back to the engineering principles catalog](../README.md#p034)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# P035 — Fail Secure / Fail Closed
|
|
2
|
+
|
|
3
|
+
## Definition
|
|
4
|
+
|
|
5
|
+
When a security control does not give permission for an operation, keep the system in its safe
|
|
6
|
+
state. Deny the capability, keep confidentiality and integrity, and give a failure result.
|
|
7
|
+
|
|
8
|
+
Authentication, authorization, validation, and policy evaluation are security controls. A missing
|
|
9
|
+
result, timeout, parse error, or exception must not become permission.
|
|
10
|
+
|
|
11
|
+
**Aliases:** fail-safe defaults, deny by default on security failure
|
|
12
|
+
|
|
13
|
+
## Provenance
|
|
14
|
+
|
|
15
|
+
**Classification:** established principle.
|
|
16
|
+
|
|
17
|
+
Saltzer and Schroeder included “fail-safe defaults” in their 1975 paper. Practitioners used “fail closed”
|
|
18
|
+
and “fail secure” after 1975. These terms can have different meanings in safety engineering.
|
|
19
|
+
|
|
20
|
+
## Decision rule
|
|
21
|
+
|
|
22
|
+
After a clear authorization result gives permission, grant the protected operation. Classify
|
|
23
|
+
missing, invalid, stale, or indeterminate security state as denial. A higher trusted contract can
|
|
24
|
+
contain a different safe-state requirement.
|
|
25
|
+
|
|
26
|
+
## How to apply
|
|
27
|
+
|
|
28
|
+
- Set each authorization decision to denial. After all necessary checks succeed, change the
|
|
29
|
+
decision to permission.
|
|
30
|
+
- Policy-service timeouts and errors are not decisions that give permission. They can share the
|
|
31
|
+
same external denial response.
|
|
32
|
+
- When request validation or authorization fails, keep the protected resource.
|
|
33
|
+
- Do tests with missing policy, dependency timeout, corrupt credentials, exception paths, and stale
|
|
34
|
+
state.
|
|
35
|
+
- Record protected diagnostics that show the difference between denial and infrastructure failure. Do not show
|
|
36
|
+
secrets or sensitive policy information.
|
|
37
|
+
- After the security dependency operates correctly, make service available again. If a higher
|
|
38
|
+
trusted contract does not give permission, do not operate without the dependency.
|
|
39
|
+
|
|
40
|
+
## Diagram
|
|
41
|
+
|
|
42
|
+
```mermaid
|
|
43
|
+
flowchart TD
|
|
44
|
+
A["Receive a protected operation"] --> B{"Does the security result satisfy the applicable policy?"}
|
|
45
|
+
B -- "No" --> C["Deny the capability"]
|
|
46
|
+
B -- "Yes" --> D{"Does the result give permission for the operation?"}
|
|
47
|
+
D -- "No" --> C
|
|
48
|
+
D -- "Yes" --> E["Grant the capability"]
|
|
49
|
+
C --> F["Keep protected state"]
|
|
50
|
+
F --> G["Record a protected diagnostic"]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Language examples
|
|
54
|
+
|
|
55
|
+
After a clear result gives permission, each example grants deletion.
|
|
56
|
+
|
|
57
|
+
### Python
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
def may_delete(policy, actor, record):
|
|
61
|
+
try:
|
|
62
|
+
decision = policy.authorize(actor, "delete", record)
|
|
63
|
+
except PolicyError:
|
|
64
|
+
return False
|
|
65
|
+
return decision is Decision.ALLOW
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Rust
|
|
69
|
+
|
|
70
|
+
```rust
|
|
71
|
+
fn may_delete(policy: &Policy, actor: &Actor, record: &Record) -> bool {
|
|
72
|
+
matches!(
|
|
73
|
+
policy.authorize(actor, Action::Delete, record),
|
|
74
|
+
Ok(Decision::Allow)
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Boundaries and tensions
|
|
80
|
+
|
|
81
|
+
Fail closed is a security rule, not a general availability rule. For a feature without security
|
|
82
|
+
risk, [P036](p036-graceful-degradation.md) can keep available service.
|
|
83
|
+
|
|
84
|
+
A physical safe state other than “deny” can be necessary in a safety-critical system. The domain
|
|
85
|
+
hazard analysis must include that state.
|
|
86
|
+
|
|
87
|
+
With [P034](p034-fail-fast.md), an invalid security state causes failure near its source. This
|
|
88
|
+
principle denies that capability. Use [P033](p033-state-safe-failure-semantics.md) for resource
|
|
89
|
+
release and the correct failure state.
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
### Positive application
|
|
94
|
+
|
|
95
|
+
An authorization service does not give a response before the deadline. The API returns an unavailable or
|
|
96
|
+
denied outcome and keeps the record. It records a protected correlation identifier for
|
|
97
|
+
operators.
|
|
98
|
+
|
|
99
|
+
### Misuse or counterexample
|
|
100
|
+
|
|
101
|
+
Code sets `is_admin` to `true`. A role query fails, and the error path keeps the value. A security
|
|
102
|
+
control that fails grants the highest privilege.
|
|
103
|
+
|
|
104
|
+
### Athena or agent workflow
|
|
105
|
+
|
|
106
|
+
When an agent cannot find authorization for a destructive command on the specified target, it
|
|
107
|
+
stops and requests direction. Uncertainty does not become permission.
|
|
108
|
+
|
|
109
|
+
## Related principles
|
|
110
|
+
|
|
111
|
+
- [P033 — State-Safe Failure Semantics](p033-state-safe-failure-semantics.md)
|
|
112
|
+
- [P034 — Fail Fast](p034-fail-fast.md)
|
|
113
|
+
- [P036 — Graceful Degradation](p036-graceful-degradation.md)
|
|
114
|
+
- [P053 — Validate at Trust Boundaries](../README.md#p053)
|
|
115
|
+
|
|
116
|
+
## References
|
|
117
|
+
|
|
118
|
+
### Source information
|
|
119
|
+
|
|
120
|
+
- [Saltzer and Schroeder, “The Protection of Information in Computer Systems” (1975)](https://doi.org/10.1109/PROC.1975.9939)
|
|
121
|
+
— the primary source for the fail-safe-defaults principle. It uses clearly given permission for
|
|
122
|
+
access decisions, not exclusion.
|
|
123
|
+
|
|
124
|
+
### Applicable information
|
|
125
|
+
|
|
126
|
+
- [OWASP, Fail Securely](https://owasp.org/www-community/Fail_securely) — applicable application
|
|
127
|
+
guidance that puts security control exceptions on the disallow path.
|
|
128
|
+
- [OWASP Developer Guide](https://owasp.org/www-project-developer-guide/assets/exports/OWASP_Developer_Guide.pdf)
|
|
129
|
+
— guidance for safe development that includes safe failure defaults in application design.
|
|
130
|
+
|
|
131
|
+
### More information
|
|
132
|
+
|
|
133
|
+
- [NIST SP 800-53 Rev. 5, AC-3 Access Enforcement](https://doi.org/10.6028/NIST.SP.800-53r5)
|
|
134
|
+
— an official control catalog for the enforcement of approved authorizations on system
|
|
135
|
+
access.
|
|
136
|
+
|
|
137
|
+
[Back to the engineering principles catalog](../README.md#p035)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# P036 — Graceful Degradation
|
|
2
|
+
|
|
3
|
+
## Definition
|
|
4
|
+
|
|
5
|
+
A system can continue after a noncritical feature or dependency fails. The system must classify that
|
|
6
|
+
capability as optional before the failure.
|
|
7
|
+
|
|
8
|
+
The reduced mode must stay correct and safe. Operators must monitor its status. It must obey the
|
|
9
|
+
specified contract.
|
|
10
|
+
If the system did not do necessary work, its result must not show that the system did all work.
|
|
11
|
+
|
|
12
|
+
**Aliases:** degraded mode, partial service, fallback capability
|
|
13
|
+
|
|
14
|
+
## Provenance
|
|
15
|
+
|
|
16
|
+
**Classification:** established principle.
|
|
17
|
+
|
|
18
|
+
Fault-tolerant and distributed systems have used this rule for many years. Athena cannot identify
|
|
19
|
+
one source for this software rule.
|
|
20
|
+
|
|
21
|
+
## Decision rule
|
|
22
|
+
|
|
23
|
+
If a capability was not in the optional category before failure, do not use a reduced mode. The
|
|
24
|
+
tested fallback must keep all necessary invariants. If it does not, give a clear operation-failure result.
|
|
25
|
+
|
|
26
|
+
## How to apply
|
|
27
|
+
|
|
28
|
+
- Before an incident, classify each capability. Use required, optional, safety-critical, or
|
|
29
|
+
security-critical categories.
|
|
30
|
+
- Give the reduced output, notice, entry condition, recovery condition, and maximum time in the
|
|
31
|
+
contract.
|
|
32
|
+
- Select a fallback with a small number of steps and a bounded cost. For example, do not include
|
|
33
|
+
recommendations but keep the primary transaction.
|
|
34
|
+
- Keep authorization, integrity, and necessary validation. Do not use a fallback without these
|
|
35
|
+
controls.
|
|
36
|
+
- Record metrics and structured events at mode entry, at set intervals, and at recovery.
|
|
37
|
+
- Do tests of the fallback during dependency failure and overload conditions.
|
|
38
|
+
|
|
39
|
+
## Diagram
|
|
40
|
+
|
|
41
|
+
```mermaid
|
|
42
|
+
flowchart TD
|
|
43
|
+
A["A capability fails"] --> B{"Was it optional before failure?"}
|
|
44
|
+
B -- No --> C["Give an operation-failure result"]
|
|
45
|
+
B -- Yes --> D{"Does the fallback keep all necessary invariants?"}
|
|
46
|
+
D -- No --> C
|
|
47
|
+
D -- Yes --> E["Give a reduced result that users can see"]
|
|
48
|
+
E --> F["Record mode state and do a recovery test"]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Language examples
|
|
52
|
+
|
|
53
|
+
Each example keeps product search and records the optional recommendation failure.
|
|
54
|
+
|
|
55
|
+
### Python
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
def build_view(products, recommendation_result):
|
|
59
|
+
if recommendation_result.is_error:
|
|
60
|
+
return {"products": products, "recommendations": [], "mode": "degraded"}
|
|
61
|
+
return {
|
|
62
|
+
"products": products,
|
|
63
|
+
"recommendations": recommendation_result.value,
|
|
64
|
+
"mode": "full",
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Rust
|
|
69
|
+
|
|
70
|
+
```rust
|
|
71
|
+
fn build_view(products: Vec<Product>, recommendations: Result<Vec<Product>, Error>) -> View {
|
|
72
|
+
match recommendations {
|
|
73
|
+
Ok(items) => View::full(products, items),
|
|
74
|
+
Err(_) => View::degraded(products, Vec::new()),
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Boundaries and tensions
|
|
80
|
+
|
|
81
|
+
Use [P034](p034-fail-fast.md) for a failed **required** capability or a violated invariant.
|
|
82
|
+
Use [P035](p035-fail-secure-fail-closed.md) for an uncertain security decision. After failure,
|
|
83
|
+
do not reclassify a capability to increase availability.
|
|
84
|
+
|
|
85
|
+
Graceful degradation is not error suppression. When that fact changes meaning, correction, or
|
|
86
|
+
service level, the result must show reduced service.
|
|
87
|
+
|
|
88
|
+
Fallback paths can add failure modes. Their value must be more than their maintenance and test
|
|
89
|
+
cost.
|
|
90
|
+
|
|
91
|
+
## Examples
|
|
92
|
+
|
|
93
|
+
### Positive application
|
|
94
|
+
|
|
95
|
+
The recommendation service for a storefront fails. Product search and checkout continue. The site
|
|
96
|
+
does not include the recommendation panel and records the reduced mode.
|
|
97
|
+
|
|
98
|
+
### Misuse or counterexample
|
|
99
|
+
|
|
100
|
+
After a card-charge request, a timeout occurs for a payment API. The charge result is unknown. The
|
|
101
|
+
API returns “order completed” and does not show the necessary transaction uncertainty.
|
|
102
|
+
|
|
103
|
+
### Athena or agent workflow
|
|
104
|
+
|
|
105
|
+
An Athena skill can continue without optional web research. It uses results from repository checks
|
|
106
|
+
and records the research limit. It must not give a citation if it did not examine the source. It
|
|
107
|
+
must do each necessary dependency check.
|
|
108
|
+
|
|
109
|
+
## Related principles
|
|
110
|
+
|
|
111
|
+
- [P031 — Propagate Rather Than Swallow](p031-propagate-rather-than-swallow.md)
|
|
112
|
+
- [P034 — Fail Fast](p034-fail-fast.md)
|
|
113
|
+
- [P035 — Fail Secure / Fail Closed](p035-fail-secure-fail-closed.md)
|
|
114
|
+
- [P042 — Fault Isolation / Bulkheads](p042-fault-isolation-bulkheads.md)
|
|
115
|
+
|
|
116
|
+
## References
|
|
117
|
+
|
|
118
|
+
### Source information
|
|
119
|
+
|
|
120
|
+
- Athena does not identify one primary source for the general software phrase. Fault-tolerance work,
|
|
121
|
+
not one company, is the source of the rule.
|
|
122
|
+
|
|
123
|
+
### Applicable information
|
|
124
|
+
|
|
125
|
+
- [Microsoft Azure Well-Architected Framework, self-preservation](https://learn.microsoft.com/en-us/azure/well-architected/reliability/self-preservation)
|
|
126
|
+
— applicable guidance for the design, activation, communication, and recovery of a clearly specified reduced
|
|
127
|
+
mode.
|
|
128
|
+
- [Google SRE, Addressing Cascading Failures](https://sre.google/sre-book/addressing-cascading-failures/)
|
|
129
|
+
— production guidance for degraded results during overload, with tests and telemetry for the
|
|
130
|
+
low-frequency path.
|
|
131
|
+
|
|
132
|
+
### More information
|
|
133
|
+
|
|
134
|
+
- [Microsoft Azure, Throttling pattern](https://learn.microsoft.com/en-us/azure/architecture/patterns/throttling)
|
|
135
|
+
— connects degradation with capacity controls, load shedding, and service-level objectives.
|
|
136
|
+
|
|
137
|
+
[Back to the engineering principles catalog](../README.md#p036)
|