From ed6f3fcb743d34d8e54225c4d2829f558c1144ac Mon Sep 17 00:00:00 2001 From: main Date: Mon, 25 May 2026 02:13:20 -0400 Subject: Add style-doctrine skill --- style-doctrine/references/python.md | 15 +++++++++++++++ style-doctrine/references/rust.md | 13 +++++++++++++ style-doctrine/references/universal.md | 23 +++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 style-doctrine/references/python.md create mode 100644 style-doctrine/references/rust.md create mode 100644 style-doctrine/references/universal.md (limited to 'style-doctrine/references') diff --git a/style-doctrine/references/python.md b/style-doctrine/references/python.md new file mode 100644 index 0000000..756827f --- /dev/null +++ b/style-doctrine/references/python.md @@ -0,0 +1,15 @@ +# Python Style Doctrine + +Python must be written as if it were statically compiled. The target is not "Pythonic" ease; the target is statically legible, brutally lean code that strong agents and type checkers can reason about. Dynamic affordances are acceptable only when they compress real structure without dissolving it. + +Use strict typing to the hilt. Ban ambient `Any` in core code; quarantine untyped third-party and IO surfaces behind typed façades. Use `Protocol`, `NewType`, `Literal`, `Final`, `TypeAlias`, `Self`, generics, overloads, `Never`/`assert_never`, `TypeGuard`/`TypeIs`, `dataclass(slots=True, frozen=True)`, enums, and ADT-like unions aggressively. If a primitive carries domain semantics, give it static shape. Prefer total constructors and narrow parser boundaries over repeated checks. + +Defensive programming is a bloating disease. Do not sprinkle `.get` defaults with no honest semantics, `None` guards proven impossible by construction, catch-and-limp wrappers, optional bags, or runtime validation theater. Fail early, loudly, and close to the violated invariant. Inside already-typed code, trust the typed representation. + +Prefer algebraic, compositional Python: pure transforms, `match`/`case`, table-driven dispatch, protocols, higher-order functions, compact comprehensions, and small domain modules. Decorators and metaprogramming are legitimate when they reduce call-site noise or enforce uniformity. Operator overloading is encouraged when the operation has the expected algebraic meaning. + +Bias toward token and line count reduction when it increases semantic density. Delete compatibility husks, duplicate builders, scattered casts, repeated fixture factories, parallel dict/list structures, ceremonial wrappers, and helper functions whose only purpose is surviving weak types. A compact typed representation beats ten "safe" branches synchronized by anxiety. + +Default to zero backward compatibility with old Python versions. If dependency constraints do not forbid it and the review is global in scope, upgrade to the latest viable Python and modernize syntax. If it can be upgraded, it should be. + +Astral tooling is mandatory doctrine: `uv`, `ruff`, and `ty` should be present unless the project has an explicit incompatible reason. `pyproject.toml` is canonical metadata, `uv.lock` should be checked in for projects, `uv run` is the execution primitive, Ruff formatting is mandatory, Ruff modernization rules should be used, and `ty check` is part of the build contract. Lint strictly by default and carve out only low-value human-readability theater with explicit intent. diff --git a/style-doctrine/references/rust.md b/style-doctrine/references/rust.md new file mode 100644 index 0000000..c45874e --- /dev/null +++ b/style-doctrine/references/rust.md @@ -0,0 +1,13 @@ +# Rust Style Doctrine + +This doctrine deliberately rejects several pieces of conventional engineering wisdom. Do not silently translate it back into "clear, simple, approachable Rust." Where it conflicts with common advice, the conflict is usually intentional: agent-maintained code prefers static truth, compact representation, and powerful abstraction over novice readability, defensive ceremony, and lowest-common-denominator style. Notice the inversion and obey it. + +Rust code is a typed semantic artifact for agents, compilers, analyzers, and refactoring tools. Optimize for correctness, static structure, token economy, and intentional shape before ordinary human approachability. The code should look designed top-down around the domain, not accreted around incidents. Delete dead paths, compatibility husks, redundant layers, speculative knobs, ceremonial wrappers, and explanatory scaffolding. Hot sites should be small and exact; cold files may contain large definitions, tables, macros, derives, and helper machinery if they make the live surface leaner. + +Make illegal states unrepresentable. Stringly closed worlds, ad-hoc tuples, bool flags, walls of optionals, and folklore invariants are design failures. If a value has semantics, give it a domain type. Use enums, newtypes, structured IDs, typestates, phase-separated types, traits, generics, const generics, and total transformations to move truth into the type system. Prefer algebraic modeling, pattern matching, iterator algebra, composable APIs, and higher-order transforms. A good module should feel like a small calculus: constrained inputs, explicit states, predictable outputs. + +Overabstraction is not a crime. Weak abstraction is. The usual danger in agentic code is not that the model invents PLT machinery too powerful to follow; it is that it spills simple concrete structs, flags, guards, and named intermediates until the real invariant is smeared across the context window. Advanced math is often clearer to agents than bulk mundane plumbing. Trade shallow readability for structural correctness when the abstraction genuinely compresses the domain. DRY is stronger than YAGNI. Prefer one precise abstraction over five simple repetitions that must be kept mentally synchronized. + +Use the full language. Macros are first-class tools for uniformity, token economy, and invariant enforcement. Operator overloading is encouraged when the operation has the expected algebraic meaning. Prefer unqualified imports at call sites: import the symbol you mean, then use it bare. Wildcard imports are acceptable and often desirable when they make a dense local vocabulary cheap; real name-resolution ambiguity remains a compiler problem, but lint taste should not tax import sites for token economy. Prefer compact, domain-faithful names, including mathematical names, non-camel aliases, and Unicode identifiers when they match standard notation and reduce ambiguity. Destructure aggressively when it removes noise. Do not write Rust as Python with types sprinkled on top. + +Fail hard unless recovery is real. `Result` is for recoverable failure, not ritual anxiety; impossible states should be impossible, and irrecoverable states should panic early with domain context. Formatting, linting, type checking, dependency pruning, and semantic navigation are part of the build contract. Run `cargo fmt` after meaningful edits. Deny strict Clippy by default, including pedantic lints, with explicit recorded exceptions for low-value noise. Use rust-analyzer before textual search for definitions, references, diagnostics, and refactors. The machine should be austere, analyzable, and exact. diff --git a/style-doctrine/references/universal.md b/style-doctrine/references/universal.md new file mode 100644 index 0000000..07b3709 --- /dev/null +++ b/style-doctrine/references/universal.md @@ -0,0 +1,23 @@ +# Universal Style Doctrine + +This doctrine is normative unless a project explicitly declares a different local policy. Language-specific guides may sharpen it, but this is the core intent. + +The primary consumer of code is agent tooling: compilers, analyzers, refactoring engines, and very high-capacity models. Optimize for semantic precision, static analyzability, deterministic structure, runtime efficiency, and token economy. Human accessibility in the classic onboarding sense is not a design objective. Code should be intelligible to strong agents and exact tools, not diluted for timid readers. + +Design must look intentional rather than accreted. Keep a top-down shape that matches what the system is. Refactor early and aggressively. Delete dead paths, compatibility husks, redundant abstractions, ceremonial wrappers, explanatory scaffolding, and contingent glue. If a feature leaves the system looking patched-on rather than designed, reshape the system. + +Illegal states must not be representable. Treat "just a dict", "just a string", "just a bool flag", "just an optional", and "just a tuple" as design odors. If a value has semantics, give it a domain shape. Encode invariants structurally: sum types, newtypes, typestates, phase-separated types, structured IDs, total constructors, closed universes, and compositional primitives. The type system is the first line of runtime performance and correctness. + +Prefer algebraic modeling. Use ADT-like structures, pattern matching, total transformations, iterator algebra, higher-order functions, and composable APIs. A good module feels like a small calculus: constrained inputs, explicit states, predictable outputs. Advanced abstraction is not suspicious; weak abstraction is. Mathematical structure is usually clearer to agents than smeared mundane plumbing. + +DRY is stronger than YAGNI. Overabstraction is not a crime when it compresses a real invariant or repeated skeleton. Prefer one precise abstraction over five "simple" repetitions that must be synchronized by memory. Hot sites should be small and exact; cold files may contain large definitions, tables, macros, derives, codegen, and helper machinery when they make live call sites lean. + +Use the full language. Powerful, modern, advanced, or experimental features are welcome when they improve correctness, performance, uniformity, or token density. Metaprogramming is first-class: macros, decorators, derives, code generation, type-level programming, and helper tables are tools, not embarrassments. Operator overloading is encouraged when the operation has the expected algebraic meaning. + +Names should be compact and domain-faithful. Prefer terse, precise, math-oriented names when they reduce semantic distance. Unicode identifiers are acceptable where the language and tooling support them and the notation is standard. Prefer imports that make call sites small and direct; qualify only when namespacing earns its keep. + +Fail hard unless recovery is real. Defensive programming is a bloating disease. Do not preserve doomed control paths with dummy defaults, nullable theater, catch-and-limp wrappers, or optional bags. Make impossible states impossible; crash early and loudly when an irrecoverable contradiction is detected. Resilience cores must identify themselves explicitly. + +Use libraries and dependencies aggressively when they buy correctness, performance, or deletion of local machinery. NIH is usually decay. Backward compatibility, shims, and parallel old/new paths are not defaults; they require an explicit reason. + +Tooling posture is strict. Formatting, linting, type checking, dependency pruning, and semantic navigation are part of the build contract. Prefer language-server and type-driven navigation before textual search. Write code as if it will be transformed by tools first and only incidentally read by humans. -- cgit v1.2.3