lgtm-specs 0.0.4
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/settings.local.json +14 -0
- package/.gemini/README.md +8 -0
- package/.gemini/config.yaml +20 -0
- package/.gemini/styleguide.md +35 -0
- package/.github/workflows/README.md +5 -0
- package/.github/workflows/release.yml +52 -0
- package/.github/workflows/validate.yml +27 -0
- package/.prettierignore +4 -0
- package/.prettierrc +1 -0
- package/AGENTS.md +151 -0
- package/README.md +98 -0
- package/VERSION +1 -0
- package/agents/README.md +73 -0
- package/agents/modes/README.md +9 -0
- package/agents/modes/build.md +88 -0
- package/agents/modes/hack.md +76 -0
- package/agents/modes/review.md +79 -0
- package/agents/roles/builder.md +75 -0
- package/agents/roles/counsel.md +96 -0
- package/agents/roles/explorer.md +77 -0
- package/agents/roles/lead.md +76 -0
- package/agents/roles/librarian.md +63 -0
- package/agents/roles/planner.md +75 -0
- package/agents/roles/reviewer/BASE.md +9 -0
- package/agents/roles/reviewer/OUTPUT_FORMAT.md +4 -0
- package/agents/roles/reviewer/README.md +48 -0
- package/agents/roles/reviewer/lite.md +51 -0
- package/agents/roles/reviewer/logic.md +48 -0
- package/agents/roles/reviewer/performance.md +45 -0
- package/agents/roles/reviewer/plan.md +52 -0
- package/agents/roles/reviewer/quality.md +49 -0
- package/agents/roles/reviewer/security.md +47 -0
- package/agents/roles/reviewer/test.md +48 -0
- package/agents/templates/README.md +6 -0
- package/agents/templates/mode.md +33 -0
- package/agents/templates/role.md +73 -0
- package/contribute/README.md +24 -0
- package/contribute/add-agent.md +29 -0
- package/contribute/add-ci.md +31 -0
- package/contribute/add-constitution.md +17 -0
- package/contribute/add-law.md +20 -0
- package/contribute/add-policy.md +27 -0
- package/contribute/checklist.md +42 -0
- package/contribute/maintenance.md +19 -0
- package/contribute/update-models.md +47 -0
- package/docs/README.md +13 -0
- package/docs/adr/0001-knowledge-engineering-workflow.md +22 -0
- package/docs/adr/0002-rule-hierarchy.md +25 -0
- package/docs/adr/0003-atomic-knowledge-graph.md +21 -0
- package/docs/adr/0004-identification-schema.md +22 -0
- package/docs/adr/0005-agent-specialization.md +39 -0
- package/docs/adr/0006-git-workflow-integrity.md +34 -0
- package/docs/adr/0007-operating-modes-and-gates.md +54 -0
- package/docs/adr/0008-rules-vs-workflows-boundary.md +64 -0
- package/docs/adr/README.md +14 -0
- package/docs/agent_architecture.md +164 -0
- package/docs/context_lifecycle.md +228 -0
- package/docs/engineering_principles.md +128 -0
- package/docs/local_policies.md +59 -0
- package/docs/meta/collaborative_dynamics.md +142 -0
- package/docs/meta/domains/README.md +8 -0
- package/docs/meta/domains/bitcoin/01-units.md +21 -0
- package/docs/meta/domains/bitcoin/02-broadcast-cancellation.md +20 -0
- package/docs/meta/domains/bitcoin/03-fee-rates-rounding.md +21 -0
- package/docs/meta/domains/bitcoin/04-confirmations-reorgs.md +20 -0
- package/docs/meta/domains/bitcoin/05-address-gap-limit.md +16 -0
- package/docs/meta/domains/bitcoin/06-relay-policy.md +27 -0
- package/docs/meta/domains/bitcoin/README.md +12 -0
- package/docs/meta/domains/git/01-workflow.md +89 -0
- package/docs/meta/domains/git/02-commits.md +57 -0
- package/docs/meta/domains/git/03-collaboration.md +40 -0
- package/docs/meta/domains/git/04-integrity.md +26 -0
- package/docs/meta/domains/git/05-configuration.md +209 -0
- package/docs/meta/domains/git/06-advanced.md +130 -0
- package/docs/meta/domains/git/README.md +29 -0
- package/docs/meta/industry_best_practices.md +555 -0
- package/docs/meta/languages/README.md +8 -0
- package/docs/meta/languages/go/01-concurrency.md +37 -0
- package/docs/meta/languages/go/02-api-design.md +30 -0
- package/docs/meta/languages/go/03-resilience.md +27 -0
- package/docs/meta/languages/go/04-errors.md +27 -0
- package/docs/meta/languages/go/05-performance.md +18 -0
- package/docs/meta/languages/go/06-safety.md +18 -0
- package/docs/meta/languages/go/07-testing.md +44 -0
- package/docs/meta/languages/go/08-config-layout.md +23 -0
- package/docs/meta/languages/go/README.md +14 -0
- package/docs/meta/languages/typescript/01-strictness.md +19 -0
- package/docs/meta/languages/typescript/02-immutability.md +15 -0
- package/docs/meta/languages/typescript/03-async.md +18 -0
- package/docs/meta/languages/typescript/04-design.md +19 -0
- package/docs/meta/languages/typescript/05-control-flow.md +11 -0
- package/docs/meta/languages/typescript/README.md +11 -0
- package/docs/meta/workflow.md +68 -0
- package/docs/philosophy.md +36 -0
- package/integrate/README.md +459 -0
- package/integrate/versioning.md +41 -0
- package/models/README.md +68 -0
- package/models/registry.yaml +55 -0
- package/package.json +11 -0
- package/rules/README.md +57 -0
- package/rules/RULE-00000-EXAMPLE.md +29 -0
- package/rules/constitution/CONS-00001-srp.md +40 -0
- package/rules/constitution/CONS-00002-ocp.md +43 -0
- package/rules/constitution/CONS-00003-lsp.md +44 -0
- package/rules/constitution/CONS-00004-isp.md +46 -0
- package/rules/constitution/CONS-00005-dip.md +37 -0
- package/rules/constitution/CONS-00006-dry.md +45 -0
- package/rules/constitution/CONS-00007-demeter.md +35 -0
- package/rules/constitution/CONS-00008-composition.md +44 -0
- package/rules/constitution/CONS-00009-deep-modules.md +39 -0
- package/rules/constitution/CONS-00010-kiss.md +47 -0
- package/rules/constitution/CONS-00011-yagni.md +49 -0
- package/rules/constitution/CONS-00012-cognitive-limits.md +28 -0
- package/rules/constitution/CONS-00013-boy-scout.md +27 -0
- package/rules/constitution/CONS-00014-broken-windows.md +35 -0
- package/rules/constitution/CONS-00015-safety.md +46 -0
- package/rules/constitution/CONS-00016-cqs.md +39 -0
- package/rules/constitution/CONS-00017-postel.md +35 -0
- package/rules/constitution/CONS-00018-cap.md +35 -0
- package/rules/constitution/CONS-00019-fallacies.md +37 -0
- package/rules/constitution/CONS-00020-shift-left.md +28 -0
- package/rules/constitution/CONS-00021-congruence.md +28 -0
- package/rules/constitution/CONS-00022-orthogonality.md +40 -0
- package/rules/constitution/CONS-00023-determinism.md +38 -0
- package/rules/constitution/CONS-00024-security.md +42 -0
- package/rules/constitution/CONS-00025-efficiency.md +38 -0
- package/rules/constitution/CONS-00026-resilience.md +41 -0
- package/rules/constitution/CONS-00027-transparency.md +40 -0
- package/rules/constitution/CONS-00028-evolvability.md +36 -0
- package/rules/constitution/CONS-00029-operability.md +36 -0
- package/rules/constitution/CONS-00030-rework-cycle.md +27 -0
- package/rules/constitution/CONS-00031-checklist.md +28 -0
- package/rules/constitution/CONS-00032-documentation.md +39 -0
- package/rules/constitution/README.md +52 -0
- package/rules/laws/README.md +15 -0
- package/rules/laws/bitcoin/BTC-00001-amounts-as-satoshis.md +39 -0
- package/rules/laws/bitcoin/BTC-00002-broadcast-not-cancelable.md +36 -0
- package/rules/laws/bitcoin/BTC-00003-fee-rate-math-rounding.md +37 -0
- package/rules/laws/bitcoin/BTC-00004-confirmations-and-reorgs.md +40 -0
- package/rules/laws/bitcoin/BTC-00005-address-gap-limit.md +37 -0
- package/rules/laws/bitcoin/BTC-00006-relay-is-policy-dependent.md +36 -0
- package/rules/laws/bitcoin/BTC-00007-dust-policy.md +36 -0
- package/rules/laws/bitcoin/BTC-00008-min-relay-fee.md +36 -0
- package/rules/laws/bitcoin/BTC-00009-feefilter.md +36 -0
- package/rules/laws/bitcoin/README.md +29 -0
- package/rules/laws/default.md +30 -0
- package/rules/laws/git/GIT-00001-atomic-commit.md +29 -0
- package/rules/laws/git/GIT-00002-imperative-subject.md +27 -0
- package/rules/laws/git/GIT-00003-formatting-50-72.md +28 -0
- package/rules/laws/git/GIT-00004-trunk-based.md +28 -0
- package/rules/laws/git/GIT-00005-public-immutability.md +26 -0
- package/rules/laws/git/GIT-00006-signing.md +27 -0
- package/rules/laws/git/GIT-00007-reviewer-capital.md +26 -0
- package/rules/laws/git/GIT-00008-patch-series.md +28 -0
- package/rules/laws/git/GIT-00009-branch-naming.md +28 -0
- package/rules/laws/git/GIT-00010-pr-hygiene.md +51 -0
- package/rules/laws/git/GIT-00011-merge-method.md +35 -0
- package/rules/laws/git/GIT-00012-conflict-resolution.md +35 -0
- package/rules/laws/git/GIT-00013-ignore-standards.md +38 -0
- package/rules/laws/git/GIT-00014-lfs-large-binaries.md +37 -0
- package/rules/laws/git/GIT-00015-git-hooks.md +35 -0
- package/rules/laws/git/GIT-00016-branch-protection.md +34 -0
- package/rules/laws/git/GIT-00017-secrets-management.md +34 -0
- package/rules/laws/git/GIT-00018-ci-enforcement.md +33 -0
- package/rules/laws/git/GIT-00019-review-checklist.md +39 -0
- package/rules/laws/git/GIT-00020-issue-references.md +34 -0
- package/rules/laws/git/GIT-00021-partial-staging.md +38 -0
- package/rules/laws/git/GIT-00022-feature-flags.md +33 -0
- package/rules/laws/git/GIT-00023-breaking-changes.md +41 -0
- package/rules/laws/git/GIT-00024-dependency-management.md +44 -0
- package/rules/laws/git/GIT-00025-large-repository-optimization.md +54 -0
- package/rules/laws/git/README.md +31 -0
- package/rules/laws/go/GO-00001-actor-model.md +51 -0
- package/rules/laws/go/GO-00002-api-design.md +37 -0
- package/rules/laws/go/GO-00003-error-handling.md +43 -0
- package/rules/laws/go/GO-00004-context.md +45 -0
- package/rules/laws/go/GO-00005-performance.md +40 -0
- package/rules/laws/go/GO-00006-packages.md +29 -0
- package/rules/laws/go/GO-00007-circuit-breakers.md +43 -0
- package/rules/laws/go/GO-00008-safety.md +39 -0
- package/rules/laws/go/GO-00009-table-driven-test.md +48 -0
- package/rules/laws/go/GO-00010-escape-analysis.md +37 -0
- package/rules/laws/go/GO-00011-retry.md +45 -0
- package/rules/laws/go/GO-00012-rate-limiting.md +42 -0
- package/rules/laws/go/GO-00013-io-buffering.md +43 -0
- package/rules/laws/go/GO-00014-memory-layout.md +41 -0
- package/rules/laws/go/GO-00015-aaa-pattern.md +49 -0
- package/rules/laws/go/GO-00016-test-libraries.md +35 -0
- package/rules/laws/go/GO-00017-comments.md +37 -0
- package/rules/laws/go/GO-00018-test-isolation.md +38 -0
- package/rules/laws/go/GO-00019-test-comments.md +36 -0
- package/rules/laws/go/GO-00020-mocking.md +36 -0
- package/rules/laws/go/GO-00021-configuration.md +36 -0
- package/rules/laws/go/GO-00022-observability.md +34 -0
- package/rules/laws/go/GO-00023-dependency-management.md +28 -0
- package/rules/laws/go/GO-00024-project-layout.md +30 -0
- package/rules/laws/go/GO-00025-concurrency-patterns.md +39 -0
- package/rules/laws/go/README.md +45 -0
- package/rules/laws/typescript/README.md +14 -0
- package/rules/laws/typescript/TS-00001-no-any.md +39 -0
- package/rules/laws/typescript/TS-00002-immutability.md +36 -0
- package/rules/laws/typescript/TS-00003-async.md +35 -0
- package/rules/laws/typescript/TS-00004-strict-null.md +38 -0
- package/rules/laws/typescript/TS-00005-unions.md +35 -0
- package/rules/laws/typescript/TS-00006-interface.md +38 -0
- package/rules/laws/typescript/TS-00007-generics.md +38 -0
- package/rules/laws/typescript/TS-00008-modules.md +28 -0
- package/rules/policies/README.md +12 -0
- package/rules/policies/default.md +28 -0
- package/scripts/README.md +45 -0
- package/scripts/generate_release_notes.py +376 -0
- package/scripts/validate_specs.py +730 -0
package/rules/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# The Atomic Rulebook (Zettelkasten)
|
|
2
|
+
|
|
3
|
+
This directory contains the machine-readable specifications ("Specs") used to inject context into LGTM Agents.
|
|
4
|
+
|
|
5
|
+
## Methodology
|
|
6
|
+
|
|
7
|
+
We use a **Zettelkasten** approach to manage engineering knowledge.
|
|
8
|
+
|
|
9
|
+
1. **Atomic**: Each file covers exactly one principle. No monolithic "Best Practices" documents.
|
|
10
|
+
2. **Linked**: Notes reference each other via `Related` links, forming a graph.
|
|
11
|
+
3. **Machine-First**: The structure is optimized for Retrieval Augmented Generation (RAG). The Metadata header allows precise filtering.
|
|
12
|
+
|
|
13
|
+
## The Brain Map
|
|
14
|
+
|
|
15
|
+
- **[The Constitution](constitution/README.md) (Universal Rules)**
|
|
16
|
+
- **Role**: The immutable "Physics" of software engineering.
|
|
17
|
+
- **Content**: Principles derived from Systems Theory, Cognitive Science, and formal Computer Science (e.g., Entropy, Complexity, Cognitive Load).
|
|
18
|
+
- **Usage**: Injected into _every_ agent to ensure high-level architectural integrity.
|
|
19
|
+
|
|
20
|
+
- **[The Laws](laws/README.md) (Domain Rules)**
|
|
21
|
+
- **Role**: The "Civil Code" of specific technologies.
|
|
22
|
+
- **Derivation**: Every Law must effectively implement a Constitutional Principle. (e.g., "No `any`" implements `Safety`).
|
|
23
|
+
- **Content**: Idioms, safety checks, and patterns specific to a language or framework.
|
|
24
|
+
- **Usage**: Injected dynamically based on the detected tech stack.
|
|
25
|
+
|
|
26
|
+
- **[The Policies](policies/README.md) (Project By-Laws)**
|
|
27
|
+
- **Role**: The "Local Ordinances" of a specific repository.
|
|
28
|
+
- **Derivation**: Policies optimize Laws/Constitution for a specific team context, but **cannot violate** the Constitution.
|
|
29
|
+
- **Content**: Configuration choices, style preferences, and workflow requirements.
|
|
30
|
+
- **Usage**: Loaded from the user's repository config to override or extend defaults.
|
|
31
|
+
|
|
32
|
+
## How to Use These Rules
|
|
33
|
+
|
|
34
|
+
The "Perfect Engineer" is constructed by layering these rules into the Agent's context.
|
|
35
|
+
|
|
36
|
+
### 1. The Assembly Formula
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
Agent Prompt =
|
|
40
|
+
[Role Definition] (e.g., "You are a Reviewer")
|
|
41
|
+
+ [Constitution] (Universal Truths)
|
|
42
|
+
+ [Laws] (Language Specifics)
|
|
43
|
+
+ [Policies] (Repo Specifics)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Context Injection Mechanism
|
|
47
|
+
|
|
48
|
+
- **Constitution**: Retrieved via **Tags**.
|
|
49
|
+
- _Scenario:_ A Reviewer checking architecture will load rules tagged `#structural` and `#coupling` (e.g., SRP, DIP).
|
|
50
|
+
- **Laws**: Selected via **Tech Stack Detection**.
|
|
51
|
+
- _Scenario:_ If `tsconfig.json` is present, inject `laws/typescript/*.md`.
|
|
52
|
+
- **Policies**: Loaded via **Path Lookup**.
|
|
53
|
+
- _Scenario:_ If `.lgtm/policies/README.md` exists, append it. If not, use `rules/policies/default.md`.
|
|
54
|
+
|
|
55
|
+
## The Spec Template
|
|
56
|
+
|
|
57
|
+
Every rule MUST follow the format defined in [RULE-00000-EXAMPLE.md](RULE-00000-EXAMPLE.md).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Rule Name (ID)
|
|
2
|
+
|
|
3
|
+
**Source**: [Link to Industry Best Practice](../docs/meta/industry_best_practices.md#anchor)
|
|
4
|
+
**Tags**: #structural #tag1 #tag2
|
|
5
|
+
**Related**: [Other Rule](constitution/CONS-00001-srp.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
A concise, 1-sentence definition of the principle.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
Actionable, testable constraints.
|
|
14
|
+
|
|
15
|
+
1. **Requirement Name**: Description.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
Specific bad practices to detect.
|
|
20
|
+
|
|
21
|
+
- **Pattern Name**: Description.
|
|
22
|
+
|
|
23
|
+
## Examples
|
|
24
|
+
|
|
25
|
+
**Bad:**
|
|
26
|
+
(Code snippet)
|
|
27
|
+
|
|
28
|
+
**Good:**
|
|
29
|
+
(Code snippet)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Single Responsibility Principle (CONS-00001)
|
|
2
|
+
|
|
3
|
+
**Source**: [SOLID Principles](../../docs/meta/industry_best_practices.md#11-single-responsibility-principle-srp)
|
|
4
|
+
**Tags**: #structural #solid #cohesion #architecture
|
|
5
|
+
**Related**: [Deep Modules](CONS-00009-deep-modules.md), [Socio-Technical Congruence](CONS-00021-congruence.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
A module should have one, and only one, reason to change.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Separation of Concerns**: A class handling business logic must NOT handle database queries or UI rendering directly.
|
|
14
|
+
2. **High Cohesion**: All methods in a class should operate on the same set of state variables.
|
|
15
|
+
3. **Layer Isolation**: Separate "Policy" (Business Rules) from "Mechanism" (IO/Frameworks).
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **God Classes**: `Manager` or `Handler` classes with mixed responsibilities (Auth + Logging + DB).
|
|
20
|
+
- **Leakage**: UI layer importing storage record types.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
class User:
|
|
28
|
+
authenticate(...)
|
|
29
|
+
save_to_storage(...)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Good:**
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
class UserAuth:
|
|
36
|
+
authenticate(...)
|
|
37
|
+
|
|
38
|
+
class UserRepository:
|
|
39
|
+
save(user)
|
|
40
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Open/Closed Principle (CONS-00002)
|
|
2
|
+
|
|
3
|
+
**Source**: [SOLID Principles](../../docs/meta/industry_best_practices.md#12-openclosed-principle-ocp)
|
|
4
|
+
**Tags**: #structural #solid #extensibility
|
|
5
|
+
**Related**: [Evolvability](CONS-00028-evolvability.md), [YAGNI](CONS-00011-yagni.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Software entities should be open for extension but closed for modification.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Extension Points**: Use interfaces or abstract classes to allow behavior changes.
|
|
14
|
+
2. **Stability**: Do not modify stable classes to add features if Inheritance or Decorators can be used.
|
|
15
|
+
3. **Strategy Pattern**: Prefer injecting a Strategy object over adding `if/else` blocks for new cases.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **Switch on Type**: `if (type === 'A') ... else if (type === 'B')`.
|
|
20
|
+
- **Monkey Patching**: Modifying objects at runtime.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
function area(shape):
|
|
28
|
+
if shape.type == "circle":
|
|
29
|
+
...
|
|
30
|
+
else if shape.type == "square":
|
|
31
|
+
...
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Good:**
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
interface Shape:
|
|
38
|
+
area()
|
|
39
|
+
|
|
40
|
+
class Circle implements Shape:
|
|
41
|
+
area():
|
|
42
|
+
...
|
|
43
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Liskov Substitution Principle (CONS-00003)
|
|
2
|
+
|
|
3
|
+
**Source**: [SOLID Principles](../../docs/meta/industry_best_practices.md#13-liskov-substitution-principle-lsp)
|
|
4
|
+
**Tags**: #behavioral #solid #correctness #types
|
|
5
|
+
**Related**: [Safety by Design](CONS-00015-safety.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Subtypes must be substitutable for their base types without altering correctness.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Contract Adherence**: A subclass must accept the same inputs and guarantee the same post-conditions.
|
|
14
|
+
2. **Exception Parity**: A subclass must not throw exceptions that are not part of the parent's contract.
|
|
15
|
+
3. **Return Consistency**: Do not restrict return types unpredictably.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **Refused Bequest**: Implementing a method by throwing `NotImplementedException`.
|
|
20
|
+
- **Type Narrowing Violation**: Returning a specific error code where the parent promised success.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
class Bird:
|
|
28
|
+
fly()
|
|
29
|
+
|
|
30
|
+
class Penguin extends Bird:
|
|
31
|
+
fly():
|
|
32
|
+
error("cannot fly")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Good:**
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
class Bird
|
|
39
|
+
|
|
40
|
+
class FlyingBird extends Bird:
|
|
41
|
+
fly()
|
|
42
|
+
|
|
43
|
+
class Penguin extends Bird
|
|
44
|
+
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Interface Segregation Principle (CONS-00004)
|
|
2
|
+
|
|
3
|
+
**Source**: [SOLID Principles](../../docs/meta/industry_best_practices.md#14-interface-segregation-principle-isp)
|
|
4
|
+
**Tags**: #structural #solid #decoupling #interface
|
|
5
|
+
**Related**: [Deep Modules](CONS-00009-deep-modules.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Clients should not be forced to depend on interfaces they do not use.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Narrow Interfaces**: Split "God Interfaces" (e.g., `IUserHandler`) into role-specific ones (`IUserReader`, `IUserWriter`).
|
|
14
|
+
2. **Role-Based Params**: Functions should accept the smallest interface possible.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **Fat Interfaces**: An interface with methods for Auth, DB, and UI.
|
|
19
|
+
- **Unused Impls**: Empty method bodies just to satisfy an interface.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
interface Worker:
|
|
27
|
+
work()
|
|
28
|
+
eat()
|
|
29
|
+
|
|
30
|
+
class Robot implements Worker:
|
|
31
|
+
work():
|
|
32
|
+
...
|
|
33
|
+
eat():
|
|
34
|
+
... # forced dependency
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Good:**
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
interface Workable:
|
|
41
|
+
work()
|
|
42
|
+
|
|
43
|
+
class Robot implements Workable:
|
|
44
|
+
work():
|
|
45
|
+
...
|
|
46
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Dependency Inversion Principle (CONS-00005)
|
|
2
|
+
|
|
3
|
+
**Source**: [SOLID Principles](../../docs/meta/industry_best_practices.md#15-dependency-inversion-principle-dip)
|
|
4
|
+
**Tags**: #structural #solid #decoupling #testability
|
|
5
|
+
**Related**: [SRP](CONS-00001-srp.md), [Orthogonality](CONS-00022-orthogonality.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
High-level modules should not depend on low-level modules. Both should depend on abstractions.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Injection**: Dependencies must be passed in (Constructor/Method Injection).
|
|
14
|
+
2. **Abstraction**: Imports in domain logic should point to `interfaces/` or `types/`, not concrete `infrastructure/`.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **Hardcoded Dependencies**: `new ConcreteDatabase()` inside a Service.
|
|
19
|
+
- **Static Cling**: Direct calls to static helper methods for IO.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
class Service:
|
|
27
|
+
init():
|
|
28
|
+
database = ConcreteDatabase() # hardcoded
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Good:**
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
class Service:
|
|
35
|
+
init(database_dep):
|
|
36
|
+
database = database_dep # injected abstraction
|
|
37
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# DRY (Don't Repeat Yourself) (CONS-00006)
|
|
2
|
+
|
|
3
|
+
**Source**: [Universal Fundamentals](../../docs/meta/industry_best_practices.md#83-dry-dont-repeat-yourself)
|
|
4
|
+
**Tags**: #structural #complexity #maintenance
|
|
5
|
+
**Related**: [SRP](CONS-00001-srp.md), [OCP](CONS-00002-ocp.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Every piece of knowledge must have a single, authoritative representation within a system.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Single Source of Truth**: Data schemas must be defined once (e.g., a single schema definition file) and types
|
|
14
|
+
generated from it.
|
|
15
|
+
2. **Logic Reuse**: Complex algorithms (e.g., tax calculation) must exist in one place.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **Copy-Paste**: Repeating the same block of code in multiple controllers.
|
|
20
|
+
- **Drift**: Two functions doing almost the same thing but diverging over time.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
# API layer
|
|
28
|
+
type User:
|
|
29
|
+
id
|
|
30
|
+
|
|
31
|
+
# Storage layer (duplicated)
|
|
32
|
+
type UserRecord:
|
|
33
|
+
id
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Good:**
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
# Shared types module
|
|
40
|
+
type User:
|
|
41
|
+
id
|
|
42
|
+
|
|
43
|
+
# API and storage both depend on the shared type
|
|
44
|
+
use(User)
|
|
45
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Law of Demeter (CONS-00007)
|
|
2
|
+
|
|
3
|
+
**Source**: [Universal Fundamentals](../../docs/meta/industry_best_practices.md#84-law-of-demeter)
|
|
4
|
+
**Tags**: #structural #coupling #encapsulation
|
|
5
|
+
**Related**: [Deep Modules](CONS-00009-deep-modules.md), [Orthogonality](CONS-00022-orthogonality.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
A module should not know about the innards of the objects it manipulates. Talk to your friends, not your friends' friends.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **One Dot Rule**: Avoid `a.b().c()`. Call methods on `a` that handle the delegation.
|
|
14
|
+
2. **Encapsulation**: Objects should expose behavior, not data structure.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **Train Wrecks**: `order.customer.address.zipCode`.
|
|
19
|
+
- **Inappropriate Intimacy**: Accessing nested private state.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
function shipping_zip_code(order):
|
|
27
|
+
return order.get_customer().get_address().get_zip_code()
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Good:**
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
function shipping_zip_code(order):
|
|
34
|
+
return order.get_shipping_zip_code()
|
|
35
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Composition Over Inheritance (CONS-00008)
|
|
2
|
+
|
|
3
|
+
**Source**: [Coupling & Cohesion](../../docs/meta/industry_best_practices.md#42-composition-over-inheritance)
|
|
4
|
+
**Tags**: #structural #coupling #flexibility
|
|
5
|
+
**Related**: [OCP](CONS-00002-ocp.md), [Orthogonality](CONS-00022-orthogonality.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Favor object composition ("has-a") over class inheritance ("is-a") to achieve code reuse and flexibility.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Flat Hierarchies**: Reject inheritance trees deeper than 2 levels.
|
|
14
|
+
2. **Delegation**: Use composition/delegation to share code between unrelated classes.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **Fragile Base Class**: A base class with many diverse methods that child classes "inherit" but don't need.
|
|
19
|
+
- **Gorilla/Banana Problem**: You wanted a banana but you got the gorilla holding the banana and the entire jungle.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
class Animal:
|
|
27
|
+
eat()
|
|
28
|
+
fly()
|
|
29
|
+
|
|
30
|
+
class Dog extends Animal:
|
|
31
|
+
fly():
|
|
32
|
+
error("cannot fly")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Good:**
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
class Dog:
|
|
39
|
+
init(eater_dep):
|
|
40
|
+
eater = eater_dep
|
|
41
|
+
|
|
42
|
+
eat():
|
|
43
|
+
return eater.eat()
|
|
44
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Deep Modules (CONS-00009)
|
|
2
|
+
|
|
3
|
+
**Source**: [A Philosophy of Software Design](../../docs/meta/industry_best_practices.md#21-deep-modules)
|
|
4
|
+
**Tags**: #structural #complexity #interface
|
|
5
|
+
**Related**: [Law of Demeter](CONS-00007-demeter.md), [Cohesion](CONS-00001-srp.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Interfaces must be significantly simpler than their implementations. Complexity should be hidden, not exposed.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Maximize Depth**: Functionality (Benefit) > Interface (Cost).
|
|
14
|
+
2. **Hide Complexity**: The implementation should handle the hard work (retries, caching).
|
|
15
|
+
3. **Reject Pass-Through**: Methods that just delegate to another object without adding value are tech debt.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **Shallow Classes**: A class named `FileUtil` that just wraps `filesystem.read` 1:1.
|
|
20
|
+
- **Leakage**: Exposing `cache strategy` in the `read()` method signature.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
class FileReader:
|
|
28
|
+
read(path, encoding, flags):
|
|
29
|
+
return filesystem.read(path, encoding, flags) # pass-through
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Good:**
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
class ConfigLoader:
|
|
36
|
+
load():
|
|
37
|
+
# Handles finding the file, reading, parsing, and validation
|
|
38
|
+
return config
|
|
39
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# KISS (Keep It Simple, Stupid) (CONS-00010)
|
|
2
|
+
|
|
3
|
+
**Source**: [Classic Engineering Wisdom](../../docs/meta/industry_best_practices.md#81-kiss-keep-it-simple-stupid)
|
|
4
|
+
**Tags**: #structural #simplicity #readability
|
|
5
|
+
**Related**: [YAGNI](CONS-00011-yagni.md), [Cognitive Limits](CONS-00012-cognitive-limits.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Complexity is a cost; avoid it unless justified by value. Most systems work best if they are kept simple.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **No Speculative Generality**: Do not build a factory for a single implementation.
|
|
14
|
+
2. **Boring Code**: Prefer standard library solutions over clever custom logic.
|
|
15
|
+
3. **Readability**: If a one-liner requires mental parsing, expand it.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **Over-Engineering**: Using the Strategy Pattern for a simple `if` statement.
|
|
20
|
+
- **Code Golf**: Minimizing characters at the expense of clarity.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
is_valid = false
|
|
28
|
+
if a:
|
|
29
|
+
if b:
|
|
30
|
+
if c:
|
|
31
|
+
is_valid = true
|
|
32
|
+
else:
|
|
33
|
+
is_valid = false
|
|
34
|
+
else:
|
|
35
|
+
is_valid = false
|
|
36
|
+
else:
|
|
37
|
+
is_valid = false
|
|
38
|
+
return is_valid
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Good:**
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
if not a or not b:
|
|
45
|
+
return false
|
|
46
|
+
return c
|
|
47
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# YAGNI (You Aren't Gonna Need It) (CONS-00011)
|
|
2
|
+
|
|
3
|
+
**Source**: [Classic Engineering Wisdom](../../docs/meta/industry_best_practices.md#82-yagni-you-arent-gonna-need-it)
|
|
4
|
+
**Tags**: #structural #simplicity #efficiency
|
|
5
|
+
**Related**: [KISS](CONS-00010-kiss.md), [OCP](CONS-00002-ocp.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Do not implement functionality until it is necessary.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Dead Code**: Remove unused functions, variables, or files.
|
|
14
|
+
2. **No Futures**: Reject "extensibility hooks" or "plugin architectures" that have no immediate use case.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **Speculative Features**: "I added an `isAdmin` flag just in case we need it later."
|
|
19
|
+
- **Commented Out Code**: Keeping old code "just in case." Use Git history for that.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
# Speculative abstraction for formats we do not support
|
|
27
|
+
parsers = {
|
|
28
|
+
current: parse_current_format,
|
|
29
|
+
future: parse_future_format, # unused
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function parse(input, format):
|
|
33
|
+
return parsers[format](input)
|
|
34
|
+
|
|
35
|
+
# TODO: implement when needed
|
|
36
|
+
function parse_future_format(input):
|
|
37
|
+
...
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Good:**
|
|
41
|
+
|
|
42
|
+
```text
|
|
43
|
+
# Code for current requirements only
|
|
44
|
+
function parse_current_format(input):
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
function parse(input):
|
|
48
|
+
return parse_current_format(input)
|
|
49
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Cognitive Limits (Batch Size) (CONS-00012)
|
|
2
|
+
|
|
3
|
+
**Source**: [Pragmatic Programmer & Code Health](../../docs/meta/industry_best_practices.md#43-cognitive-limits-batch-size)
|
|
4
|
+
**Tags**: #operational #human-factors #review
|
|
5
|
+
**Related**: [Deep Modules](CONS-00009-deep-modules.md), [KISS](CONS-00010-kiss.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Human review effectiveness drops precipitously after 400 LOC. Beyond this, the reviewer switches from "Analytical Mode" to "Pattern Matching Mode."
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Atomic Commits**: A commit must handle one logical change.
|
|
14
|
+
2. **PR Size**: Pull Requests should stay under 400 LOC.
|
|
15
|
+
3. **Single Story**: A PR cannot mix Refactoring and Feature work.
|
|
16
|
+
|
|
17
|
+
## Anti-Patterns
|
|
18
|
+
|
|
19
|
+
- **The Big Bang**: A 2,000 line PR named "V2 rewrite."
|
|
20
|
+
- **The Kitchen Sink**: A feature PR that also reformats the entire codebase.
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
**Bad:**
|
|
25
|
+
`feat: add auth and reformat utils and upgrade dependency` (Files changed: 45)
|
|
26
|
+
|
|
27
|
+
**Good:**
|
|
28
|
+
`feat(auth): add login endpoint` (Files changed: 3)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# The Boy Scout Rule (CONS-00013)
|
|
2
|
+
|
|
3
|
+
**Source**: [Pragmatic Programmer & Code Health](../../docs/meta/industry_best_practices.md#41-the-boy-scout-rule)
|
|
4
|
+
**Tags**: #operational #maintenance #refactoring
|
|
5
|
+
**Related**: [Broken Windows](CONS-00014-broken-windows.md), [Congruence](CONS-00021-congruence.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Always leave the code cleaner than you found it. Continuous, incremental improvement beats "Big Bang" refactors.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Incidental Cleanup**: If you touch a file, fix existing lint warnings or bad names in the immediate context.
|
|
14
|
+
2. **No Regression**: Do not introduce new technical debt (TODOs without tickets) in the name of speed.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **"Not My Job"**: Seeing a typo and ignoring it because it wasn't part of the ticket.
|
|
19
|
+
- **Drive-By Trashing**: Adding a hack to a clean file because "it was already messy."
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
Leaving a variable named `x` when modifying the function it lives in.
|
|
25
|
+
|
|
26
|
+
**Good:**
|
|
27
|
+
Renaming `x` to `user_index` while updating the loop logic.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Broken Windows Theory (CONS-00014)
|
|
2
|
+
|
|
3
|
+
**Source**: [Pragmatic Programmer & Code Health](../../docs/meta/industry_best_practices.md#42-broken-windows-theory)
|
|
4
|
+
**Tags**: #operational #maintenance #quality
|
|
5
|
+
**Related**: [The Boy Scout Rule](CONS-00013-boy-scout.md), [Operability](CONS-00029-operability.md)
|
|
6
|
+
|
|
7
|
+
## Definition
|
|
8
|
+
|
|
9
|
+
Bad designs, wrong decisions, and poor code, when left unrepaired, encourage more of the same. Normalization of deviance.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
1. **Zero Tolerance**: Do not ignore "warn" level linting errors. Fix them.
|
|
14
|
+
2. **Debt Repayment**: If a hack is necessary, it must be encapsulated and marked with a deprecation plan.
|
|
15
|
+
|
|
16
|
+
## Anti-Patterns
|
|
17
|
+
|
|
18
|
+
- **Disabled Tests**: Commenting out a failing test instead of fixing it.
|
|
19
|
+
- **"Temporary" Hacks**: Code marked `// TODO: Fix this` from 3 years ago.
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
**Bad:**
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
# Suppressing a safety/static-analysis warning instead of fixing the cause
|
|
27
|
+
suppress_warning("unsafe_type")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Good:**
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
# Refactor so the code satisfies checks without suppression
|
|
34
|
+
value = parse_and_validate(input)
|
|
35
|
+
```
|