@hassangameryt/freeflow 0.5.0 → 0.7.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +4 -5
- package/README.md +141 -163
- package/capabilities/cognitive-routing/SKILL.md +387 -0
- package/capabilities/context-virtualization/SKILL.md +103 -0
- package/capabilities/conversation-history/SKILL.md +53 -0
- package/command-surface.json +6 -37
- package/hooks/freeflow-runtime-context.mjs +50 -541
- package/hooks/hooks.json +1 -26
- package/hooks/tests/check-runtime-context-hook.sh +114 -308
- package/package.json +27 -17
- package/pi-extension/dist/cognitive-routing/commands.js +96 -0
- package/pi-extension/dist/cognitive-routing/config.js +232 -0
- package/pi-extension/dist/cognitive-routing/controller.js +1292 -0
- package/pi-extension/dist/cognitive-routing/history.js +451 -0
- package/pi-extension/dist/cognitive-routing/host.js +188 -0
- package/pi-extension/dist/cognitive-routing/pi-routing-session.js +414 -0
- package/pi-extension/dist/cognitive-routing/pi-session-control.js +320 -0
- package/pi-extension/dist/cognitive-routing/runtime.js +43 -0
- package/pi-extension/dist/cognitive-routing/tool.js +212 -0
- package/pi-extension/dist/cognitive-routing/types.js +6 -0
- package/pi-extension/dist/context-virtualization/commands.js +89 -0
- package/pi-extension/dist/context-virtualization/projector.js +42 -0
- package/pi-extension/dist/context-virtualization/runtime.js +356 -0
- package/pi-extension/dist/context-virtualization/state.js +57 -0
- package/pi-extension/dist/context-virtualization/types.js +10 -0
- package/pi-extension/dist/conversation-history/passages.js +66 -0
- package/pi-extension/dist/conversation-history/ranking.js +105 -0
- package/pi-extension/dist/conversation-history/runtime.js +226 -0
- package/pi-extension/dist/conversation-history/search.js +56 -0
- package/pi-extension/dist/conversation-history/types.js +1 -0
- package/pi-extension/dist/freeflow-context/resolver.js +120 -0
- package/pi-extension/dist/freeflow-context/runtime.js +80 -0
- package/pi-extension/dist/freeflow-context/source-projector.js +95 -0
- package/pi-extension/dist/freeflow-context/tool.js +308 -0
- package/pi-extension/dist/freeflow-context/types.js +12 -0
- package/pi-extension/dist/freeflow-context/visibility.js +28 -0
- package/pi-extension/dist/index.js +564 -129
- package/pi-extension/dist/runtime/runtime-context.js +357 -470
- package/pi-extension/dist/runtime/runtime-identity.js +5 -0
- package/pi-extension/dist/settings/settings-tui.js +78 -0
- package/pi-extension/dist/settings/settings-ui.js +572 -826
- package/pi-extension/dist/ui/text-component.js +57 -0
- package/pi-extension/src/cognitive-routing/commands.ts +129 -0
- package/pi-extension/src/cognitive-routing/config.ts +303 -0
- package/pi-extension/src/cognitive-routing/controller.ts +1628 -0
- package/pi-extension/src/cognitive-routing/history.ts +650 -0
- package/pi-extension/src/cognitive-routing/host.ts +266 -0
- package/pi-extension/src/cognitive-routing/pi-routing-session.ts +538 -0
- package/pi-extension/src/cognitive-routing/pi-session-control.ts +444 -0
- package/pi-extension/src/cognitive-routing/runtime.ts +57 -0
- package/pi-extension/src/cognitive-routing/tool.ts +273 -0
- package/pi-extension/src/cognitive-routing/types.ts +89 -0
- package/pi-extension/src/context-virtualization/commands.ts +111 -0
- package/pi-extension/src/context-virtualization/projector.ts +62 -0
- package/pi-extension/src/context-virtualization/runtime.ts +406 -0
- package/pi-extension/src/context-virtualization/state.ts +79 -0
- package/pi-extension/src/context-virtualization/types.ts +92 -0
- package/pi-extension/src/conversation-history/passages.ts +81 -0
- package/pi-extension/src/conversation-history/ranking.ts +155 -0
- package/pi-extension/src/conversation-history/runtime.ts +250 -0
- package/pi-extension/src/conversation-history/search.ts +79 -0
- package/pi-extension/src/conversation-history/types.ts +31 -0
- package/pi-extension/src/freeflow-context/resolver.ts +139 -0
- package/pi-extension/src/freeflow-context/runtime.ts +100 -0
- package/pi-extension/src/freeflow-context/source-projector.ts +106 -0
- package/pi-extension/src/freeflow-context/tool.ts +360 -0
- package/pi-extension/src/freeflow-context/types.ts +70 -0
- package/pi-extension/src/freeflow-context/visibility.ts +53 -0
- package/pi-extension/src/index.ts +597 -135
- package/pi-extension/src/runtime/runtime-context.ts +373 -491
- package/pi-extension/src/runtime/runtime-identity.ts +8 -0
- package/pi-extension/src/settings/settings-tui.ts +93 -0
- package/pi-extension/src/settings/settings-ui.ts +679 -910
- package/pi-extension/src/ui/text-component.ts +66 -0
- package/pi-extension/tests/cognitive-routing/commands.test.js +134 -0
- package/pi-extension/tests/cognitive-routing/controller.test.js +1128 -0
- package/pi-extension/tests/cognitive-routing/extension-lifecycle.test.js +1142 -0
- package/pi-extension/tests/cognitive-routing/history.test.js +274 -0
- package/pi-extension/tests/cognitive-routing/host-fixture.js +4 -0
- package/pi-extension/tests/cognitive-routing/host-identity.test.js +63 -0
- package/pi-extension/tests/cognitive-routing/pi-normal-lifecycle.test.js +434 -0
- package/pi-extension/tests/cognitive-routing/pi-session-control.test.js +174 -0
- package/pi-extension/tests/cognitive-routing/pi-session-history.test.js +91 -0
- package/pi-extension/tests/cognitive-routing/profile-resolution.test.js +279 -0
- package/pi-extension/tests/cognitive-routing/tool.test.js +230 -0
- package/pi-extension/tests/context-virtualization/extension.test.js +749 -0
- package/pi-extension/tests/context-virtualization/projector.test.js +110 -0
- package/pi-extension/tests/context-virtualization/runtime.test.js +216 -0
- package/pi-extension/tests/conversation-history/runtime.test.js +98 -0
- package/pi-extension/tests/conversation-history/search.test.js +97 -0
- package/pi-extension/tests/integration/mode-free-core.test.js +218 -0
- package/pi-extension/tests/integration/pi-extension.test.js +532 -3701
- package/pi-extension/tests/integration/prompt-architecture.test.js +350 -0
- package/pi-extension/tests/integration/unaffected-regressions.test.js +411 -0
- package/runtime/prompts/cognitive-routing.md +10 -0
- package/runtime/prompts/context-virtualization.md +3 -0
- package/runtime/prompts/conversation-history.md +3 -0
- package/runtime/prompts/core.md +84 -0
- package/runtime/prompts/interaction-contract.md +11 -0
- package/skills/action-selection/SKILL.md +140 -0
- package/skills/action-selection/references/trajectory-stalls.md +71 -0
- package/skills/bypass/SKILL.md +109 -38
- package/skills/commit-work/SKILL.md +94 -55
- package/skills/commit-work/references/git-state-edges.md +94 -0
- package/skills/commit-work/references/simple-push.md +92 -0
- package/skills/commit-work/references/staging-decisions.md +79 -46
- package/skills/decision-gate/SKILL.md +80 -22
- package/skills/design-for-depth/SKILL.md +206 -60
- package/skills/design-for-depth/references/design-pressure-signals.md +108 -240
- package/skills/design-for-depth/references/interface-design-loop.md +77 -97
- package/skills/design-for-depth/references/module-and-dependency-design.md +147 -0
- package/skills/design-for-depth/references/software-design-philosophy.md +128 -174
- package/skills/design-for-depth/references/state-and-failure-boundaries.md +136 -0
- package/skills/diagnose-failure/SKILL.md +200 -48
- package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +18 -6
- package/skills/diagnose-failure/references/{flaky-and-performance.md → flaky-and-performance-diagnosis.md} +13 -5
- package/skills/discuss/SKILL.md +119 -65
- package/skills/discuss/references/discussion-continuity.md +123 -0
- package/skills/evaluate-skill/SKILL.md +166 -52
- package/skills/evaluate-skill/references/{definition-schema.md → evaluation-definition-schema.md} +43 -3
- package/skills/evaluate-skill/references/evaluation-design.md +56 -30
- package/skills/evaluate-skill/references/execution-and-evidence.md +8 -3
- package/skills/evaluate-skill/references/review-and-revision.md +62 -21
- package/skills/evaluate-skill/scripts/lib/definitions.mjs +114 -3
- package/skills/evaluate-skill/scripts/lib/grade-interaction.mjs +156 -1
- package/skills/evaluate-skill/scripts/lib/grade.mjs +9 -1
- package/skills/evaluate-skill/scripts/lib/pi.mjs +147 -32
- package/skills/evaluate-skill/scripts/lib/rpc.mjs +4 -4
- package/skills/evaluate-skill/scripts/lib/runner.mjs +36 -14
- package/skills/evaluate-skill/scripts/lib/sandbox.mjs +92 -0
- package/skills/evaluate-skill/scripts/pi-guard.mjs +1 -1
- package/skills/evaluate-skill/scripts/pi-observer.mjs +66 -0
- package/skills/evaluate-skill/scripts/skill-eval.mjs +6 -5
- package/skills/execute-work/SKILL.md +99 -57
- package/skills/execute-work/references/code-practices.md +4 -4
- package/skills/execute-work/references/execute-work-edges.md +62 -0
- package/skills/finish-branch/SKILL.md +2 -2
- package/skills/finish-branch/references/integration-options.md +1 -1
- package/skills/handoff/SKILL.md +3 -3
- package/skills/launch-work/SKILL.md +1 -1
- package/skills/launch-work/references/launch-readiness.md +2 -2
- package/skills/migration-work/SKILL.md +2 -2
- package/skills/migration-work/references/migration-lifecycle.md +1 -1
- package/skills/release-work/SKILL.md +1 -1
- package/skills/release-work/references/release-evidence.md +1 -1
- package/skills/review-artifact/SKILL.md +129 -66
- package/skills/review-artifact/references/adjudicate-artifact-review.md +101 -0
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +159 -0
- package/skills/review-work/SKILL.md +113 -68
- package/skills/review-work/references/adjudicate-work-review.md +97 -0
- package/skills/review-work/references/independent-work-reviewer-contract.md +139 -0
- package/skills/review-work/references/security-risk-lens.md +18 -16
- package/skills/setup-freeflow/SKILL.md +16 -17
- package/skills/setup-freeflow/references/activation-contract.md +24 -30
- package/skills/setup-freeflow/references/host-setup.md +6 -7
- package/skills/simplify-code/SKILL.md +97 -39
- package/skills/simplify-code/references/simplification-patterns.md +1 -1
- package/skills/tdd/SKILL.md +100 -53
- package/skills/tdd/references/test-design.md +3 -3
- package/skills/track-work/SKILL.md +195 -58
- package/skills/track-work/references/working-record-format.md +515 -0
- package/skills/track-work/scripts/lib/document.mjs +713 -0
- package/skills/track-work/scripts/lib/format.mjs +166 -0
- package/skills/track-work/scripts/lib/store.mjs +233 -0
- package/skills/track-work/scripts/lib/transitions.mjs +790 -0
- package/skills/track-work/scripts/lib/views.mjs +40 -0
- package/skills/track-work/scripts/working-record.mjs +316 -0
- package/skills/verify-work/SKILL.md +57 -19
- package/skills/verify-work/references/browser-runtime-evidence.md +2 -2
- package/skills/verify-work/references/integration-evidence.md +1 -7
- package/skills/verify-work/references/performance-evidence.md +2 -2
- package/skills/workflow/SKILL.md +137 -55
- package/skills/workflow/references/domain-skill-composition.md +26 -40
- package/skills/write-plan/SKILL.md +1 -1
- package/skills/write-skill/SKILL.md +218 -61
- package/skills/write-skill/references/activation-boundaries.md +63 -21
- package/skills/write-skill/references/agent-first-instructions.md +61 -27
- package/skills/write-skill/references/progressive-disclosure.md +97 -33
- package/skills/write-skill/references/skill-dependency-graphs.md +190 -0
- package/capabilities/output-router/SKILL.md +0 -206
- package/capabilities/output-router/references/safety-policy.md +0 -40
- package/capabilities/output-router/references/setup.md +0 -110
- package/pi-extension/dist/output-router/host-producer-identification.js +0 -232
- package/pi-extension/dist/output-router/native-safety-net.js +0 -216
- package/pi-extension/dist/output-router/observed-tool-routing.js +0 -122
- package/pi-extension/dist/output-router/renderers.js +0 -1023
- package/pi-extension/dist/output-router/router-tools.js +0 -554
- package/pi-extension/dist/output-router/schemas.js +0 -383
- package/pi-extension/dist/output-router/status.js +0 -744
- package/pi-extension/dist/output-router/utils.js +0 -502
- package/pi-extension/src/output-router/host-producer-identification.ts +0 -256
- package/pi-extension/src/output-router/native-safety-net.ts +0 -248
- package/pi-extension/src/output-router/observed-tool-routing.ts +0 -134
- package/pi-extension/src/output-router/renderers.ts +0 -1108
- package/pi-extension/src/output-router/router-tools.ts +0 -579
- package/pi-extension/src/output-router/schemas.ts +0 -387
- package/pi-extension/src/output-router/status.ts +0 -791
- package/pi-extension/src/output-router/utils.ts +0 -554
- package/pi-extension/tests/output-router/observed-producers.test.js +0 -132
- package/pi-extension/tests/output-router/search.test.js +0 -722
- package/router/dist/benchmarks/benchmark-harness.d.ts +0 -35
- package/router/dist/benchmarks/benchmark-harness.js +0 -92
- package/router/dist/benchmarks/benchmarks.d.ts +0 -109
- package/router/dist/benchmarks/benchmarks.js +0 -979
- package/router/dist/benchmarks/codex-qa-benchmarks.d.ts +0 -95
- package/router/dist/benchmarks/codex-qa-benchmarks.js +0 -500
- package/router/dist/benchmarks/command-benchmarks.d.ts +0 -143
- package/router/dist/benchmarks/command-benchmarks.js +0 -698
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.d.ts +0 -82
- package/router/dist/benchmarks/context-mode-normalized-benchmarks.js +0 -773
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.d.ts +0 -132
- package/router/dist/benchmarks/context-mode-real-deep-benchmark.js +0 -1380
- package/router/dist/benchmarks/context-saving-baseline.d.ts +0 -60
- package/router/dist/benchmarks/context-saving-baseline.js +0 -470
- package/router/dist/benchmarks/index-benchmarks.d.ts +0 -103
- package/router/dist/benchmarks/index-benchmarks.js +0 -862
- package/router/dist/benchmarks/storage-policy-benchmarks.d.ts +0 -101
- package/router/dist/benchmarks/storage-policy-benchmarks.js +0 -618
- package/router/dist/benchmarks/vault-index-benchmarks.d.ts +0 -56
- package/router/dist/benchmarks/vault-index-benchmarks.js +0 -322
- package/router/dist/config/config.d.ts +0 -103
- package/router/dist/config/config.js +0 -632
- package/router/dist/config/router-contract.d.ts +0 -10
- package/router/dist/config/router-contract.js +0 -54
- package/router/dist/config/schema.d.ts +0 -27
- package/router/dist/config/schema.js +0 -648
- package/router/dist/config/types.d.ts +0 -573
- package/router/dist/config/types.js +0 -41
- package/router/dist/evidence/bounded-evidence.d.ts +0 -40
- package/router/dist/evidence/bounded-evidence.js +0 -323
- package/router/dist/evidence/evidence-range-selector.d.ts +0 -24
- package/router/dist/evidence/evidence-range-selector.js +0 -232
- package/router/dist/evidence/evidence-search.d.ts +0 -27
- package/router/dist/evidence/evidence-search.js +0 -490
- package/router/dist/evidence/evidence.d.ts +0 -38
- package/router/dist/evidence/evidence.js +0 -200
- package/router/dist/evidence/failure-contracts.d.ts +0 -37
- package/router/dist/evidence/failure-contracts.js +0 -166
- package/router/dist/evidence/line-ranges.d.ts +0 -24
- package/router/dist/evidence/line-ranges.js +0 -22
- package/router/dist/experiments/local-index.d.ts +0 -64
- package/router/dist/experiments/local-index.js +0 -581
- package/router/dist/index.d.ts +0 -30
- package/router/dist/index.js +0 -32
- package/router/dist/local/local-traversal.d.ts +0 -18
- package/router/dist/local/local-traversal.js +0 -334
- package/router/dist/processing/engine.d.ts +0 -132
- package/router/dist/processing/engine.js +0 -533
- package/router/dist/processing/reducers.d.ts +0 -280
- package/router/dist/processing/reducers.js +0 -1673
- package/router/dist/processing/renderers.d.ts +0 -31
- package/router/dist/processing/renderers.js +0 -195
- package/router/dist/processing/scripts.d.ts +0 -91
- package/router/dist/processing/scripts.js +0 -386
- package/router/dist/repo/repo-traversal.d.ts +0 -18
- package/router/dist/repo/repo-traversal.js +0 -245
- package/router/dist/routing/observed-reducers.d.ts +0 -41
- package/router/dist/routing/observed-reducers.js +0 -661
- package/router/dist/routing/observed-routing.d.ts +0 -26
- package/router/dist/routing/observed-routing.js +0 -378
- package/router/dist/routing/parsers.d.ts +0 -16
- package/router/dist/routing/parsers.js +0 -521
- package/router/dist/routing/run-filters.d.ts +0 -60
- package/router/dist/routing/run-filters.js +0 -238
- package/router/dist/routing/run-reducers.d.ts +0 -49
- package/router/dist/routing/run-reducers.js +0 -122
- package/router/dist/sandbox/adapter-roots.d.ts +0 -46
- package/router/dist/sandbox/adapter-roots.js +0 -66
- package/router/dist/sandbox/eryx-python-adapter.d.ts +0 -13
- package/router/dist/sandbox/eryx-python-adapter.js +0 -868
- package/router/dist/sandbox/jq-wasm-adapter.d.ts +0 -9
- package/router/dist/sandbox/jq-wasm-adapter.js +0 -429
- package/router/dist/sandbox/quickjs-wasi-adapter.d.ts +0 -13
- package/router/dist/sandbox/quickjs-wasi-adapter.js +0 -384
- package/router/dist/sandbox/script-sandbox.d.ts +0 -134
- package/router/dist/sandbox/script-sandbox.js +0 -337
- package/router/dist/setup/script-transform-adapters.d.ts +0 -32
- package/router/dist/setup/script-transform-adapters.js +0 -278
- package/router/dist/tools/batch.d.ts +0 -33
- package/router/dist/tools/batch.js +0 -586
- package/router/dist/tools/run.d.ts +0 -62
- package/router/dist/tools/run.js +0 -1304
- package/router/dist/tools/search.d.ts +0 -66
- package/router/dist/tools/search.js +0 -1364
- package/router/dist/transform/engine.d.ts +0 -168
- package/router/dist/transform/engine.js +0 -2072
- package/router/dist/vault/vault-index.d.ts +0 -125
- package/router/dist/vault/vault-index.js +0 -416
- package/router/dist/vault/vault.d.ts +0 -138
- package/router/dist/vault/vault.js +0 -630
- package/runtime/interaction-contract.md +0 -16
- package/skills/discuss/references/checkpoints.md +0 -66
- package/skills/execute-work/references/execution-loop.md +0 -77
- package/skills/mode-contract/SKILL.md +0 -104
- package/skills/review-artifact/references/reviewer-prompt.md +0 -148
- package/skills/review-work/references/reviewer-prompt.md +0 -134
- package/skills/track-work/references/working-record-schema.md +0 -378
- package/skills/workflow/references/workflow-loop.md +0 -92
- /package/skills/handoff/references/{templates.md → handoff-templates.md} +0 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Module And Dependency Design
|
|
2
|
+
|
|
3
|
+
Read this when module decomposition, cohesion, dependency direction, cycles, layering, policy-versus-infrastructure ownership, or change propagation materially affects the design.
|
|
4
|
+
|
|
5
|
+
Do not use this reference merely because the codebase has many files or dependencies.
|
|
6
|
+
|
|
7
|
+
## Decompose Around Coherent Decisions
|
|
8
|
+
|
|
9
|
+
A module should own one coherent outcome, policy, state boundary, or failure unit.
|
|
10
|
+
|
|
11
|
+
Do not split only by:
|
|
12
|
+
|
|
13
|
+
- processing step;
|
|
14
|
+
- technical file type;
|
|
15
|
+
- framework convention;
|
|
16
|
+
- arbitrary size;
|
|
17
|
+
- desire for more abstractions.
|
|
18
|
+
|
|
19
|
+
Ask:
|
|
20
|
+
|
|
21
|
+
- Which behavior changes together?
|
|
22
|
+
- Which decision has one reason to change?
|
|
23
|
+
- Which state and failure behavior belong together?
|
|
24
|
+
- What should callers stop coordinating?
|
|
25
|
+
|
|
26
|
+
## Prefer Cohesion Over Convenience
|
|
27
|
+
|
|
28
|
+
High cohesion means related behavior, invariants, state, and failure handling live together.
|
|
29
|
+
|
|
30
|
+
Pressure exists when:
|
|
31
|
+
|
|
32
|
+
- one module owns unrelated policies;
|
|
33
|
+
- one policy is spread across many modules;
|
|
34
|
+
- state transitions are separated from their invariants;
|
|
35
|
+
- failure handling is detached from the operation it protects;
|
|
36
|
+
- callers assemble the real behavior from helpers.
|
|
37
|
+
|
|
38
|
+
Do not centralize unrelated behavior merely to reduce duplication.
|
|
39
|
+
|
|
40
|
+
## Direct Dependencies Toward Stable Policy
|
|
41
|
+
|
|
42
|
+
Policy should not depend directly on volatile infrastructure details when those details can change independently.
|
|
43
|
+
|
|
44
|
+
Prefer:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
stable outcome or policy
|
|
48
|
+
-> small dependency interface
|
|
49
|
+
-> infrastructure adapter
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Use dependency inversion only when it hides real variation, provider mechanics, migration, or testing control.
|
|
53
|
+
|
|
54
|
+
Do not add interfaces around every concrete implementation.
|
|
55
|
+
|
|
56
|
+
## Detect Dependency Cycles
|
|
57
|
+
|
|
58
|
+
A dependency cycle often indicates:
|
|
59
|
+
|
|
60
|
+
- responsibilities are divided incorrectly;
|
|
61
|
+
- shared policy has no owner;
|
|
62
|
+
- state is jointly owned;
|
|
63
|
+
- interfaces expose implementation details;
|
|
64
|
+
- modules must know each other’s lifecycle.
|
|
65
|
+
|
|
66
|
+
Do not break a cycle by moving imports or creating a neutral-looking utility while preserving the same conceptual cycle.
|
|
67
|
+
|
|
68
|
+
Name the shared decision and assign ownership.
|
|
69
|
+
|
|
70
|
+
## Preserve Honest Layering
|
|
71
|
+
|
|
72
|
+
A layer is useful when it hides a distinct level of decision.
|
|
73
|
+
|
|
74
|
+
A layer is shallow when it:
|
|
75
|
+
|
|
76
|
+
- forwards calls;
|
|
77
|
+
- renames types;
|
|
78
|
+
- exposes lower-layer errors and states;
|
|
79
|
+
- requires callers to understand both layers;
|
|
80
|
+
- exists only to satisfy a pattern.
|
|
81
|
+
|
|
82
|
+
Allow a higher-level module to request outcomes. Keep infrastructure details below the boundary.
|
|
83
|
+
|
|
84
|
+
## Use Ports And Adapters Proportionately
|
|
85
|
+
|
|
86
|
+
A port is an outcome or capability required by policy. An adapter supplies concrete infrastructure.
|
|
87
|
+
|
|
88
|
+
Use when:
|
|
89
|
+
|
|
90
|
+
- provider variation exists;
|
|
91
|
+
- migration is known;
|
|
92
|
+
- infrastructure details leak into policy;
|
|
93
|
+
- tests require safe dependency control.
|
|
94
|
+
|
|
95
|
+
Avoid when:
|
|
96
|
+
|
|
97
|
+
- one stable implementation exists;
|
|
98
|
+
- the wrapper hides no decision;
|
|
99
|
+
- the generic interface preserves provider quirks;
|
|
100
|
+
- caller complexity does not decrease.
|
|
101
|
+
|
|
102
|
+
## Keep Shared Code From Becoming Shared Ownership
|
|
103
|
+
|
|
104
|
+
A shared helper may centralize syntax while leaving policy ownership scattered.
|
|
105
|
+
|
|
106
|
+
Before extracting shared code, ask:
|
|
107
|
+
|
|
108
|
+
- Is this one concept that should evolve together?
|
|
109
|
+
- Who owns its behavior and failure contract?
|
|
110
|
+
- Are callers still making the same decision independently?
|
|
111
|
+
- Does extraction remove coordination or merely relocate code?
|
|
112
|
+
|
|
113
|
+
Some duplication is cheaper than a shared abstraction with unclear ownership.
|
|
114
|
+
|
|
115
|
+
## Test Through Module Contracts
|
|
116
|
+
|
|
117
|
+
Module tests should protect:
|
|
118
|
+
|
|
119
|
+
- coherent behavior;
|
|
120
|
+
- invariants;
|
|
121
|
+
- public failure semantics;
|
|
122
|
+
- dependency contracts;
|
|
123
|
+
- real seams.
|
|
124
|
+
|
|
125
|
+
Question module shape when tests must:
|
|
126
|
+
|
|
127
|
+
- construct many internals;
|
|
128
|
+
- reproduce dependency ordering;
|
|
129
|
+
- mock several owned collaborators;
|
|
130
|
+
- inspect states callers should not know.
|
|
131
|
+
|
|
132
|
+
Do not make production architecture imitate the test framework.
|
|
133
|
+
|
|
134
|
+
## Return
|
|
135
|
+
|
|
136
|
+
Return:
|
|
137
|
+
|
|
138
|
+
- affected modules and responsibilities;
|
|
139
|
+
- policy, state, or failure ownership;
|
|
140
|
+
- dependency direction;
|
|
141
|
+
- cycle or layering pressure;
|
|
142
|
+
- proposed boundary and caller contract;
|
|
143
|
+
- variation or migration justifying seams;
|
|
144
|
+
- evidence and unresolved decisions;
|
|
145
|
+
- narrowest supported route.
|
|
146
|
+
|
|
147
|
+
Stop when dependencies support the selected outcome without unnecessary coordination. Do not reorganize the entire codebase for conceptual purity.
|
|
@@ -1,248 +1,202 @@
|
|
|
1
1
|
# Software Design Philosophy
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Read this when structural pressure is supported but the likely-changing decision or missing information-hiding boundary cannot yet be named.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Use only the principle that identifies the missing ownership. Do not produce a literature review, pattern catalog, or system-wide redesign.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Complexity Is Coordination
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Complexity is not line count. It appears as:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- **Change amplification:** one behavior change requires many surrounding edits.
|
|
12
|
+
- **Cognitive load:** callers must remember many facts to use the module correctly.
|
|
13
|
+
- **Obscurity:** important rules or ownership are difficult to discover.
|
|
14
|
+
- **Dependency burden:** safe change requires understanding unrelated modules.
|
|
15
|
+
- **Unknown unknowns:** a caller cannot tell what else it must inspect.
|
|
12
16
|
|
|
13
|
-
|
|
17
|
+
A large implementation can be simple to use. A small helper can be complex when every caller must know its quirks.
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
### Complexity
|
|
18
|
-
|
|
19
|
-
Complexity shows up as:
|
|
19
|
+
Ask:
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- unknown unknowns, where a future agent cannot tell what it must inspect.
|
|
21
|
+
- What must a future caller or maintainer know?
|
|
22
|
+
- How many locations must change together?
|
|
23
|
+
- Which important facts are difficult to discover?
|
|
24
|
+
- Which dependencies must be inspected before a safe change?
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
## Deep Modules
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
A deep module provides substantial coherent behavior through a small interface.
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
Callers state the outcome they need. The module owns:
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
- sequencing;
|
|
33
|
+
- likely-changing policy;
|
|
34
|
+
- internal state transitions;
|
|
35
|
+
- cleanup;
|
|
36
|
+
- provider mechanics;
|
|
37
|
+
- internal failure handling.
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
- implementation owns sequencing and policy details;
|
|
37
|
-
- tests can verify behavior through the public interface;
|
|
38
|
-
- future changes stay localized;
|
|
39
|
-
- docs and review comments do not need to explain the hidden machinery every time.
|
|
39
|
+
A wrapper is not deep merely because it hides lines. It is deep when callers stop knowing concepts or coordinating protocol.
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Depth is not breadth. A god module hiding unrelated decisions is not deep.
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
- callers pass many flags and know ordering rules;
|
|
45
|
-
- tests assert internal call sequences;
|
|
46
|
-
- wrappers rename work without hiding decisions;
|
|
47
|
-
- future agents still need to inspect everything to use it safely.
|
|
43
|
+
## Strategic And Tactical Design
|
|
48
44
|
|
|
49
|
-
|
|
45
|
+
A tactical change makes the current patch fit.
|
|
50
46
|
|
|
51
|
-
|
|
47
|
+
A strategic change spends proportionate effort so that the next likely change remains local and correct use remains simple.
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
Do not redesign everything in anticipation of the future. Do stop when the current patch clearly:
|
|
54
50
|
|
|
55
|
-
|
|
51
|
+
- spreads a likely-changing decision;
|
|
52
|
+
- adds caller protocol;
|
|
53
|
+
- exposes internal state;
|
|
54
|
+
- creates another required workaround;
|
|
55
|
+
- makes the next accepted change materially harder.
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
- Do stop when the local patch clearly makes the next slice, review, or bug fix harder.
|
|
59
|
-
- Return the structural evidence to [Workflow](../../workflow/SKILL.md) when a tactical patch is becoming structural work.
|
|
57
|
+
Strategic design is proportionate investment, not maximal architecture.
|
|
60
58
|
|
|
61
|
-
##
|
|
59
|
+
## Hide Likely-Changing Decisions
|
|
62
60
|
|
|
63
|
-
|
|
61
|
+
Organize modules around decisions likely to change, not merely processing steps.
|
|
64
62
|
|
|
65
|
-
|
|
63
|
+
Instead of exposing:
|
|
66
64
|
|
|
67
65
|
```text
|
|
68
|
-
parse -> validate -> send -> log
|
|
66
|
+
parse -> validate -> retry -> send -> log -> clean up
|
|
69
67
|
```
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
look for the decision those steps implement:
|
|
72
70
|
|
|
73
71
|
```text
|
|
74
|
-
notification delivery policy
|
|
72
|
+
notification delivery policy
|
|
75
73
|
```
|
|
76
74
|
|
|
77
|
-
A good module hides the unstable decision.
|
|
78
|
-
|
|
79
|
-
For consequential systems, failure behavior is often the unstable decision. Hide the contract in the module before callers invent their own retries, fallbacks, state writes, escalation paths, or graceful-failure claims.
|
|
80
|
-
|
|
81
75
|
Ask:
|
|
82
76
|
|
|
83
|
-
- What decision would cause the most edits if it changed?
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
- What
|
|
87
|
-
-
|
|
88
|
-
- Can one module own it?
|
|
89
|
-
- What interface would let callers stop knowing it?
|
|
77
|
+
- What decision would cause the most surrounding edits if it changed?
|
|
78
|
+
- Which callers currently know it?
|
|
79
|
+
- Who should own it?
|
|
80
|
+
- What outcome-level interface would let callers stop knowing it?
|
|
81
|
+
- Is the decision accepted or still user-owned?
|
|
90
82
|
|
|
91
|
-
|
|
83
|
+
Failure and recovery policy are often likely-changing decisions.
|
|
92
84
|
|
|
93
|
-
|
|
94
|
-
- Notification retry/fallback policy should not be duplicated in each route.
|
|
95
|
-
- Permission semantics should not be separately encoded in frontend, backend, and test setup.
|
|
96
|
-
- Cache invalidation rules should not require every caller to remember freshness knobs.
|
|
85
|
+
## Preserve Conceptual Integrity
|
|
97
86
|
|
|
98
|
-
|
|
87
|
+
A module should express one coherent model of its outcome, state, and failure behavior.
|
|
99
88
|
|
|
100
|
-
|
|
89
|
+
Pressure exists when:
|
|
101
90
|
|
|
102
|
-
|
|
91
|
+
- the same concept has different names or rules across callers;
|
|
92
|
+
- several modules partially own the same decision;
|
|
93
|
+
- one module exposes unrelated mental models;
|
|
94
|
+
- callers translate between incompatible representations;
|
|
95
|
+
- each feature adds another exception to the shared concept.
|
|
103
96
|
|
|
104
|
-
|
|
97
|
+
Prefer one clear ownership model over several locally convenient but incompatible ones.
|
|
105
98
|
|
|
106
|
-
|
|
107
|
-
- Do not create seams merely because a pattern sounds clean.
|
|
108
|
-
- Prefer seams that match real variation or observability needs.
|
|
99
|
+
Conceptual integrity does not mean one module or one abstraction. It means related behavior follows one coherent set of decisions.
|
|
109
100
|
|
|
110
|
-
|
|
101
|
+
## Use Seams And Enabling Points For Real Leverage
|
|
111
102
|
|
|
112
|
-
|
|
113
|
-
- Where can that variation enter without editing callers?
|
|
114
|
-
- What enabling point supplies the adapter or behavior?
|
|
115
|
-
- Does the seam protect production code and tests, or only add indirection?
|
|
103
|
+
A seam allows behavior, dependencies, or observation to change without editing surrounding code.
|
|
116
104
|
|
|
117
|
-
|
|
105
|
+
An enabling point supplies the variation:
|
|
118
106
|
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
-
|
|
107
|
+
- adapter;
|
|
108
|
+
- provider;
|
|
109
|
+
- fake;
|
|
110
|
+
- clock;
|
|
111
|
+
- probe;
|
|
112
|
+
- policy;
|
|
113
|
+
- migration implementation.
|
|
123
114
|
|
|
124
|
-
|
|
115
|
+
Good seams correspond to:
|
|
125
116
|
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
117
|
+
- demonstrated provider or environment variation;
|
|
118
|
+
- known migration;
|
|
119
|
+
- dependency control required by tests;
|
|
120
|
+
- observation or fault injection;
|
|
121
|
+
- policy that changes independently from infrastructure.
|
|
130
122
|
|
|
131
|
-
|
|
123
|
+
Weak seams:
|
|
132
124
|
|
|
133
|
-
|
|
125
|
+
- wrap one stable call;
|
|
126
|
+
- add factories without ownership;
|
|
127
|
+
- expose provider quirks through generic names;
|
|
128
|
+
- exist only to mock internals while the caller interface remains awkward.
|
|
134
129
|
|
|
135
|
-
|
|
130
|
+
## Separate Policy From Infrastructure
|
|
136
131
|
|
|
137
|
-
|
|
138
|
-
- The adapter owns provider mechanics.
|
|
139
|
-
- The interface between them says what the core needs or provides.
|
|
132
|
+
When infrastructure details leak into product or domain policy, use a boundary where:
|
|
140
133
|
|
|
141
|
-
|
|
134
|
+
```text
|
|
135
|
+
policy requests outcome
|
|
136
|
+
-> adapter performs provider mechanics
|
|
137
|
+
```
|
|
142
138
|
|
|
143
139
|
Examples:
|
|
144
140
|
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
|
|
150
|
-
Do not over-apply ports/adapters:
|
|
151
|
-
|
|
152
|
-
- simple scripts may not need ports;
|
|
153
|
-
- a single stable library call may not need an adapter;
|
|
154
|
-
- wrapping an SDK without hiding policy or provider quirks is often shallow.
|
|
155
|
-
|
|
156
|
-
## Public Contract Cost
|
|
157
|
-
|
|
158
|
-
Hyrum's Law applies beyond public HTTP APIs: every observable flag, path, state, ordering rule, filename, error, timing behavior, and fallback can become depended upon.
|
|
159
|
-
|
|
160
|
-
Expose a fact only when the caller owns it or correct use requires it. Internal protocols may remain detailed and independently tested without becoming public seams.
|
|
161
|
-
|
|
162
|
-
A useful split:
|
|
163
|
-
|
|
164
|
-
- **Public:** caller-owned outcome, decisions, stable invariants, and observable failure semantics.
|
|
165
|
-
- **Internal:** storage layout, provider mechanics, retries, cleanup, integrity publication, temporary states, and optimization machinery.
|
|
166
|
-
|
|
167
|
-
Public flexibility has permanent coordination cost. One outcome-level operation is often deeper than a toolkit that lets callers reconstruct the module's lifecycle.
|
|
141
|
+
- billing policy should not depend on payment-provider error names;
|
|
142
|
+
- notification policy should not be repeated in each provider call;
|
|
143
|
+
- permission semantics should not depend on database representation;
|
|
144
|
+
- user-flow state should not depend on browser event plumbing.
|
|
168
145
|
|
|
169
|
-
|
|
146
|
+
Do not add ports and adapters around every stable library call. The boundary is useful only when it hides policy, variation, or mechanics callers should not own.
|
|
170
147
|
|
|
171
|
-
|
|
148
|
+
## Treat Observable Facts As Contracts
|
|
172
149
|
|
|
173
|
-
|
|
174
|
-
- efficiency, scale, and portability require accepted requirements or observed pressure.
|
|
150
|
+
Callers may depend on any observable:
|
|
175
151
|
|
|
176
|
-
|
|
152
|
+
- flag;
|
|
153
|
+
- path;
|
|
154
|
+
- state;
|
|
155
|
+
- error;
|
|
156
|
+
- timing rule;
|
|
157
|
+
- fallback;
|
|
158
|
+
- ordering behavior;
|
|
159
|
+
- filename;
|
|
160
|
+
- retry count.
|
|
177
161
|
|
|
178
|
-
|
|
162
|
+
Expose a fact only when:
|
|
179
163
|
|
|
180
|
-
|
|
164
|
+
- the caller owns the decision;
|
|
165
|
+
- correct use requires it;
|
|
166
|
+
- it is stable enough to support;
|
|
167
|
+
- its compatibility cost is understood.
|
|
181
168
|
|
|
182
|
-
-
|
|
183
|
-
- repeated review findings;
|
|
184
|
-
- flaky tests around ordering;
|
|
185
|
-
- many mocks for one behavior;
|
|
186
|
-
- hard-to-explain correctness;
|
|
187
|
-
- one bug fix causing another;
|
|
188
|
-
- “just add this flag everywhere.”
|
|
169
|
+
Public flexibility has lasting coordination cost. Prefer one outcome-level operation over a toolkit that requires callers to reconstruct the lifecycle.
|
|
189
170
|
|
|
190
|
-
|
|
171
|
+
## Separate Required Capability From Speculation
|
|
191
172
|
|
|
192
|
-
Classify
|
|
173
|
+
Classify proposed mechanisms as:
|
|
193
174
|
|
|
194
|
-
- **
|
|
195
|
-
- **
|
|
196
|
-
- **
|
|
197
|
-
- **
|
|
175
|
+
- **Trust:** required to know the result is valid.
|
|
176
|
+
- **Safety:** prevents damage, leakage, or runaway behavior.
|
|
177
|
+
- **Efficiency:** saves time, requests, or money.
|
|
178
|
+
- **Scale:** supports concurrency or volume.
|
|
179
|
+
- **Portability:** supports additional environments or providers.
|
|
198
180
|
|
|
199
|
-
|
|
181
|
+
Required trust and safety cannot be deferred merely to simplify the design.
|
|
200
182
|
|
|
201
|
-
|
|
183
|
+
Efficiency, scale, and portability require accepted requirements or observed pressure. Do not turn imagined future variation into present interface cost.
|
|
202
184
|
|
|
203
|
-
|
|
185
|
+
## Name The Missing Boundary
|
|
204
186
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
- Which decision is most likely to change?
|
|
208
|
-
- Who should know this rule?
|
|
209
|
-
- What should callers stop coordinating?
|
|
210
|
-
- What future variation is real, not imagined?
|
|
211
|
-
- Which tests should survive a provider or implementation change?
|
|
212
|
-
|
|
213
|
-
### In specs
|
|
214
|
-
|
|
215
|
-
Specs name behavior and boundaries. They should not lock in unproven module shapes.
|
|
216
|
-
|
|
217
|
-
Use:
|
|
218
|
-
|
|
219
|
-
```text
|
|
220
|
-
Tentative: notification delivery may need one policy-owning module if retries/fallbacks continue spreading.
|
|
221
|
-
Open: whether provider variation is real now or deferred.
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
not:
|
|
187
|
+
Use supported evidence to state:
|
|
225
188
|
|
|
226
189
|
```text
|
|
227
|
-
|
|
190
|
+
Outcome:
|
|
191
|
+
Coordination currently spread across:
|
|
192
|
+
Likely-changing decision:
|
|
193
|
+
Current owners:
|
|
194
|
+
Proposed owner:
|
|
195
|
+
What callers would stop knowing:
|
|
196
|
+
Failure unit:
|
|
197
|
+
Evidence still missing:
|
|
228
198
|
```
|
|
229
199
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
Use [Write Plan](../../write-plan/SKILL.md) only when the ordered strategy can be stated without guessing. When later direction remains provisional, keep it in [Track Work](../../track-work/SKILL.md) or return the evidence to [Workflow](../../workflow/SKILL.md) rather than freezing it as a Plan.
|
|
233
|
-
|
|
234
|
-
For consequential systems, make failure behavior explicit before implementation choices harden. Do not leave it as an implementer guess after planning only the happy path.
|
|
235
|
-
|
|
236
|
-
A good slice can be verified through the intended interface. If the slice requires broad caller choreography, revise the slice.
|
|
237
|
-
|
|
238
|
-
### In review
|
|
239
|
-
|
|
240
|
-
Review design depth by asking whether the diff reduces or increases caller knowledge.
|
|
241
|
-
|
|
242
|
-
A diff can pass tests and still fail design review if it scatters policy or creates a shallow interface.
|
|
243
|
-
|
|
244
|
-
### In diagnosis
|
|
245
|
-
|
|
246
|
-
Repeated failures may indicate that the system is missing a module, seam, or source-truth decision.
|
|
200
|
+
If the decision cannot yet be named, define one bounded learning question. Do not create a generic abstraction as a substitute for understanding.
|
|
247
201
|
|
|
248
|
-
|
|
202
|
+
Stop once the missing decision or boundary is named—or evidence shows no worthwhile boundary change is supported.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# State And Failure Boundaries
|
|
2
|
+
|
|
3
|
+
Read this when correctness materially depends on canonical state, partial effects, atomic visibility, concurrency, cancellation, retries, recovery, reconciliation, or evidence of the final outcome.
|
|
4
|
+
|
|
5
|
+
Do not apply this reference to a simple local value change whose state owner and failure behavior are already sound.
|
|
6
|
+
|
|
7
|
+
## Name Canonical State
|
|
8
|
+
|
|
9
|
+
Identify:
|
|
10
|
+
|
|
11
|
+
- canonical source of truth;
|
|
12
|
+
- who may create, replace, or invalidate it;
|
|
13
|
+
- visible states and invariants;
|
|
14
|
+
- commit or visibility point;
|
|
15
|
+
- diagnostic versus authoritative records;
|
|
16
|
+
- what callers may safely cache or infer.
|
|
17
|
+
|
|
18
|
+
Do not let several modules each behave as the source of truth.
|
|
19
|
+
|
|
20
|
+
A log, cache, temporary file, UI projection, or recovery marker is not canonical merely because it is observable.
|
|
21
|
+
|
|
22
|
+
## Define State Transitions
|
|
23
|
+
|
|
24
|
+
For every material transition, establish:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
precondition
|
|
28
|
+
-> accepted operation
|
|
29
|
+
-> commit or visibility point
|
|
30
|
+
-> resulting canonical state
|
|
31
|
+
-> evidence
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Name forbidden transitions and partial states.
|
|
35
|
+
|
|
36
|
+
Prefer one owner for transition policy. Callers should not reproduce state-machine rules independently.
|
|
37
|
+
|
|
38
|
+
## Bound Partial Effects
|
|
39
|
+
|
|
40
|
+
When an operation affects several resources or can fail midway, establish:
|
|
41
|
+
|
|
42
|
+
- which effects may occur before commitment;
|
|
43
|
+
- which effects are forbidden before commitment;
|
|
44
|
+
- what must be rolled back, reconciled, or retained;
|
|
45
|
+
- what prior accepted state must survive;
|
|
46
|
+
- how partial outcomes are detected;
|
|
47
|
+
- what result is safe to expose.
|
|
48
|
+
|
|
49
|
+
Atomicity may come from transactions, staging, replacement, versioning, or explicit reconciliation. Do not claim atomic behavior from intention alone.
|
|
50
|
+
|
|
51
|
+
## Separate Retry, Resume, And Replay
|
|
52
|
+
|
|
53
|
+
These are different capabilities:
|
|
54
|
+
|
|
55
|
+
- **Retry:** attempt the same operation again.
|
|
56
|
+
- **Resume:** continue incomplete work from preserved state.
|
|
57
|
+
- **Replay:** apply an event or request again.
|
|
58
|
+
- **Idempotency:** repeated application has one supported effect.
|
|
59
|
+
- **Recovery:** restore a safe supported state.
|
|
60
|
+
- **Reconciliation:** compare and resolve divergent state.
|
|
61
|
+
|
|
62
|
+
Supporting one does not imply the others.
|
|
63
|
+
|
|
64
|
+
Expose them only when required by accepted behavior or observed failure.
|
|
65
|
+
|
|
66
|
+
## Design Concurrency Deliberately
|
|
67
|
+
|
|
68
|
+
When operations can overlap, identify:
|
|
69
|
+
|
|
70
|
+
- shared state;
|
|
71
|
+
- ordering and visibility;
|
|
72
|
+
- lost-update or duplicate-effect risk;
|
|
73
|
+
- serialization or conflict rule;
|
|
74
|
+
- cancellation behavior;
|
|
75
|
+
- stale-read policy;
|
|
76
|
+
- observer capable of proving the required outcome.
|
|
77
|
+
|
|
78
|
+
Do not add locks, queues, retries, or optimistic versions without naming the invariant they protect.
|
|
79
|
+
|
|
80
|
+
## Define Failure And Recovery
|
|
81
|
+
|
|
82
|
+
For the failure unit, state:
|
|
83
|
+
|
|
84
|
+
- who observes failure;
|
|
85
|
+
- canonical state after failure;
|
|
86
|
+
- diagnostic evidence;
|
|
87
|
+
- forbidden partial effects;
|
|
88
|
+
- fail-open, fail-closed, degrade, stop, retry, or escalation behavior;
|
|
89
|
+
- safe restart or recovery operation;
|
|
90
|
+
- evidence proving recovery.
|
|
91
|
+
|
|
92
|
+
A graceful error response does not prove graceful state handling.
|
|
93
|
+
|
|
94
|
+
## Keep Recovery Out Of Ordinary Callers
|
|
95
|
+
|
|
96
|
+
Callers should normally request an outcome and receive supported success or failure.
|
|
97
|
+
|
|
98
|
+
Do not require every caller to know:
|
|
99
|
+
|
|
100
|
+
- cleanup order;
|
|
101
|
+
- retry schedule;
|
|
102
|
+
- temporary paths;
|
|
103
|
+
- partial-state markers;
|
|
104
|
+
- provider error translation;
|
|
105
|
+
- reconciliation commands.
|
|
106
|
+
|
|
107
|
+
Publish diagnostics without exposing recovery choreography unless callers genuinely own recovery.
|
|
108
|
+
|
|
109
|
+
## Test State And Failure Through Observable Invariants
|
|
110
|
+
|
|
111
|
+
Tests should verify:
|
|
112
|
+
|
|
113
|
+
- accepted final state;
|
|
114
|
+
- preserved prior state;
|
|
115
|
+
- forbidden writes;
|
|
116
|
+
- composed failures;
|
|
117
|
+
- retry or replay behavior when required;
|
|
118
|
+
- cancellation and recovery;
|
|
119
|
+
- evidence at the real observing boundary.
|
|
120
|
+
|
|
121
|
+
A passing happy-path test does not prove partial-failure safety.
|
|
122
|
+
|
|
123
|
+
## Return
|
|
124
|
+
|
|
125
|
+
Return:
|
|
126
|
+
|
|
127
|
+
- canonical state and owner;
|
|
128
|
+
- material invariants;
|
|
129
|
+
- transition and visibility boundary;
|
|
130
|
+
- failure unit;
|
|
131
|
+
- forbidden partial outcomes;
|
|
132
|
+
- retry, resume, replay, and recovery capabilities actually required;
|
|
133
|
+
- evidence and remaining uncertainty;
|
|
134
|
+
- narrowest supported route.
|
|
135
|
+
|
|
136
|
+
Stop when state and failure ownership are sufficient for the current design decision. Do not design every theoretical failure mode.
|