@deftai/directive-content 0.55.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/.agents/skills/deft/SKILL.md +6 -0
- package/.agents/skills/deft-directive-article-review/SKILL.md +11 -0
- package/.agents/skills/deft-directive-build/SKILL.md +10 -0
- package/.agents/skills/deft-directive-cost/SKILL.md +12 -0
- package/.agents/skills/deft-directive-debug/SKILL.md +13 -0
- package/.agents/skills/deft-directive-gh-arch/SKILL.md +11 -0
- package/.agents/skills/deft-directive-gh-slice/SKILL.md +10 -0
- package/.agents/skills/deft-directive-glossary/SKILL.md +10 -0
- package/.agents/skills/deft-directive-interview/SKILL.md +9 -0
- package/.agents/skills/deft-directive-pre-pr/SKILL.md +9 -0
- package/.agents/skills/deft-directive-refinement/SKILL.md +10 -0
- package/.agents/skills/deft-directive-release/SKILL.md +12 -0
- package/.agents/skills/deft-directive-review-cycle/SKILL.md +10 -0
- package/.agents/skills/deft-directive-setup/SKILL.md +10 -0
- package/.agents/skills/deft-directive-swarm/SKILL.md +10 -0
- package/.agents/skills/deft-directive-sync/SKILL.md +9 -0
- package/.agents/skills/deft-directive-triage/SKILL.md +9 -0
- package/.agents/skills/deft-directive-write-skill/SKILL.md +9 -0
- package/LICENSE.md +22 -0
- package/QUICK-START.md +167 -0
- package/UPGRADING.md +517 -0
- package/coding/build-output.md +28 -0
- package/coding/coding.md +235 -0
- package/coding/debugging.md +110 -0
- package/coding/holzmann.md +96 -0
- package/coding/hygiene.md +127 -0
- package/coding/security.md +158 -0
- package/coding/testing.md +162 -0
- package/coding/toolchain.md +44 -0
- package/commands.md +300 -0
- package/context/context.md +57 -0
- package/context/deterministic-split.md +67 -0
- package/context/examples.md +26 -0
- package/context/fractal-summaries.md +69 -0
- package/context/long-horizon.md +46 -0
- package/context/spec-deltas.md +177 -0
- package/context/tool-design.md +34 -0
- package/context/working-memory.md +62 -0
- package/contracts/boundary-maps.md +65 -0
- package/contracts/deterministic-questions.md +59 -0
- package/contracts/hierarchy.md +77 -0
- package/conventions/content-manifest.json +399 -0
- package/conventions/machine-generated-banner.md +130 -0
- package/conventions/references.md +120 -0
- package/conventions/rule-ownership.json +382 -0
- package/conventions/task-caching.md +43 -0
- package/conventions/vbrief-filenames.md +70 -0
- package/deployments/README.md +37 -0
- package/deployments/agentuity/README.md +138 -0
- package/deployments/agentuity/via-cli.md +380 -0
- package/deployments/agentuity/via-cloud.md +425 -0
- package/deployments/agentuity/via-github-actions.md +664 -0
- package/deployments/agentuity/via-gravity-network.md +606 -0
- package/deployments/agentuity/via-vpc.md +607 -0
- package/deployments/aws/README.md +38 -0
- package/deployments/aws/via-app-runner.md +612 -0
- package/deployments/aws/via-ecs-fargate.md +561 -0
- package/deployments/aws/via-elastic-beanstalk.md +628 -0
- package/deployments/aws/via-lambda.md +649 -0
- package/deployments/azure/README.md +37 -0
- package/deployments/azure/via-aks.md +390 -0
- package/deployments/azure/via-app-service.md +564 -0
- package/deployments/azure/via-container-apps.md +599 -0
- package/deployments/azure/via-functions.md +552 -0
- package/deployments/cloud-gov/README.md +63 -0
- package/deployments/cloud-gov/agents/compliance-docs.md +154 -0
- package/deployments/cloud-gov/agents.md +39 -0
- package/deployments/cloud-gov/cicd.md +64 -0
- package/deployments/cloud-gov/deployment.md +150 -0
- package/deployments/cloud-gov/logging.md +43 -0
- package/deployments/cloud-gov/manifest.md +121 -0
- package/deployments/cloud-gov/overview.md +58 -0
- package/deployments/cloud-gov/security.md +46 -0
- package/deployments/cloud-gov/services.md +72 -0
- package/deployments/cloud-gov/upstream/README.md +18 -0
- package/deployments/cloudflare/README.md +33 -0
- package/deployments/cloudflare/via-dashboard.md +83 -0
- package/deployments/cloudflare/via-git.md +90 -0
- package/deployments/cloudflare/via-github-actions.md +185 -0
- package/deployments/cloudflare/via-terraform.md +157 -0
- package/deployments/cloudflare/via-wrangler.md +165 -0
- package/deployments/fly-io/README.md +37 -0
- package/deployments/fly-io/via-dockerfile.md +648 -0
- package/deployments/fly-io/via-flyctl.md +653 -0
- package/deployments/fly-io/via-github-actions.md +695 -0
- package/deployments/fly-io/via-multi-region.md +598 -0
- package/deployments/google/README.md +34 -0
- package/deployments/google/via-app-engine.md +42 -0
- package/deployments/google/via-cloud-functions.md +23 -0
- package/deployments/google/via-cloud-run.md +330 -0
- package/deployments/google/via-gke.md +23 -0
- package/deployments/netlify/README.md +99 -0
- package/deployments/netlify/via-cli.md +17 -0
- package/deployments/netlify/via-functions.md +19 -0
- package/deployments/netlify/via-git.md +25 -0
- package/deployments/vercel/README.md +90 -0
- package/deployments/vercel/via-api.md +16 -0
- package/deployments/vercel/via-cli.md +17 -0
- package/deployments/vercel/via-git.md +24 -0
- package/docs/BROWNFIELD.md +179 -0
- package/docs/getting-started.md +137 -0
- package/docs/good-agents-md.md +137 -0
- package/events/README.md +89 -0
- package/events/event-record.schema.json +26 -0
- package/events/registry.json +166 -0
- package/events/registry.schema.json +71 -0
- package/glossary.md +145 -0
- package/incidents/README.md +81 -0
- package/incidents/_template.md +38 -0
- package/interfaces/cli.md +104 -0
- package/interfaces/rest.md +212 -0
- package/interfaces/tui.md +242 -0
- package/interfaces/web.md +123 -0
- package/languages/6502-DASM.md +132 -0
- package/languages/c.md +235 -0
- package/languages/commands.md +23 -0
- package/languages/cpp.md +132 -0
- package/languages/csharp.md +259 -0
- package/languages/dart.md +183 -0
- package/languages/delphi.md +218 -0
- package/languages/elixir.md +208 -0
- package/languages/go.md +78 -0
- package/languages/java.md +278 -0
- package/languages/javascript.md +163 -0
- package/languages/julia.md +175 -0
- package/languages/kotlin.md +193 -0
- package/languages/markdown.md +168 -0
- package/languages/mermaid.md +146 -0
- package/languages/officejs.md +392 -0
- package/languages/python.md +209 -0
- package/languages/r.md +163 -0
- package/languages/rust.md +216 -0
- package/languages/sql.md +216 -0
- package/languages/swift.md +153 -0
- package/languages/typescript.md +132 -0
- package/languages/vba.md +279 -0
- package/languages/vhdl.md +180 -0
- package/languages/visual-basic.md +151 -0
- package/languages/zig.md +196 -0
- package/meta/SOUL.md +27 -0
- package/meta/code-field.md +44 -0
- package/meta/morals.md +40 -0
- package/meta/philosophy.md +39 -0
- package/meta/project.md +49 -0
- package/meta/ralph.md +223 -0
- package/meta/security.md +80 -0
- package/meta/versioning.md +326 -0
- package/package.json +22 -0
- package/packs/lessons/lessons-pack-0.1.json +553 -0
- package/packs/patterns/patterns-pack-0.1.json +57 -0
- package/packs/rules/rules-pack-0.1.json +4767 -0
- package/packs/skills/skills-pack-0.1.json +262 -0
- package/packs/strategies/strategies-pack-0.1.json +167 -0
- package/packs/swarm-spec/swarm-spec-pack-0.1.json +17 -0
- package/patterns/executor-layer-credentials.md +227 -0
- package/patterns/llm-app.md +156 -0
- package/patterns/multi-agent.md +278 -0
- package/patterns/prompt-assembly-layer-ordering.md +154 -0
- package/patterns/role-as-overlay.md +179 -0
- package/platforms/2600.md +137 -0
- package/platforms/unity.md +329 -0
- package/references/composer-skill-porting.md +152 -0
- package/references/cost-models.md +163 -0
- package/references/ip-risk.md +246 -0
- package/references/plain-english-ux.md +275 -0
- package/resilience/context-pruning.md +67 -0
- package/resilience/continue-here.md +62 -0
- package/scm/changelog.md +276 -0
- package/scm/git.md +139 -0
- package/scm/github.md +265 -0
- package/secrets/.gitkeep +0 -0
- package/skills/deft-build/SKILL.md +20 -0
- package/skills/deft-directive-article-review/SKILL.md +156 -0
- package/skills/deft-directive-build/SKILL.md +302 -0
- package/skills/deft-directive-cost/SKILL.md +201 -0
- package/skills/deft-directive-debug/SKILL.md +140 -0
- package/skills/deft-directive-decompose/SKILL.md +96 -0
- package/skills/deft-directive-gh-arch/SKILL.md +160 -0
- package/skills/deft-directive-gh-slice/SKILL.md +199 -0
- package/skills/deft-directive-glossary/SKILL.md +118 -0
- package/skills/deft-directive-interview/SKILL.md +528 -0
- package/skills/deft-directive-pre-pr/SKILL.md +131 -0
- package/skills/deft-directive-probe/SKILL.md +127 -0
- package/skills/deft-directive-refinement/SKILL.md +403 -0
- package/skills/deft-directive-release/SKILL.md +266 -0
- package/skills/deft-directive-review-cycle/SKILL.md +401 -0
- package/skills/deft-directive-setup/SKILL.md +717 -0
- package/skills/deft-directive-swarm/SKILL.md +989 -0
- package/skills/deft-directive-sync/SKILL.md +288 -0
- package/skills/deft-directive-triage/SKILL.md +137 -0
- package/skills/deft-directive-write-skill/SKILL.md +169 -0
- package/skills/deft-interview/SKILL.md +16 -0
- package/skills/deft-pre-pr/SKILL.md +16 -0
- package/skills/deft-review-cycle/SKILL.md +16 -0
- package/skills/deft-roadmap-refresh/SKILL.md +16 -0
- package/skills/deft-setup/SKILL.md +20 -0
- package/skills/deft-swarm/SKILL.md +16 -0
- package/skills/deft-sync/SKILL.md +16 -0
- package/strategies/README.md +83 -0
- package/strategies/artifact-guards.md +85 -0
- package/strategies/bdd.md +115 -0
- package/strategies/brownfield.md +7 -0
- package/strategies/discuss.md +129 -0
- package/strategies/emit-hints.md +69 -0
- package/strategies/enterprise.md +193 -0
- package/strategies/interview.md +551 -0
- package/strategies/map.md +179 -0
- package/strategies/probe.md +151 -0
- package/strategies/rapid.md +155 -0
- package/strategies/research.md +155 -0
- package/strategies/roadmap.md +9 -0
- package/strategies/speckit.md +437 -0
- package/strategies/v0-20-contract.md +134 -0
- package/strategies/yolo.md +169 -0
- package/swarm/swarm.md +300 -0
- package/templates/COST-ESTIMATE.md +114 -0
- package/templates/PULL_REQUEST_TEMPLATE.md +35 -0
- package/templates/agent-prompt-preamble.md +409 -0
- package/templates/agents-entry.md +211 -0
- package/templates/agents-entry.placeholders.md +75 -0
- package/templates/embed.go +20 -0
- package/templates/embed_test.go +36 -0
- package/templates/make-spec-example.md +9 -0
- package/templates/make-spec.md +246 -0
- package/templates/project.md.template +52 -0
- package/templates/specification.md +1 -0
- package/templates/swarm-greptile-poller-prompt.md +556 -0
- package/templates/user.md.template +31 -0
- package/tools/RWLDL.md +80 -0
- package/tools/greptile.md +141 -0
- package/tools/installer.md +23 -0
- package/tools/taskfile-migration.md +32 -0
- package/tools/taskfile.md +185 -0
- package/tools/telemetry.md +285 -0
- package/vbrief/schemas/cache-meta.schema.json +137 -0
- package/vbrief/schemas/candidates.schema.json +130 -0
- package/vbrief/schemas/codebase-map.schema.json +213 -0
- package/vbrief/schemas/lessons-pack.schema.json +134 -0
- package/vbrief/schemas/patterns-pack.schema.json +84 -0
- package/vbrief/schemas/rules-pack.schema.json +105 -0
- package/vbrief/schemas/skills-pack.schema.json +94 -0
- package/vbrief/schemas/slices.schema.json +87 -0
- package/vbrief/schemas/strategies-pack.schema.json +89 -0
- package/vbrief/schemas/swarm-spec-pack.schema.json +84 -0
- package/vbrief/schemas/vbrief-core.schema.json +1022 -0
- package/vbrief/vbrief.md +684 -0
- package/verification/integration.md +76 -0
- package/verification/plan-checking.md +85 -0
- package/verification/uat.md +60 -0
- package/verification/verification.md +117 -0
package/coding/coding.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
2
|
+
<!-- Purpose: rendered coding rules -->
|
|
3
|
+
<!-- Source of truth: packs/rules/rules-pack-0.1.json -->
|
|
4
|
+
<!-- Regenerate with: task packs:render -->
|
|
5
|
+
<!-- Edit the source, not this file. Slice instead of loading every coding doc: task packs:slice rules by-tier --tier <TIER> (or by-domain, list) -->
|
|
6
|
+
|
|
7
|
+
# Coding Guidelines
|
|
8
|
+
|
|
9
|
+
Software development specific guidelines for AI agents.
|
|
10
|
+
|
|
11
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
12
|
+
|
|
13
|
+
**⚠️ See also** (load only when needed):
|
|
14
|
+
- [../main.md](../../main.md) - General AI behavior and agent persona
|
|
15
|
+
- [PROJECT.md](../../PROJECT.md) - For project-specific overrides
|
|
16
|
+
- [../tools/telemetry.md](../tools/telemetry.md) - When implementing logging/tracing/metrics
|
|
17
|
+
|
|
18
|
+
## Code Organization
|
|
19
|
+
|
|
20
|
+
**Documentation:**
|
|
21
|
+
- ! All *.md in `docs/` directory (except README.md, AGENTS.md, WARP.md)
|
|
22
|
+
- ! Prior tasks/plans in `history/`
|
|
23
|
+
|
|
24
|
+
**Filenames:**
|
|
25
|
+
- ~ Use hyphens not underscores (unless language idiom)
|
|
26
|
+
|
|
27
|
+
**Secrets:**
|
|
28
|
+
- ! ALL secrets in `secrets/` dir as .env files
|
|
29
|
+
- ⊗ Secrets in code
|
|
30
|
+
|
|
31
|
+
## Code Search
|
|
32
|
+
|
|
33
|
+
- ! use `rg`, or `ast-grep` (when available) instead of grep
|
|
34
|
+
- ! Use Warp's built-in grep (which is rg) when running on warp
|
|
35
|
+
- ~ Install if missing
|
|
36
|
+
- ? Fall back to `grep` command only if tools cannot be installed
|
|
37
|
+
|
|
38
|
+
## Version Control
|
|
39
|
+
|
|
40
|
+
See [../scm/git.md](../scm/git.md) for:
|
|
41
|
+
- Commit conventions (Conventional Commits)
|
|
42
|
+
- Safety rules (no force-push without permission)
|
|
43
|
+
- Branch workflows
|
|
44
|
+
|
|
45
|
+
## Code Design
|
|
46
|
+
|
|
47
|
+
**Modularity:**
|
|
48
|
+
- ! One responsibility per file/module
|
|
49
|
+
- ~ Files <300 lines ideal; <500 lines recommended; <1000 lines a review trigger — split when exceeded unless genuinely single-responsibility (size is a smell, not a hard cap; #1488)
|
|
50
|
+
- ! Explicit scope in task descriptions
|
|
51
|
+
- ~ DRY: extract shared abstractions when logic is duplicated across 2+ call sites
|
|
52
|
+
- ⊗ Copy-paste logic with minor variations — parameterise instead
|
|
53
|
+
|
|
54
|
+
**Dependency Direction:**
|
|
55
|
+
- ⊗ Circular imports between modules/packages
|
|
56
|
+
- ~ Layered architecture: high-level modules depend on low-level ones, never the reverse
|
|
57
|
+
- ! Use dependency inversion (interfaces/protocols) to break coupling across layers
|
|
58
|
+
- See [hygiene.md](hygiene.md) for detection tools (madge, pydeps, Go compiler)
|
|
59
|
+
|
|
60
|
+
**Contract-First:**
|
|
61
|
+
- ! Define interfaces/types/protocols before implementation
|
|
62
|
+
- ! Changes to public interfaces require explicit versioning or deprecation path
|
|
63
|
+
- ! Document all public API contracts clearly
|
|
64
|
+
|
|
65
|
+
**Immutability:**
|
|
66
|
+
- ~ Prefer immutable data + pure functions
|
|
67
|
+
- ~ When mutation needed, use narrow owned scopes (context managers, RAII)
|
|
68
|
+
- ⊗ Global or singleton mutable state (almost always)
|
|
69
|
+
|
|
70
|
+
**Error Handling:**
|
|
71
|
+
- ~ Prefer Result/Option types or explicit exceptions over None/null/undefined
|
|
72
|
+
- ! Document possible exceptions/error codes for all public functions
|
|
73
|
+
- ! Validate all inputs at API boundaries
|
|
74
|
+
- ⊗ Trust caller without validation
|
|
75
|
+
- ⊗ Empty catch/except/recover blocks that swallow errors silently
|
|
76
|
+
- ⊗ Returning neutral/zero values (None, {}, [], 0, false, "") to mask errors — propagate explicitly
|
|
77
|
+
- ⊗ Log-and-continue: catching an error and proceeding as if it didn't happen, unless provably non-fatal and documented
|
|
78
|
+
- See [hygiene.md](hygiene.md) for full error-hiding anti-pattern catalogue
|
|
79
|
+
|
|
80
|
+
**Readability:**
|
|
81
|
+
- ! Follow language idioms strictly
|
|
82
|
+
- ! Meaningful names over short names
|
|
83
|
+
- ! Comments explain **why**, code shows **what**
|
|
84
|
+
- ⊗ Clever code over clear code
|
|
85
|
+
|
|
86
|
+
## Quality Standards
|
|
87
|
+
|
|
88
|
+
**General:**
|
|
89
|
+
- ! Run all relevant checks (lint, fmt, quality, build, test) before submitting changes
|
|
90
|
+
- ⊗ Claim checks passed without running them
|
|
91
|
+
- ! If checks cannot run, explicitly state why and what would have been executed
|
|
92
|
+
- ~ Prioritize code quality and readability over backwards compatibility
|
|
93
|
+
|
|
94
|
+
**Testing:**
|
|
95
|
+
- ! Implementation is INCOMPLETE until tests written AND `task test:coverage` passes
|
|
96
|
+
- See [../coding/testing.md](../coding/testing.md) for universal requirements
|
|
97
|
+
|
|
98
|
+
**Security:**
|
|
99
|
+
- ! Apply baseline security standards to every project from day one
|
|
100
|
+
- See [../coding/security.md](../coding/security.md) for input validation, authn/authz, secrets, dependency, and agent-specific threats (#661)
|
|
101
|
+
|
|
102
|
+
**Codebase Hygiene:**
|
|
103
|
+
- See [hygiene.md](hygiene.md) for: dead code removal, circular dependency detection, error hiding patterns, legacy/deprecated code cleanup
|
|
104
|
+
|
|
105
|
+
**Telemetry:**
|
|
106
|
+
- See [../tools/telemetry.md](../tools/telemetry.md) for recommendations
|
|
107
|
+
- ~ Structured logging for production
|
|
108
|
+
- ~ Error tracking (Sentry.io or equivalent)
|
|
109
|
+
- ? Distributed tracing for complex systems
|
|
110
|
+
|
|
111
|
+
## Fail Loud: Completion Claims Require Outcome Verification (#1006)
|
|
112
|
+
|
|
113
|
+
The failure mode is the agent stating completion at the level of **intent** ("I ran the migration", "the tests pass", "the feature works") rather than at the level of **outcome verification** ("all 167 records migrated, 0 skipped", "42 tests collected, 42 passed, 0 skipped, 0 xfailed", "the edge case asked about was reproduced and now returns the expected value"). Outcome-blind completion claims hide silent skips, swallowed exceptions, suppressed errors, and unverified edge cases behind successful-sounding language. The example from the source: a database migration that completed "successfully" had silently skipped 14% of records on a constraint violation; the skip was logged but not surfaced; the bad reports were discovered 11 days later.
|
|
114
|
+
|
|
115
|
+
This rule is the OPERATIONAL complement to the EPISTEMIC honesty rules elsewhere in the framework (`main.md` morals section: don't present speculation as fact; label unverified claims). Morals.md says "don't lie". Fail-loud says "count the records, check the logs, run the edge case, **then** claim completion." It is also the output-side complement to goal-gate-determinism (the gate specifies what evidence is required) and machine-verifiable-spec (verification commands prevent silent skips) -- without fail-loud, an agent can satisfy the letter of a gate ("tests pass") while hiding the gap ("some tests were skipped").
|
|
116
|
+
|
|
117
|
+
- ! Before claiming a batch operation succeeded, MUST verify the record count and surface it in the claim ("migrated 167/167 records, 0 skipped, 0 errored" -- not "migration completed")
|
|
118
|
+
- ! Before claiming "tests pass", MUST report the count of collected / passed / skipped / xfailed / errored tests ("42 collected, 42 passed, 0 skipped" -- not "tests pass"). A skipped or xfailed test is NOT a passing test for the purpose of this claim
|
|
119
|
+
- ! Before claiming "the feature works", MUST report the specific edge case that was verified (if the user asked about a specific edge case, that edge case MUST be in the verification report; "the happy path works" is not equivalent to "the feature works")
|
|
120
|
+
- ! Before claiming a migration / data transform / batch job completed, MUST check the error log AND the skip log AND the constraint-violation surface; surface the counts even when zero ("0 skipped, 0 errored" is the load-bearing claim, not silence)
|
|
121
|
+
- ! When uncertainty exists about whether something worked, MUST surface the uncertainty explicitly ("the migration completed and reported success but I have not verified the per-record count -- recommend running `<verification-command>` before declaring done")
|
|
122
|
+
- ⊗ MUST NOT claim "tests pass" when any test was skipped, xfailed, or run with errors suppressed -- report the full counts instead
|
|
123
|
+
- ⊗ MUST NOT claim "migration completed" / "batch succeeded" / "job finished" without checking and reporting the per-record outcome counts
|
|
124
|
+
- ⊗ MUST NOT claim "feature works" when only the happy path was verified -- name the edge case that was tested, or surface that it wasn't
|
|
125
|
+
- ⊗ MUST NOT use successful-sounding completion phrasing to paper over uncertainty -- default to surfacing uncertainty, not hiding it
|
|
126
|
+
- ⊗ MUST NOT suppress error output (`2>$null`, `2>/dev/null`, `try/except: pass` around the verification command) and then claim completion based on the resulting silence
|
|
127
|
+
|
|
128
|
+
The rule applies to agent completion claims during task execution. It applies equally to claims to the user, claims in commit messages, claims in PR bodies, claims in CHANGELOG entries, and claims in status messages to a parent agent. A short, honest "the migration completed; I did not verify the per-record count" is strictly preferred over a confident "migration completed successfully" that hides the gap.
|
|
129
|
+
|
|
130
|
+
**Cross-references:** `## Quality Standards` above (`⊗ Claim checks passed without running them` -- the sibling rule that this expands from process to outcome); `hygiene.md` `## Error Handling: No Hiding` (the same hiding pattern at the code-write level, not the claim level); `skills/deft-directive-pre-pr/SKILL.md` (pre-PR verification claims); `skills/deft-directive-build/SKILL.md` Step 4 Quality Gates (task-completion claims); `skills/deft-directive-review-cycle/SKILL.md` (the review-cycle skill explicitly checks for hidden incompleteness in fix-batch completion claims).
|
|
131
|
+
|
|
132
|
+
## Calling LLM APIs (#481)
|
|
133
|
+
|
|
134
|
+
When the project calls LLM APIs (OpenAI, Anthropic, Cohere, local models, etc.) or builds agentic functionality, the architectural standards in `patterns/llm-app.md` apply alongside the coding rules above. The short form:
|
|
135
|
+
|
|
136
|
+
- ! User input is NEVER placed in the system prompt; the system prompt is the trust boundary
|
|
137
|
+
- ! External content is ALWAYS wrapped in explicit delimiters (`<user_input>`, `<document>`, `<tool_result>`) and surfaces its trust tier
|
|
138
|
+
- ! Tool call arguments are validated against a schema BEFORE execution (the LLM is a confused deputy)
|
|
139
|
+
- ! LLM outputs are validated against expected schemas before being acted upon (no eval-of-output, no shell-of-output, no SQL-of-output)
|
|
140
|
+
- ⊗ MUST NOT write LLM outputs back into the retrieval corpus in the same session without validation (RAG poisoning vector)
|
|
141
|
+
|
|
142
|
+
See [../patterns/llm-app.md](../patterns/llm-app.md) for the full standards: prompt construction, trust tiers, tool/function-call validation, RAG hygiene, output handling, multi-agent orchestration, and LLM-specific observability. See [../tools/telemetry.md](../tools/telemetry.md) `## LLM-specific observability (#481)` for the matching observability surface.
|
|
143
|
+
|
|
144
|
+
## Debugging and Root-Cause Investigation (#1621)
|
|
145
|
+
|
|
146
|
+
When a bug, failure, or unexpected behaviour needs diagnosis, the root-cause standards in `debugging.md` apply. The short form:
|
|
147
|
+
|
|
148
|
+
- ! No fixes without root-cause investigation first (the Iron Law)
|
|
149
|
+
- ! Reproduce the failure consistently before proposing a fix — a non-reproducible bug is not yet understood
|
|
150
|
+
- ! Every factual claim cites evidence; an uncited claim is a `[HYPOTHESIS]`, not a finding (evidence before narrative)
|
|
151
|
+
- ! Runtime/config values are proven from the runtime, never inferred from source code (config is not code)
|
|
152
|
+
- ⊗ MUST NOT present a duration or an exit status ("slow because phase X took N minutes", "failed because it timed out") as a root cause — name a mechanism (no tautologies)
|
|
153
|
+
- ! After 3 failed distinct fixes, STOP and escalate for architectural review (the 3-fix gate)
|
|
154
|
+
|
|
155
|
+
See [debugging.md](debugging.md) for the full four-phase process, evidence discipline, Fact vs Hypothesis labeling (#1580), the observability-gap loop, and the rationalization table. For a sustained multi-agent investigation posture, see the `deft-directive-debug` skill.
|
|
156
|
+
|
|
157
|
+
## Build Automation
|
|
158
|
+
|
|
159
|
+
**Taskfile:**
|
|
160
|
+
- ! Use Task ([go-task](https://taskfile.dev)) for all repeatable operations
|
|
161
|
+
- ! If `task` not found, attempt to install go-task
|
|
162
|
+
- ! If installation fails, stop and ask user for help
|
|
163
|
+
- See [../tools/taskfile.md](../tools/taskfile.md) for standards and common commands
|
|
164
|
+
|
|
165
|
+
**Toolchain Validation:**
|
|
166
|
+
- See [../coding/toolchain.md](../coding/toolchain.md) for rules on verifying required tools are installed before implementation begins
|
|
167
|
+
|
|
168
|
+
**Build Output Validation:**
|
|
169
|
+
- See [../coding/build-output.md](../coding/build-output.md) for rules on verifying `dist/` artifacts and non-compiled assets after custom build scripts run
|
|
170
|
+
|
|
171
|
+
## Change Management
|
|
172
|
+
|
|
173
|
+
**Impact Awareness:**
|
|
174
|
+
- ! Before changing shared code, identify affected downstream modules/files
|
|
175
|
+
- ~ Prefer additive changes (new functions, fields with defaults) over breaking renames
|
|
176
|
+
- ! Make small, reversible changes
|
|
177
|
+
- ! Explain impact and migration path for breaking changes
|
|
178
|
+
|
|
179
|
+
**Production Safety:**
|
|
180
|
+
- ! Assume production impact unless stated otherwise
|
|
181
|
+
- ! Call out risk when touching: auth, billing, data, APIs, build systems
|
|
182
|
+
- ⊗ Silent breaking behavior
|
|
183
|
+
- ~ Test changes in staging/dev environment when possible
|
|
184
|
+
|
|
185
|
+
## Language-Specific Guidelines
|
|
186
|
+
|
|
187
|
+
**Languages:**
|
|
188
|
+
- C++: [../languages/cpp.md](../languages/cpp.md)
|
|
189
|
+
- Go: [../languages/go.md](../languages/go.md)
|
|
190
|
+
- Office.js: [../languages/officejs.md](../languages/officejs.md)
|
|
191
|
+
- Python: [../languages/python.md](../languages/python.md)
|
|
192
|
+
- TypeScript: [../languages/typescript.md](../languages/typescript.md)
|
|
193
|
+
- VBA: [../languages/vba.md](../languages/vba.md)
|
|
194
|
+
|
|
195
|
+
**Interface Types:**
|
|
196
|
+
- CLI: [../interfaces/cli.md](../interfaces/cli.md)
|
|
197
|
+
- TUI: [../interfaces/tui.md](../interfaces/tui.md)
|
|
198
|
+
- Web: [../interfaces/web.md](../interfaces/web.md)
|
|
199
|
+
- REST API: [../interfaces/rest.md](../interfaces/rest.md)
|
|
200
|
+
|
|
201
|
+
## Development Workflow
|
|
202
|
+
|
|
203
|
+
**Localhost:**
|
|
204
|
+
- No permission needed for curl localhost
|
|
205
|
+
|
|
206
|
+
**Plans:**
|
|
207
|
+
- ~ Create both:
|
|
208
|
+
1. Warp plan (using `create_plan` tool)
|
|
209
|
+
2. Archive copy in `history/plan-YYYY-MM-DD-description.md`
|
|
210
|
+
|
|
211
|
+
## Project Context
|
|
212
|
+
|
|
213
|
+
- ! Check [PROJECT.md](../../PROJECT.md) for project-specific overrides
|
|
214
|
+
- ~ Inspect project config (package.json, pyproject.toml, etc.) for available scripts
|
|
215
|
+
- ! Follow project-specific testing, coverage, and quality requirements
|
|
216
|
+
|
|
217
|
+
## Anti-Patterns
|
|
218
|
+
|
|
219
|
+
- ⊗ Secrets in code or version control
|
|
220
|
+
- ⊗ Claiming checks passed without running them
|
|
221
|
+
- ⊗ Single files mixing multiple responsibilities (large line count, e.g. >1000 lines, is a trigger to check cohesion — not a defect by itself; #1488)
|
|
222
|
+
- ⊗ Skipping quality checks
|
|
223
|
+
- ⊗ Breaking changes without explicit approval
|
|
224
|
+
- ⊗ Using `grep` command when `rg` or Warp grep available
|
|
225
|
+
- ⊗ Implementing code without tests
|
|
226
|
+
- ⊗ Claiming "done" before running test:coverage
|
|
227
|
+
- ⊗ Ignoring coverage drops
|
|
228
|
+
- ⊗ Weak types (`any`, `interface{}`, untyped `object`) where concrete types are knowable
|
|
229
|
+
- ⊗ Dead code: unused functions, unreachable branches, stale feature flags, commented-out blocks
|
|
230
|
+
- ⊗ Error hiding: empty catch blocks, silent fallbacks, swallowed exceptions
|
|
231
|
+
- ⊗ Circular imports between modules
|
|
232
|
+
- ⊗ Duplicate logic across 2+ call sites without shared abstraction
|
|
233
|
+
- ⊗ Outcome-blind completion claims: "tests pass" with skipped tests, "migration completed" without per-record counts, "feature works" without naming the verified edge case (#1006 -- see `## Fail Loud` above)
|
|
234
|
+
- ⊗ Averaging contradicting codebase patterns: writing new code that satisfies both of two conflicting patterns simultaneously (#1005 -- see `hygiene.md` `## Surface Conflicts`)
|
|
235
|
+
- ⊗ Debugging by guess-and-check: fixing before reproducing, treating the first plausible hypothesis as confirmed, or presenting a duration/exit-status as a root cause (#1621 -- see `debugging.md`)
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
2
|
+
<!-- Purpose: rendered coding rules -->
|
|
3
|
+
<!-- Source of truth: packs/rules/rules-pack-0.1.json -->
|
|
4
|
+
<!-- Regenerate with: task packs:render -->
|
|
5
|
+
<!-- Edit the source, not this file. Slice instead of loading every coding doc: task packs:slice rules by-tier --tier <TIER> (or by-domain, list) -->
|
|
6
|
+
|
|
7
|
+
# Debugging and Root-Cause Investigation (#1621)
|
|
8
|
+
|
|
9
|
+
Systematic root-cause process for AI agents. The failure mode this file prevents
|
|
10
|
+
is **thrashing**: retrying random fixes, fixing before understanding, and
|
|
11
|
+
treating the first plausible hypothesis as correct. Debugging is an
|
|
12
|
+
evidence-discipline, not a guess-and-check loop.
|
|
13
|
+
|
|
14
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
15
|
+
|
|
16
|
+
For a sustained, multi-agent investigation posture (claim ledger, falsification
|
|
17
|
+
waves, validator gate), see the `deft-directive-debug` skill and the vendored
|
|
18
|
+
reference design under `docs/reference/forensic-research/`.
|
|
19
|
+
|
|
20
|
+
## The Iron Law
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
NO FIXES WITHOUT ROOT-CAUSE INVESTIGATION FIRST
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- ! Before proposing or writing any fix, the root cause MUST be identified with evidence.
|
|
27
|
+
- ⊗ MUST NOT propose a fix while the investigation phase is incomplete — violating the letter of this process is violating the spirit of debugging.
|
|
28
|
+
|
|
29
|
+
## The Four Phases
|
|
30
|
+
|
|
31
|
+
Each phase MUST complete before the next begins.
|
|
32
|
+
|
|
33
|
+
### Phase 1 — Root-Cause Investigation
|
|
34
|
+
- ! Read the error message completely before doing anything else.
|
|
35
|
+
- ! Reproduce the failure consistently — a non-reproducible bug is not yet understood.
|
|
36
|
+
- ! Check recent changes (what changed when the symptom appeared?).
|
|
37
|
+
- ! Gather evidence at component boundaries — add diagnostic instrumentation before proposing fixes.
|
|
38
|
+
- ! Trace data flow backward from the symptom toward the cause.
|
|
39
|
+
|
|
40
|
+
### Phase 2 — Pattern Analysis
|
|
41
|
+
- ! Find a working example of similar functionality in the codebase.
|
|
42
|
+
- ! Compare the failing path against the working reference and identify what is structurally different.
|
|
43
|
+
- ~ Look for the pattern, not just the instance.
|
|
44
|
+
|
|
45
|
+
### Phase 3 — Hypothesis Testing
|
|
46
|
+
- ! Form one hypothesis and test it minimally.
|
|
47
|
+
- ! Change one variable at a time.
|
|
48
|
+
- ! Confirm the fix addresses the root cause, not just the symptom.
|
|
49
|
+
|
|
50
|
+
### Phase 4 — Implementation
|
|
51
|
+
- ! Write a failing test that demonstrates the bug.
|
|
52
|
+
- ! Implement the single fix.
|
|
53
|
+
- ! Verify the test passes and that no regressions were introduced.
|
|
54
|
+
|
|
55
|
+
## The 3-Fix Architecture Gate
|
|
56
|
+
|
|
57
|
+
- ! If 3 or more distinct fixes have failed, STOP. MUST NOT attempt a fourth fix.
|
|
58
|
+
- ! Escalate with: "N fixes attempted, root cause not found — architectural review needed." The architecture may be the problem.
|
|
59
|
+
|
|
60
|
+
## Multi-Component Systems
|
|
61
|
+
|
|
62
|
+
- ! Before proposing fixes in a multi-component system, add diagnostic instrumentation at every boundary to observe the actual data flow.
|
|
63
|
+
- ⊗ MUST NOT guess which component is at fault without boundary evidence.
|
|
64
|
+
|
|
65
|
+
## Evidence Discipline (forensic rigor)
|
|
66
|
+
|
|
67
|
+
These rules raise the four-phase loop from "structured guessing" to
|
|
68
|
+
evidence-based investigation. They are adapted from the vendored
|
|
69
|
+
`forensic-research` reference design.
|
|
70
|
+
|
|
71
|
+
- ! **Evidence before narrative** — every factual claim MUST cite specific evidence (a log line, a metric, a file:line, a reproduction). An uncited claim is a `[HYPOTHESIS]`, not a finding.
|
|
72
|
+
- ! **Config is not code** — a production/runtime flag value MUST be proven from the runtime (env dump, secrets manager, a log line showing the actual value). ⊗ MUST NOT infer a runtime value from source code or docs alone.
|
|
73
|
+
- ! **Proof-required disproval** — "no evidence found" resolves a theory to `unknown`, never to `failed`. Marking a theory `failed` (ruled out) MUST cite specific counter-evidence.
|
|
74
|
+
- ! **Falsification before fixation** — before committing to a leading theory, MUST attempt the cheapest test that would disprove it. A theory that survives a real disproof attempt is stronger than one merely asserted.
|
|
75
|
+
- ⊗ **No tautologies** — "it failed because it timed out" and "it was slow because phase X took N minutes" MUST NOT be presented as root causes. Name a **mechanism**, or state "mechanism not verified" after exhausting the cheap checks. A duration is evidence for the mechanism search, not the mechanism.
|
|
76
|
+
|
|
77
|
+
## Fact vs Hypothesis Labeling
|
|
78
|
+
|
|
79
|
+
- ! Every finding MUST be labeled **Fact** (an observable claim grounded in file:line / log / metric evidence) or **Hypothesis** (an interpretation that could be wrong and still needs verification).
|
|
80
|
+
- ! A finding labeled Fact MUST carry its evidence citation.
|
|
81
|
+
|
|
82
|
+
This is the debugging-side adoption of the review/triage labeling vocabulary
|
|
83
|
+
owned by #1580 — that issue remains the owner of the review-cycle and triage
|
|
84
|
+
findings-format surface; this file is a consumer of the shared vocabulary.
|
|
85
|
+
|
|
86
|
+
## Observability Gaps (close the loop)
|
|
87
|
+
|
|
88
|
+
- ! When the root cause was reached by **inference** (indirect evidence, missing telemetry), the investigation MUST emit an "observability gaps" note: what could not be measured, what to log/measure next time, and why it would make the next investigation definitive.
|
|
89
|
+
- ~ Treat each investigation as an opportunity to improve the system's telemetry, not just to land a fix.
|
|
90
|
+
|
|
91
|
+
## Rationalization Table
|
|
92
|
+
|
|
93
|
+
| Excuse | Reality |
|
|
94
|
+
|---|---|
|
|
95
|
+
| "This seems obvious" | Obvious bugs have root causes too |
|
|
96
|
+
| "I'll investigate if this fix doesn't work" | The first fix sets the pattern — investigate first |
|
|
97
|
+
| "We're under time pressure" | Rushing guarantees rework; systematic is faster than thrashing |
|
|
98
|
+
| "One more fix attempt" | 3+ failures = architectural problem; question the pattern |
|
|
99
|
+
| "No evidence, so it's not that" | No evidence means `unknown`, not ruled out |
|
|
100
|
+
|
|
101
|
+
## Anti-Patterns
|
|
102
|
+
|
|
103
|
+
- ⊗ Fixing before reproducing the failure
|
|
104
|
+
- ⊗ Cargo-cult debugging: changing things until it works, with no understanding of why
|
|
105
|
+
- ⊗ Treating the first plausible hypothesis as confirmed without testing it
|
|
106
|
+
- ⊗ Skipping Phase 2 because a fix seems obvious
|
|
107
|
+
- ⊗ Presenting a duration or an exit status as a root cause (tautology)
|
|
108
|
+
- ⊗ Inferring a runtime config value from source code instead of proving it at runtime
|
|
109
|
+
- ⊗ Marking a theory "ruled out" without counter-evidence
|
|
110
|
+
- ⊗ A fourth fix attempt after three have failed without an architectural review
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
2
|
+
<!-- Purpose: rendered coding rules -->
|
|
3
|
+
<!-- Source of truth: packs/rules/rules-pack-0.1.json -->
|
|
4
|
+
<!-- Regenerate with: task packs:render -->
|
|
5
|
+
<!-- Edit the source, not this file. Slice instead of loading every coding doc: task packs:slice rules by-tier --tier <TIER> (or by-domain, list) -->
|
|
6
|
+
|
|
7
|
+
# Power of Ten – Adapted for Deft
|
|
8
|
+
JPL/NASA-inspired rules for reliable, verifiable code
|
|
9
|
+
(Original: Gerard J. Holzmann, "The Power of Ten – Rules for Developing Safety-Critical Code", IEEE Computer, June 2006)
|
|
10
|
+
|
|
11
|
+
**⚠️ See also** (load only when needed):
|
|
12
|
+
- [coding.md](coding.md) - General coding guidelines
|
|
13
|
+
- [../verification/verification.md](../verification/verification.md) - Verification practices (Holzmann ladder)
|
|
14
|
+
|
|
15
|
+
! These rules MUST be understood as the canonical high-assurance reference for Deft.
|
|
16
|
+
~ Apply the general intent across all languages.
|
|
17
|
+
~ Put language-specific enforcement, tooling, and exceptions only in languages/*.md files.
|
|
18
|
+
|
|
19
|
+
## Notation Legend (Deft RFC 2119 compact style)
|
|
20
|
+
! = MUST (required, mandatory)
|
|
21
|
+
~ = SHOULD (recommended, strong preference)
|
|
22
|
+
≉ = SHOULD NOT (discouraged, avoid unless justified)
|
|
23
|
+
⊗ = MUST NOT (forbidden, never do this)
|
|
24
|
+
? = MAY
|
|
25
|
+
|
|
26
|
+
## The Adapted Rules
|
|
27
|
+
|
|
28
|
+
1. Simple control flow
|
|
29
|
+
⊗ Use direct or indirect recursion
|
|
30
|
+
~ Use explicit iteration or stacks instead.
|
|
31
|
+
⊗ Exotic/non-local jumps (goto where supported, longjmp equivalents, setjmp).
|
|
32
|
+
~ Restrict control flow to basic constructs: if/else, bounded for/while, switch/case/match.
|
|
33
|
+
! Keep code analyzable and provably terminating where possible.
|
|
34
|
+
|
|
35
|
+
2. Bounded loops
|
|
36
|
+
! Every loop MUST have a statically provable fixed upper bound or mechanically verifiable termination condition.
|
|
37
|
+
⊗ Naked infinite loops (while True:, for {} without escape guarantee) are forbidden.
|
|
38
|
+
~ Prefer for i in range(MAX) / for i := 0; i < MAX; i++ {} patterns wherever practical.
|
|
39
|
+
! Termination guarantee MUST be preserved in all loops.
|
|
40
|
+
|
|
41
|
+
3. Fixed resource allocation after initialization
|
|
42
|
+
~ Allocate/grow dynamic structures (lists, maps, slices, heaps) during startup/initialization phase only.
|
|
43
|
+
≉ Grow structures (append, map inserts, slice appends) in hot paths or long-running loops unless bounded.
|
|
44
|
+
⊗ Unbounded dynamic allocation/growth in steady-state operation is forbidden (where language-relevant).
|
|
45
|
+
! Resource usage MUST remain predictable after initialization.
|
|
46
|
+
|
|
47
|
+
4. Small functions
|
|
48
|
+
~ Functions SHOULD be ≤ 40–60 lines (aim for one screen / printed page).
|
|
49
|
+
~ Cyclomatic complexity SHOULD be ≤ 10 per function.
|
|
50
|
+
! Small, focused functions MUST be preferred for verifiability and reviewability.
|
|
51
|
+
|
|
52
|
+
5. Runtime checks & assertions
|
|
53
|
+
~ Every non-trivial function SHOULD include at least two explicit runtime checks/assertions.
|
|
54
|
+
~ Use preconditions, postconditions, or invariants via language-native mechanisms.
|
|
55
|
+
! Runtime checks MUST catch violations early in non-trivial logic.
|
|
56
|
+
|
|
57
|
+
6. Minimal data scope
|
|
58
|
+
! Mutable shared/global state MUST be minimized — prefer local, passed, or immutable data.
|
|
59
|
+
⊗ Unnecessary module/package-level mutable variables (except constants) are forbidden.
|
|
60
|
+
~ Dependency injection or functional style SHOULD be used where practical.
|
|
61
|
+
! Scope reduction MUST reduce coupling and side effects.
|
|
62
|
+
|
|
63
|
+
7. Error & return checking
|
|
64
|
+
! Non-void return values and error indicators MUST never be ignored.
|
|
65
|
+
! In error-returning languages every error MUST be checked or explicitly propagated.
|
|
66
|
+
⊗ Silent failure / ignored exceptions are forbidden unless explicitly documented as safe.
|
|
67
|
+
! Explicit error handling MUST be enforced.
|
|
68
|
+
|
|
69
|
+
8. Restricted metaprogramming
|
|
70
|
+
⊗ Complex/multi-level macros or preprocessor abuse are forbidden (C/C++).
|
|
71
|
+
≉ Heavy decorators, metaclasses, or code generation that obscures control flow SHOULD be avoided.
|
|
72
|
+
~ Metaprogramming SHOULD remain minimal and local in safety-critical paths.
|
|
73
|
+
! Analyzability MUST be preserved; metaprogramming MUST NOT obscure control flow.
|
|
74
|
+
|
|
75
|
+
9. Restricted indirection
|
|
76
|
+
⊗ Multi-level pointers / double indirection are forbidden (C/C++ raw pointers).
|
|
77
|
+
≉ Deep pointer chains or excessive indirection SHOULD be avoided in other languages.
|
|
78
|
+
~ Prefer slices, references, or owned types (Rust, Go).
|
|
79
|
+
! Indirection MUST be kept simple to reduce aliasing risk.
|
|
80
|
+
|
|
81
|
+
10. Maximum static checking
|
|
82
|
+
! Compile/lint with maximum warnings enabled and treat warnings as errors.
|
|
83
|
+
! Strictest static analysis tools available for the language MUST be used.
|
|
84
|
+
! Static checking MUST catch issues at build time.
|
|
85
|
+
|
|
86
|
+
## Additional Holzmann-inspired Practices
|
|
87
|
+
~ Lightweight, interactive analysis tools SHOULD be preferred (Cobra philosophy).
|
|
88
|
+
~ Consider adding task cobra target for repo-wide queries (functions >40 lines, unbounded loops).
|
|
89
|
+
! Verification ladder MUST integrate with verification/ practices.
|
|
90
|
+
~ Every significant PR SHOULD include a short verifiability note.
|
|
91
|
+
|
|
92
|
+
## References
|
|
93
|
+
~ Original paper: https://spinroot.com/gerard/pdf/P10.pdf
|
|
94
|
+
~ Holzmann's SPIN model checker: https://spinroot.com
|
|
95
|
+
|
|
96
|
+
! This adaptation preserves JPL flight-software reliability philosophy for Deft's layered system.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<!-- AUTO-GENERATED by task packs:render -- DO NOT EDIT MANUALLY -->
|
|
2
|
+
<!-- Purpose: rendered coding rules -->
|
|
3
|
+
<!-- Source of truth: packs/rules/rules-pack-0.1.json -->
|
|
4
|
+
<!-- Regenerate with: task packs:render -->
|
|
5
|
+
<!-- Edit the source, not this file. Slice instead of loading every coding doc: task packs:slice rules by-tier --tier <TIER> (or by-domain, list) -->
|
|
6
|
+
|
|
7
|
+
# Codebase Hygiene
|
|
8
|
+
|
|
9
|
+
Rules for ongoing codebase health — keeping existing code clean, not just writing new code well.
|
|
10
|
+
|
|
11
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
12
|
+
|
|
13
|
+
**⚠️ See also**:
|
|
14
|
+
- [coding.md](coding.md) — Code design principles
|
|
15
|
+
- [verification/verification.md](../verification/verification.md) — Stub and legacy detection
|
|
16
|
+
- [coding/testing.md](testing.md) — Test coverage requirements
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Dead Code Removal
|
|
21
|
+
|
|
22
|
+
Dead code accumulates silently and degrades readability and maintainability.
|
|
23
|
+
|
|
24
|
+
- ! Before marking any refactor or cleanup task done, verify no unreferenced code was left behind
|
|
25
|
+
- ⊗ Commented-out code blocks committed to version control — delete, don't comment out
|
|
26
|
+
- ⊗ Functions, classes, or variables that are defined but never called/imported anywhere
|
|
27
|
+
- ⊗ Unused imports, dependencies, or exports
|
|
28
|
+
- ~ Use language-specific dead code tools as part of periodic hygiene passes:
|
|
29
|
+
- Python: `vulture` — detects unused functions, classes, variables
|
|
30
|
+
- Go: `deadcode` (golang.org/x/tools/cmd/deadcode) or `staticcheck` unused analysis
|
|
31
|
+
- TypeScript/JS: `knip` — detects unused exports, files, and dependencies
|
|
32
|
+
- ~ Run dead code tools before major releases or after significant refactors
|
|
33
|
+
- ? Add dead code tool as a Taskfile target (e.g. `task hygiene`) for periodic use
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Circular Dependencies
|
|
38
|
+
|
|
39
|
+
Circular imports create tight coupling, prevent modular testing, and indicate architectural problems.
|
|
40
|
+
|
|
41
|
+
- ⊗ Circular imports between modules/packages — detect and eliminate
|
|
42
|
+
- ! When circular dependency exists, resolve by extracting shared types/interfaces to a lower-level module, not by restructuring import order
|
|
43
|
+
- ~ Enforce layered architecture: high-level modules depend on low-level ones, never the reverse
|
|
44
|
+
- ! Use dependency inversion (interfaces/protocols) to break necessary coupling across layers
|
|
45
|
+
- ~ Use language-specific tools to detect cycles:
|
|
46
|
+
- Python: `pydeps` or `importlab` for full cycle detection
|
|
47
|
+
- Go: the compiler rejects import cycles — trust the error; fix by extracting shared packages
|
|
48
|
+
- TypeScript/JS: `madge` — visualises and detects circular dependencies
|
|
49
|
+
- ~ For large codebases, add `madge --circular --exit-code` (or equivalent) as a CI check
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Error Handling: No Hiding
|
|
54
|
+
|
|
55
|
+
Try/catch and equivalent constructs serve a legitimate purpose at **API/input boundaries** — sanitizing unknown or untrusted input. Everywhere else, they should propagate errors explicitly.
|
|
56
|
+
|
|
57
|
+
**Legitimate uses:**
|
|
58
|
+
- Parsing external input (JSON, user input, file content)
|
|
59
|
+
- Third-party SDK calls that may throw undocumented errors
|
|
60
|
+
- Top-level process handlers (recover from unexpected crashes with logging)
|
|
61
|
+
|
|
62
|
+
**Illegitimate uses (remove these):**
|
|
63
|
+
|
|
64
|
+
- ⊗ Empty catch/except/recover blocks that swallow errors silently
|
|
65
|
+
- ⊗ `except Exception: pass` or equivalent — log at minimum, re-raise if appropriate
|
|
66
|
+
- ⊗ Returning neutral/zero values (None, {}, [], 0, false, "") to mask an error — propagate explicitly
|
|
67
|
+
- ⊗ Log-and-continue: catching an error, logging it, and proceeding as if nothing happened — unless the error is provably non-fatal AND that decision is documented in a comment
|
|
68
|
+
- ⊗ Fallback patterns that hide failures from callers (e.g. "if this fails, return cached/stale data" without surfacing the error)
|
|
69
|
+
- ! When removing a try/catch, confirm the error propagates to a caller that can handle it — do not simply delete
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Legacy and Deprecated Code
|
|
74
|
+
|
|
75
|
+
Legacy accumulation makes codebases fragile and hard to reason about. Code should have one active path, not a graveyard of old approaches alongside new ones.
|
|
76
|
+
|
|
77
|
+
- ⊗ Parallel implementations: old approach and new approach coexisting without a migration path
|
|
78
|
+
- ⊗ Feature flags or toggle branches where the flag is always-on or always-off — collapse to the live path
|
|
79
|
+
- ⊗ Compatibility shims maintained beyond their stated removal date
|
|
80
|
+
- ! When replacing an implementation: delete the old one in the same commit, not "after testing"
|
|
81
|
+
- ~ Scan for these markers as legacy indicators:
|
|
82
|
+
- Comments: `# deprecated`, `// TODO: remove`, `LEGACY`, `COMPAT`, `OLD_`, `# old way`
|
|
83
|
+
- Python decorators: `@deprecated`
|
|
84
|
+
- Go: `// Deprecated:` godoc marker (legitimate when part of a public API — remove the symbol if internal)
|
|
85
|
+
- ~ When encountering legacy code during unrelated work, file a hygiene task rather than ignoring it
|
|
86
|
+
- ⊗ Comments describing in-flight replacement work ("this used to be X, now it's Y") — remove once the migration is complete; they are noise for future readers
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Surface Conflicts: Pick One, Explain, Flag the Other (#1005)
|
|
91
|
+
|
|
92
|
+
When two existing patterns in the codebase contradict each other (error-handling shapes, state-management approaches, naming conventions, component patterns, test structure, API-shape conventions), the path of least resistance is to write new code that satisfies BOTH simultaneously. The result is doubled logic (two error handlers, two validation paths), incoherent behaviour at the seam where both patterns interact, and a future agent facing the same two-pattern conflict and averaging again. **"Average" code that satisfies both contradicting rules is the worst code.**
|
|
93
|
+
|
|
94
|
+
- ! When two existing patterns in the codebase contradict, MUST pick ONE -- prefer the more recent OR the more tested -- and write new code against that pattern only
|
|
95
|
+
- ! MUST explain the choice in the commit message, PR body, or an inline comment near the new code (one sentence -- which pattern was chosen, which was dropped, why)
|
|
96
|
+
- ! MUST flag the dropped pattern as deprecated for cleanup: either (a) file a follow-up GitHub issue and reference its number, or (b) add a `# deprecated: see <ref>` / `// Deprecated: see <ref>` marker on the dropped pattern in the same PR so the legacy-code rules above pick it up on the next hygiene pass
|
|
97
|
+
- ⊗ MUST NOT blend the two patterns -- doubled error handlers, dual validation paths, parallel state stores, or any other "satisfy both" shape
|
|
98
|
+
- ⊗ MUST NOT silently choose one pattern without recording the choice -- a future agent must be able to read the commit / PR / comment and understand why this code does not match the other pattern they see elsewhere
|
|
99
|
+
- ? Exception: if the contradiction is INTENTIONAL (e.g. legacy path maintained for backward compat, gradual migration in flight), MUST document that explicitly (`# kept for v1 compat -- removal tracked in #NNN`) rather than flagging for cleanup
|
|
100
|
+
|
|
101
|
+
This applies across: error handling, state management, naming conventions, component patterns, test structure, API-shape conventions, dependency-injection styles, configuration-loading patterns, and any other surface where contradicting patterns can accumulate over a codebase's lifetime.
|
|
102
|
+
|
|
103
|
+
**Cross-references:** sibling rule `## Legacy and Deprecated Code` above (the dropped pattern lands under those rules once flagged); `coding/coding.md` `## Code Design` (the modularity rules that govern the kept pattern); `skills/deft-directive-build/SKILL.md` Step 1 (the build skill applies this rule when it encounters contradicting patterns during a brownfield implementation).
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## DRY: Don't Repeat Yourself
|
|
108
|
+
|
|
109
|
+
Duplication is the root cause of inconsistent behaviour and maintenance burden.
|
|
110
|
+
|
|
111
|
+
- ~ Extract shared abstractions when logic is duplicated across 2+ call sites
|
|
112
|
+
- ⊗ Copy-paste logic with minor variations — parameterise instead
|
|
113
|
+
- ! When deduplicating, verify the abstraction is actually shared behaviour, not coincidental similarity
|
|
114
|
+
- ≉ Premature abstraction — only extract when the duplication is real and the shared contract is clear
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Comments: Signal vs. Noise
|
|
119
|
+
|
|
120
|
+
Comments should explain **why**, not **what**. Remove noise; keep signal.
|
|
121
|
+
|
|
122
|
+
- ⊗ Comments describing what the code does (the code itself shows this)
|
|
123
|
+
- ⊗ In-motion commentary: "replaced X with Y", "temporarily disabled", "new approach below"
|
|
124
|
+
- ⊗ Commented-out code — delete it; version control preserves history
|
|
125
|
+
- ⊗ Section dividers and banners that add no information (e.g. `# --- helpers ---`)
|
|
126
|
+
- ! When editing a file, remove stale comments as you go — do not leave them for later
|
|
127
|
+
- ~ When a comment is needed, be concise: one line explaining the non-obvious reason, not a paragraph
|