diff --git a/CREDITS.md b/CREDITS.md index fda776e..1ab60b0 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -23,7 +23,7 @@ The designer plugin's knowledge base is distilled from publicly available design - **Typography and layout** - Bringhurst's *Elements of Typographic Style*, MΓΌller-Brockmann's grid systems - **Design systems** - Patterns observed across Linear, Stripe, Vercel, Apple HIG, Carbon, shadcn, Notion, Supabase, and Figma - used as reference, not reproduced -The design-patterns-skill draws on principles from: +The best-practices skill draws on principles from: - *Clean Code* - Robert C. Martin - *The Pragmatic Programmer* - Hunt and Thomas diff --git a/README.md b/README.md index b4b15b4..c059884 100755 --- a/README.md +++ b/README.md @@ -265,7 +265,7 @@ Domain-expert lenses `hyper` auto-engages when their triggers match the request | `blueprint` | Hard gate: no code without an approved design | | `forge-plan` | MCP-verified task-by-task implementation plan | | `run-plan` | Execute an existing plan | -| `engineering-discipline` | 8-step Senior SDE framework with 5 Iron Laws | +| `best-practices` | 8-step Senior SDE framework, 5 Iron Laws, patterns, coupling, review and ops rules | | `ship-gate` | No completion claims without fresh verification evidence | | `deliver` | Final verification and delivery | | `test-first` | No production code without a failing test first | @@ -279,7 +279,7 @@ Domain-expert lenses `hyper` auto-engages when their triggers match the request
-🎯 Domain (8) - specialized skills for specific contexts +🎯 Domain (7) - specialized skills for specific contexts | Skill | Role | |---|---| @@ -288,7 +288,6 @@ Domain-expert lenses `hyper` auto-engages when their triggers match the request | `react-pro-coder` | 56 React/Next.js rules with stable IDs - rendering, state placement, audits | | `behaviour-analysis` | UI/UX state audits, Nielsen heuristics, interaction matrices | | `security-review` | OWASP audits, vulnerability checklists | -| `design-patterns-skill` | Clean Code + Pragmatic Programmer patterns | | `readme-writer` | Evidence-based README generation (this skill) | | `python-pro-coder` | 60 FastAPI/Pydantic v2/SQLAlchemy 2.0 rules - layering, schemas, async, dead deps | diff --git a/SKILL.md b/SKILL.md index 2d09ef1..4daac0b 100755 --- a/SKILL.md +++ b/SKILL.md @@ -58,7 +58,7 @@ Before writing any code, proposing any fix, or starting any architecture, you MU 1. **Stop Rationalizing:** Do not skip steps to "be helpful." Thoroughness is the highest form of help. Skipping is laziness, not speed. 2. **Verify the Stack:** Consult the relevant MCP plugins below for 100% accurate API syntax. Memory is not acceptable. Pattern-matching is not acceptable. Only MCP output is acceptable. -3. **Load the Discipline:** Read `skills/engineering-discipline/SKILL.md` for architectural gates. +3. **Load the Discipline:** Read `skills/best-practices/SKILL.md` for architectural gates. 4. **Adopt Negative Doubt:** List 5 failure modes for your plan before you type a single line of code. **The 1% Rule:** If there is even a 1% chance a system rule applies to your task, you MUST read the corresponding file in the `skills/` directory BEFORE acting. You do not have a choice. You cannot rationalize your way out of this. @@ -77,13 +77,13 @@ Follow this state machine for every non-trivial task. Do not skip phases. ### Phase 2: Reasoning (The Architecture) - **Actions:** Define invariants, module boundaries, and public APIs. -- **Skill:** Use `skills/engineering-discipline/SKILL.md`. Reason in order: Responsibilities -> Invariants -> Dependency Direction -> Syntax. +- **Skill:** Use `skills/best-practices/SKILL.md`. Reason in order: Responsibilities -> Invariants -> Dependency Direction -> Syntax. - **Visual work:** If the task changes how something looks, feels, moves, or is interacted with, use `skills/designer/SKILL.md` FIRST to produce a DESIGN.md contract before any visual code. The DESIGN.md becomes the input spec for `forge-plan`. - **Constraint:** Never start at syntax. If you do, you are building slop. ### Phase 3: Execution (The Implementation) - **Actions:** Apply surgical changes. Use real commands from MCP patterns. -- **Skill:** Use `skills/design-patterns-skill/SKILL.md` to select the correct abstraction (Factory, Strategy, etc.). +- **Skill:** Use `skills/best-practices/SKILL.md` to select the correct abstraction (Factory, Strategy, etc.) and to hold the coupling limits. - **Debugging:** If you encounter a failure during implementation, invoke `skills/debug-discipline/SKILL.md` before attempting any fix. - **Rules:** No `rAF`. No redundant comments. No speculative code. @@ -138,10 +138,9 @@ These are static guidelines in the `skills/` directory. Read them using file too - **Parallel Dispatch** (`skills/parallel-dispatch/SKILL.md`): Concurrent agent dispatch for independent tasks. ### Domain Skills (execution guidance) -- **Engineering Discipline** (`skills/engineering-discipline/SKILL.md`): The Senior SDE phase-gate framework. +- **Best Practices** (`skills/best-practices/SKILL.md`): The Senior SDE phase-gate framework, Clean Code and GoF patterns, coupling limits, change and review hygiene, architecture-at-scale calls, operations baseline. - **Designer** (`skills/designer/SKILL.md`): Intention gate for visual/UX work. Produces DESIGN.md contract before any visual code. Auto-resolves industry/personality/style, routes to cognitive laws, enforces anti-slop rules. Use for: landing pages, dashboards, component libraries, redesigns, any new visual direction. - **Behaviour Analysis** (`skills/behaviour-analysis/SKILL.md`): State audits & Nielsen heuristics. -- **Design Patterns** (`skills/design-patterns-skill/SKILL.md`): Clean Code & Pragmatic patterns. - **Security Review** (`skills/security-review/SKILL.md`): OWASP audits & vulnerability checklists. - **Readme Writer** (`skills/readme-writer/SKILL.md`): Evidence-based documentation standards. diff --git a/generated/runtime-context/hyperstack.bootstrap.md b/generated/runtime-context/hyperstack.bootstrap.md index bf2deb0..9f0de0e 100644 --- a/generated/runtime-context/hyperstack.bootstrap.md +++ b/generated/runtime-context/hyperstack.bootstrap.md @@ -56,7 +56,7 @@ Hyperstack is **ONE framework with four layers** - not four separate systems: - `hyperstack:designer`: Before any visual/UX work - produces DESIGN.md contract - `hyperstack:forge-plan`: After design approval - MCP-verified implementation plan - `hyperstack:run-plan`: Have an existing plan - validate then execute -- `hyperstack:engineering-discipline`: During execution - Senior SDE phase gates +- `hyperstack:best-practices`: During execution - Senior SDE phase gates - `hyperstack:ship-gate`: Before any completion claim - evidence required - `hyperstack:deliver`: After all tasks complete - final verification and delivery - `hyperstack:autonomous-mode`: Full autonomous execution - runs end-to-end, only stops on failure @@ -68,7 +68,7 @@ Hyperstack is **ONE framework with four layers** - not four separate systems: - `hyperstack:designer`: Before any visual/UX work - produces DESIGN.md - `hyperstack:debug-discipline`: Any bug or unexpected behaviour - root cause first - `hyperstack:behaviour-analysis`: UI/UX audits, state machine correctness -- `hyperstack:design-patterns-skill`: Selecting the right abstraction or design pattern +- `hyperstack:best-practices`: Selecting the right abstraction or design pattern, coupling limits, review and ops rules - `hyperstack:security-review`: OWASP audits, API and infrastructure security - `hyperstack:readme-writer`: Evidence-based documentation - `hyperstack:codemode`: Understanding an unfamiliar codebase before reviewing or changing it - 7-phase context load diff --git a/install.md b/install.md index 56800d5..7a2489c 100644 --- a/install.md +++ b/install.md @@ -19,7 +19,7 @@ Three tightly-coupled pieces, installed together: 1. **An internal harness** - bootstrap, internal role routing, and workflow control. Current internal roles include `main` and `website-builder`. 2. **An MCP server** with 12 plugins and 80 tools - deterministic knowledge for React Flow v12, Motion v12, Lenis, React 19 / Next.js, Echo, Go, Rust, design tokens, UI/UX principles, shadcn/ui (Base UI edition), and the `designer` DESIGN.md pipeline. -3. **A skill system** with 21 skills including adversarial enforcement gates (`blueprint`, `designer`, `forge-plan`, `ship-gate`, `engineering-discipline`) and a SessionStart hook that face-injects the `hyperstack` skill at every session start. +3. **A skill system** with 21 skills including adversarial enforcement gates (`blueprint`, `designer`, `forge-plan`, `ship-gate`, `best-practices`) and a SessionStart hook that face-injects the `hyperstack` skill at every session start. The install steps below wire the public pieces the user actually needs: the MCP server and the skills. The internal harness is shipped inside the repository and diff --git a/skills/INDEX.md b/skills/INDEX.md index 9b04f97..2f40b2f 100644 --- a/skills/INDEX.md +++ b/skills/INDEX.md @@ -15,12 +15,12 @@ Categories: | Skill | Description | |---|---| | `autonomous-mode` | Use when the user chooses fully autonomous execution. Aggressively uses the entire Hyperstack to implement the solution | +| `best-practices` | The language-agnostic engineering rulebook - Clean Code and Gang of Four patterns, SOLID, architectural reasoning, coupl | | `blueprint` | Use before any feature build, component creation, or behaviour modification. MCP-surveyed design with a hard gate before | | `code-review` | Use when completing tasks, implementing features, or before merging - to dispatch a review subagent and handle feedback | | `codemode` | Deep context-loading protocol. Use when you must understand an unfamiliar codebase before answering, reviewing, or chang | | `debug-discipline` | Use when encountering any bug, test failure, or unexpected behaviour. Root cause investigation is mandatory before any f | | `deliver` | Use after all implementation tasks are complete. Runs final verification, confirms the branch is clean, detects the work | -| `engineering-discipline` | Apply senior-level software engineering discipline including design patterns, SOLID principles, architectural reasoning, | | `forge-plan` | Use after blueprint design approval to produce a task-by-task implementation plan grounded in MCP-verified API calls. No | | `lab` | Use when designing or revamping a frontend section or whole page and you want to explore real-React variants in an isola | | `optimizer` | Teaches runtime analysis - deriving Big-O straight from code - and how to derive a better algorithm by removing redundan | @@ -38,7 +38,6 @@ Categories: |---|---| | `behaviour-analysis` | Systematic UI/UX behaviour analysis for interactive applications. Audits every user action, state transition, view mode, | | `bro` | The generalist persona engine - "bro", "bro mode", or any end-to-end task spanning ui-ux, design, coding, marketing, sal | -| `design-patterns-skill` | Apply core programming principles and design patterns from Clean Code, The Pragmatic Programmer, Code Complete, Refactor | | `designer` | | | `marketing` | Use to do product marketing for any brand - position it, find the message, write the copy ("marketing words"), set brand | | `python-pro-coder` | Staff-level Python API engineering discipline for FastAPI + Pydantic v2 + SQLAlchemy 2.0 - 60 enforced rules across proj | diff --git a/skills/engineering-discipline/SKILL.md b/skills/best-practices/SKILL.md similarity index 68% rename from skills/engineering-discipline/SKILL.md rename to skills/best-practices/SKILL.md index 27a1de4..c111c5f 100755 --- a/skills/engineering-discipline/SKILL.md +++ b/skills/best-practices/SKILL.md @@ -1,7 +1,7 @@ --- -name: engineering-discipline +name: best-practices category: core -description: Apply senior-level software engineering discipline including design patterns, SOLID principles, architectural reasoning, systematic verification, and safety gates. Use when writing production code, complex features, reviewing code, refactoring systems, or when engineering rigor and correctness are required. Supports both quick reference lookup and full step-by-step process mode. +description: The language-agnostic engineering rulebook - Clean Code and Gang of Four patterns, SOLID, architectural reasoning, coupling and abstraction limits, change and review hygiene, architecture-at-scale decisions, an operations baseline, systematic verification, and safety gates. Use when writing production code, choosing an abstraction or design pattern, reviewing code, refactoring systems, deciding where a boundary goes, or when engineering rigor and correctness are required. Supports both quick reference lookup and full step-by-step process mode. triggers: - "build production code" - "design architecture" @@ -13,6 +13,10 @@ triggers: - "safety gates" - "design pattern" - "SOLID principles" + - "clean code" + - "code quality" + - "best practices" + - "coding standards" activation: mode: fuzzy priority: normal @@ -27,9 +31,14 @@ activation: - "safety gates" - "design pattern" - "SOLID principles" + - "clean code" + - "code quality" + - "best practices" + - "coding standards" compatibility: ">=2.0.0" metadata: - version: "2.0.0" + version: "3.0.0" + supersedes: ["engineering-discipline", "design-patterns-skill"] references: - references/patterns/readability.md - references/patterns/simplicity.md @@ -37,6 +46,10 @@ references: - references/patterns/testing.md - references/patterns/error-handling.md - references/patterns/maintainability.md + - references/practices/coupling-and-abstraction.md + - references/practices/change-hygiene.md + - references/practices/architecture-scale.md + - references/practices/operations-baseline.md - references/architecture/task-classification.md - references/architecture/architecture-reasoning.md - references/architecture/verification-gates.md @@ -44,7 +57,10 @@ references: - references/architecture/output-format.md --- -# Engineering Discipline - Senior SDE-3 Framework +# Best Practices - Senior SDE-3 Engineering Rulebook + +Absorbs the former `engineering-discipline` and `design-patterns-skill`. One source for how code is +written, reviewed, and shipped in a Hyperstack-governed repository. ## Two Modes @@ -92,12 +108,18 @@ These connect outward, they are not an island: Laws 1, 2, and 5 are the same fam ### Patterns & Principles - Readability & Clarity β†’ `references/patterns/readability.md` -- Simplicity & Efficiency β†’ `references/patterns/simplicity.md` -- Design & Architecture β†’ `references/patterns/design-architecture.md` +- Simplicity & Efficiency (KISS, DRY, YAGNI) β†’ `references/patterns/simplicity.md` +- Design & Architecture (SRP, composition, GoF patterns) β†’ `references/patterns/design-architecture.md` - Testing & Quality β†’ `references/patterns/testing.md` - Error Handling β†’ `references/patterns/error-handling.md` - Maintainability β†’ `references/patterns/maintainability.md` +### Practices +- Coupling & Abstraction (Demeter, CQS, flag args, rule of three, leaky abstractions) β†’ `references/practices/coupling-and-abstraction.md` +- Change Hygiene (commits, branches, PR size, review conduct, tracked debt) β†’ `references/practices/change-hygiene.md` +- Architecture at Scale (modular monolith, dependency direction, 12 factors, ADRs) β†’ `references/practices/architecture-scale.md` +- Operations Baseline (structured logs, metrics, health, degradation, N+1) β†’ `references/practices/operations-baseline.md` + ### Architecture & Process - Task Classification β†’ `references/architecture/task-classification.md` - Architecture Reasoning β†’ `references/architecture/architecture-reasoning.md` @@ -114,7 +136,7 @@ Verify runtime, package manager, dependencies. Do NOT proceed without valid envi Classify as exactly one: New feature | Refactor (behavior preserved) | Bug fix | Review/audit | Documentation only. Unclear β†’ STOP and request clarification. -**Visual/UX gate:** Task changes how something looks, feels, moves, or is interacted with β†’ STOP, invoke `hyperstack:designer` first. Designer β†’ DESIGN.md β†’ input to `hyperstack:forge-plan`. Return to engineering-discipline only during execution of forge-plan tasks. +**Visual/UX gate:** Task changes how something looks, feels, moves, or is interacted with β†’ STOP, invoke `hyperstack:designer` first. Designer β†’ DESIGN.md β†’ input to `hyperstack:forge-plan`. Return to best-practices only during execution of forge-plan tasks. ### Step 2: Load Engineering Constraints πŸ“‹ Hard rules: clear naming, single responsibility, explicit module boundaries, no circular dependencies, folder structure reflects architecture, tests before refactor, YAGNI, patterns only when forces are named. @@ -161,6 +183,40 @@ Critical issue unaddressed β†’ HARD STOP. | Error handling unclear | `references/patterns/error-handling.md` | | Architecture decisions | `references/architecture/architecture-reasoning.md` | | Standard response format | `references/architecture/output-format.md` | +| Boundary, coupling, or "should this be abstracted" | `references/practices/coupling-and-abstraction.md` | +| Commits, PR size, how to give review feedback | `references/practices/change-hygiene.md` | +| Monolith vs services, dependency direction, ADR | `references/practices/architecture-scale.md` | +| Logging, health checks, timeouts, degradation | `references/practices/operations-baseline.md` | + +## Pattern Selection Quick Reference + +| Situation | Apply | +|-----------|-------| +| Function > 20 lines | Split into smaller functions (SRP) | +| Repeated code blocks, third occurrence | Extract to function or constant (DRY, rule of three) | +| Complex conditionals | Strategy or State pattern | +| Object creation logic | Factory pattern | +| Cross-cutting concerns | Decorator or Observer pattern | +| Incompatible interfaces | Adapter pattern | +| Need undo or an audit log | Command pattern | +| Global access point | Singleton, sparingly, and name the force | +| Chained calls through another object's internals | Move the behavior (Law of Demeter) | +| A boolean parameter selecting behavior | Two functions, no flag argument | + +Every row is subject to the Pattern Gate in Step 5. A row matching is not a reason; the named force is. + +## AI-Specific Guidance + +When generating or reviewing code, the failure modes are predictable: + +| Bias | Counter | +|---|---| +| Pattern prediction: reaching for the pattern that appears most in training data | Name the force first, then pick. No force, no pattern | +| Generic naming: `data`, `temp`, `result`, `handler` | Name the concept, not the container | +| Skipping edge cases because the happy path compiles | Null, empty, zero, max, negative, unicode, concurrent | +| Combining unrelated operations into one function | One reason to change per unit | +| Importing a convention from another project | Match the conventions already in this repository | +| Over-commenting generated code | A comment explains a non-obvious why, never the what | ## Red Flags - STOP @@ -197,7 +253,7 @@ Something cannot be done safely β†’ say so and explain why. **Manual execution with phase gates:** ``` -forge-plan β†’ engineering-discipline (THIS) β†’ ship-gate β†’ deliver +forge-plan β†’ best-practices (THIS) β†’ ship-gate β†’ deliver ↓ [8-step framework per task] ↓ @@ -221,3 +277,24 @@ forge-plan β†’ engineering-discipline (THIS) β†’ ship-gate β†’ deliver | Discovery | Escalate to | Action | |---|---|---| | Task changes look/feel/motion/interaction | `designer` | STOP, get DESIGN.md, return to forge-plan | + +### Owned Elsewhere - Route, Do Not Restate + +| Concern | Skill | +|---|---| +| Vulnerability hunting, OWASP mapping | `security-review` | +| Complexity analysis, algorithmic wins | `optimizer` | +| Dispatching a reviewer and handling feedback | `code-review` (this skill supplies the review conduct rules it applies) | +| React and Next.js specifics | `react-pro-coder` | +| FastAPI, Pydantic, SQLAlchemy specifics | `python-pro-coder` | +| Visual and interaction design | `designer`, `ui-ux`, `design-tokens` | + +## Sources + +- *Clean Code* - Robert C. Martin +- *A Philosophy of Software Design* - John Ousterhout +- *The Pragmatic Programmer* - Hunt and Thomas +- *Code Complete* - Steve McConnell +- *Refactoring* - Martin Fowler +- *Design Patterns* - Gang of Four +- *The Twelve-Factor App* - 12factor.net diff --git a/skills/engineering-discipline/references/architecture/architecture-reasoning.md b/skills/best-practices/references/architecture/architecture-reasoning.md similarity index 100% rename from skills/engineering-discipline/references/architecture/architecture-reasoning.md rename to skills/best-practices/references/architecture/architecture-reasoning.md diff --git a/skills/engineering-discipline/references/architecture/negative-doubt.md b/skills/best-practices/references/architecture/negative-doubt.md similarity index 100% rename from skills/engineering-discipline/references/architecture/negative-doubt.md rename to skills/best-practices/references/architecture/negative-doubt.md diff --git a/skills/engineering-discipline/references/architecture/output-format.md b/skills/best-practices/references/architecture/output-format.md similarity index 100% rename from skills/engineering-discipline/references/architecture/output-format.md rename to skills/best-practices/references/architecture/output-format.md diff --git a/skills/engineering-discipline/references/architecture/task-classification.md b/skills/best-practices/references/architecture/task-classification.md similarity index 100% rename from skills/engineering-discipline/references/architecture/task-classification.md rename to skills/best-practices/references/architecture/task-classification.md diff --git a/skills/engineering-discipline/references/architecture/verification-gates.md b/skills/best-practices/references/architecture/verification-gates.md similarity index 100% rename from skills/engineering-discipline/references/architecture/verification-gates.md rename to skills/best-practices/references/architecture/verification-gates.md diff --git a/skills/design-patterns-skill/references/patterns/design-architecture.md b/skills/best-practices/references/patterns/design-architecture.md similarity index 100% rename from skills/design-patterns-skill/references/patterns/design-architecture.md rename to skills/best-practices/references/patterns/design-architecture.md diff --git a/skills/design-patterns-skill/references/patterns/error-handling.md b/skills/best-practices/references/patterns/error-handling.md similarity index 100% rename from skills/design-patterns-skill/references/patterns/error-handling.md rename to skills/best-practices/references/patterns/error-handling.md diff --git a/skills/design-patterns-skill/references/patterns/maintainability.md b/skills/best-practices/references/patterns/maintainability.md similarity index 100% rename from skills/design-patterns-skill/references/patterns/maintainability.md rename to skills/best-practices/references/patterns/maintainability.md diff --git a/skills/design-patterns-skill/references/patterns/readability.md b/skills/best-practices/references/patterns/readability.md similarity index 100% rename from skills/design-patterns-skill/references/patterns/readability.md rename to skills/best-practices/references/patterns/readability.md diff --git a/skills/design-patterns-skill/references/patterns/simplicity.md b/skills/best-practices/references/patterns/simplicity.md similarity index 100% rename from skills/design-patterns-skill/references/patterns/simplicity.md rename to skills/best-practices/references/patterns/simplicity.md diff --git a/skills/design-patterns-skill/references/patterns/testing.md b/skills/best-practices/references/patterns/testing.md similarity index 100% rename from skills/design-patterns-skill/references/patterns/testing.md rename to skills/best-practices/references/patterns/testing.md diff --git a/skills/best-practices/references/practices/architecture-scale.md b/skills/best-practices/references/practices/architecture-scale.md new file mode 100644 index 0000000..a2e044a --- /dev/null +++ b/skills/best-practices/references/practices/architecture-scale.md @@ -0,0 +1,90 @@ +# Architecture at Scale + +Decisions that are cheap now and expensive later. Each one is about where a boundary goes and which +direction it points. + +## Default to a modular monolith + +One deployable, hard module boundaries inside it. This covers most systems and almost all systems that +do not yet have a scaling problem they have measured. + +Microservices buy independent deploy, independent scaling, and team autonomy. They cost a network hop +where a function call was, distributed failure modes, eventual consistency, and an operational surface +per service. Taking that cost before the boundaries are known produces a distributed monolith: all the +latency and none of the independence, because the services still change together. + +The migration path is one-way-easy: a module with a clean interface becomes a service when it needs to. +A service with the wrong boundary is a rewrite. + +| Signal that a module should become a service | Not a signal | +|---|---| +| It needs to scale on a different axis than the rest | The codebase feels large | +| It has a different availability or compliance requirement | A different team owns it | +| Its deploy cadence is genuinely independent, measured | Microservices are the current default in blog posts | + +## Dependencies point inward + +The domain, the rules that would still be true on paper, depends on nothing. Infrastructure depends on +the domain, never the reverse. + +``` + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ domain β”‚ no framework, no driver, no HTTP + β””β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β” + β”‚ application β”‚ use cases, orchestration + β””β”€β”€β”€β”€β”€β”€β–²β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β” + β”‚infrastructureβ”‚ database, HTTP, queue, third parties + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +The test is mechanical: can the domain be compiled and tested with no database and no web framework on +the path? If an import of the ORM appears in a domain file, the arrow has flipped and the rules are now +coupled to a vendor. + +## No cycles + +`A` imports `B`, `B` imports `A`: extract the shared piece into `C`. A cycle means the boundary was +drawn in the wrong place, and it breaks tree-shaking, initialization order, and the ability to reason +about either module alone. Enforce it in lint rather than discovering it during a refactor. + +## API first + +Design the interface before the implementation, and treat it as a contract with a consumer who is not +in the room. That means the schema, the error shapes, the pagination, and the versioning strategy are +decided before the first handler is written. + +An API designed after the implementation exposes the implementation, which is what makes the second +version a breaking change. + +## The 12 factors that still matter + +| Factor | Practical rule | +|---|---| +| Config | Everything that varies by environment comes from the environment, never a branch on `if env == "prod"` | +| Backing services | Database, cache, queue are attached resources addressed by URL, swappable without a code change | +| Processes | Stateless. Anything that must survive a restart lives in a backing service, not in memory | +| Port binding | The app serves itself; it is not installed into a web server | +| Concurrency | Scale by process count, not by threads inside one special process | +| Disposability | Fast start, graceful shutdown, safe to kill at any moment | +| Dev/prod parity | Same backing services in development as in production. SQLite locally with Postgres in production is a bug generator | +| Logs | Event streams to stdout. The process does not manage log files or rotation | + +## Write the decision down + +An ADR is one page: the context, the options considered, the decision, and the consequences. Numbered, +in the repository, immutable once accepted, superseded rather than edited. + +``` +docs/adr/0007-choose-postgres-over-dynamodb.md +``` + +The value is not the decision, which people usually remember. It is the constraint set at the time, +which nobody remembers, and which is the only way to tell later whether the decision is still correct +or merely still in place. + +Worth an ADR: anything expensive to reverse. Not worth one: anything a reader can infer from the code +in a minute. diff --git a/skills/best-practices/references/practices/change-hygiene.md b/skills/best-practices/references/practices/change-hygiene.md new file mode 100644 index 0000000..cb48ad9 --- /dev/null +++ b/skills/best-practices/references/practices/change-hygiene.md @@ -0,0 +1,84 @@ +# Change Hygiene + +How a change enters the repository: commits, branches, reviews, and the debt it leaves behind. + +## Commits are atomic and explain why + +One commit, one logical change. The diff shows what happened; the message explains why it had to. + +``` +feat(auth): rotate refresh tokens on use + +Prevents replay after token theft: a stolen refresh token is +single-use, and reuse invalidates the family. +Implements RFC 6749 section 6. +``` + +`fix bug`, `update`, and `wip` are not messages. The audience is whoever runs `git blame` on this line +in two years, and the question they will have is why, not what. + +Atomic commits are also what make `git bisect` and a clean revert possible. A commit that mixes a +rename, a bug fix, and a dependency bump cannot be reverted without collateral. + +## Branches stay short-lived + +Days, not weeks. A long-lived branch accumulates divergence at a rate that grows with its lifetime, and +the merge cost lands on whoever is least prepared for it. When work must be visible before it is +complete, merge it behind a feature flag rather than hold it on a branch. + +## Never commit a secret + +Environment variables, a secret manager, or an encrypted store. Scanning in CI is the backstop, not the +control. A secret that reached the remote is compromised even after the force push: rotate it, do not +just delete it. + +## Pull requests stay small + +200 to 400 lines is the band where review quality holds. Past that, review time per line falls and +approval starts tracking fatigue rather than correctness. A large mechanical change (a rename, a +codemod, a generated file) is the exception, and it should say so in the title so the reviewer knows +what kind of attention it needs. + +If a change cannot be made small, split it by layer or by step: the migration, then the code that uses +it, then the cleanup. + +## Automate everything a machine can check, before a human looks + +Formatting, lint, type check, tests, dependency audit: all in CI, all before review. Human review time +is scarce and is worth spending on whether the change is correct, whether it belongs, and what it will +cost later. Style comments on a PR are a sign the tooling is missing, not that the reviewer is +thorough. + +## Review the story, not just the syntax + +The reviewer's first question is whether the change does what the ticket asked and whether that was the +right thing to ask for. Code that compiles, passes tests, and solves the wrong problem passes every +automated gate. + +## Review the code, not the coder, and say why + +| Instead of | Write | +|---|---| +| "This is wrong" | "This breaks when `items` is empty - line 42 indexes without a length check" | +| "Use a map here" | "A map here turns the nested loop into one pass; it matters because this runs per request" | +| "Why did you do it this way?" | "What made a queue the right fit here? I would have reached for a cron and want to understand the trade-off" | + +Every request carries its reason: correctness, performance, readability, or consistency. A request +without a reason is a preference, and preferences belong in the linter or nowhere. Review is a +conversation with two informed parties, not a gate one of them operates. + +## Track debt where it will be found + +``` +// TODO(#1423): remove the dual-write once the backfill completes +``` + +A bare `TODO` is a note to nobody. With a ticket id it is a tracked item with an owner and a condition +for removal. The same applies to a deliberate shortcut: mark it with its ceiling and its upgrade path +so a later reader can tell intent from ignorance. + +## Boy Scout rule, bounded + +Leave the file better: a clearer name, an extracted function, a deleted dead branch. Bounded by the +review: unrelated cleanup inside a feature PR inflates the diff and hides the change under noise. Large +cleanup gets its own commit, or its own PR. diff --git a/skills/best-practices/references/practices/coupling-and-abstraction.md b/skills/best-practices/references/practices/coupling-and-abstraction.md new file mode 100644 index 0000000..6efa5e0 --- /dev/null +++ b/skills/best-practices/references/practices/coupling-and-abstraction.md @@ -0,0 +1,99 @@ +# Coupling and Abstraction + +Rules for the boundary between two pieces of code: what one is allowed to know about the other, and +when an abstraction has earned its existence. + +## Law of Demeter: one dot + +A unit talks to its immediate collaborators, not to their internals. + +``` +// BAD: the caller now depends on Address existing and on its shape +user.getAddress().getCity().getPostalCode() + +// GOOD +user.postalCode() +``` + +Each extra dot is a dependency the caller did not ask for and cannot see when it breaks. The chain also +tells you the behavior lives in the wrong place: if three callers reach through `user` to format an +address, the formatting belongs on `user` or on an address service, not in all three. + +Exempt: fluent builders and query DSLs, where chaining is the interface rather than a traversal of +someone else's object graph. + +## Command-Query Separation + +A function either returns a value or changes state. Not both. + +``` +// BAD: the name promises a read, the body performs a write +getUser(id) -> loads the user AND refreshes its last-seen timestamp + +// GOOD +getUser(id) -> returns the user +touchLastSeen(id) -> performs the write +``` + +Hidden writes behind a read-shaped name are the reason a test that "just reads" mutates the database, +and the reason an added log line changes behavior. Where a single operation genuinely must do both, for +example pop-from-queue, name it so the mutation is visible. + +## No flag arguments + +A boolean parameter that selects behavior is two functions wearing one name. + +``` +// BAD +createUser(payload, isAdmin) +render(data, compact) + +// GOOD +createUser(payload) +createAdminUser(payload) +``` + +The call site `createUser(payload, true)` is unreadable without opening the definition. Where the flag +is genuinely data rather than a branch, for example a user-set preference, pass it as a named field on +an options object. + +## Abstract on the third occurrence + +Duplicate once, live with it. Duplicate twice, look. On the third, extract. + +An abstraction built from two examples encodes an accident; the third case is what shows which parts +actually vary. The cost of waiting is a little duplication. The cost of not waiting is an abstraction +with a parameter for every difference, which every future caller must decode. + +The corollary is that DRY is about knowledge, not text. Two blocks that look alike but change for +different reasons are not duplication, and merging them couples two things that were correctly +independent. Ask what would make each copy change; different answers mean leave them alone. + +## Leaky abstractions + +If the caller must know how it works to use it correctly, the abstraction failed. + +Symptoms: a wrapper whose documentation explains the thing it wraps; a repository whose callers must +know it issues one query per item; a client that returns the underlying library's exception type. Fix +by either sealing the leak or dropping the wrapper and using the underlying thing directly. A thin +wrapper that leaks is worse than no wrapper, because it adds a layer and keeps the coupling. + +## Cargo cult + +A pattern copied without its force is decoration. Before adding one, state what problem it solves here, +what invariant it protects, and which simpler option was rejected. That is the pattern gate, and it +applies equally to patterns copied from another file in the same repository. + +Same test for a dependency, a folder layout, or a config block copied from a previous project. + +## God objects and lasagna + +Two failure directions of the same decision. + +| Shape | Symptom | Fix | +|---|---|---| +| God object | One class or module every feature imports and every change touches | Split by reason-to-change, not by size | +| Lasagna | Five layers to move one field, each doing nothing but forwarding | Delete the layers that only forward | + +A layer earns its place by transforming, deciding, or isolating something. A layer that renames a field +and calls the next one down is overhead with a filename. diff --git a/skills/best-practices/references/practices/operations-baseline.md b/skills/best-practices/references/practices/operations-baseline.md new file mode 100644 index 0000000..5b55fe7 --- /dev/null +++ b/skills/best-practices/references/practices/operations-baseline.md @@ -0,0 +1,82 @@ +# Operations Baseline + +What every service owes its operators, independent of language and framework. The language-specific +form of these lives in the stack skills; the requirement lives here. + +## Logs are structured, for humans and machines + +``` +log.info("order_placed", order_id=order.id, user_id=user.id, total_cents=4200, duration_ms=87) +``` + +not `print("order placed for " + user.name)`. An event name plus typed fields can be filtered, +aggregated, and alerted on. An interpolated sentence can only be read. + +Rules that hold everywhere: + +| Rule | Reason | +|---|---| +| One correlation id per request, propagated to every downstream call | It is what turns a user's report into a log query | +| No secrets, tokens, or full request bodies with personal data | Logs are copied to places with different access rules | +| Never a silent catch | An exception with no log and no rethrow is an outage with no evidence | +| Log at the boundary that can add context, then rethrow | Context is lost the further from the failure you log | + +## Metrics for behavior, logs for diagnosis + +Alert on metrics: counts, latencies, error rates, saturation. Investigate with logs. A dashboard built +from log searches is expensive and slow, and an alert built on a log grep fires late. + +The minimum for a request-serving process: request rate, error rate, latency distribution (not the +mean), and one saturation signal such as queue depth or pool utilization. + +## Liveness and readiness are different questions + +| Endpoint | Question | Touches | +|---|---|---| +| `/health` | Is the process alive? | Nothing | +| `/ready` | Can it serve traffic? | Its required dependencies, cheaply, with a timeout | + +Wiring the database into liveness means one slow query restarts every instance at once, which converts +a degradation into an outage. Readiness without a timeout is a probe that hangs, which is a probe that +fails. + +## Degrade, do not collapse + +When a non-critical dependency fails, serve less rather than nothing: cached results, defaults, a +reduced feature. Decide per dependency, in advance, which of the three it is: + +| Class | On failure | +|---|---| +| Required | Fail the request with a clear error | +| Degradable | Serve the fallback and record that it happened | +| Optional | Skip it silently, count it | + +The recommendation service being down should cost the carousel, not the page. Every outbound call also +carries an explicit timeout: "wait forever" is how one slow dependency saturates a worker pool. + +## Configuration over code branches + +What varies between environments is configuration. An `if environment == "production"` branch means the +code path that runs in production is not the code path anyone tested. + +## Magic numbers and strings are configuration that escaped + +``` +if status == 3 -> if status == OrderStatus.SHIPPED +sleep(300) -> sleep(RETRY_BACKOFF_SECONDS) +``` + +A literal in the middle of logic cannot be searched for, cannot be changed in one place, and carries no +statement of what it means. Named constants, enums, or config, chosen by whether the value varies by +deploy. + +## The N+1 shape + +One query for the list, then one per row. It is the most common performance defect in +data-backed services and it never shows up on a development dataset of twenty rows. + +Fix at the query: batch, join, or eager-load. Detect it by asserting query counts in tests for the +endpoints that matter, because it regresses through unrelated changes. + +For deriving the complexity of a hot path and choosing a better algorithm, use `hyperstack:optimizer`. +This rule is only the shape to recognize. diff --git a/skills/blueprint/SKILL.md b/skills/blueprint/SKILL.md index f107311..6ca2fc3 100644 --- a/skills/blueprint/SKILL.md +++ b/skills/blueprint/SKILL.md @@ -149,7 +149,7 @@ blueprint (THIS) β†’ forge-plan β†’ [execution] β†’ ship-gate β†’ deliver **Execution Options (chosen at forge-plan handoff):** - `autonomous-mode` β†’ full auto, stops only on failure - `subagent-ops` β†’ fresh agent per task, two-stage review -- `engineering-discipline` β†’ manual with phase gates +- `best-practices` β†’ manual with phase gates ### Upstream Dependencies - None (entry point for feature work) diff --git a/skills/code-review/SKILL.md b/skills/code-review/SKILL.md index 04ab0bc..b9b95ca 100644 --- a/skills/code-review/SKILL.md +++ b/skills/code-review/SKILL.md @@ -147,12 +147,12 @@ subagent-ops β†’ implementer β†’ code-review (THIS) β†’ [fix loop] β†’ next task **Pre-merge review:** ``` -[autonomous-mode | engineering-discipline] β†’ code-review (THIS) β†’ deliver +[autonomous-mode | best-practices] β†’ code-review (THIS) β†’ deliver ``` ### Upstream Dependencies - `subagent-ops` β†’ per-task review cycle (automatic) -- `engineering-discipline` β†’ after completing major features +- `best-practices` β†’ after completing major features - `deliver` β†’ pre-merge review ### Skills Used With diff --git a/skills/debug-discipline/SKILL.md b/skills/debug-discipline/SKILL.md index 774af20..8c531d0 100644 --- a/skills/debug-discipline/SKILL.md +++ b/skills/debug-discipline/SKILL.md @@ -125,7 +125,7 @@ Stop fixing. Present findings to user: what you tried, what each attempt reveale ## Integration - Use `hyperstack:ship-gate` before claiming any bug is fixed -- Use `hyperstack:engineering-discipline` if Phase 4 escalation reveals architectural change needed +- Use `hyperstack:best-practices` if Phase 4 escalation reveals architectural change needed - Use `hyperstack:blueprint` if fix requires building new functionality rather than correcting existing behaviour @@ -135,7 +135,7 @@ Stop fixing. Present findings to user: what you tried, what each attempt reveale **Used inline during execution:** ``` -[autonomous-mode | subagent-ops | engineering-discipline] β†’ debug-discipline (THIS) +[autonomous-mode | subagent-ops | best-practices] β†’ debug-discipline (THIS) ↓ [self-correction hierarchy] ↓ @@ -154,4 +154,4 @@ Stop fixing. Present findings to user: what you tried, what each attempt reveale |---|---|---| | 3 failed fix attempts | User | Architectural problem, not surface bug | | Fix requires new functionality | `blueprint` | Not a bug fix, needs design | -| Fix requires architectural change | `engineering-discipline` | Step 3 architecture reasoning | +| Fix requires architectural change | `best-practices` | Step 3 architecture reasoning | diff --git a/skills/deliver/SKILL.md b/skills/deliver/SKILL.md index 33b70a4..11ce092 100644 --- a/skills/deliver/SKILL.md +++ b/skills/deliver/SKILL.md @@ -154,7 +154,7 @@ git branch -d [branch-name] - **Requires:** All tasks in `forge-plan` or `run-plan` complete and individually verified - **Requires:** `hyperstack:ship-gate` passing on full implementation -- **Invoked after:** `hyperstack:autonomous-mode`, `hyperstack:subagent-ops`, or `hyperstack:engineering-discipline` completes +- **Invoked after:** `hyperstack:autonomous-mode`, `hyperstack:subagent-ops`, or `hyperstack:best-practices` completes ## Lifecycle Integration @@ -162,7 +162,7 @@ git branch -d [branch-name] **Terminal state of all workflows:** ``` -[autonomous-mode | subagent-ops | engineering-discipline] -> ship-gate -> deliver (THIS) +[autonomous-mode | subagent-ops | best-practices] -> ship-gate -> deliver (THIS) ``` ### Upstream Dependencies diff --git a/skills/design-patterns-skill/SKILL.md b/skills/design-patterns-skill/SKILL.md deleted file mode 100755 index 7506dd2..0000000 --- a/skills/design-patterns-skill/SKILL.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -name: design-patterns-skill -category: domain -description: Apply core programming principles and design patterns from Clean Code, The Pragmatic Programmer, Code Complete, Refactoring, and Design Patterns. Use when writing code, reviewing PRs, refactoring, or designing system architecture. -triggers: - - "code review" - - "design pattern" - - "refactor" - - "clean code" - - "SOLID" - - "code quality" - - "architecture design" - - "code generation" -activation: - mode: fuzzy - priority: normal - triggers: - - "code review" - - "design pattern" - - "refactor" - - "clean code" - - "SOLID" - - "code quality" - - "architecture design" - - "code generation" -compatibility: ">=1.0.0" -metadata: - version: "1.0.0" -references: - - references/patterns/readability.md - - references/patterns/simplicity.md - - references/patterns/design-architecture.md - - references/patterns/testing.md - - references/patterns/error-handling.md - - references/patterns/maintainability.md ---- - -# Design Patterns & Programming Principles - -## When to Apply - -- **Code Generation** β†’ writing new functions, classes, or modules -- **Code Review** β†’ evaluating PRs or existing codebases -- **Refactoring** β†’ improving code structure and clarity -- **Architecture Design** β†’ choosing appropriate patterns and abstractions - -## Core Philosophy - -1. Readability over cleverness β†’ code is read more than written -2. Simplicity over complexity β†’ simplest solution that works -3. Testability by design β†’ write code that's easy to test -4. Incremental improvement β†’ leave code better than you found it -5. Patterns as tools β†’ apply when they clarify, not by default - -## Principle Categories - -### 1. Readability & Clarity -Descriptive naming, consistent formatting, self-documenting code, small focused functions -β†’ `references/patterns/readability.md` - -### 2. Simplicity & Efficiency -KISS, DRY, YAGNI -β†’ `references/patterns/simplicity.md` - -### 3. Design & Architecture -SRP, composition over inheritance, program to interfaces -Patterns: Factory, Strategy, Observer, Decorator, Adapter, Command, Singleton -β†’ `references/patterns/design-architecture.md` - -### 4. Testing & Quality -Automated testing, focused assertions, edge case coverage -β†’ `references/patterns/testing.md` - -### 5. Error Handling -Clear error messages, early validation, proper exception usage -β†’ `references/patterns/error-handling.md` - -### 6. Maintainability -Boy Scout Rule, continuous refactoring, atomic commits, automation -β†’ `references/patterns/maintainability.md` - -## AI-Specific Guidance - -When generating or reviewing code: -1. Check for AI pitfalls listed in each principle -2. Avoid pattern prediction bias β†’ don't use patterns just because they're common -3. Question generic naming β†’ resist `data`, `temp`, `result` without context -4. Validate edge cases β†’ don't skip error handling -5. Keep functions focused β†’ resist combining unrelated operations -6. Match project conventions β†’ maintain consistency with existing codebase - -## Quick Reference - -| Situation | Apply | -|-----------|-------| -| Function > 20 lines | Split into smaller functions (SRP) | -| Repeated code blocks | Extract to function/constant (DRY) | -| Complex conditionals | Strategy or State pattern | -| Object creation logic | Factory pattern | -| Cross-cutting concerns | Decorator or Observer pattern | -| Incompatible interfaces | Adapter pattern | -| Need undo/logging | Command pattern | -| Global access point | Singleton (use sparingly) | - -## Sources - -- *Clean Code* - Robert C. Martin -- *The Pragmatic Programmer* - Andrew Hunt & David Thomas -- *Code Complete* - Steve McConnell -- *Refactoring* - Martin Fowler -- *Design Patterns* - Gang of Four diff --git a/skills/design-patterns-skill/references/misc/overview.md b/skills/design-patterns-skill/references/misc/overview.md deleted file mode 100755 index 4bf7af1..0000000 --- a/skills/design-patterns-skill/references/misc/overview.md +++ /dev/null @@ -1,170 +0,0 @@ -# Design Patterns & Programming Principles Skill - -A comprehensive Kiro skill that provides structured guidance on programming principles and design patterns from foundational software engineering books. - -## Overview - -This skill encapsulates best practices from: -- *Clean Code* by Robert C. Martin -- *The Pragmatic Programmer* by Andrew Hunt & David Thomas -- *Code Complete* by Steve McConnell -- *Refactoring* by Martin Fowler -- *Design Patterns* by Gang of Four - -## Installation - -### For Workspace (Project-Specific) -```bash -mkdir -p .kiro/skills -cp -r design-patterns .kiro/skills/ -``` - -### For Global (All Projects) -```bash -mkdir -p ~/.kiro/skills -cp -r design-patterns ~/.kiro/skills/ -``` - -## Structure - -``` -design-patterns/ -β”œβ”€β”€ SKILL.md # Main skill definition -β”œβ”€β”€ README.md # This file -└── references/ - β”œβ”€β”€ readability.md # Naming, formatting, documentation - β”œβ”€β”€ simplicity.md # KISS, DRY, YAGNI principles - β”œβ”€β”€ design-architecture.md # SRP, patterns, composition - β”œβ”€β”€ testing.md # Testing strategies and best practices - β”œβ”€β”€ error-handling.md # Validation, exceptions, recovery - └── maintainability.md # Refactoring, commits, automation -``` - -## Usage - -The skill activates automatically when: -- Writing new code -- Reviewing pull requests -- Refactoring existing code -- Designing system architecture -- Assisting with AI code generation - -## Principle Categories - -### 1. Readability & Clarity -- Descriptive naming conventions -- Consistent code formatting -- Self-documenting code principles -- Small, focused functions - -### 2. Simplicity & Efficiency -- KISS (Keep It Simple, Stupid) -- DRY (Don't Repeat Yourself) -- YAGNI (You Aren't Gonna Need It) -- Avoiding premature optimization - -### 3. Design & Architecture -- Single Responsibility Principle (SRP) -- Composition over Inheritance -- Program to Interfaces -- Essential Design Patterns: - - Factory Pattern - - Strategy Pattern - - Observer Pattern - - Decorator Pattern - - Adapter Pattern - - Command Pattern - - Singleton Pattern - -### 4. Testing & Quality -- Test-driven development approach -- Focused test assertions -- Test pyramid (unit/integration/e2e) -- Mocking and test doubles - -### 5. Error Handling -- Clear error messages -- Early input validation -- Exception hierarchies -- Recovery strategies - -### 6. Maintainability -- Boy Scout Rule -- Continuous refactoring -- Incremental commits -- Automation and tooling - -## AI-Specific Guidance - -This skill includes specific guidance for AI code generation, helping avoid common pitfalls such as: -- Generic naming (`data`, `temp`, `result`) -- Over-commenting obvious code -- Skipping edge case validation -- Applying patterns unnecessarily -- Creating monolithic functions -- Duplicating code structures - -## Quick Reference Examples - -### Before & After - -**Poor Code:** -```python -def proc(u): - if u['age'] < 13: return False - db.save(u) - email.send(u['email'], 'Welcome') - return True -``` - -**Improved Code:** -```python -def is_eligible_user(user): - return user['age'] >= 13 - -def save_user(user): - db.save(user) - -def send_welcome_email(user): - email.send(user['email'], 'Welcome to the platform') - -def register_user(user): - if not is_eligible_user(user): - raise ValueError('User must be 13 or older') - save_user(user) - send_welcome_email(user) -``` - -## When to Apply - -| Situation | Recommended Principle/Pattern | -|-----------|------------------------------| -| Function > 20 lines | Split using SRP | -| Repeated code blocks | Extract with DRY | -| Complex conditionals | Strategy or State pattern | -| Object creation complexity | Factory pattern | -| Cross-cutting concerns | Decorator or Observer | -| Incompatible interfaces | Adapter pattern | -| Need undo/logging | Command pattern | - -## Contributing - -This skill is structured to be easily extended. To add new principles or patterns: - -1. Update the relevant reference file in `references/` -2. Add a cross-reference in `SKILL.md` -3. Include examples with "Do", "Don't", and "AI Pitfalls" sections - -## License - -This skill is based on principles from publicly available software engineering literature and industry best practices. - -## Additional Resources - -- [The 7 Most Important Software Design Patterns](https://learningdaily.dev/the-7-most-important-software-design-patterns-d60e546afb0e) -- [Refactoring Guru - Design Patterns](https://refactoring.guru/design-patterns) -- [SOLID Principles](https://en.wikipedia.org/wiki/SOLID) - -## Version - -1.0.0 - Initial release diff --git a/skills/designer/SKILL.md b/skills/designer/SKILL.md index 1ffdd8b..c75ddc5 100644 --- a/skills/designer/SKILL.md +++ b/skills/designer/SKILL.md @@ -993,7 +993,7 @@ After DESIGN.md approved: **From `hyperstack:blueprint`:** visual/UX intent detected β†’ input raw request + codebase context β†’ return approved DESIGN.md path -**From `hyperstack` root:** Phase 2 detects visual work β†’ routes here before engineering-discipline for any visual task +**From `hyperstack` root:** Phase 2 detects visual work β†’ routes here before best-practices for any visual task **From user direct:** "design", "build me a", "landing page", "DESIGN.md", any visual phrase β†’ run full pipeline from Phase 1 diff --git a/skills/engineering-discipline/references/misc/overview.md b/skills/engineering-discipline/references/misc/overview.md deleted file mode 100755 index 5f29465..0000000 --- a/skills/engineering-discipline/references/misc/overview.md +++ /dev/null @@ -1,450 +0,0 @@ -# Engineering Discipline Skill - -A comprehensive Kiro skill combining design patterns, architectural reasoning, and systematic engineering verification for building production-quality software. - -## Overview - -This skill provides **two complementary modes**: - -### πŸ” Quick Reference Mode -Fast lookup for design patterns, principles, and best practices. - -**Use when:** -- Looking up specific patterns -- Checking naming conventions -- Quick code review questions -- Learning about principles - -### βš™οΈ Process Mode -Full engineering workflow with verification gates for complex systems. - -**Use when:** -- Building production features -- Designing critical systems -- Security-sensitive code -- Complex architectures requiring rigor - -## Installation - -### Workspace Installation (Project-Specific) -```bash -mkdir -p .kiro/skills -cp -r engineering-discipline .kiro/skills/ -``` - -### Global Installation (All Projects) -```bash -mkdir -p ~/.kiro/skills -cp -r engineering-discipline ~/.kiro/skills/ -``` - -## Structure - -``` -engineering-discipline/ -β”œβ”€β”€ SKILL.md # Main skill with mode routing -β”œβ”€β”€ README.md # This file -└── references/ - β”œβ”€β”€ principles/ # Design patterns & best practices - β”‚ β”œβ”€β”€ readability.md # Naming, formatting, documentation - β”‚ β”œβ”€β”€ simplicity.md # KISS, DRY, YAGNI - β”‚ β”œβ”€β”€ design-architecture.md # Patterns, SRP, composition - β”‚ β”œβ”€β”€ testing.md # TDD, test pyramid, mocking - β”‚ β”œβ”€β”€ error-handling.md # Validation, exceptions - β”‚ └── maintainability.md # Refactoring, commits, tooling - └── process/ # Engineering workflow - β”œβ”€β”€ task-classification.md # Classify before coding - β”œβ”€β”€ architecture-reasoning.md # 9-layer thinking hierarchy - β”œβ”€β”€ verification-gates.md # Safety checkpoints - └── negative-doubt.md # Adversarial verification -``` - -## Quick Reference Mode Examples - -### Pattern Lookup -``` -User: "What pattern should I use for swappable payment processors?" - -Response: "Use the Strategy Pattern. It allows you to encapsulate -different payment algorithms (Stripe, PayPal, etc.) and make them -interchangeable at runtime..." -``` - -### Principle Check -``` -User: "Is this function too long?" - -Response: "Yes. At 45 lines with mixed abstraction levels, it violates -the Single Responsibility Principle. Consider extracting..." -``` - -### Best Practice -``` -User: "How should I name this variable?" - -Response: "Use a descriptive noun that indicates purpose. Instead of -'data', use 'user_records' or 'payment_transactions'..." -``` - -## Process Mode Examples - -### Building a System -``` -User: "Build a rate limiting service for our API" - -Response: -**Task Classification:** New Feature - -**Architecture:** -Responsibilities: -- RateLimiter: Track request counts per user -- Storage: Persist counter state -- Middleware: Intercept requests and enforce limits - -Invariants: -- Counter never negative -- Counter resets at time boundary -- Max requests per window enforced - -Dependencies: -RateLimiter β†’ Storage (interface) -Middleware β†’ RateLimiter - -[Full 9-layer architecture...] - -**Code:** [Implementation] - -**Tests:** [Comprehensive test suite] - -**Negative Doubt Log:** -- Failure mode: Race condition β†’ Added atomic increment -- Failure mode: Time drift β†’ Used monotonic clock -... -``` - -## Principle Categories - -### 1. Readability & Clarity -**Goal:** Code that reads like natural language - -- Descriptive naming (nouns for data, verbs for actions) -- Consistent formatting and style -- Self-documenting code (minimal comments) -- Small, focused functions (< 20 lines ideal) - -**Key Quote:** "Code is read 10x more than it's written" - -### 2. Simplicity & Efficiency -**Goal:** Minimal viable abstraction - -- KISS: Simplest solution that works -- DRY: No duplicated logic -- YAGNI: Build only what's needed now -- Defer optimization until profiling proves need - -**Key Quote:** "Premature optimization is the root of all evil" - -### 3. Design & Architecture -**Goal:** Modular, flexible, testable systems - -- Single Responsibility Principle -- Composition over Inheritance -- Depend on interfaces, not implementations -- 7 Essential Patterns: - - Factory, Strategy, Observer - - Decorator, Adapter, Command, Singleton - -**Key Quote:** "Architecture enables change velocity" - -### 4. Testing & Quality -**Goal:** Behavior locked by tests - -- Write tests first or alongside code -- Test pyramid: Many unit, fewer integration, minimal e2e -- One assertion per test (focused) -- Mock external dependencies - -**Key Quote:** "No refactor without tests" - -### 5. Error Handling -**Goal:** Fail fast and clearly - -- Validate inputs at entry points -- Use specific exception types -- Provide actionable error messages -- Guard clauses to reduce nesting - -**Key Quote:** "Explicit is better than implicit" - -### 6. Maintainability -**Goal:** Code that's easy to change - -- Boy Scout Rule: Leave it better -- Continuous small refactors -- Atomic commits with clear messages -- Automate quality checks (linting, formatting) - -**Key Quote:** "Technical debt compounds like financial debt" - -## Process Mode Workflow - -### Step 0: Environment Gate ⚠️ -**ALWAYS FIRST** - -Verify: -- Language version -- Package manager -- Dependencies -- Development tools - -### Step 1: Task Classification -Classify as ONE of: -- New Feature -- Refactor (behavior preserved) -- Bug Fix -- Review/Audit -- Documentation - -**If unclear β†’ STOP** - -### Step 2: Load Engineering Constraints -Apply principles as hard rules: -- Single responsibility -- No circular dependencies -- Tests before refactoring -- No speculative features -- Patterns need stated forces - -### Step 3: Architecture-First Reasoning -Think in 9 layers (never skip): - -1. Responsibilities -2. Invariants -3. Dependencies -4. Module boundaries -5. Public APIs -6. Folder structure -7. Files -8. Functions -9. Syntax - -### Step 4: Behavior & Invariants -Document: -- Observable behavior -- Input/output contracts -- State invariants -- Ordering requirements - -### Step 5: Pattern Gate -Use pattern ONLY if: -- Force is stated -- Simpler alternative rejected -- Invariant being protected is clear - -### Step 6: Implementation -Generate code following: -- Explicit boundaries -- Minimal public surface -- No utils/common without ownership -- Flat structures over deep nesting - -### Step 7: Test-Driven -Include: -- Unit tests for logic -- Integration tests for dependencies -- Edge case coverage -- Error path tests - -### Step 8: Negative Doubt Routine -Adversarial verification: - -1. List 5 failure modes -2. Falsify assumptions -3. Check invariant enforcement -4. Audit dependencies -5. Try simpler alternative -6. Inject failure tests -7. Revise design -8. Document findings -9. Hard stop if unsafe - -### Step 9: Assumptions Disclosure -Always state: -- Input assumptions -- State invariants -- Ordering guarantees -- Non-goals - -## Mode Detection - -### Quick Reference Triggers -- "What pattern for...?" -- "How should I...?" -- "Best practice..." -- Pattern/principle names -- Short, focused questions - -### Process Mode Triggers -- "Build [system]" -- "Design [architecture]" -- "Production code for..." -- Keywords: critical, secure, complex -- Multi-component systems - -## Quick Decision Tables - -### When to Use Design Patterns? - -| Need | Pattern | Alternative | -|------|---------|-------------| -| Swap implementations | Strategy | If/else (for 2-3 variants) | -| Complex object creation | Factory | Direct constructor (simple objects) | -| Event notification | Observer | Direct calls (1-2 listeners) | -| Add capabilities | Decorator | Subclassing (stable hierarchy) | -| Interface mismatch | Adapter | Refactor interfaces | -| Undo/logging | Command | Direct methods (no history needed) | -| Single instance | Singleton | Dependency injection | - -### When to Refactor vs Rewrite? - -| Tests Exist? | Code Quality | Action | -|--------------|--------------|--------| -| βœ“ Yes | Poor structure | Incremental refactor | -| βœ— No | Poor structure | Write tests β†’ refactor | -| βœ— No | Fundamentally wrong | Rewrite with TDD | -| βœ“ Yes | Security flaw | Fix β†’ add regression test | - -### When to Add Abstraction? - -| Condition | Add? | Reason | -|-----------|------|--------| -| Duplicated in 3+ places | Yes | DRY principle | -| Future variation anticipated | No | YAGNI - wait for actual need | -| 2+ implementations exist | Yes | Interface for polymorphism | -| 1 implementation, simple | No | KISS - keep it simple | - -## Anti-Patterns Caught by This Skill - -### Common AI Code Generation Issues -- ❌ Generic variable names (`data`, `temp`, `result`) -- ❌ Over-commenting obvious code -- ❌ Skipping input validation -- ❌ Applying patterns without justification -- ❌ Monolithic functions (100+ lines) -- ❌ Copy-pasted code with minor changes -- ❌ Missing error handling - -### Engineering Anti-Patterns -- ❌ Coding before defining architecture -- ❌ Refactoring without tests -- ❌ Circular dependencies -- ❌ God objects (do everything) -- ❌ Premature optimization -- ❌ Unclear module boundaries -- ❌ Vague variable names - -## Example Usage - -### Quick Mode: Pattern Question -```bash -kiro "When should I use the Observer pattern instead of direct callbacks?" - -# Response includes: -# - Forces that justify Observer -# - When callbacks are simpler -# - Code example of both -# - Trade-offs -``` - -### Process Mode: Build Feature -```bash -kiro "Build authentication service with JWT tokens for production API" - -# Response includes: -# - Task classification (New Feature) -# - Architecture (9 layers) -# - Dependencies (interfaces) -# - Public API contracts -# - Full implementation -# - Comprehensive tests -# - Negative doubt log -# - Security considerations -``` - -## Verification Gates - -| Gate | Checks | Hard Stop If | -|------|--------|--------------| -| 0. Environment | Runtime, tools, deps | Missing required tools | -| 1. Requirements | Clarity, scope | Ambiguous or vague | -| 2. Architecture | Dependencies, boundaries | Circular deps | -| 3. Patterns | Justified forces | No force stated | -| 4. Tests | Coverage, edge cases | Critical paths untested | -| 5. Quality | Linting, formatting | Violations present | -| 6. Security | Validation, secrets | Vulnerabilities found | -| 7. Performance | Benchmarks (if critical) | Requirements not met | - -## Benefits - -### For Individual Developers -- Faster pattern selection -- Fewer bugs through verification -- Better architecture decisions -- Clearer code review criteria - -### For Teams -- Consistent engineering practices -- Shared vocabulary (patterns) -- Reduced technical debt -- Faster onboarding - -### For Production Systems -- Higher reliability (gates catch issues) -- Better maintainability (clear structure) -- Easier debugging (explicit invariants) -- Safer refactoring (tests lock behavior) - -## When NOT to Use Full Process Mode - -**Use lightweight reference mode for:** -- Prototypes and experiments -- Personal scripts -- Learning exercises -- Throwaway code - -**But always state:** "This is a prototype, skipping gates X, Y, Z" - -## Sources & Credits - -### Design Patterns & Principles -- *Clean Code* - Robert C. Martin -- *The Pragmatic Programmer* - Hunt & Thomas -- *Code Complete* - Steve McConnell -- *Refactoring* - Martin Fowler -- *Design Patterns* - Gang of Four - -### Engineering Process -- Senior SDE-3 industry practices -- Production systems methodology -- Safety-critical software engineering - -## Philosophy - -> **You are not an autocomplete engine.** -> **You are an engineering constraint solver.** - -This skill treats engineering as a discipline of **preserving correctness** through: -- Explicit constraints -- Verifiable invariants -- Systematic reasoning -- Adversarial verification - -Code is the output, not the input, of engineering. - -## Version - -2.0.0 - Combined design patterns + ProCoder engineering process - -## License - -Based on publicly available software engineering literature and industry best practices. diff --git a/skills/engineering-discipline/references/patterns/design-architecture.md b/skills/engineering-discipline/references/patterns/design-architecture.md deleted file mode 100755 index fc1cd6c..0000000 --- a/skills/engineering-discipline/references/patterns/design-architecture.md +++ /dev/null @@ -1,477 +0,0 @@ -# Design & Architecture Principles - -## Single Responsibility Principle (SRP) - -**Definition:** Each class or module should have only one reason to change. It should encapsulate one cohesive responsibility. - -**Supported by:** *Clean Code*, *The Pragmatic Programmer*, SOLID Principles - -### Examples - -```python -# Bad - Multiple responsibilities -class User: - def __init__(self, name, email): - self.name = name - self.email = email - - def save_to_database(self): - # Database logic - pass - - def send_welcome_email(self): - # Email logic - pass - - def generate_report(self): - # Reporting logic - pass - -# Good - Separated concerns -class User: - def __init__(self, name, email): - self.name = name - self.email = email - -class UserRepository: - def save(self, user): - # Database logic - pass - -class EmailService: - def send_welcome(self, user): - # Email logic - pass - -class UserReportGenerator: - def generate(self, user): - # Reporting logic - pass -``` - -### Do -- Encapsulate related data and behavior -- Separate concerns (data access, business logic, presentation) -- Create cohesive modules -- Make reasons for change explicit - -### Don't -- Mix data access, logic, and UI in one class -- Create "god objects" that do everything -- Couple unrelated functionality - -### AI Pitfalls -- Cramming multiple operations into one class -- Creating utility classes with unrelated methods -- Mixing infrastructure and domain logic - ---- - -## Composition Over Inheritance - -**Definition:** Prefer combining objects to form behavior over creating deep class hierarchies. Favor "has-a" relationships over "is-a". - -**Supported by:** *The Pragmatic Programmer*, *Design Patterns* - -### Examples - -```python -# Bad - Rigid inheritance hierarchy -class Bird: - def fly(self): - return "Flying" - -class Penguin(Bird): - def fly(self): - raise Exception("Penguins cannot fly") - -# Good - Composition with behavior injection -class FlyBehavior: - def fly(self): - pass - -class CanFly(FlyBehavior): - def fly(self): - return "Flying" - -class CannotFly(FlyBehavior): - def fly(self): - return "Cannot fly" - -class Bird: - def __init__(self, fly_behavior): - self.fly_behavior = fly_behavior - - def perform_fly(self): - return self.fly_behavior.fly() - -# Usage -sparrow = Bird(CanFly()) -penguin = Bird(CannotFly()) -``` - -### Do -- Use interfaces or protocols to define contracts -- Inject dependencies and behaviors -- Compose small, focused objects -- Favor delegation over inheritance - -### Don't -- Create deep inheritance hierarchies (>3 levels) -- Inherit just to override behavior -- Use inheritance for code reuse alone -- Force unnatural "is-a" relationships - -### AI Pitfalls -- Defaulting to inheritance for code reuse -- Creating rigid class hierarchies -- Not recognizing when composition is clearer - ---- - -## Program to an Interface, Not an Implementation - -**Definition:** Depend on abstractions (interfaces, protocols) rather than concrete implementations. This enables flexibility and testability. - -**Supported by:** *Design Patterns*, *Code Complete*, Dependency Inversion Principle - -### Examples - -```python -# Bad - Depends on concrete implementation -class OrderProcessor: - def __init__(self): - self.payment = StripePayment() # Hard-coded dependency - - def process(self, order): - self.payment.charge(order.total) - -# Good - Depends on abstraction -class PaymentProcessor: - def charge(self, amount): - raise NotImplementedError - -class StripePayment(PaymentProcessor): - def charge(self, amount): - # Stripe-specific logic - pass - -class PayPalPayment(PaymentProcessor): - def charge(self, amount): - # PayPal-specific logic - pass - -class OrderProcessor: - def __init__(self, payment_processor: PaymentProcessor): - self.payment = payment_processor - - def process(self, order): - self.payment.charge(order.total) - -# Usage - Easy to swap implementations -processor = OrderProcessor(StripePayment()) -# or -processor = OrderProcessor(PayPalPayment()) -``` - -### Do -- Define interfaces for key abstractions -- Inject dependencies via constructors -- Use dependency injection frameworks when appropriate -- Code against contracts, not implementations - -### Don't -- Hard-code concrete class names -- Use `isinstance()` checks to switch behavior -- Create tight coupling to specific implementations - -### AI Pitfalls -- Using fixed class names instead of interfaces -- Not recognizing opportunities for abstraction -- Creating concrete dependencies in constructors - ---- - -## Essential Design Patterns - -### Factory Pattern - -**Purpose:** Delegate object creation to factory methods or classes. Decouples client code from concrete instantiation. - -**Use when:** Object creation is complex or varies based on conditions. - -```python -# Example -class LoggerFactory: - @staticmethod - def get_logger(log_type): - if log_type == "file": - return FileLogger() - elif log_type == "console": - return ConsoleLogger() - elif log_type == "cloud": - return CloudLogger() - else: - raise ValueError(f"Unknown logger type: {log_type}") - -# Usage -logger = LoggerFactory.get_logger("file") -logger.log("Application started") -``` - -### Strategy Pattern - -**Purpose:** Define a family of interchangeable algorithms and make them swappable at runtime. - -**Use when:** You need different behaviors for the same operation. - -```python -# Example -class SortStrategy: - def sort(self, data): - raise NotImplementedError - -class QuickSort(SortStrategy): - def sort(self, data): - # Quick sort implementation - pass - -class MergeSort(SortStrategy): - def sort(self, data): - # Merge sort implementation - pass - -class DataProcessor: - def __init__(self, sort_strategy: SortStrategy): - self.sorter = sort_strategy - - def process(self, data): - sorted_data = self.sorter.sort(data) - return sorted_data - -# Usage -processor = DataProcessor(MergeSort()) -result = processor.process([3, 1, 4, 1, 5]) -``` - -### Observer Pattern - -**Purpose:** Define a one-to-many dependency where changes in one object notify all dependents automatically. - -**Use when:** Multiple objects need to react to state changes. - -```python -# Example -class Subject: - def __init__(self): - self._observers = [] - - def attach(self, observer): - self._observers.append(observer) - - def notify(self, event): - for observer in self._observers: - observer.update(event) - -class Observer: - def update(self, event): - raise NotImplementedError - -class EmailNotifier(Observer): - def update(self, event): - print(f"Sending email for: {event}") - -class SlackNotifier(Observer): - def update(self, event): - print(f"Posting to Slack: {event}") - -# Usage -order_system = Subject() -order_system.attach(EmailNotifier()) -order_system.attach(SlackNotifier()) -order_system.notify("Order #123 shipped") -``` - -### Decorator Pattern - -**Purpose:** Dynamically add responsibilities to objects without modifying their class. - -**Use when:** You need flexible, composable enhancements. - -```python -# Example -class Notifier: - def send(self, message): - raise NotImplementedError - -class BasicNotifier(Notifier): - def send(self, message): - print(f"Basic notification: {message}") - -class NotifierDecorator(Notifier): - def __init__(self, notifier: Notifier): - self._notifier = notifier - - def send(self, message): - self._notifier.send(message) - -class SlackDecorator(NotifierDecorator): - def send(self, message): - super().send(message) - print(f"Also sent to Slack: {message}") - -class EmailDecorator(NotifierDecorator): - def send(self, message): - super().send(message) - print(f"Also sent via email: {message}") - -# Usage - Compose behaviors -notifier = EmailDecorator(SlackDecorator(BasicNotifier())) -notifier.send("System alert") -``` - -### Adapter Pattern - -**Purpose:** Convert one interface into another that clients expect. Enables incompatible interfaces to work together. - -**Use when:** Integrating legacy systems or third-party libraries. - -```python -# Example -class LegacyPrinter: - def print_text(self, text): - print(f"[LEGACY] {text}") - -class ModernPrinter: - def print(self, content): - raise NotImplementedError - -class PrinterAdapter(ModernPrinter): - def __init__(self, legacy_printer: LegacyPrinter): - self.legacy = legacy_printer - - def print(self, content): - self.legacy.print_text(content) - -# Usage -old_printer = LegacyPrinter() -adapter = PrinterAdapter(old_printer) -adapter.print("Hello World") # Uses modern interface, delegates to legacy -``` - -### Command Pattern - -**Purpose:** Encapsulate a request as an object, enabling queuing, logging, or undoable operations. - -**Use when:** You need to queue operations, support undo/redo, or log actions. - -```python -# Example -class Command: - def execute(self): - raise NotImplementedError - - def undo(self): - raise NotImplementedError - -class Light: - def on(self): - print("Light is ON") - - def off(self): - print("Light is OFF") - -class LightOnCommand(Command): - def __init__(self, light: Light): - self.light = light - - def execute(self): - self.light.on() - - def undo(self): - self.light.off() - -class LightOffCommand(Command): - def __init__(self, light: Light): - self.light = light - - def execute(self): - self.light.off() - - def undo(self): - self.light.on() - -# Usage -living_room_light = Light() -light_on = LightOnCommand(living_room_light) -light_on.execute() # Light is ON -light_on.undo() # Light is OFF -``` - -### Singleton Pattern - -**Purpose:** Ensure only one instance of a class exists globally. - -**Use when:** You need a single point of access (e.g., config, logger, connection pool). - -**Caution:** Often overused. Consider dependency injection instead. - -```python -# Example -class Singleton: - _instance = None - - def __new__(cls): - if cls._instance is None: - cls._instance = super().__new__(cls) - return cls._instance - -class ConfigManager(Singleton): - def __init__(self): - if not hasattr(self, 'initialized'): - self.config = {} - self.initialized = True - -# Usage -config1 = ConfigManager() -config2 = ConfigManager() -assert config1 is config2 # Same instance -``` - ---- - -## Pattern Usage Guidelines - -### Do -- Apply patterns when they improve clarity and flexibility -- Choose patterns based on structural fit -- Use patterns to communicate design intent -- Combine patterns when appropriate - -### Don't -- Force patterns into simple code -- Use patterns for the sake of patterns -- Apply patterns without understanding the problem -- Over-abstract with unnecessary pattern layers - -### AI Pitfalls -- Predicting patterns where none are needed -- Misnaming pattern roles (e.g., calling a simple factory a "Factory Pattern") -- Misapplying pattern intent (e.g., Singleton for everything) -- Creating pattern boilerplate without actual benefit - ---- - -## Summary - -Good architecture is: -- **Modular** - clear boundaries and responsibilities -- **Flexible** - uses composition and interfaces -- **Abstract** - depends on contracts, not implementations -- **Pattern-aware** - applies proven solutions appropriately - -When designing systems, ask: -- Does each module have one clear responsibility? -- Can I swap implementations easily? -- Am I using inheritance or composition? -- Does this pattern solve a real structural problem? diff --git a/skills/engineering-discipline/references/patterns/error-handling.md b/skills/engineering-discipline/references/patterns/error-handling.md deleted file mode 100755 index 1b1c25f..0000000 --- a/skills/engineering-discipline/references/patterns/error-handling.md +++ /dev/null @@ -1,364 +0,0 @@ -# Error Handling & Input Validation - -## Handle Errors Clearly - -**Definition:** Use exceptions for unexpected states and provide clear error messages. Fail early and explicitly rather than allowing silent failures. - -**Supported by:** *Code Complete*, *Clean Code*, *The Pragmatic Programmer* - -### Examples - -```python -# Bad - Silent failure -def divide(a, b): - if b == 0: - return None # Caller has to check for None - return a / b - -# Good - Explicit error -def divide(a, b): - if b == 0: - raise ValueError("Cannot divide by zero") - return a / b -``` - -```python -# Bad - Vague error message -def process_user(user): - if not user: - raise Exception("Error") - -# Good - Descriptive error message -def process_user(user): - if user is None: - raise ValueError("User object cannot be None") - if not user.email: - raise ValueError(f"User {user.id} must have a valid email address") -``` - -### Do -- Use exceptions for exceptional conditions -- Provide descriptive error messages -- Include context (what failed, why, what was expected) -- Fail fast - validate inputs early -- Use specific exception types -- Document what exceptions can be raised - -### Don't -- Return None or -1 as error codes -- Swallow exceptions silently -- Use exceptions for control flow -- Provide generic error messages ("Error occurred") -- Catch exceptions you can't handle - -### AI Pitfalls -- Skipping edge-case validation -- Empty except blocks: `except: pass` -- Returning default values instead of raising errors -- Generic exception types instead of specific ones - ---- - -## Validate Inputs Early - -**Definition:** Check preconditions at the entry point of functions. Reject invalid input before processing. - -**Supported by:** *Code Complete*, *Clean Code* - -### Examples - -```python -# Bad - Late validation, partial processing -def register_user(username, email, age): - user = User(username, email, age) - save_to_database(user) - if age < 18: # Too late - already saved! - raise ValueError("User must be 18 or older") - -# Good - Early validation -def register_user(username, email, age): - if not username or len(username) < 3: - raise ValueError("Username must be at least 3 characters") - if not email or '@' not in email: - raise ValueError("Invalid email address") - if age < 18: - raise ValueError("User must be 18 or older") - - user = User(username, email, age) - save_to_database(user) -``` - -### Guard Clauses - -Use guard clauses to validate and exit early: - -```python -# Bad - Nested conditions -def process_order(order): - if order is not None: - if order.items: - if order.total > 0: - # Main logic here - charge_payment(order) - ship_order(order) - -# Good - Guard clauses -def process_order(order): - if order is None: - raise ValueError("Order cannot be None") - if not order.items: - raise ValueError("Order must contain at least one item") - if order.total <= 0: - raise ValueError("Order total must be positive") - - # Main logic - no nesting - charge_payment(order) - ship_order(order) -``` - -### Do -- Validate at function entry -- Use guard clauses to reduce nesting -- Check preconditions explicitly -- Validate types and ranges -- Use type hints and runtime validation - -### Don't -- Defer validation until deep in the logic -- Assume inputs are valid -- Mix validation with business logic - ---- - -## Exception Hierarchy - -**Definition:** Use specific exception types to allow targeted error handling. - -### Examples - -```python -# Bad - Generic exceptions -def fetch_user(user_id): - if user_id < 0: - raise Exception("Invalid ID") - user = db.get(user_id) - if not user: - raise Exception("Not found") - return user - -# Good - Specific exceptions -class InvalidUserIdError(ValueError): - pass - -class UserNotFoundError(LookupError): - pass - -def fetch_user(user_id): - if user_id < 0: - raise InvalidUserIdError(f"User ID must be positive, got {user_id}") - user = db.get(user_id) - if not user: - raise UserNotFoundError(f"User with ID {user_id} not found") - return user - -# Caller can handle specifically -try: - user = fetch_user(user_id) -except InvalidUserIdError as e: - return {"error": "bad_request", "message": str(e)} -except UserNotFoundError as e: - return {"error": "not_found", "message": str(e)} -``` - -### Do -- Create custom exception classes for domain errors -- Inherit from appropriate built-in exceptions -- Use exception hierarchies for related errors -- Document exception types in docstrings - -### Don't -- Raise generic `Exception` or `RuntimeError` -- Create exceptions for every possible error -- Use exceptions for non-exceptional cases - ---- - -## Error Recovery Strategies - -### Retry with Backoff - -```python -import time - -def fetch_with_retry(url, max_attempts=3): - for attempt in range(max_attempts): - try: - return http.get(url) - except TransientError as e: - if attempt == max_attempts - 1: - raise - wait_time = 2 ** attempt # Exponential backoff - time.sleep(wait_time) -``` - -### Fallback Mechanisms - -```python -def get_user_avatar(user_id): - try: - return cdn.fetch_avatar(user_id) - except CDNError: - # Fallback to default avatar - return DEFAULT_AVATAR_URL -``` - -### Circuit Breaker - -```python -class CircuitBreaker: - def __init__(self, failure_threshold=5): - self.failure_count = 0 - self.threshold = failure_threshold - self.state = "closed" # closed, open, half-open - - def call(self, func, *args): - if self.state == "open": - raise CircuitOpenError("Service is temporarily unavailable") - - try: - result = func(*args) - self.on_success() - return result - except Exception as e: - self.on_failure() - raise - - def on_success(self): - self.failure_count = 0 - self.state = "closed" - - def on_failure(self): - self.failure_count += 1 - if self.failure_count >= self.threshold: - self.state = "open" -``` - ---- - -## Logging vs. Exceptions - -**Definition:** Log for diagnostics, use exceptions for control flow. - -### When to Log - -```python -# Log operational info -logger.info(f"Processing order {order_id}") - -# Log warnings for recoverable issues -logger.warning(f"Slow query detected: {duration}ms") - -# Log errors with context -try: - process_payment(order) -except PaymentError as e: - logger.error(f"Payment failed for order {order.id}", exc_info=True) - raise # Re-raise after logging -``` - -### When to Raise Exceptions - -```python -# Invalid input - exception -def set_age(age): - if age < 0 or age > 150: - raise ValueError(f"Invalid age: {age}") - -# Business rule violation - exception -def withdraw(account, amount): - if account.balance < amount: - raise InsufficientFundsError(f"Balance: {account.balance}, requested: {amount}") - -# Operational issue - log + exception -def connect_to_database(): - try: - return db.connect() - except ConnectionError as e: - logger.error("Database connection failed", exc_info=True) - raise DatabaseUnavailableError("Cannot connect to database") from e -``` - -### Do -- Log context before re-raising -- Include exception traceback in logs -- Use structured logging for searchability -- Set appropriate log levels - -### Don't -- Log and swallow exceptions -- Log sensitive data (passwords, tokens) -- Over-log routine operations - ---- - -## Error Messages Best Practices - -### Good Error Messages - -**What went wrong:** -``` -"Invalid email address: 'user@domain' - missing top-level domain" -``` - -**What was expected:** -``` -"Order total must be positive, got -50.00" -``` - -**How to fix it:** -``` -"File not found: '/data/input.csv'. Check that the file exists and path is correct." -``` - -**Actionable context:** -``` -"User authentication failed: Invalid API key. Please check your credentials in the dashboard." -``` - -### Bad Error Messages - -``` -"Error" # Too vague -"Something went wrong" # Unhelpful -"Invalid input" # Missing details -"Error code: 42" # No explanation -``` - -### Do -- Explain what failed and why -- Include actual vs. expected values -- Suggest corrective actions -- Avoid technical jargon for user-facing errors -- Use clear, plain language - -### Don't -- Expose internal implementation details to end users -- Include stack traces in user-facing messages -- Use codes without explanations -- Be condescending ("You entered invalid data") - ---- - -## Summary - -Effective error handling: -- **Fails fast** - Validates early and explicitly -- **Provides clarity** - Error messages explain what and why -- **Uses exceptions correctly** - For exceptional conditions only -- **Enables recovery** - Appropriate retry and fallback strategies - -When handling errors, ask: -- Have I validated all inputs? -- Will the error message help someone fix the issue? -- Am I using the right exception type? -- Should this be logged, raised, or both? diff --git a/skills/engineering-discipline/references/patterns/maintainability.md b/skills/engineering-discipline/references/patterns/maintainability.md deleted file mode 100755 index a085889..0000000 --- a/skills/engineering-discipline/references/patterns/maintainability.md +++ /dev/null @@ -1,548 +0,0 @@ -# Maintainability & Best Practices - -## Boy Scout Rule - -**Definition:** "Leave the code better than you found it." Make small improvements whenever you touch existing code. - -**Supported by:** *Clean Code*, *The Pragmatic Programmer* - -### Examples - -```python -# Before - Existing code you're modifying -def calc(a, b): - return a + b - -# After - Improved while making your change -def calculate_sum(a, b): - """Return the sum of two numbers.""" - return a + b -``` - -```python -# Before - Adding a feature to messy code -def processUser(u): - # Check age - if u.age<18:return False - db.save(u) - return True - -# After - Clean up while you're here -def process_user(user): - """Register an eligible user.""" - if not is_eligible_user(user): - return False - save_user(user) - return True - -def is_eligible_user(user): - return user.age >= 18 -``` - -### Do -- Improve variable names -- Extract magic numbers to constants -- Add missing docstrings -- Fix formatting inconsistencies -- Remove dead code -- Simplify complex conditions - -### Don't -- Make unrelated large refactors -- Change behavior without tests -- Add hacks or workarounds -- Ignore obvious issues ("not my code") - -### AI Pitfalls -- Regenerating dirty code without improvements -- Not suggesting cleanup opportunities -- Adding to technical debt instead of reducing it - ---- - -## Continuous Refactoring - -**Definition:** Improve code structure regularly through small, safe changes backed by tests. Refactoring should be ongoing, not a separate phase. - -**Supported by:** *Refactoring*, *Code Complete*, *Clean Code* - -### Common Refactorings - -**Extract Method** -```python -# Before -def process_order(order): - # Validate - if not order.items: - raise ValueError("Empty order") - - # Calculate total - total = 0 - for item in order.items: - total += item.price * item.quantity - - # Apply discount - if order.customer.is_premium: - total *= 0.9 - - return total - -# After -def process_order(order): - validate_order(order) - total = calculate_total(order) - return apply_discount(total, order.customer) - -def validate_order(order): - if not order.items: - raise ValueError("Empty order") - -def calculate_total(order): - return sum(item.price * item.quantity for item in order.items) - -def apply_discount(total, customer): - if customer.is_premium: - return total * 0.9 - return total -``` - -**Extract Variable** -```python -# Before -if (user.age >= 18 and user.has_verified_email and user.account_status == 'active'): - grant_access() - -# After -is_adult = user.age >= 18 -has_verified_email = user.has_verified_email -is_active = user.account_status == 'active' - -if is_adult and has_verified_email and is_active: - grant_access() -``` - -**Rename** -```python -# Before -def fn(x, y): - return x * y - -# After -def calculate_area(width, height): - return width * height -``` - -**Replace Magic Numbers** -```python -# Before -def calculate_price(quantity): - if quantity > 100: - return quantity * 9.99 * 0.85 - return quantity * 9.99 - -# After -UNIT_PRICE = 9.99 -BULK_DISCOUNT = 0.85 -BULK_THRESHOLD = 100 - -def calculate_price(quantity): - price = quantity * UNIT_PRICE - if quantity > BULK_THRESHOLD: - price *= BULK_DISCOUNT - return price -``` - -### Refactoring Workflow - -1. **Ensure tests pass** - Start with green tests -2. **Make one change** - Small, focused refactor -3. **Run tests** - Verify behavior unchanged -4. **Commit** - Save working state -5. **Repeat** - Iterate on improvements - -### Do -- Refactor in small steps -- Run tests after each change -- Commit frequently -- Use IDE refactoring tools -- Keep behavior identical - -### Don't -- Refactor without tests -- Mix refactoring with feature work -- Make multiple changes at once -- Skip running tests -- Delay commits - -### AI Pitfalls -- Suggesting large refactors without incremental steps -- Omitting test runs between changes -- Changing behavior during refactoring - ---- - -## Version Control & Incremental Work - -**Definition:** Commit code in logical, testable chunks. Each commit should represent a complete, working unit of change. - -**Supported by:** *Refactoring*, *The Pragmatic Programmer*, Agile practices - -### Good Commit Practices - -**Atomic Commits** -``` -βœ“ "Add user email validation" -βœ“ "Extract payment processing to service" -βœ“ "Fix off-by-one error in pagination" - -βœ— "Fixed stuff" -βœ— "WIP" -βœ— "Updated files" -``` - -**Commit Messages** -``` -# Good - Imperative mood, clear intent -Add password strength validation - -Implement validation rules: -- Minimum 8 characters -- At least one uppercase letter -- At least one number -- At least one special character - -Closes #123 - -# Bad -fixed login -``` - -### Commit Workflow - -```bash -# 1. Make a focused change -# 2. Run tests -pytest - -# 3. Review changes -git diff - -# 4. Stage related files -git add user_validator.py tests/test_validator.py - -# 5. Commit with clear message -git commit -m "Add email format validation" - -# 6. Repeat for next logical change -``` - -### Do -- Commit working, tested code -- Write descriptive commit messages -- Keep commits focused and atomic -- Use branches for features -- Commit frequently - -### Don't -- Commit broken code -- Mix unrelated changes in one commit -- Skip commit messages -- Commit sensitive data (API keys, passwords) -- Leave uncommitted changes overnight - -### AI Pitfalls -- Generating large changes without guiding commit boundaries -- Not suggesting logical commit points -- Creating code that can't be committed incrementally - ---- - -## Code Reviews - -**Definition:** Systematic examination of code changes by peers to catch issues, share knowledge, and maintain quality. - -### Review Checklist - -**Correctness** -- Does it solve the stated problem? -- Are edge cases handled? -- Is error handling appropriate? -- Are there off-by-one errors or race conditions? - -**Design** -- Is it in the right place? -- Does it follow existing patterns? -- Is complexity warranted? -- Could it be simpler? - -**Readability** -- Are names clear? -- Is logic easy to follow? -- Are comments helpful (not redundant)? -- Is formatting consistent? - -**Testing** -- Are tests included? -- Do tests cover edge cases? -- Are tests readable and maintainable? - -**Security** -- Is input validated? -- Are secrets hardcoded? -- Are SQL queries parameterized? -- Is authentication/authorization correct? - -### Review Etiquette - -**As Reviewer** -``` -βœ“ "Consider extracting this to a helper function for reusability" -βœ“ "Could we add a test for the empty list case?" -βœ“ "This is clever! Can we add a comment explaining the algorithm?" - -βœ— "This is terrible" -βœ— "Why didn't you just..." -βœ— "Obviously this is wrong" -``` - -**As Author** -- Respond to all feedback -- Ask for clarification -- Explain non-obvious decisions -- Be open to suggestions -- Thank reviewers - -### Do -- Review promptly -- Focus on substance over style -- Suggest improvements, don't demand -- Automate style checks -- Learn from reviews you receive - -### Don't -- Approve without reading -- Nitpick trivial issues -- Review your own PRs -- Take criticism personally -- Skip review for "small" changes - ---- - -## Automation and Tooling - -**Definition:** Automate repetitive tasks and use tools to maintain consistency and quality. - -**Supported by:** *The Pragmatic Programmer*, *Clean Code* - -### Essential Tools - -**Linters** - Catch common mistakes -```bash -# Python -pylint myapp/ -flake8 myapp/ - -# JavaScript -eslint src/ - -# Go -golangci-lint run -``` - -**Formatters** - Maintain consistent style -```bash -# Python -black myapp/ - -# JavaScript -prettier --write src/ - -# Rust -rustfmt src/ -``` - -**Type Checkers** - Catch type errors -```bash -# Python -mypy myapp/ - -# TypeScript -tsc --noEmit - -# Flow -flow check -``` - -**Test Runners** - Verify behavior -```bash -# Python -pytest - -# JavaScript -jest - -# Go -go test ./... -``` - -### Continuous Integration - -```yaml -# .github/workflows/ci.yml -name: CI -on: [push, pull_request] - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install dependencies - run: pip install -r requirements.txt - - name: Lint - run: flake8 . - - name: Type check - run: mypy . - - name: Test - run: pytest --cov - - name: Security scan - run: bandit -r . -``` - -### Pre-commit Hooks - -```bash -# .pre-commit-config.yaml -repos: - - repo: https://github.com/psf/black - hooks: - - id: black - - repo: https://github.com/pycqa/flake8 - hooks: - - id: flake8 - - repo: https://github.com/pre-commit/pre-commit-hooks - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml -``` - -### Do -- Integrate tools into workflow -- Run checks locally before pushing -- Fail builds on violations -- Configure tools consistently -- Update tools regularly - -### Don't -- Rely on manual checks -- Ignore tool warnings -- Skip tools for "quick fixes" -- Disable checks without good reason - -### AI Pitfalls -- Producing code that doesn't pass linting -- Ignoring type annotations -- Generating code incompatible with project tools - ---- - -## Documentation - -**Definition:** Provide context and explanations where code alone isn't sufficient. - -### What to Document - -**APIs and Public Interfaces** -```python -def calculate_shipping_cost(weight_kg: float, destination: str) -> float: - """Calculate shipping cost based on weight and destination. - - Args: - weight_kg: Package weight in kilograms (must be positive) - destination: ISO 3166-1 alpha-2 country code - - Returns: - Shipping cost in USD - - Raises: - ValueError: If weight is negative or destination is invalid - - Example: - >>> calculate_shipping_cost(2.5, 'US') - 12.50 - """ -``` - -**Complex Algorithms** -```python -def dijkstra(graph, start): - """Find shortest paths using Dijkstra's algorithm. - - Time complexity: O((V + E) log V) where V is vertices, E is edges - Space complexity: O(V) - - See: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm - """ -``` - -**Non-Obvious Decisions** -```python -# Using MD5 for cache keys only - NOT for security -# MD5 is fast and collision-resistant enough for this use case -cache_key = hashlib.md5(url.encode()).hexdigest() -``` - -**Setup and Configuration** -```markdown -# README.md - -## Installation - -pip install -r requirements.txt - -## Configuration - -Set environment variables: -- `DATABASE_URL`: PostgreSQL connection string -- `API_KEY`: Third-party service API key - -## Running - -python app.py -``` - -### Don't Document - -- Obvious code (let code be self-documenting) -- Implementation details that change frequently -- Duplicated information available elsewhere - -### Do -- Keep docs close to code -- Update docs with code changes -- Use examples liberally -- Link to external references - -### Don't -- Let docs become stale -- Over-document simple code -- Duplicate info across files - ---- - -## Summary - -Maintainable code: -- **Improves incrementally** - Boy Scout Rule -- **Refactors continuously** - Small, safe improvements -- **Commits logically** - Atomic, tested changes -- **Automates quality** - Linters, formatters, CI/CD -- **Documents appropriately** - Context where needed - -When maintaining code, ask: -- Can I improve this while I'm here? -- Is this change small and safe? -- Should I commit now? -- Are my tools catching issues? -- Does this need documentation? diff --git a/skills/engineering-discipline/references/patterns/readability.md b/skills/engineering-discipline/references/patterns/readability.md deleted file mode 100755 index edf85e0..0000000 --- a/skills/engineering-discipline/references/patterns/readability.md +++ /dev/null @@ -1,195 +0,0 @@ -# Readability & Clarity Principles - -## Descriptive Naming - -**Definition:** Use clear, meaningful names for variables, functions, classes, etc., so code reads like natural language. Avoid vague, abbreviated, or encoded names. Good names explain intent without requiring comments. - -**Supported by:** *Clean Code*, *Code Complete* - -### Examples - -```python -# Bad -def calc(a, b): - return a * b + 3 - -# Good -def calculate_rectangle_area(width, height): - margin = 3 - return width * height + margin -``` - -### Do -- Use nouns for data structures and variables -- Use verbs for functions and methods -- Use consistent domain terminology -- Make names pronounceable and searchable -- Use solution/problem domain names - -### Don't -- Use single-letter names (except loop counters in small scopes) -- Create misleading names -- Use encodings or prefixes (Hungarian notation) -- Use abbreviations unless universally known -- Mix naming conventions in the same scope - -### AI Pitfalls -- Repeating generic names like `data`, `temp`, `foo`, `result` -- Inconsistent naming across similar concepts -- Using placeholder names and forgetting to rename -- Over-shortening meaningful names for brevity - ---- - -## Consistent Style & Formatting - -**Definition:** Follow a uniform coding style and project conventions. Consistency aids readability and reduces cognitive load. - -**Supported by:** *Clean Code*, *Code Complete* - -### Examples - -```javascript -// Bad - Inconsistent spacing, braces, indentation -if(x>0){ -y= x+10; - console.log(y);} - -// Good - Consistent formatting -if (x > 0) { - let result = x + 10; - console.log(result); -} -``` - -### Do -- Stick to one brace style (K&R, Allman, etc.) -- Use consistent indentation (2 or 4 spaces, never mix tabs/spaces) -- Follow language conventions (PEP 8 for Python, Airbnb for JS) -- Maintain consistent line length (80-120 characters) -- Use automated formatters (Prettier, Black, rustfmt) - -### Don't -- Mix different formatting styles in one file -- Ignore project linting rules -- Use inconsistent whitespace -- Create overly long lines - -### AI Pitfalls -- Producing inconsistent formatting across code blocks -- Mixing indentation styles -- Ignoring existing project formatting conventions - ---- - -## Self-Documenting Code (Minimize Comments) - -**Definition:** Write code so its intent is clear from the code itself. Comments should explain *why*, not *what*. - -**Supported by:** *Clean Code*, *Code Complete* - -### Examples - -```python -# Bad - Redundant comment -# Increment i by 1 -i = i + 1 - -# Good - No comment needed -i = i + 1 - -# Acceptable - Explains business rule -# Block access for users under minimum age requirement -if user.age < 13: - block_access() - -# Good - Explains non-obvious why -# Using exponential backoff to avoid API rate limits -retry_delay = base_delay * (2 ** attempt_count) -``` - -### Do -- Use clear naming and logic structure -- Comment complex algorithms or business rules -- Explain performance optimizations -- Document API contracts and side effects -- Add TODO comments for future work (with ticket IDs) - -### Don't -- Write comments that restate the code -- Leave commented-out code -- Write misleading or outdated comments -- Use comments to fix bad naming - -### AI Pitfalls -- Over-commenting obvious operations -- Leaving stale or contradictory comments -- Using comments instead of refactoring unclear code - ---- - -## Small Functions & Single Responsibility - -**Definition:** Functions and methods should do one thing and do it well. Small, cohesive units are easier to understand, test, and maintain. - -**Supported by:** *Clean Code*, *Code Complete* - -### Examples - -```python -# Bad - Function does too many things -def update_user(data): - validate(data) - update_database(data) - send_email(data) - log_activity(data) - invalidate_cache(data) - -# Good - Separated concerns -def update_user(data): - validated_data = validate(data) - save_user(validated_data) - notify_user(validated_data) - -def save_user(data): - update_database(data) - invalidate_cache(data) - -def notify_user(data): - send_email(data) - log_activity(data) -``` - -### Do -- Keep functions under 20-30 lines when possible -- Extract helper functions for complex logic -- Use descriptive function names that indicate purpose -- Limit function parameters (ideally ≀ 3) -- Make one level of abstraction per function - -### Don't -- Combine unrelated operations -- Create deeply nested logic -- Use flag arguments to control behavior -- Write functions that both query and modify state - -### AI Pitfalls -- Creating monolithic functions with multiple responsibilities -- Over-fragmenting into excessive tiny functions -- Mixing abstraction levels within one function -- Generating functions that modify global state unexpectedly - ---- - -## Summary - -Readable code is: -- **Self-explanatory** through naming -- **Consistent** in style and structure -- **Minimal in comments** - code speaks for itself -- **Small and focused** - easy to understand at a glance - -When writing or reviewing code, ask: -- Can I understand this without the author present? -- Would I want to debug this at 2 AM? -- Does this follow the team's conventions? diff --git a/skills/engineering-discipline/references/patterns/simplicity.md b/skills/engineering-discipline/references/patterns/simplicity.md deleted file mode 100755 index 54b8d1d..0000000 --- a/skills/engineering-discipline/references/patterns/simplicity.md +++ /dev/null @@ -1,279 +0,0 @@ -# Simplicity & Efficiency Principles - -## KISS (Keep It Simple, Stupid) - -**Definition:** Use the simplest solution that solves the problem. Avoid unnecessary complexity, over-engineering, or premature optimization. - -**Supported by:** *Clean Code*, *The Pragmatic Programmer* - -### Examples - -```javascript -// Bad - Unnecessary abstraction -class SingleValueContainer { - constructor(value) { - this.values = [value]; - } - add(value) { - this.values.push(value); - } - getValue() { - return this.values[0]; - } -} - -// Good - Use built-in features -let numbers = [5]; -numbers.push(7); -let firstNumber = numbers[0]; -``` - -```python -# Bad - Over-complicated -def is_even(n): - return True if n % 2 == 0 else False - -# Good - Direct and clear -def is_even(n): - return n % 2 == 0 -``` - -### Do -- Use language built-ins and standard libraries -- Choose clear, direct solutions -- Optimize only when profiling shows need -- Prefer composition of simple parts -- Write code for the current requirement - -### Don't -- Create abstractions without clear benefit -- Add complexity for hypothetical future needs -- Use clever tricks that obscure intent -- Build custom solutions when standard ones exist - -### AI Pitfalls -- Using classes or design patterns unnecessarily -- Creating abstractions for single-use code -- Over-complicating simple conditional logic -- Generating enterprise patterns for simple scripts - ---- - -## DRY (Don't Repeat Yourself) - -**Definition:** Eliminate duplicated code and logic. Every piece of knowledge should have a single, authoritative representation. - -**Supported by:** *The Pragmatic Programmer*, *Clean Code* - -### Examples - -```python -# Bad - Duplicated logic -def circle_area(radius): - return 3.14159 * radius * radius - -def quarter_circle_area(radius): - return 3.14159 * radius * radius / 4 - -def sphere_volume(radius): - return (4/3) * 3.14159 * radius * radius * radius - -# Good - Extracted constant and reused logic -PI = 3.14159 - -def circle_area(radius): - return PI * radius ** 2 - -def quarter_circle_area(radius): - return circle_area(radius) / 4 - -def sphere_volume(radius): - return (4/3) * PI * radius ** 3 -``` - -```javascript -// Bad - Repeated validation -function createUser(name, email) { - if (!email.includes('@')) throw Error('Invalid email'); - // ... -} - -function updateEmail(userId, email) { - if (!email.includes('@')) throw Error('Invalid email'); - // ... -} - -// Good - Extracted validation -function validateEmail(email) { - if (!email.includes('@')) { - throw Error('Invalid email'); - } -} - -function createUser(name, email) { - validateEmail(email); - // ... -} - -function updateEmail(userId, email) { - validateEmail(email); - // ... -} -``` - -### Do -- Extract common logic into functions -- Use constants for repeated values -- Abstract similar patterns -- Share code across modules appropriately -- Keep abstractions at the right level - -### Don't -- Copy-paste code blocks -- Duplicate business rules -- Repeat validation logic -- Hard-code the same values multiple times -- Create premature abstractions (see Rule of Three) - -### Rule of Three -Wait until you see duplication **three times** before abstracting. Two instances might be coincidental; three suggests a pattern. - -### AI Pitfalls -- Producing repeated code structures from pattern prediction -- Duplicating similar functions instead of parameterizing -- Repeating validation or error handling logic -- Not recognizing when to extract shared utilities - ---- - -## YAGNI (You Aren't Gonna Need It) - -**Definition:** Don't implement features or infrastructure until you actually need them. Avoid speculative development. - -**Supported by:** *The Pragmatic Programmer*, Extreme Programming (XP) - -### Examples - -```python -# Bad - Building for hypothetical futures -def process_order(order): - prepare_invoice(order) - apply_future_discount_system(order) # Not used yet - schedule_loyalty_rewards(order) # Not needed now - prepare_for_blockchain_audit(order) # Speculative - -# Good - Only what's needed now -def process_order(order): - prepare_invoice(order) - charge_payment(order) - ship_order(order) -``` - -```javascript -// Bad - Over-engineered configuration -class DatabaseConfig { - constructor() { - this.primaryHost = 'localhost'; - this.replicaHosts = []; // Not using replication - this.shardingStrategy = null; // Not sharding - this.cacheLayer = null; // No cache yet - } -} - -// Good - Current requirements only -class DatabaseConfig { - constructor(host) { - this.host = host; - } -} -``` - -### Do -- Write code for current, known requirements -- Add features when they're actually requested -- Keep infrastructure minimal -- Refactor when new needs emerge -- Trust that future changes will be manageable - -### Don't -- Build "just in case" features -- Create extensibility points without use cases -- Add configuration for hypothetical scenarios -- Implement features before they're specified - -### AI Pitfalls -- Generating code for unspecified future features -- Adding unnecessary configuration options -- Creating extensibility hooks without current need -- Building infrastructure beyond MVP scope - ---- - -## Premature Optimization - -**Definition:** Don't optimize until you have evidence of a performance problem. Clarity and correctness come first. - -**Supported by:** *The Pragmatic Programmer*, Donald Knuth's famous quote - -> "Premature optimization is the root of all evil" - Donald Knuth - -### Examples - -```python -# Bad - Premature optimization -def find_user(user_id): - # Using complex caching before knowing if it's needed - cache_key = f"user:{user_id}:v2" - if cache_key in cache: - return deserialize(decompress(cache[cache_key])) - user = db.query(user_id) - cache[cache_key] = compress(serialize(user)) - return user - -# Good - Start simple, optimize if needed -def find_user(user_id): - return db.query(user_id) - -# Later, if profiling shows this is slow: -def find_user(user_id): - cached = cache.get(f"user:{user_id}") - if cached: - return cached - user = db.query(user_id) - cache.set(f"user:{user_id}", user) - return user -``` - -### Do -- Write clear, correct code first -- Profile before optimizing -- Optimize only proven bottlenecks -- Measure impact of optimizations -- Document why optimizations were made - -### Don't -- Sacrifice readability for unmeasured performance -- Optimize without profiling data -- Use complex algorithms for small datasets -- Cache everything "just in case" - -### AI Pitfalls -- Adding caching layers without justification -- Using complex data structures for simple cases -- Micro-optimizing at the expense of clarity - ---- - -## Summary - -Simple code is: -- **Direct** - solves the problem at hand -- **DRY** - has no unnecessary duplication -- **Minimal** - contains only what's needed now -- **Clear** - prioritizes readability over premature optimization - -When writing code, ask: -- Is this the simplest approach that works? -- Am I repeating myself? -- Do I actually need this now? -- Am I optimizing based on evidence? diff --git a/skills/engineering-discipline/references/patterns/testing.md b/skills/engineering-discipline/references/patterns/testing.md deleted file mode 100755 index 6ddc615..0000000 --- a/skills/engineering-discipline/references/patterns/testing.md +++ /dev/null @@ -1,309 +0,0 @@ -# Testing & Quality Principles - -## Write Automated Tests Early - -**Definition:** Use tests to guide design, prevent regressions, and validate behavior. Testing should be part of the development process, not an afterthought. - -**Supported by:** *Refactoring*, *The Pragmatic Programmer*, Test-Driven Development (TDD) - -### Examples - -```python -# Test-first approach -def test_calculate_discount(): - # Arrange - price = 100 - discount_percent = 10 - - # Act - result = calculate_discount(price, discount_percent) - - # Assert - assert result == 90 - -def calculate_discount(price, discount_percent): - return price * (1 - discount_percent / 100) -``` - -```python -# Test edge cases -def test_user_age_validation(): - assert is_adult(18) == True - assert is_adult(17) == False - assert is_adult(0) == False - assert is_adult(150) == True # No upper bound check yet - -def is_adult(age): - return age >= 18 -``` - -### Do -- Write tests before or alongside code -- Test edge cases and boundary conditions -- Test business logic thoroughly -- Use descriptive test names -- Keep tests fast and independent -- Use test fixtures and setup/teardown appropriately - -### Don't -- Skip tests for "simple" code -- Test implementation details instead of behavior -- Write brittle tests that break on refactoring -- Ignore failing tests -- Write tests that depend on external state - -### AI Pitfalls -- Missing tests entirely -- Writing overly broad test functions -- Not testing edge cases or error paths -- Creating tests with vague assertions - ---- - -## One Assert Per Test (Focus) - -**Definition:** Keep tests focused on a single behavior or scenario. This makes failures easy to diagnose. - -**Supported by:** *Clean Code*, TDD best practices - -### Examples - -```python -# Bad - Multiple unrelated assertions -def test_user(): - user = User("Alice", 25) - assert user.name == "Alice" - assert user.age == 25 - assert user.is_adult() == True - assert user.can_vote() == True - assert user.get_greeting() == "Hello, Alice" - -# Good - Focused tests -def test_user_name_is_set_correctly(): - user = User("Alice", 25) - assert user.name == "Alice" - -def test_user_age_is_set_correctly(): - user = User("Alice", 25) - assert user.age == 25 - -def test_user_is_adult_when_age_18_or_above(): - user = User("Alice", 25) - assert user.is_adult() == True - -def test_user_is_not_adult_when_age_below_18(): - user = User("Bob", 17) - assert user.is_adult() == False -``` - -### Guideline Exceptions - -Multiple assertions are acceptable when: -- Testing object state after a single operation -- Verifying related properties of one concept -- Testing list/collection contents - -```python -# Acceptable - Related assertions on same concept -def test_order_creation(): - order = Order(items=[item1, item2]) - assert len(order.items) == 2 - assert order.total == 50.00 - assert order.status == OrderStatus.PENDING -``` - -### Do -- Use test names to describe expected behavior -- Group related tests in test classes -- Use parametrized tests for similar scenarios -- Make test intent crystal clear - -### Don't -- Group many checks together -- Test multiple behaviors in one test -- Create generic test names like `test_user()` - -### AI Pitfalls -- Combining multiple assertions in one test function -- Creating catch-all test functions -- Not using descriptive test names - ---- - -## Test Coverage Guidelines - -**Definition:** Aim for meaningful coverage of critical paths, not just high percentages. Focus on business logic, edge cases, and failure modes. - -### What to Test - -**High Priority:** -- Business logic and algorithms -- Input validation and error handling -- State transitions -- Integration points -- Security-critical code - -**Medium Priority:** -- Data transformations -- Configuration handling -- User-facing features - -**Low Priority:** -- Trivial getters/setters -- Framework-generated code -- External library wrappers - -### Coverage Anti-Patterns - -```python -# Bad - Testing for coverage, not correctness -def test_add(): - add(2, 3) # No assertion! - -# Good - Test actual behavior -def test_add_returns_sum(): - result = add(2, 3) - assert result == 5 -``` - -### Do -- Focus on critical code paths -- Test public interfaces, not private methods -- Use code coverage as a guide, not a goal -- Write tests that catch real bugs - -### Don't -- Aim for 100% coverage blindly -- Test trivial code just for metrics -- Ignore untested critical paths - ---- - -## Test Pyramid - -**Definition:** Balance different types of tests - many unit tests, fewer integration tests, even fewer end-to-end tests. - -``` - /\ - / \ Few E2E tests (slow, brittle) - /____\ - / \ More integration tests (moderate speed) - /________\ - / \ Many unit tests (fast, isolated) -``` - -### Unit Tests -- Test individual functions/classes in isolation -- Fast execution (milliseconds) -- Mock external dependencies -- High count (hundreds to thousands) - -### Integration Tests -- Test interactions between components -- Moderate speed (seconds) -- Use real dependencies where practical -- Medium count (dozens to hundreds) - -### End-to-End Tests -- Test complete user workflows -- Slow execution (minutes) -- Test through actual UI/API -- Low count (handful to dozens) - -### Do -- Rely primarily on unit tests -- Use integration tests for critical paths -- Reserve E2E tests for key user journeys - -### Don't -- Over-rely on E2E tests -- Skip unit tests in favor of integration tests -- Test everything through the UI - ---- - -## Test Quality Checklist - -Good tests are: - -- **Fast** - Run in milliseconds -- **Isolated** - No shared state or order dependency -- **Repeatable** - Same result every time -- **Self-validating** - Pass/fail is clear -- **Timely** - Written close to code - -### Do -- Use test fixtures for setup -- Clean up resources in teardown -- Use meaningful test data -- Avoid test interdependence - -### Don't -- Rely on external services without mocks -- Use production data -- Write flaky tests -- Commit commented-out tests - ---- - -## Mocking & Test Doubles - -**Definition:** Use test doubles (mocks, stubs, fakes) to isolate the code under test. - -### Types of Test Doubles - -**Stub** - Returns canned responses -```python -class StubPaymentGateway: - def charge(self, amount): - return {"status": "success", "transaction_id": "123"} -``` - -**Mock** - Verifies interactions -```python -def test_order_charges_payment(): - mock_gateway = Mock() - processor = OrderProcessor(mock_gateway) - processor.process(order) - mock_gateway.charge.assert_called_once_with(100.00) -``` - -**Fake** - Simplified working implementation -```python -class FakeDatabase: - def __init__(self): - self.data = {} - - def save(self, key, value): - self.data[key] = value - - def get(self, key): - return self.data.get(key) -``` - -### Do -- Mock external dependencies (APIs, databases, file systems) -- Use dependency injection to enable mocking -- Verify behavior, not implementation -- Keep mocks simple - -### Don't -- Mock everything (test real code when possible) -- Create complex mock hierarchies -- Over-specify mock expectations - ---- - -## Summary - -Effective testing: -- **Guides design** - Tests drive better architecture -- **Prevents regressions** - Catches bugs early -- **Documents behavior** - Tests are living specifications -- **Enables refactoring** - Confidence to improve code - -When writing tests, ask: -- Does this test verify actual behavior? -- Will this test catch real bugs? -- Is this test easy to understand and maintain? -- Can this test run quickly and reliably? diff --git a/skills/forge-plan/SKILL.md b/skills/forge-plan/SKILL.md index a08511e..0d29bd8 100644 --- a/skills/forge-plan/SKILL.md +++ b/skills/forge-plan/SKILL.md @@ -141,7 +141,7 @@ Then offer: > > 1. **Autonomous** - execute all tasks end-to-end without pausing. Tests, reviews, ship-gate run automatically. Only stops on failure. > 2. **Subagent-driven** (`hyperstack:subagent-ops`) - fresh agent per task, automated two-stage review between tasks. -> 3. **Inline with checkpoints** (`hyperstack:engineering-discipline`) - execute tasks in this session, pause for human review at phase gates. +> 3. **Inline with checkpoints** (`hyperstack:best-practices`) - execute tasks in this session, pause for human review at phase gates. > > Which approach?" @@ -183,7 +183,7 @@ Every API call, prop name, hook signature, or library pattern must trace to an M - **Requires (backend/infra):** `hyperstack:blueprint` approved design - **Requires (visual/UX):** `hyperstack:designer` approved DESIGN.md -- **Executes via:** Autonomous mode, `hyperstack:subagent-ops`, or `hyperstack:engineering-discipline` +- **Executes via:** Autonomous mode, `hyperstack:subagent-ops`, or `hyperstack:best-practices` - **Completes via:** `hyperstack:ship-gate` β†’ `hyperstack:deliver` ## Reverse Escalation @@ -221,14 +221,14 @@ blueprint β†’ forge-plan (THIS) β†’ [execution] β†’ ship-gate β†’ deliver **Execution handoff (user chooses):** - `autonomous-mode` β†’ full auto end-to-end - `subagent-ops` β†’ fresh agent per task -- `engineering-discipline` β†’ manual with checkpoints +- `best-practices` β†’ manual with checkpoints ### Upstream Dependencies - `blueprint` β†’ approved architecture note (backend/infra) - `designer` β†’ approved DESIGN.md (visual/UX) ### Downstream Consumers -- `autonomous-mode` | `subagent-ops` | `engineering-discipline` β†’ executes plan +- `autonomous-mode` | `subagent-ops` | `best-practices` β†’ executes plan - `shadcn-expert` β†’ if Q11b=shadcn, per-component guidance - `worktree-isolation` β†’ clean workspace before execution diff --git a/skills/hyperstack/SKILL.md b/skills/hyperstack/SKILL.md index 00d608e..8f19df0 100644 --- a/skills/hyperstack/SKILL.md +++ b/skills/hyperstack/SKILL.md @@ -133,7 +133,7 @@ This is non-negotiable. Silent skill invocations are invisible to the user and c | `hyperstack:designer` | Before any visual/UX work - produces DESIGN.md contract | **HARD GATE** | | `hyperstack:forge-plan` | After design approval - MCP-verified implementation plan | Requires approved design | | `hyperstack:run-plan` | Have an existing plan - validate then execute | Requires plan | -| `hyperstack:engineering-discipline` | During execution - Senior SDE phase gates | Phase gates | +| `hyperstack:best-practices` | During execution - Senior SDE phase gates | Phase gates | | `hyperstack:ship-gate` | Before any completion claim - evidence required | **HARD GATE** | | `hyperstack:deliver` | After all tasks complete - final verification and delivery | Gate | @@ -155,7 +155,7 @@ This is non-negotiable. Silent skill invocations are invisible to the user and c | `hyperstack:designer` | Before any visual/UX work - produces DESIGN.md | | `hyperstack:debug-discipline` | Any bug or unexpected behaviour - root cause first | | `hyperstack:behaviour-analysis` | UI/UX audits, state machine correctness | -| `hyperstack:design-patterns-skill` | Selecting the right abstraction or design pattern | +| `hyperstack:best-practices` | Selecting the right abstraction or design pattern, coupling limits, review and ops rules | | `hyperstack:security-review` | OWASP audits, API and infrastructure security | | `hyperstack:readme-writer` | Evidence-based documentation | | `hyperstack:codemode` | Understanding an unfamiliar codebase before reviewing or changing it - 7-phase context load | @@ -174,7 +174,7 @@ Existing: run-plan ─── β”‚ β”œβ†’ autonomous-mode (full auto, stops only on failure) β”œβ†’ subagent-ops (fresh agent per task, two-stage review) - β””β†’ engineering-discipline (manual, human checkpoints) + β””β†’ best-practices (manual, human checkpoints) Before execution: worktree-isolation (clean workspace) Debugging: debug-discipline β†’ parallel-dispatch (if independent failures) diff --git a/skills/optimizer/SKILL.md b/skills/optimizer/SKILL.md index be61f2f..12dcf01 100644 --- a/skills/optimizer/SKILL.md +++ b/skills/optimizer/SKILL.md @@ -81,7 +81,7 @@ Gated by Coding Law 0 / YAGNI. **Do not optimize what does not need it.** A naiv | Connection | Wiring | |---|---| | Gated by | Coding Law 0 / YAGNI | -| Deepens | `engineering-discipline` Step 8 (negative doubt: "try a better alternative") | +| Deepens | `best-practices` Step 8 (negative doubt: "try a better alternative") | | Adds a dimension to | `code-review` - "right algorithm + complexity?" | | Hands off to | `golang_*` / `rust_*` / `react_*` for idiomatic implementation | | Verifies via | web search (catalog ships no code - algorithms are stable, specifics get checked) | diff --git a/skills/parallel-dispatch/SKILL.md b/skills/parallel-dispatch/SKILL.md index 69c5e5d..b7b87d2 100644 --- a/skills/parallel-dispatch/SKILL.md +++ b/skills/parallel-dispatch/SKILL.md @@ -111,7 +111,7 @@ Return: Summary of root cause and changes made. **Used when multiple independent failures:** ``` -[autonomous-mode | subagent-ops | engineering-discipline] β†’ parallel-dispatch (THIS) +[autonomous-mode | subagent-ops | best-practices] β†’ parallel-dispatch (THIS) ↓ [concurrent agent investigations] ↓ diff --git a/skills/run-plan/SKILL.md b/skills/run-plan/SKILL.md index efebd72..b2b6222 100644 --- a/skills/run-plan/SKILL.md +++ b/skills/run-plan/SKILL.md @@ -73,7 +73,7 @@ Wait for user's decision. No issues β†’ create task list and state: -> "Plan validated. Starting execution with `hyperstack:engineering-discipline`." +> "Plan validated. Starting execution with `hyperstack:best-practices`." ### Step 5: Execute @@ -105,7 +105,7 @@ All tasks marked complete β†’ invoke `hyperstack:deliver`. ## Integration - **Alternative entry:** No plan exists β†’ `hyperstack:blueprint` β†’ `hyperstack:forge-plan` first -- **Execution:** Uses `hyperstack:engineering-discipline` phase gates per task +- **Execution:** Uses `hyperstack:best-practices` phase gates per task - **Per-task gate:** `hyperstack:ship-gate` before marking each task complete - **Terminal:** `hyperstack:deliver` after all tasks complete @@ -116,7 +116,7 @@ All tasks marked complete β†’ invoke `hyperstack:deliver`. **Alternative entry (existing plan):** ``` -run-plan (THIS) β†’ [autonomous-mode | subagent-ops | engineering-discipline] β†’ ship-gate β†’ deliver +run-plan (THIS) β†’ [autonomous-mode | subagent-ops | best-practices] β†’ ship-gate β†’ deliver ↓ [MCP validation] ``` @@ -131,7 +131,7 @@ run-plan β†’ [execution] (existing plan) - User-provided plan (external or previous session) ### Downstream Consumers -- `autonomous-mode` | `subagent-ops` | `engineering-discipline` β†’ executes validated plan +- `autonomous-mode` | `subagent-ops` | `best-practices` β†’ executes validated plan - `deliver` β†’ final delivery ### Escalation Paths diff --git a/skills/ship-gate/SKILL.md b/skills/ship-gate/SKILL.md index c7d965d..be61b95 100644 --- a/skills/ship-gate/SKILL.md +++ b/skills/ship-gate/SKILL.md @@ -173,7 +173,7 @@ Run this skill before: - Reporting status to the user - Claiming a bug is fixed - Handing work off to a subagent or reviewer -- Transitioning between phases in `hyperstack:engineering-discipline` +- Transitioning between phases in `hyperstack:best-practices` ## Lifecycle Integration @@ -182,7 +182,7 @@ Run this skill before: **All execution paths converge here:** ``` -[autonomous-mode | subagent-ops | engineering-discipline] β†’ ship-gate (THIS) β†’ deliver +[autonomous-mode | subagent-ops | best-practices] β†’ ship-gate (THIS) β†’ deliver ``` **DESIGN.md compliance (visual/UX only):** @@ -193,7 +193,7 @@ ship-gate β†’ designer_verify_implementation β†’ [PASS β†’ deliver | FAIL β†’ fi ### Upstream Dependencies - `autonomous-mode` β†’ final gate before delivery - `subagent-ops` β†’ final gate after all tasks -- `engineering-discipline` β†’ per-task + final gate +- `best-practices` β†’ per-task + final gate ### Downstream Consumers - `deliver` β†’ only proceeds if ship-gate passes diff --git a/skills/test-first/SKILL.md b/skills/test-first/SKILL.md index 71e0a1e..ba86452 100644 --- a/skills/test-first/SKILL.md +++ b/skills/test-first/SKILL.md @@ -122,7 +122,7 @@ Can't check all boxes? β†’ You skipped TDD. Start over. ## Integration -- **Invoked by:** `hyperstack:engineering-discipline` (Step 7), `hyperstack:forge-plan` (task steps), `hyperstack:subagent-ops` (implementer subagents) +- **Invoked by:** `hyperstack:best-practices` (Step 7), `hyperstack:forge-plan` (task steps), `hyperstack:subagent-ops` (implementer subagents) - **Pairs with:** `hyperstack:debug-discipline` (write failing test after root cause found) - **Verified by:** `hyperstack:ship-gate` (checks test evidence before completion claims) @@ -133,7 +133,7 @@ Can't check all boxes? β†’ You skipped TDD. Start over. **Used inline during all implementation:** ``` -[autonomous-mode | subagent-ops | engineering-discipline] β†’ test-first (THIS) +[autonomous-mode | subagent-ops | best-practices] β†’ test-first (THIS) ↓ [red-green-refactor per task] ``` diff --git a/skills/worktree-isolation/SKILL.md b/skills/worktree-isolation/SKILL.md index 37a2e5d..c4ea84e 100644 --- a/skills/worktree-isolation/SKILL.md +++ b/skills/worktree-isolation/SKILL.md @@ -307,7 +307,7 @@ git worktree remove **Pre-flight for all execution modes:** ``` -forge-plan -> worktree-isolation (THIS) -> [autonomous-mode | subagent-ops | engineering-discipline] +forge-plan -> worktree-isolation (THIS) -> [autonomous-mode | subagent-ops | best-practices] ``` **Cleanup after delivery:** diff --git a/src/internal/context-compiler.ts b/src/internal/context-compiler.ts index 847536a..287403a 100644 --- a/src/internal/context-compiler.ts +++ b/src/internal/context-compiler.ts @@ -38,7 +38,7 @@ const REQUIRED_BOOTSTRAP_MARKERS = [ "run-plan", "autonomous-mode", "subagent-ops", - "engineering-discipline", + "best-practices", "worktree-isolation", "debug-discipline", "parallel-dispatch", diff --git a/summary.md b/summary.md index 341133a..5fd274e 100644 --- a/summary.md +++ b/summary.md @@ -70,8 +70,8 @@ Hyperstack uses internal roles to manage complexity. These roles are **internal ### 9. The Skill System (21 skills, 3 categories) Every skill has a `category:` frontmatter field. The index at `skills/INDEX.md` is auto-generated from frontmatter by `bash scripts/generate-skills-index.sh`. -- **Core (13):** blueprint, forge-plan, run-plan, engineering-discipline, ship-gate, deliver, test-first, debug-discipline, code-review, autonomous-mode, subagent-ops, parallel-dispatch, worktree-isolation -- **Domain (6):** designer, shadcn-expert, behaviour-analysis, security-review, design-patterns-skill, readme-writer +- **Core (13):** blueprint, forge-plan, run-plan, best-practices, ship-gate, deliver, test-first, debug-discipline, code-review, autonomous-mode, subagent-ops, parallel-dispatch, worktree-isolation +- **Domain (6):** designer, shadcn-expert, behaviour-analysis, security-review, readme-writer, python-pro-coder, react-pro-coder - **Meta (2):** hyperstack, testing-skills ### 10. Skill Testing Discipline (`testing-skills`) @@ -116,7 +116,7 @@ Every skill references its upstream and downstream edges explicitly. Eleven plugins, seventy-nine tools, twenty-one skills, and two internal agents (`hyper` and `website-builder`). The SessionStart hook is wired. The adversarial enforcement is in place. The designer pipeline works end-to-end (verified via test harness). shadcn is integrated as an optional choice. ### Remaining work -- More pressure-test scenarios for gate skills (forge-plan, engineering-discipline, behaviour-analysis, test-first) +- More pressure-test scenarios for gate skills (forge-plan, best-practices, behaviour-analysis, test-first) - Additional backend-focused loops (API-build workflow, security-audit loop) - End-to-end integration tests beyond the designer pipeline - More curated components in the shadcn plugin (currently 4: Button, Dialog, Field, Select)