diff --git a/.agents/skills/backend-guidance/SKILL.md b/.agents/skills/backend-guidance/SKILL.md index bf05fb2..d58f0d0 100644 --- a/.agents/skills/backend-guidance/SKILL.md +++ b/.agents/skills/backend-guidance/SKILL.md @@ -5,10 +5,15 @@ description: Overlay for server-side networked code — HTTP handlers, gRPC serv # Backend Guidance -Read `AGENTS.md` first. This is a composable overlay, not a standalone workflow. +This is a composable overlay, not a standalone workflow. Use alongside the repo's implementation skill (e.g. **coding-guidance-cpp**, **project-core-dev**) when the change touches backend code. +Use this as the thin default backend overlay for ordinary backend work. +If the task includes service-boundary refactors, repository or transaction work, +queue or webhook reliability, stronger testing expectations, or explicit +trust-boundary hardening, prefer `backend-systems-guidance`. + ## When to use The repo has server-side networked code: HTTP route handlers, gRPC service diff --git a/.agents/skills/backend-systems-guidance/SKILL.md b/.agents/skills/backend-systems-guidance/SKILL.md new file mode 100644 index 0000000..eca8a1c --- /dev/null +++ b/.agents/skills/backend-systems-guidance/SKILL.md @@ -0,0 +1,131 @@ +--- +name: backend-systems-guidance +description: Canonical overlay for server-side networked code that needs stronger architecture, testing, reliability, and security discipline. Use alongside the repo's implementation skill when implementing or reviewing backend services, APIs, middleware, queues, repositories, or backend refactors. +--- + +# Backend Systems Guidance + +This is a composable overlay, not a standalone workflow. +Use alongside the repo's implementation skill when the change touches backend +code. + +This is the canonical backend overlay in this repo. +It extends the thin baseline `backend-guidance` overlay with stronger guidance +for non-trivial service boundaries, repositories, reliability, and trust +boundaries. + +Prefer it over `backend-guidance` when the task includes new endpoints or +consumers, multi-layer refactors, repository or transaction work, auth or +trust-boundary logic, or backend review that needs explicit testing and +reliability checks. + +Use the bundled references only when needed: + +- [references/trigger-evals.md](references/trigger-evals.md) for lightweight + prompt checks when revising the trigger or scope + +## When to use + +- the repo has server-side networked code such as HTTP handlers, gRPC methods, + webhooks, queue consumers, or message producers +- the task adds or reshapes routes, controllers, services, repositories, + middleware, or request-processing boundaries +- the task changes auth, authorization, validation, idempotency, retries, + external requests, caching, or observability +- the task needs backend review beyond basic handler thinness, especially for + security, data access, or missing tests + +## Not for + +- HTTP client code, CLI tooling, offline batch scripts, or data pipelines with + no request or consumer boundary +- frontend-only work +- threat modeling or security audit work where `security` should be the primary + workflow skill + +Do not fold infrastructure deployment workflows, outbound-client-only guidance, +or full security-audit checklists into this skill. Keep this overlay centered +on backend request and consumer systems plus their immediate reliability and +trust boundaries. + +## Core workflow + +1. Read the touched backend files and map the request or consumer path end to + end: boundary, service logic, data access, external calls, and state + changes. +2. Pick the mode before changing code: + - baseline backend change when the work is mostly a thin handler or small + service fix + - service-boundary change when responsibilities, data access, or dependency + direction may need to move + - reliability-hardening or review mode when the main risk is missing tests, + auth gaps, retries, observability, or unsafe failure handling +3. Keep the boundary thin: decode input, authenticate and authorize, validate, + call a service, map transport errors, and serialize output. Business + decisions belong in service code that can run without the transport layer. +4. Place persistence and external integrations deliberately: + - repositories or data adapters own query shape, batching, and transaction + details when that improves clarity or testing + - services coordinate business rules, idempotency, retries, and side-effect + ordering + - handlers and controllers do not reach directly into ORM or network clients + unless the change is truly trivial and stays trivial +5. Harden cross-cutting concerns at the edge: + - validate external input once at the boundary + - enforce auth and authorization before business actions + - set timeouts, retry rules, and destination allowlists for outbound calls + - use structured logging, correlation identifiers, and explicit error + mapping for observable failure paths +6. Choose the smallest test set that proves the change: + - unit tests for service logic and decision branches + - integration tests for handlers, consumers, repositories, and transaction + behavior + - auth and permission tests for protected flows + - contract or schema tests when the change alters external API or event + shapes + - load or concurrency tests only for changed hotspots, queue throughput, or + latency-sensitive paths +7. Review the result for boundary leaks, unsafe defaults, data-access + inefficiency, and missing verification before finishing. + +## Decision rules + +- Start with `backend-guidance` for ordinary backend edits. Use this overlay + when the task needs stronger design pressure, harder review, or explicit + backend quality gates. +- Keep handlers thin in responsibility, not by literal line count. If a + handler or consumer owns business decisions, retries, transaction branching, + or query orchestration, extract inward. +- Keep business logic transport-free. If testing a rule requires booting HTTP, + gRPC, or queue infrastructure, the logic is in the wrong place. +- Add a repository or data-access interface when it reduces duplication, + isolates non-trivial queries, helps transaction composition, or makes tests + materially simpler. Do not add one for single-call trivial CRUD. +- Prefer one validation pass at the outer edge plus typed internal data. Avoid + repeated validation in every layer unless a trust boundary changes. +- Treat retries as a design choice, not a default. Only retry idempotent or + explicitly deduplicated work, and pair retries with deadlines or backoff. +- Use idempotency keys or duplicate-detection for retried creates, webhook + handlers, and queue consumers that can be re-delivered. +- Every outbound request needs a timeout and failure policy. For user-controlled + destinations, apply allowlists or equivalent SSRF protections. +- Keep error handling explicit: domain code returns or throws domain-level + failures; boundary code maps them to HTTP, gRPC, queue, or job semantics. +- Measure before adding caching. Cache only stable read paths with clear + invalidation or bounded staleness. + +## Validation + +A backend change is done when, in addition to the base implementation skill's +validation: + +- handlers or consumers stay as boundary glue and delegate business decisions to + testable service code +- data access and external I/O live behind clear seams when the change is + non-trivial +- external input, auth, and transport-specific error mapping stay at the edge +- retries, idempotency, timeouts, and failure handling are explicit where the + change can duplicate work or call remote systems +- tests cover the changed behavior at the correct level, including integration + coverage for boundary behavior and permission or failure cases when relevant +- new high-risk paths emit enough evidence to debug production behavior diff --git a/.agents/skills/backend-systems-guidance/references/trigger-evals.md b/.agents/skills/backend-systems-guidance/references/trigger-evals.md new file mode 100644 index 0000000..dc99e51 --- /dev/null +++ b/.agents/skills/backend-systems-guidance/references/trigger-evals.md @@ -0,0 +1,44 @@ +# Backend Systems Guidance Trigger Evals + +Use these prompts to spot over-triggering and boundary drift between +`backend-guidance` and `backend-systems-guidance`. + +## Expected `backend-guidance` + +- "Fix this HTTP handler so it stops doing auth checks inline and just calls the service." +- "Clean up this gRPC method and move input parsing to the boundary." +- "Review this small message consumer and make sure transport concerns stay at the edge." + +## Expected `backend-systems-guidance` + +- "Add idempotent webhook handling with retries, timeout rules, and integration tests." +- "Refactor this endpoint stack into controller, service, and repository layers and check for N+1 queries." +- "Review this backend change for auth gaps, transaction boundaries, outbound request safety, and missing tests." + +## Expected Neither + +- "Tune this HTTP client retry policy for outbound SDK calls." +- "Threat-model our auth system and list likely attack paths." +- "Set up Kubernetes deployment manifests and production dashboards." + +## Manual Simulation Summary + +Prompts used: + +- positive-obvious: "Refactor this endpoint stack into controller, service, and repository layers and check for N+1 queries." +- positive-paraphrased: "This backend change touches retries, auth, and webhook deduplication. Use the stronger backend overlay." +- negative-adjacent: "Tune this HTTP client retry policy for outbound SDK calls." + +What passed: + +- obvious multi-layer backend work points clearly to `backend-systems-guidance` +- paraphrased reliability and trust-boundary work still triggers the stronger + overlay +- outbound-client-only work stays out of scope + +Residual risk: + +- backend review requests may still need judgment when they are narrow enough to + fit `backend-guidance` +- if the stronger overlay grows more review-specific, re-check whether a + companion review overlay would be cleaner diff --git a/.agents/skills/coding-guidance-bash/SKILL.md b/.agents/skills/coding-guidance-bash/SKILL.md new file mode 100644 index 0000000..9e706cb --- /dev/null +++ b/.agents/skills/coding-guidance-bash/SKILL.md @@ -0,0 +1,244 @@ +--- +name: coding-guidance-bash +description: Bash implementation and review skill. Use when writing, modifying, refactoring, or reviewing Bash scripts, especially automation and repo tooling that need defensive error handling, safe quoting, predictable control flow, and maintainable shell boundaries. Portable across Bash-based repos and script stacks. +--- + +# Bash Coding Guidance + +This skill adds portable Bash implementation, refactoring, and review guidance. + +## Adjacent Skills + +This skill provides portable Bash engineering principles. Compose with: + +- **Workflow:** **thinking** (planning), **recursive-thinking** (stress-testing), + **security** (threat modeling) +- **Domain overlays:** **project-core-dev** (repo-specific build/test commands), + **project-platform-diagnose** (environment-sensitive diagnosis) + +## When Not to Lean on This Skill + +- non-shell work +- POSIX `sh` portability work where Bash-only features are not allowed +- large data processing jobs that should realistically move to Python, awk, or + another language with stronger structure + +## Implementation Workflow + +1. Read the touched scripts, entrypoints, call sites, and nearby docs before + editing. +2. Infer the intended contract from current usage text, flags, tests, and + environment assumptions. Ask only when multiple plausible script behaviors + would change semantics. +3. Keep the contract narrow: inputs, outputs, exit codes, environment + dependencies, filesystem effects, and external tool requirements should be + explicit. +4. Implement with defensive mode, safe quoting, arrays for argv construction, + functions for meaningful substeps, and cleanup traps for temporary state. +5. Add or update shell tests when the repo has them; otherwise add the smallest + reproducible validation path you can run directly. +6. Run the narrowest relevant formatter, linter, and script tests the repo + supports. + +## Refactoring Workflow + +Use this instead of the default implementation workflow when the task is +primarily cleanup or restructuring: + +1. Capture current behavior, flags, environment assumptions, platform + dependencies, and failure modes. +2. Break the refactor into small slices that preserve behavior. +3. Replace copy-pasted command assembly, hidden globals, unsafe loops, and + tangled control flow one step at a time. +4. Keep tests or runnable validation passing after each slice; add + characterization coverage first when behavior is unclear. +5. Stop when the script is easier to read, safer to invoke, and easier to + debug. + +## Review Workflow + +When reviewing (not implementing), skip the implementation workflow and use this +instead: + +1. Read the change in full before commenting. +2. Identify findings, ordered by severity: `Critical` > `Important` > + `Suggestion`. +3. Prioritize quoting and word-splitting bugs, globbing hazards, accidental + masking of failing commands, trap and cleanup bugs, unsafe temp-file + handling, destructive command risks, portability mismatches, environment + assumptions, and missing tests. +4. State findings with concrete evidence and the likely consequence. + +## Bash Rules + +### First tier - causes bugs + +- Start executable Bash scripts with `#!/usr/bin/env bash` unless the repo has + a stricter shebang convention +- Use `set -Eeuo pipefail` unless the script has a documented reason to manage + failures differently; scope exceptions narrowly +- Quote expansions by default: `"$var"`, `"${arr[@]}"`, and `"$(cmd)"` +- Use arrays for argument vectors; do not build command lines with string + concatenation +- Distinguish stdout data from stderr diagnostics so callers can compose the + script safely +- Check exit statuses deliberately; do not rely on pipelines, subshells, or + command substitutions without understanding how failures propagate +- Clean up temp files and directories with `trap` when the script allocates + them +- Treat `$IFS`, globs, current working directory, and environment variables as + boundary conditions, not stable ambient assumptions + +### Second tier - prevents mistakes + +- Prefer functions for meaningful units of behavior; keep top-level script flow + readable +- Use `local` inside functions unless a variable is intentionally shared +- Prefer `[[ ... ]]` for Bash conditionals and `case` for multi-branch string + matching +- Prefer `printf` over `echo` when escaping, flags, or portability ambiguity + matter +- Use command substitution `$()` instead of backticks +- Name flags, env vars, and functions for what they do; shell scripts become + unreadable quickly when names get vague +- Keep shellcheck findings at zero in repo-owned code unless the script has a + documented exception + +### Defensive patterns + +- Consider `shopt -s inherit_errexit` when the Bash version and repo contract + allow it and command-substitution failures must propagate cleanly +- Validate required env vars explicitly with `: "${VAR:?message}"` +- Detect missing external tools up front with `command -v tool >/dev/null 2>&1` +- Use `mktemp` for temp files and directories; never hand-roll temp paths in + shared locations +- Prefer dry-run modes and idempotent behavior before destructive or expensive + operations +- Use `trap` for cleanup and, when helpful, targeted `ERR` reporting with line + or function context + +### Command and process discipline + +- Pass user-controlled values as individual argv elements, not through `eval` + or re-parsed strings +- Avoid `eval` unless the script is explicitly a shell metaprogramming tool and + the risk is justified +- Prefer explicit path resolution and file existence checks before destructive + operations +- When calling external tools, preserve argument boundaries and treat tool exit + codes as part of the contract +- Be deliberate about `cd`; either scope it to a subshell or restore the prior + directory clearly +- End option parsing with `--` when forwarding user arguments to external + commands +- If the script spawns background jobs, make ownership explicit: track PIDs, + aggregate `wait` results deliberately, and forward or handle termination + signals rather than abandoning children +- Avoid casual parallel destructive work; if concurrency matters, define the + locking, isolation, or idempotency rule up front +- If concurrent invocations can interfere with each other, use an explicit lock + strategy such as `flock` or a documented equivalent instead of hoping paths + or timing stay unique + +### Input, output, and contract design + +- Provide `--help` or usage text for non-trivial scripts +- Make required env vars, positional args, flags, and side effects explicit + near the top of the file +- Exit with non-zero status on real failure and reserve zero for success +- Print machine-consumable output in a stable format when other tools are meant + to parse it +- Avoid silent fallbacks on missing tools or files unless the script is + explicitly best-effort +- Use stable exit-code meanings when the script is likely to be called by other + automation + +### Safe iteration and file handling + +- Prefer `while IFS= read -r line; do ...; done` over loops that split on + whitespace implicitly +- Use NUL-safe patterns for filenames from `find`, `git`, or similar tools: + `-print0`, `xargs -0`, or `read -r -d ''` +- Use `readarray` or `mapfile` when populating arrays from command output in + Bash-specific scripts +- Avoid `for f in $(...)` for filenames or untrusted data; it is usually a bug +- Prefer built-ins and parameter expansion over unnecessary subprocesses when + they make the script clearer and safer + +### Portability and platform fit + +- Use Bash-specific features only when the shebang and repo contract allow them +- If the script must run on multiple platforms, check GNU vs. BSD tool + differences before adding flags with inconsistent behavior +- If platform behavior matters, detect it explicitly instead of assuming Linux +- Prefer the repo's existing helper scripts and path conventions over ad hoc + temp locations or duplicated wrappers +- Move non-trivial parsing, JSON handling, or data shaping to a better-suited + language when shell stops being the clearest tool + +### Style, testing, and tooling + +- Prefer long, readable option names for user-facing interfaces when the repo + does not already prescribe a short-only style +- Keep functions small enough to understand locally; split when one function + starts owning parsing, validation, execution, and reporting all at once +- Run `shellcheck` and `shfmt` where the repo uses them +- Prefer Bats or the repo's existing shell-test framework for non-trivial + scripts +- Document required tools and minimum Bash features when the script depends on + them + +## Decision Heuristics + +Use these when the right choice is not obvious: + +- **Language fit:** if the task needs nested data structures, complex parsing, + or large in-memory transforms, shell may be the wrong tool. +- **Quoting pressure:** if command construction becomes hard to reason about, + switch to arrays or redesign the interface before adding more flags. +- **Failure visibility:** if `set -e` behavior is unclear in a construct, make + the check explicit rather than assuming the shell will fail the right way. +- **Process ownership:** if the script backgrounds work, define who waits, + cleans up, and reports failures before adding more parallelism. +- **Portability pressure:** if a script relies on GNU-only flags, a Bash 5.x + feature, or OS-specific tools, document and validate that boundary instead of + hiding it. +- **Repo conventions:** if the repo has established patterns for shebangs, + strict mode, shellcheck, shfmt, or helper libraries, follow them unless they + create a correctness or safety problem. +- **Narrowness vs. quality:** implement the narrowest change that solves the + problem. When narrowness conflicts with correctness or safety, prefer + correctness. When it conflicts with style alone, prefer narrowness unless the + task is explicitly a cleanup. +- **Refactor boundary:** outside explicit refactor work, fix at most one small + adjacent issue while you are in the file. +- **Abstraction threshold:** three similar command sequences or repeated flag + parsing pain is a pattern; before extracting, check whether a function, a + helper script, or a small move to another language is the simpler move. +- **External-tool boundary:** if a script depends on `jq`, `awk`, `sed`, or + platform-specific tooling, treat that dependency as part of the user-facing + contract. + +## Validation + +A change is done when: + +- shellcheck or the repo's equivalent linter reports no new findings +- shell formatting is run when the repo has a formatter +- changed `--help`, argument parsing, or top-level script startup paths are + smoke-tested before deeper functional validation +- existing shell tests pass +- new or changed behavior has test coverage, or the lack of coverage is called + out with a concrete reason +- non-trivial scripts have a direct smoke path such as `--help` or a minimal + fixture invocation +- destructive or environment-mutating paths were verified against a safe test + fixture rather than assumed correct +- portability-sensitive changes were tested on the affected platform or the + remaining platform risk was called out explicitly +- review findings at `Critical` and `Important` severity are addressed + +## Examples + +- `Review this Bash deploy script for quoting, traps, and rollback safety` +- `Refactor this repo automation script to use arrays, safe temp files, and better argument parsing` diff --git a/.agents/skills/coding-guidance-cpp/SKILL.md b/.agents/skills/coding-guidance-cpp/SKILL.md index 4079387..202d654 100644 --- a/.agents/skills/coding-guidance-cpp/SKILL.md +++ b/.agents/skills/coding-guidance-cpp/SKILL.md @@ -1,11 +1,11 @@ --- name: coding-guidance-cpp -description: C++ implementation and review skill. Use when writing, modifying, or reviewing C++ code — feature work, bug fixes, refactors, or code review. Portable across C++ repos and build systems. +description: C++ implementation and review skill. Use when writing, modifying, refactoring, or reviewing C++ code, especially modern C++17/20/23 code that needs strong ownership, type safety, and testable design. Portable across C++ repos and build systems. --- # C++ Coding Guidance -Read `AGENTS.md` first. This skill adds C++ implementation and review guidance. +This skill adds portable C++ implementation, refactoring, and review guidance. ## Adjacent Skills @@ -14,17 +14,60 @@ This skill provides portable C++ engineering principles. Compose with: - **Workflow:** **thinking** (planning), **recursive-thinking** (stress-testing), **security** (threat modeling) - **Domain overlays:** **backend-guidance** (server-side code), + **backend-systems-guidance** (stronger backend architecture, reliability, and + trust-boundary work), **ui-guidance** (graphical UI/web frontend), **project-core-dev** (repo-specific build/test commands) +## When Not to Lean on This Skill + +- non-C++ work +- legacy or bare-metal environments where modern C++ guidance must be adapted + selectively +- pure architecture or process work with no C++ design or code judgment needed +- repo-specific style packs or platform policies that should be enforced by + local `clang-tidy`, compiler, or overlay rules rather than a portable + principle skill + +## Boundary Contract + +Keep this skill focused on portable C++ engineering judgment. + +- Put repo-specific exception policy, warning policy, formatter choices, and + include-order rules in repo config or repo docs +- Put style-pack rules from ecosystems such as Google, LLVM, Abseil, or + platform/vendor bundles in repo config or overlays, not here +- Put library- or platform-specific API policy in repo config or a domain + overlay +- When a rule is analyzer-shaped but not portable, keep it in `clang-tidy` + config or the reference note rather than adding it to the main skill + ## Implementation Workflow -1. Read the touched code, build shape, and existing tests. -2. Identify the narrowest change that solves the problem. -3. Implement with simple, behavior-oriented interfaces. -4. Add or update tests using the repo's established test framework, close to the - changed behavior. -5. Run the repo's formatter, then run relevant build, test, and analyzer targets. +1. Read the touched code, build shape, existing tests, and any nearby docs or + shorthand notes before editing. +2. If the request is partially specified, infer the intended behavior from the + existing code and tests. Ask only when multiple plausible C++ designs would + change semantics. +3. Choose the narrowest change that solves the problem without hiding ownership, + lifetime, or error-handling contracts. +4. Implement with simple, strongly typed interfaces and modern C++ defaults. +5. Add or update tests close to the changed behavior. +6. Run the narrowest relevant format, build, test, sanitizer, and analyzer + targets the repo supports. + +## Refactoring Workflow + +Use this instead of the default implementation workflow when the task is +primarily cleanup or restructuring: + +1. Capture current behavior, invariants, side effects, and risky hotspots. +2. Break the refactor into small slices that preserve behavior. +3. Remove duplication, long functions, or muddled responsibilities one step at + a time. +4. Keep tests passing after each slice; add characterization coverage first when + behavior is unclear. +5. Stop when the code is simpler and safer. ## Review Workflow @@ -32,62 +75,296 @@ When reviewing (not implementing), skip the implementation workflow and use this instead: 1. Read the change in full before commenting. -2. Identify findings, ordered by severity: `Critical` > `Important` > `Suggestion`. -3. Prioritize: bugs and regressions, ownership/lifetime issues, missing - validation or error handling, missing tests, security or performance risks - with real impact. -4. Report findings first. Skip praise unless the change is notably well-done. +2. Identify findings, ordered by severity: `Critical` > `Important` > + `Suggestion`. +3. Prioritize bugs and regressions, ownership and lifetime errors, exception or + error-path holes, thread-safety issues, security risks, performance mistakes + with real impact, and missing tests. +4. State findings with concrete evidence and the likely consequence. ## C++ Rules -### First tier — causes bugs - -- Treat raw pointers and references as non-owning; make ownership transfer - explicit in the type or documented in a comment -- Avoid `new`/`delete` — use RAII wrappers and smart pointers -- Prefer `std::unique_ptr` by default when single ownership is intended; use - `std::shared_ptr` only when shared lifetime is a real requirement -- Avoid unchecked bounds access — prefer `.at()`, range-for, or - iterator patterns over raw indexing when bounds are uncertain -- Avoid silent narrowing conversions — use explicit casts or `narrow_cast` - -### Second tier — prevents mistakes - -- Avoid C-style casts — use `static_cast`, `const_cast`, `reinterpret_cast` - to make intent visible -- Prefer rule-of-zero types; if you write a destructor, justify it -- Prefer `std::array` over C arrays, `std::string_view` and, where available, - `std::span` over raw pointer-plus-length pairs when lifetime rules are clear -- Prefer explicit helper structs over ambiguous adjacent parameters of the - same type -- Use `[[nodiscard]]` on functions where ignoring the return value is a bug -- Avoid unnecessary copies in range-for — use `const auto&` by default, but - prefer value iteration for cheap copy types or when ownership transfer is the - point +Read these by failure theme, not as an exhaustive checklist. + +### Construction, ownership, and lifetime + +- Treat raw pointers and references as non-owning; never transfer ownership by + raw pointer or reference +- Avoid `new` and `delete`; bind resource lifetime to object lifetime with RAII +- Prefer `std::unique_ptr` by default; use `std::shared_ptr` only for real + shared lifetime and `std::weak_ptr` to break cycles +- Prefer values and stack allocation over heap allocation when ownership is + simple +- Prefer rule-of-zero types; if you write a destructor or custom special member + function, justify it +- Initialize objects into valid states immediately; construction should + establish invariants instead of relying on later “remember to initialize” + steps +- Do not store or return references, views, iterators, or pointers into + temporaries or short-lived owners; when the lifetime proof is not obvious, + return or store an owning value instead +- Treat moved-from objects as valid but semantically narrow; only destroy, + reassign, or call operations whose post-move contract is explicit +- Do not cross async, callback, coroutine-suspend, or thread-handoff + boundaries with borrowed state unless the lifetime proof is explicit + +### Type, bounds, and representation safety + +- Avoid unchecked bounds access; prefer `.at()`, iterators, range-for, or + `std::span` when bounds are uncertain +- Avoid silent narrowing conversions; use explicit casts or narrowing helpers +- Avoid signed/unsigned comparison traps; use `std::cmp_*`, `std::in_range`, + or a deliberate common type when integer domains differ +- Prefer compile-time checking to runtime checking when the type system can + express the rule +- Avoid C-style casts; use `static_cast`, `const_cast`, `reinterpret_cast`, and + `dynamic_cast` deliberately +- Prefer `std::bit_cast` or byte-wise copy for object-representation + reinterpretation; do not use `reinterpret_cast` where aliasing or lifetime + rules make the behavior fragile +- Avoid raw memory APIs, `memset`/`memcpy` tricks, or pointer arithmetic on + non-trivial, polymorphic, or lifetime-sensitive types +- Use `const` and `constexpr` by default; mutability should be the exception +- Prefer `enum class` over plain enums and `nullptr` over `NULL` +- Prefer `std::array` over C arrays, `std::string_view` for non-owning strings, + and `std::span` for non-owning ranges when lifetime rules are clear + +### API contracts and call-site clarity + +- Do not mix exception and error-code styles inconsistently inside one path +- Do not ignore must-check results from allocation, parsing, synchronization, + numeric conversion, or OS/library APIs when failure changes behavior +- Use `[[nodiscard]]` when ignoring a result is likely a bug +- Prefer explicit constructors, conversions, and named types when ownership, + units, or semantics would otherwise be implicit +- Avoid forwarding, overload, and default-argument combinations that make calls + ambiguous or silently select the wrong overload +- Treat virtual dispatch boundaries as bug-prone: use `override`, avoid near + misses, and do not rely on shadowing or signature accidents +- Keep declarations and definitions consistent across headers and sources: + parameter names, qualifiers, defaults, and ownership cues should not drift +- Be suspicious of adjacent same-type parameters; named types, parameter + objects, or strong typedefs are often clearer than comments +- Prefer interfaces that make argument order hard to misuse and bool/int/string + sentinels hard to confuse +- Prefer APIs that encode units, domains, and nullability in types rather than + relying on comments, magic values, or positional conventions + +### Headers, globals, and build surface + +- Avoid `using namespace std` in headers - Keep warnings at zero in repo-owned code +- Keep macros narrow, parenthesized, side-effect-safe, and out of API shaping; + prefer language features unless a macro is the least-bad tool +- Avoid reserved identifiers, namespace pollution, and definitions in headers + that quietly change ODR or rebuild behavior +- Prefer include sets that are minimal and explicit; unused includes, include + cycles, and transitive-include dependence are design smells +- Use `constinit` for non-local static or thread-local objects that must not + rely on dynamic initialization +- Prefer compile-time constants, local statics, or explicit startup wiring over + hidden global initialization side effects + +### Concurrency, async, and testability + +- Prefer structured thread ownership and explicit cancellation over detached + threads or ad hoc stop flags; `std::jthread` and `std::stop_token` are good + defaults when the codebase already uses standard thread primitives +- Assume container modifications may invalidate iterators, references, pointers, + and views unless the container contract says otherwise +- Prefer seams that keep core logic testable without real threads, clocks, + filesystem, process state, or ambient globals when the domain does not + require those dependencies + +### Expressive modern defaults + +- Prefer vocabulary types such as `std::optional`, `std::variant`, and + `std::expected` when they encode real domain states better than sentinels or + ad hoc conventions +- Prefer standard algorithms and ranges over open-coded loops when they make the + intent clearer +- Prefer standard library and language replacements for deprecated, + legacy-C-leaning, or handwritten utilities when the replacement is clearer + and already acceptable in the repo toolchain + +### Advanced feature selection + +- Use C++20 or C++23 features when they make contracts clearer, not to signal + modernity +- Use `consteval` only when every call must be a compile-time evaluation +- Use concepts to constrain templates when the constraint is part of the public + contract; avoid them for local cleverness +- Use ranges when they improve readability; avoid long adaptor pipelines that + hide cost or control flow +- Use `std::span` and `std::string_view` for non-owning parameters only when + the caller can satisfy the lifetime contract clearly +- Use forwarding references only when perfect forwarding is the actual contract; + otherwise prefer plain overloads, values, or `const&` +- Use coroutines only when the repo already embraces them or when they simplify + asynchronous control flow more than callback, future, or thread-based + alternatives +- In coroutine code, avoid captured or reference state that may outlive the + source scope, and do not suspend while holding locks or other scoped guards +- Do not introduce template metaprogramming, custom allocators, or exotic + zero-cost abstractions unless measurement or reuse pressure justifies them + +### Design judgment - error and contract model + +- Pick one primary error model per subsystem: exceptions, status-return, or + `std::expected`; cross-model adapters should be explicit at boundaries +- Use exceptions for exceptional failures only when the repo and call graph are + already built around exception safety +- Prefer return-value error models where failure is routine, expected, or part + of normal control flow +- Mark destructors, `swap`, and move operations `noexcept` when that matches + reality; throwing moves silently degrade container behavior and can weaken + strong exception guarantees +- State ownership, nullability, lifetime, and thread-safety contracts in the + type system when possible, and in comments only when the type system cannot + express them cleanly +- Public APIs should make invalid states hard to represent and expensive states + visible to callers +- Prefer parse and conversion APIs that report failure explicitly; unchecked + string-to-number and narrowing paths are common production defects + +### Design judgment - headers and interfaces + +- Minimize header surface; prefer forward declarations when they reduce stable + dependencies without obscuring the contract +- Do not put heavy includes, macros, or implementation-only dependencies in + public headers without a clear reason +- Keep inline and template-heavy code in headers only when required by the + language or justified by measurement +- Be deliberate with namespace-scope initialization; prefer `constexpr`, + `constinit`, or function-local statics over cross-translation-unit dynamic + initialization +- Prefer free functions or narrow interfaces over large classes that force + unnecessary rebuild and dependency coupling +- Be explicit when ABI stability, plugin boundaries, or C interop constrain the + design +- Treat rebuild surface, transitive include fan-out, and template instantiation + cost as design costs, not just build-system problems +- Avoid anonymous namespaces, non-inline definitions, and hidden state in + headers when those choices change linkage or duplicate objects across + translation units +- Keep include ordering, guards, and dependency direction consistent with repo + conventions; header hygiene is part of correctness, not just style + +### Design judgment - concurrency and synchronization + +- Make thread ownership and synchronization strategy explicit; “probably + thread-safe” is not a contract +- Prefer message passing, task ownership, or data partitioning before shared + mutable state +- Protect invariants, not individual fields; lock scope should match the real + consistency boundary +- Use atomics only when the memory-ordering contract is understood and simpler + locking would not be clearer +- Treat coroutine, callback, and thread handoff points as lifetime hazards +- Do not use async-signal-unsafe functions, cancellation modes, or wake-up + assumptions that break library contracts under contention or interruption + +### Design judgment - APIs and abstraction + +- Functions should do one thing, stay at one level of abstraction, and justify + more than two meaningful parameters +- Treat boolean flag parameters as a design smell; split behavior or introduce a + parameter object when that makes the contract clearer +- Prefer composition and value semantics over inheritance unless polymorphism is + the actual domain model +- Avoid “config bag” APIs where many weakly related booleans, enums, or strings + simulate a missing type +- Make ownership and mutation visible at API boundaries; hidden allocation, + caching, or global state is a design smell in “clean-looking” code +- Be suspicious of abstractions that look tidy but add virtual dispatch, + allocation, copies, or lifetime coupling without a clear benefit +- Be suspicious of public template abstractions that improve local elegance but + increase compile time, error verbosity, or rebuild cost across the repo +- Prefer moving implementation detail out of headers when doing so preserves the + contract and reduces dependency drag +- Prefer parameter names and call sites that communicate semantics directly; + ambiguous names, magic literals, and comment-only argument meaning are review + smells + +## Clang-Tidy-derived emphasis + +Use the full `clang-tidy` catalog as a source of recurring failure modes, not as +a portable checklist to paste into every repo. + +- Treat `bugprone`, `cppcoreguidelines`, `modernize`, `performance`, `misc`, + `portability`, and the CERT/HIC++ aliases as high-signal prompts for code + review and refactoring +- Fold only portable semantics into this principle skill; repo-specific naming, + include order, formatter preferences, test-framework style, platform APIs, + and library-pack rules belong in repo config or overlays +- If a repo ships `clang-tidy`, read its enabled checks before introducing new + patterns; local suppressions and allowlists often document real constraints +- When multiple checks point at the same design issue, fix the design cause + instead of satisfying each warning mechanically + +## Resource map + +- [references/clang-tidy-derived-guidance.md](references/clang-tidy-derived-guidance.md): + triage of the current clang-tidy check catalog into portable principles, + repo-level rules, and non-portable families that should stay out of this + skill ## Decision Heuristics Use these when the right choice is not obvious: - **Scope check:** if a change touches more than 3 public interfaces, stop and - plan before continuing — the change is bigger than it looks. -- **Ownership clarity:** if resource ownership is not obvious from the type - signature alone, add a one-line comment documenting the contract. + plan before continuing; the change is bigger than it looks. +- **Ownership clarity:** if ownership is not obvious from the type signature, + redesign the interface or add a one-line contract comment. +- **Error-model consistency:** do not mix exceptions, error codes, and + `expected`-style returns within one subsystem unless the boundary is explicit. +- **Exception-safety pressure:** when mutating multi-step state, decide whether + the operation offers no-fail, strong, or basic exception safety and structure + the code to match. - **Repo conventions:** if the repo has established rules for exceptions, - ownership types, containers, or error handling, follow them unless they cause - a correctness or safety problem. -- **Test setup size:** if test setup exceeds ~20 lines, extract a fixture — but - only if the setup is reused by at least 2 tests. + containers, ownership types, or naming, follow them unless they create a + correctness or safety problem. +- **Feature pressure:** do not introduce concepts, ranges, coroutines, or + metaprogramming unless they make the code simpler for this repo's likely + maintainers. +- **Interface pressure:** if a header starts dragging in broad dependencies or + exposing implementation detail, narrow the interface before adding more code. +- **Build-surface pressure:** if a design pushes more logic, templates, or + dependencies into public headers, justify the compile-time and rebuild cost. +- **Parameter pressure:** when adjacent parameters have the same type, or the + function needs more than 2-3 meaningful inputs, prefer a named type or helper + struct. +- **Lifetime pressure:** if a non-owning type crosses async, callback, return, + or storage boundaries, prefer an owning type unless the lifetime proof is + obvious from the interface. +- **Initialization pressure:** if correct behavior depends on a later + “remember to initialize” step, move that requirement into construction or the + type itself. +- **Call-site pressure:** if two arguments are easy to swap or a call needs + comments to explain literals, redesign the API before adding more call sites. +- **Header pressure:** if a header starts accumulating definitions, globals, + unnecessary includes, or hidden initialization, push behavior back behind a + source boundary. +- **Testability pressure:** if a design forces tests to spin threads, sleep, + touch the real filesystem, or patch globals just to exercise core logic, + introduce a seam before adding more behavior. +- **Test setup size:** if test setup exceeds about 20 lines, extract a fixture + only when the setup is reused or the test intent becomes unclear. - **Narrowness vs. quality:** implement the narrowest change that solves the problem. When narrowness conflicts with correctness or safety, prefer - correctness. When it conflicts with style, prefer narrowness unless - explicitly time-boxed for cleanup. -- **Refactor boundary:** when modifying a file, fix at most one small adjacent - issue. Do not refactor unrelated code in the same change. -- **Abstraction threshold:** three similar code blocks is a pattern; two is - coincidence. Do not extract a helper until the third occurrence unless the - duplication crosses a module boundary. + correctness. When it conflicts with style alone, prefer narrowness unless the + task is explicitly a cleanup. +- **Refactor boundary:** outside explicit refactor work, fix at most one small + adjacent issue while you are in the file. +- **Abstraction threshold:** three similar code blocks or repeated API-shaping + pain is a pattern; before extracting, check whether a free function, helper + type, or composed object is the simpler move. +- **Performance rule:** optimize only after measurement, except for obvious + ownership, allocation, or algorithmic mistakes on hot paths. +- **UB-sensitive optimization:** treat optimizations that rely on subtle + lifetime, aliasing, or memory-order assumptions as high-risk until proven by + evidence and tooling. ## Validation @@ -96,7 +373,11 @@ A change is done when: - the code compiles without new warnings, unless the repo explicitly treats a known warning set as baseline debt outside the change - existing tests pass -- new or changed behavior has test coverage +- new or changed behavior has test coverage, or the lack of coverage is called + out with a concrete reason - the repo's formatter has been run -- static analyzers (if configured) report no new findings +- configured static analyzers report no new findings +- available sanitizers are clean for the touched paths when the change affects + memory safety, threading, or undefined-behavior risk +- performance-sensitive changes are measured instead of justified by intuition - review findings at `Critical` and `Important` severity are addressed diff --git a/.agents/skills/coding-guidance-cpp/references/clang-tidy-derived-guidance.md b/.agents/skills/coding-guidance-cpp/references/clang-tidy-derived-guidance.md new file mode 100644 index 0000000..e986875 --- /dev/null +++ b/.agents/skills/coding-guidance-cpp/references/clang-tidy-derived-guidance.md @@ -0,0 +1,111 @@ +# Clang-Tidy-derived guidance for `coding-guidance-cpp` + +This note records how the current `clang-tidy` catalog at + was triaged for this +principle skill. + +Use it to keep the skill aligned with the tool without turning the main +`SKILL.md` into an analyzer index. + +## Goal + +Extract portable engineering guidance from the full check list while keeping +repo-local style policy, platform quirks, and library-pack rules out of the +default skill. + +## What belongs in the principle skill + +These check families reinforce portable C++ guidance and should shape the main +skill wording: + +- `bugprone-*`: dangling handles, unchecked optional/status access, suspicious + arithmetic, overload mistakes, swapped arguments, use-after-move, macro + hazards, raw-memory misuse, dangerous static initialization, signal-handler + mistakes +- `cppcoreguidelines-*`: ownership, bounds, initialization, special members, + slicing, varargs avoidance, globals, narrowing, virtual-destructor safety, + coroutine hazards +- `modernize-*`: safer language/library defaults such as `override`, + `nullptr`, `[[nodiscard]]`, `noexcept`, member initializers, safer factory + functions, constrained templates, and standard replacements for deprecated + constructs +- `performance-*`: avoid accidental copies, hidden reallocations, ineffective + moves, slow string and container patterns, and obviously inefficient + algorithms +- `misc-*`: header definitions, include cycles, identifier confusion, + const-correctness, recursion, hostile RAII/coroutine interactions, custom + `new`/`delete` pitfalls +- `portability-*`: non-portable headers and constructs, assembler usage, + pragma-specific assumptions, allocator and template patterns with toolchain + or ABI risk +- `readability-*`: argument clarity, complexity, brace consistency, implicit + bool conversion, magic numbers, declaration isolation, redundant casts, and + smart-pointer misuse at call sites +- CERT and HIC++ aliases: useful because they cluster around real correctness + and safety concerns, but most are already covered by the families above + +## What should stay out of the principle skill + +These families are real, but too repo-, platform-, framework-, or vendor- +specific to bake into portable default guidance: + +- `abseil-*`, `boost-*`: library-pack conventions for repos that depend on + those ecosystems +- `altera-*`, `mpi-*`, `openmp-*`: specialized parallel or accelerator domains +- `android-*`, `darwin-*`, `fuchsia-*`, `linuxkernel-*`, `zircon-*`: OS- or + platform-specific policy +- `google-*`, `llvm-*`: style-pack and ecosystem-specific conventions +- `objc-*`: Objective-C specific +- `clang-analyzer-*`: valuable when available, but they represent a different + analyzer layer than portable C++ coding guidance + +For these, prefer repo-local `clang-tidy` config, a domain overlay, or explicit +project documentation. + +## Signals worth emphasizing in future revisions + +The full catalog strongly suggests these themes deserve explicit wording in the +main skill: + +- construction and initialization correctness +- borrowed-lifetime hazards across async and coroutine boundaries +- overload and parameter-list designs that invite swapped or ambiguous calls +- header hygiene as a correctness and build-surface concern +- macro and identifier discipline +- unchecked conversions, parsing, and status-return paths +- modern replacements for deprecated or C-leaning constructs when the repo can + support them +- performance guidance framed as “avoid obvious cost leaks,” not “micro-opt by + default” + +## Easy-to-miss checks worth remembering + +These are not separate principles, but they are good reminders because they +reveal failure modes that teams often underweight: + +- swapped or easily-swappable arguments: a signal to redesign the API, not just + annotate call sites +- default-argument and overload interactions: small convenience features can + quietly turn into ambiguous or wrong-call hazards +- coroutine capture and suspend-with-lock hazards: async code often fails at + lifetime and scope boundaries, not in the happy-path logic +- dynamic or throwing static initialization: startup order and initialization + side effects deserve the same design scrutiny as normal runtime code +- raw-memory operations on non-trivial types: “fast” low-level code is often + just undefined behavior with a familiar shape +- ineffective move patterns and hidden copies: performance reviews should look + for semantic cost leaks before algorithm heroics +- suspicious string, numeric-conversion, and status-access paths: parsing and + boundary code remain a dense source of production defects + +## Maintenance rule + +When the clang-tidy catalog grows: + +1. Check whether a new family exposes a portable semantic issue or only a repo- + specific policy. +2. If it is portable and high-signal, fold the principle into `SKILL.md`. +3. If it is narrow, move it into repo config, a domain overlay, or leave it in + this reference note. +4. Prefer consolidating by design issue, not by adding one bullet per analyzer + check. diff --git a/.agents/skills/coding-guidance-python/SKILL.md b/.agents/skills/coding-guidance-python/SKILL.md new file mode 100644 index 0000000..b7b9ba8 --- /dev/null +++ b/.agents/skills/coding-guidance-python/SKILL.md @@ -0,0 +1,260 @@ +--- +name: coding-guidance-python +description: Python implementation and review skill. Use when writing, modifying, refactoring, or reviewing Python code, especially production Python that needs clear contracts, type safety, testability, and maintainable module boundaries. Portable across Python repos and tooling stacks. +--- + +# Python Coding Guidance + +This skill adds portable Python implementation, refactoring, and review guidance. + +## Adjacent Skills + +This skill provides portable Python engineering principles. Compose with: + +- **Workflow:** **thinking** (planning), **recursive-thinking** (stress-testing), + **security** (threat modeling) +- **Domain overlays:** **backend-guidance** (server-side code), + **backend-systems-guidance** (stronger backend architecture, reliability, and + trust-boundary work), + **ui-guidance** (graphical UI/web frontend), + **project-core-dev** (repo-specific build/test commands) + +Open the bundled references only when the task actually touches package +distribution, entrypoint layout, or a real I/O/service boundary. + +## When Not to Lean on This Skill + +- non-Python work +- notebook-first exploratory work where reproducibility and module design are + not the main concern +- one-off throwaway scripts where the repo explicitly does not want production + Python standards + +## Implementation Workflow + +1. Read the touched modules, entrypoints, tests, package metadata, and nearby + docs before editing. +2. Infer intended behavior from existing code, imports, and tests when the + request is only partially specified. Ask only when multiple plausible + designs would change semantics. +3. Choose the narrowest change that keeps contracts, side effects, error + handling, and public API shape explicit. +4. Implement with simple functions, clear module boundaries, explicit types + where they improve the contract, and production-safe behavior at I/O + boundaries. +5. Add or update tests close to the changed behavior; prefer pytest-native + fixtures and parameterization over ad hoc setup. +6. Run the narrowest relevant formatter, linter, type checker, packaging check, + and test targets the repo supports. + +## Refactoring Workflow + +Use this instead of the default implementation workflow when the task is +primarily cleanup or restructuring: + +1. Capture current behavior, side effects, hidden globals, import shape, and + mutation hotspots. +2. Break the refactor into small slices that preserve behavior. +3. Remove long functions, muddled responsibilities, implicit coupling, and + anti-patterns one step at a time. +4. Keep tests passing after each slice; add characterization coverage first + when behavior is unclear. +5. Stop when the code is simpler, more explicit, easier to test, and easier to + operate. + +## Review Workflow + +When reviewing (not implementing), skip the implementation workflow and use this +instead: + +1. Read the change in full before commenting. +2. Identify findings, ordered by severity: `Critical` > `Important` > + `Suggestion`. +3. Prioritize bugs and regressions, exception or error-path holes, mutable + shared-state mistakes, typing and interface mismatches, packaging or import + breakage, performance mistakes with real impact, security risks, and missing + tests. Add service-boundary observability, retry, and timeout findings when + the change actually crosses a real external boundary. +4. State findings with concrete evidence and the likely consequence. + +## Python Rules + +### First tier - causes bugs + +- Keep module side effects minimal; avoid import-time network calls, filesystem + mutation, or heavy initialization unless the module is explicitly an + entrypoint +- Prefer explicit parameters and return values over hidden globals, ambient + context, or mutation of module-level state +- Do not use mutable default arguments +- Treat `None` handling, optional fields, and missing keys as contract design, + not cleanup for callers to guess +- Preserve exception context; do not catch broadly and discard the original + failure without adding useful domain context +- Use context managers for files, locks, subprocess pipes, and other resources + with lifetime rules +- Be explicit about text vs. bytes boundaries, timezone-aware vs. naive + datetimes, and sync vs. async call paths +- Do not block the event loop with synchronous I/O in async code +- Do not mix sync and async APIs inside one path without a clear boundary + +### Second tier - prevents mistakes + +- Prefer small functions and plain data flow before introducing classes +- Use classes when they model stateful domain objects or a stable behavior + boundary, not just to group helpers +- Prefer `pathlib.Path` over stringly typed path manipulation +- Prefer `dataclass`, `TypedDict`, `Protocol`, `Enum`, and other standard + library types when they make contracts clearer +- Use comprehensions and built-ins when they make intent clearer; avoid dense + one-liners that hide control flow +- Avoid boolean flag parameters when separate functions or a small config type + would make behavior clearer +- Keep warnings, lint findings, and type-checker regressions at zero in + repo-owned code + +### Typing and interfaces + +- Add type hints to public functions, methods, and non-trivial internal seams + where they clarify real contracts +- Prefer concrete types at boundaries and protocols for substitution seams + rather than broad `Any` +- Use `Any` only when the repo truly needs a dynamic escape hatch and the cost + is explicit +- Prefer modern union syntax and type narrowing over comments or sentinel-heavy + calling conventions +- Public APIs should make invalid states hard to represent and expensive work + visible to callers +- If a function takes more than 2-3 meaningful parameters, prefer a named type, + config object, or split responsibility +- Make mutation visible in names and interfaces; hidden in-place updates are a + design smell +- Use strict type checking where the repo supports it; if the codebase is not + yet strict, tighten changed modules instead of broadening exemptions + +### Tests and verification + +- Prefer pytest-style tests with clear arrange-act-assert flow +- Use fixtures for reusable setup and teardown, not for hiding the meaning of + a test +- Use parameterized tests when the same contract should hold across multiple + inputs +- Mock external boundaries, not the internal behavior you are trying to prove +- Add integration coverage when the change crosses package, transport, + persistence, or subprocess boundaries +- Coverage is a signal, not a goal; prioritize meaningful path coverage over + percentage chasing + +### Data and state discipline + +- Keep validation, serialization, persistence, and business rules separated + enough that each can be tested directly +- Be suspicious of dict-shaped data flowing through many layers without a named + contract +- Prefer immutable or append-only data flow where shared mutation would make + behavior harder to reason about +- Cache only when measurement or repeated cost justifies it; make cache scope + and invalidation rules explicit +- Treat environment-variable reads, current working directory assumptions, and + process-global configuration as boundary concerns +- Validate external input at the boundary instead of letting malformed data fail + deep in the call graph + +### Modules, structure, and packaging + +- Prefer narrow modules with clear import direction over utility grab bags +- Avoid circular imports by moving shared contracts to a lower layer instead of + using late imports as a default escape hatch +- Keep CLI, transport, persistence, and domain logic separated enough to test + each piece in isolation +- Prefer shallow directory structures unless there is a real sub-domain split +- Expose public package APIs deliberately; do not leak internal helpers, + framework types, or persistence models as public contracts by accident +- Packaging-specific guidance that would otherwise bloat this file lives in + [references/python-packaging-and-layout.md](references/python-packaging-and-layout.md) + +### Architecture and anti-patterns + +- Prefer composition over inheritance unless inheritance matches the real domain + model +- Wait for repeated pressure before extracting abstractions; avoid clever + registries, factories, or framework indirection that do not buy real clarity +- Keep I/O and business logic separated enough that core logic can be tested + without transport or database setup +- Do not duplicate retry, timeout, or fallback behavior at multiple layers +- Do not hard-code secrets, production hosts, or environment-specific settings +- Do not swallow exceptions, ignore partial failures silently, or hide + destructive side effects behind benign names + +### Concurrency, observability, and resilience + +- Keep sync and async entrypoints separate unless the repo already has a clear + bridging pattern +- In async code, await real work promptly; do not create background tasks + casually without ownership, cancellation, and error propagation rules +- Protect invariants, not individual fields, when threads or async tasks share + mutable state +- Service-boundary concerns become first-class only when the task actually + crosses a real external boundary such as HTTP, queues, subprocesses, or + persistent workers +- Service-boundary observability and resilience guidance lives in + [references/python-service-boundaries.md](references/python-service-boundaries.md) + +## Decision Heuristics + +Use these when the right choice is not obvious: + +- **Scope check:** if a change touches more than 3 modules or public entrypoints, + stop and plan before continuing; the change is bigger than it looks. +- **State visibility:** if mutation or side effects are hard to see from the + function signature, redesign the interface or add a one-line contract comment. +- **Typing pressure:** if `Any`, untyped dicts, or loose tuples start spreading, + introduce a clearer type boundary before adding more code. +- **Async boundary:** if a change crosses sync and async code, name the boundary + explicitly and keep adaptation local. +- **Packaging pressure:** if the change affects imports, entrypoints, package + layout, or published metadata, treat that as a compatibility boundary rather + than a refactor detail. +- **I/O boundary pressure:** if an external boundary can fail, time out, retry, + or degrade, make the ownership and diagnostics explicit; local helper code + usually does not need the same instrumentation. +- **Repo conventions:** if the repo has established formatter, linter, typing, + or framework conventions, follow them unless they create a correctness or + maintainability problem. +- **Narrowness vs. quality:** implement the narrowest change that solves the + problem. When narrowness conflicts with correctness or clarity, prefer + correctness. When it conflicts with style alone, prefer narrowness unless the + task is explicitly a cleanup. +- **Refactor boundary:** outside explicit refactor work, fix at most one small + adjacent issue while you are in the file. +- **Abstraction threshold:** three similar code blocks or repeated data-shaping + pain is a pattern; before extracting, check whether a helper function, named + type, or boundary cleanup is the simpler move. +- **Performance rule:** optimize only after measurement, except for obvious + algorithmic, allocation, or I/O mistakes on hot paths. +- **Framework pressure:** if a framework convenience hides control flow, data + ownership, or test seams, prefer the plainer construct. +- **Language-fit check:** if the problem is mostly shell orchestration, keep it + in shell; if the problem needs rich data shaping, type-safe contracts, or + non-trivial retry and observability logic, prefer Python over stretching shell + too far. + +## Validation + +A change is done when: + +- the code passes the repo's formatter or format-check +- lint and static analysis report no new findings +- type checking reports no new regressions where the repo uses type checking +- existing tests pass +- new or changed behavior has test coverage, or the lack of coverage is called + out with a concrete reason +- changed CLI, import, or service entrypoints have a narrow smoke path +- packaging metadata and import paths are verified when the change affects a + distributable library or CLI +- review findings at `Critical` and `Important` severity are addressed + +## Examples + +- `Refactor this Python service module without breaking its typed public API` +- `Review this async Python worker for retry, timeout, and test gaps` diff --git a/.agents/skills/coding-guidance-python/references/python-packaging-and-layout.md b/.agents/skills/coding-guidance-python/references/python-packaging-and-layout.md new file mode 100644 index 0000000..004c4b9 --- /dev/null +++ b/.agents/skills/coding-guidance-python/references/python-packaging-and-layout.md @@ -0,0 +1,16 @@ +# Packaging and layout + +Use this reference only when the Python task affects distribution, package +layout, imports across package boundaries, or published CLI entrypoints. + +- Prefer `pyproject.toml` as the packaging configuration source of truth +- Treat import paths, console entrypoints, and published metadata as + compatibility boundaries, not routine refactor detail +- Prefer `src/` layout for distributable libraries unless the repo has a clear + reason not to +- For typed libraries, ship `py.typed` and keep runtime dependencies distinct + from dev-only tooling +- After package-layout changes, verify imports from an installed or package-like + context rather than trusting local source-tree imports alone +- After CLI packaging changes, run a narrow entrypoint smoke test so broken + console-script wiring is caught early diff --git a/.agents/skills/coding-guidance-python/references/python-service-boundaries.md b/.agents/skills/coding-guidance-python/references/python-service-boundaries.md new file mode 100644 index 0000000..5268d6f --- /dev/null +++ b/.agents/skills/coding-guidance-python/references/python-service-boundaries.md @@ -0,0 +1,15 @@ +# Service boundaries + +Use this reference only when the Python task crosses a real I/O boundary such +as HTTP, queues, cron jobs, subprocesses, or persistent workers. + +- Emit enough structured logs, metrics, or trace context to explain what + happened without redeploying for diagnosis +- Use stable, bounded log and metric fields; do not emit high-cardinality + labels such as raw user IDs into metrics +- Distinguish expected operational events from real failures; do not log normal + validation or user mistakes as `ERROR` +- Be explicit about timeouts, retries, idempotency, and backpressure at I/O + boundaries +- Retry only transient failures, with bounded attempts and jittered backoff +- Keep retry ownership in one layer; double-retry behavior is usually a bug diff --git a/.agents/skills/coding-guidance-qt/SKILL.md b/.agents/skills/coding-guidance-qt/SKILL.md new file mode 100644 index 0000000..f504847 --- /dev/null +++ b/.agents/skills/coding-guidance-qt/SKILL.md @@ -0,0 +1,366 @@ +--- +name: coding-guidance-qt +description: Qt implementation and review skill. Use when writing, modifying, refactoring, or reviewing Qt C++ QWidget desktop code, especially Widgets, `.ui` forms, Designer-generated UI, models, `QAbstractItemModel`, signals and slots, `eventFilter`, `QThread`, CMake-based Qt5/Qt6 builds, layout-heavy UI, and QObject lifetime or thread-affinity problems. Portable across Qt-based C++ application repos. +--- + +# Qt Coding Guidance + +This skill adds portable Qt implementation, refactoring, and review guidance +for Qt C++ code with a QWidget desktop focus. Widget, dialog, model/view, +Designer, and desktop-UX guidance here is specific to Widgets work; broader +QObject, threading, and build guidance also applies to non-UI Qt C++ code. + +## Adjacent Skills + +This skill provides portable Qt engineering principles. Compose with: + +- **Workflow:** **thinking** (planning), **recursive-thinking** (stress-testing), + **security** (threat modeling) +- **Domain overlays:** **ui-guidance** (ordinary graphical UI work), + **ui-design-guidance** (stronger design and UX work), + **project-core-dev** (repo-specific build/test commands), + **project-platform-diagnose** (environment-sensitive diagnosis) + +Use this as the default principle skill for Qt code. Reach for +**coding-guidance-cpp** only when the task is mostly non-Qt C++ or needs deeper +general C++ design judgment than Qt-specific guidance. + +## Quick Routing + +Open bundled references only when the task actually needs them: + +- [references/qt-build-compatibility.md](references/qt-build-compatibility.md) + for CMake, generated-code, or Qt5/Qt6 compatibility work +- [references/qt-debugging-checklist.md](references/qt-debugging-checklist.md) + for diagnosis-heavy tasks +- [references/qt-designer-ui-files.md](references/qt-designer-ui-files.md) + for `.ui` files, Qt Widgets Designer, `uic`, or generated `ui_*.h` code +- [references/qt-layouts-and-desktop-ux.md](references/qt-layouts-and-desktop-ux.md) + for layout, dialog, panel, and desktop-UX work +- [references/qt-model-view-checklist.md](references/qt-model-view-checklist.md) + for `QAbstractItemModel`, roles, resets, selections, and model/view contract work + +Stay in the main skill when the task is broad Qt implementation or review and +no single failure mode dominates yet. + +## When Not to Lean on This Skill + +- non-Qt work +- pure backend or library code written in C++ that does not use Qt types, + eventing, object lifetime, or Qt build tooling +- Qt Quick or QML-first work +- design-only work where no Qt API, object model, build, or code judgment is + needed + +## Implementation Workflow + +1. Read the touched widgets, models, controllers, dialogs, `.ui` forms, tests, + and build files before editing. +2. Infer intended behavior from current signals and slots, ownership, thread + affinity, layouts, and tests when the request is partially specified. Ask + only when multiple plausible Qt designs would change semantics. +3. Choose the narrowest change that keeps QObject ownership, event ordering, + layout behavior, model contracts, and UI-thread rules explicit. +4. Implement with one clear application bootstrap, small widget responsibilities, + modern typed `connect` usage, minimal GUI-thread work, and narrow seams + between widgets and domain logic. +5. Add or update deterministic tests close to the changed behavior. Default: + Qt Test for widget, signal-slot, and model behavior; GoogleTest for pure + non-Qt domain logic. Do not mix both in the same seam without a reason. If + the repo already uses Qt Test, use `QSignalSpy`-style assertions for signal + contracts. +6. Run the narrowest relevant formatter, build, test, and affected-platform + smoke path the repo supports. If the change touches Qt5/Qt6 compatibility, + validate each supported build variant. + +## Refactoring Workflow + +Use this instead of the default implementation workflow when the task is +primarily cleanup or restructuring: + +1. Capture current ownership, signal flow, event-loop assumptions, thread + affinity, layout behavior, and model or binding contracts. +2. Break the refactor into small slices that preserve visible behavior. +3. Remove long widget constructors, tangled signal chains, view-model leakage, + duplicated object wiring, and layout hacks one step at a time. +4. Keep tests or smoke paths passing after each slice; add characterization + coverage first when behavior is unclear. +5. Stop when the code is simpler, safer around lifetime and threading, and + easier to reason about. + +## Review Workflow + +When reviewing (not implementing), skip the implementation workflow and use this +instead: + +1. Read the change in full before commenting. +2. Identify findings, ordered by severity: `Critical` > `Important` > + `Suggestion`. +3. Prioritize ownership and deletion bugs, cross-thread QObject misuse, + connection lifetime mistakes, GUI-thread blocking, model/view contract + violations, layout breakage, Qt5/Qt6 build regressions, resource-path and + platform assumptions, and missing tests. +4. State findings with concrete evidence and the likely consequence. +5. For Qt-specific claims, name the proof: sender/receiver types and lifetimes + for signal issues, thread affinity for cross-thread issues, begin/end and + reset boundaries for model issues, and the visible interaction path for + layout or `.ui` regressions. + +## Qt Rules + +### First tier - causes bugs + +- These rules apply to Qt C++ broadly; Widget-specific rules appear in later + sections. +- Treat `QObject` ownership, parent-child lifetime, and thread affinity as core + contracts, not cleanup details +- Every Widgets application gets exactly one `QApplication`; create it before + any widget, `QPixmap`, `QIcon`, or other GUI object +- Do not copy `QObject` subclasses; keep lifetime and ownership explicit +- Use `deleteLater()` rather than immediate deletion when an object may still be + participating in the event loop +- Do not touch GUI objects from non-GUI threads +- Bind connection lifetime to a context object when possible so queued work does + not outlive the receiver +- Prefer the typed `connect` syntax over string-based `SIGNAL` and `SLOT` + macros unless the repo is constrained by old APIs +- Do not block the GUI thread with filesystem, network, database, or heavy CPU + work +- When model data changes, emit the correct notifications and bracket + structural changes with the correct begin/end calls +- Do not hand-place widgets with `setGeometry()` when a real layout should own + sizing and positioning + +### Second tier - prevents mistakes + +- Keep widgets, models, delegates, dialogs, and business logic separated + enough to test behavior without full UI setup +- Prefer explicit ownership and small helper objects over hidden globals or + wide controller classes +- Keep slot bodies short; move non-trivial work into named helpers, presenters, + or model logic +- Prefer Qt containers, strings, and utilities where the repo already uses + them; do not introduce needless conversions at every boundary +- Follow the repo's Qt version and idioms before introducing newer Qt APIs +- Keep compiler, clazy, and Qt-specific warnings at zero in repo-owned code + +### Architecture and object lifetime + +- This section mixes general Qt lifetime guidance with QWidget screen-structure + defaults. +- For Widgets apps, keep application bootstrap, main-window construction, and + signal wiring easy to find +- In `QMainWindow` code, separate central-widget setup, action/menu setup, and + signal wiring instead of burying everything in one constructor +- Use this default boundary unless the repo already chose differently: + plain C++ domain logic owns rules and state transitions; Qt-facing models or + adapters translate domain state for the UI; widgets own presentation, local + interaction, and signal wiring +- For non-trivial screens, a presenter, controller, or adapter seam is often + simpler than stuffing decisions into slots +- Parent-child ownership is convenient, but only when the parent truly owns the + child for the same lifetime +- Use raw pointers for non-owning QObject references only when lifetime is + obvious; use `QPointer` or a clearer ownership boundary when deletion can race + with callbacks or queued work +- Avoid parented stack objects and mixed manual-plus-parent ownership +- Make who creates, owns, and tears down long-lived objects obvious near the + construction site +- Be careful with lambdas connected to signals; capture only what can outlive + the connection or tie the connection to a context object + +### Signals, slots, and events + +- These rules apply to Qt C++ broadly, not only Widgets screens. +- Treat signals as contracts; name them for state changes or completed actions, + not vague implementation detail +- Prefer one clear signal over several partially overlapping ones when callers + need a stable contract +- Avoid long signal chains that make control flow impossible to follow +- Be explicit about connection type when thread hops or reentrancy matter +- Guard against recursive updates and signal storms when setters feed models, + bindings, or other observers +- If a signal appears connected but never fires, verify sender lifetime, + signature compatibility, and that moc ran after the last `Q_OBJECT` change +- Use event filters sparingly; prefer normal event handlers when ownership and + routing are local + +### Models, views, and UI boundaries + +- This section is mostly QWidget model/view guidance; use the reference for + contract-heavy model work. +- Preserve the formal contract of Qt item models; invalid indexes, role names, + and reset behavior are compatibility boundaries +- Keep view state, model state, and domain state separated enough that each can + be tested and debugged directly +- Prefer explicit model roles and property names over stringly ad hoc data + blobs +- Avoid doing heavy logic in delegates, bindings, or paint paths +- When a view needs derived presentation state, prefer a model or adapter seam + over burying logic in widget callbacks +- In mixed QML/Widgets code, treat binding loops and context-property sprawl as + design smells; this skill still defaults to the QWidget side +- Detailed model/view rules and review checks live in + [references/qt-model-view-checklist.md](references/qt-model-view-checklist.md) + +### Layouts and desktop UX + +- This section is Widgets-specific. +- Layouts own geometry; use real layout types and desktop-native composition + instead of manual sizing or geometry hacks +- Use `QFormLayout`, `QSplitter`, `QDockWidget`, `QGroupBox`, and + `QDialogButtonBox` deliberately where their semantics match the screen +- Prefer standard buttons, shortcuts, dialogs, icons, and paths when Qt + provides them, instead of hard-coding one platform's desktop conventions +- Be deliberate with `QSizePolicy`, stretch factors, margins, spacing, + accessibility names, and keyboard flow +- Detailed layout and desktop-UX patterns live in + [references/qt-layouts-and-desktop-ux.md](references/qt-layouts-and-desktop-ux.md) + +### Threading, async, and responsiveness + +- These rules apply to Qt C++ broadly, not only Widgets screens. +- Move blocking or long-running work off the GUI thread and define how results + are marshaled back +- Use queued delivery deliberately when crossing thread boundaries; do not + assume the default connection behavior is always correct +- Do not create children for a parent that lives in another thread +- Do not move an object to another thread unless its ownership, children, and + event handling model all remain valid there +- Prefer explicit task ownership, cancellation, and teardown rules for timers, + workers, and asynchronous replies +- Treat shutdown, application quit, and window close paths as lifetime hazards + for queued callbacks and pending replies + +### Build and version compatibility + +- These rules apply to Qt C++ broadly; `.ui` guidance is Widgets-specific. +- Respect moc, uic, qrc, and build-system boundaries; file moves or class shape + changes that affect generated code are not trivial refactors +- Do not edit generated `ui_*.h` files; change the `.ui` form, the wrapper + widget, or the build inputs that generate them +- When a repo uses Qt Widgets Designer, treat `.ui` XML, form settings, custom + widget declarations, and generated includes as part of the source contract +- If the repo supports both Qt5 and Qt6, use version-driven CMake patterns + rather than hard-coded `Qt5::` or `Qt6::` targets +- In Qt6-first CMake repos that are not already standardized on a stable local + pattern, prefer Qt's own helper commands such as + `qt_standard_project_setup()` and `qt_add_executable()` over ad hoc target + setup +- Treat Qt version compatibility as a public build contract; test each claimed + variant instead of assuming dynamic `find_package` is enough +- Prefer stable resource lookup and path handling over current-working-directory + assumptions +- Mark user-visible strings for translation through the repo's chosen path, + `tr()` by default; do not introduce raw UI text that bypasses extraction +- Keep translation keys, object names, and user-visible strings deliberate + rather than incidental +- Do not introduce obsolete Qt classes or deprecated members in new code when a + maintained alternative exists; if a touched API is obsolete, treat migration + pressure as part of the design review +- If a subsystem is mostly plain C++, keep Qt-specific concerns at the boundary + instead of spreading Qt types everywhere without benefit +- Detailed build and compatibility patterns live in + [references/qt-build-compatibility.md](references/qt-build-compatibility.md) + +### Testing and debugging + +- Test visible behavior, model transitions, emitted signals, and lifecycle + edges, not just private helper functions +- Prefer deterministic UI tests and offscreen smoke paths over fragile timing- + dependent visual assertions +- Treat build verification as part of test completion; generated or updated + tests that do not compile are incomplete +- Use `qDebug()` and `qWarning()` deliberately for widget size, object class, + state transitions, and connection-path diagnostics +- For memory or lifecycle bugs in C++, prefer AddressSanitizer and Qt-aware + lifetime inspection over guessing +- Detailed failure categorization and diagnosis steps live in + [references/qt-debugging-checklist.md](references/qt-debugging-checklist.md) + +## Review Hotspots + +- missing `Q_OBJECT`, stale moc output, or signal/slot signature mismatch +- wrong QObject ownership or `deleteLater()` timing +- cross-thread object parenting or GUI-thread violations +- incorrect model notifications, reset behavior, or invalid index handling +- edits to generated `ui_*.h` instead of the underlying `.ui` or wrapper code +- new user-visible strings that bypass translation or break existing i18n paths +- newly introduced obsolete Qt APIs or deprecated members +- hidden layout regressions from `QSizePolicy`, stretch, spacing, or minimum + size changes +- Qt5/Qt6 target-family drift in CMake + +## Review Evidence + +- For signal or slot bugs, name the sender, receiver, connection style, and the + lifetime or signature fact that breaks the path +- For thread-affinity bugs, name which object lives on which thread and where + the illegal GUI or parenting access occurs +- For model/view bugs, name which contract breaks: wrong `data()` role, + missing `begin*/end*`, invalid index handling, reset misuse, or stale + selection/persistent-index assumptions +- For layout or `.ui` bugs, name the affected screen path and the geometry or + form-setting change that causes the regression +- For build or generated-code bugs, name the specific moc/uic/qrc or CMake + input that is stale, missing, or version-skewed + +## Decision Heuristics + +Use these when the right choice is not obvious: + +- **Lifetime pressure:** if it is not obvious who owns a QObject or when it can + die, redesign the boundary before adding more behavior. +- **Thread-affinity pressure:** if a callback, timer, or reply may arrive on a + different thread, make that hop explicit and local. +- **Model-contract pressure:** if a change touches model indexes, role names, + or reset behavior, treat it as a compatibility boundary rather than a local + cleanup. +- **Layout pressure:** if you are about to use manual geometry, spacer hacks, or + magic sizes, stop and check whether the right layout type, size policy, or + stretch factor would solve it cleanly. +- **Build-compatibility pressure:** if a repo claims both Qt5 and Qt6 support, + do not hard-code one target family or test only one build. +- **Architecture pressure:** if widget code starts owning business rules, + persistence, and orchestration together, introduce a presenter/controller seam + before adding more slots. +- **UI responsiveness:** if the feature can stall input, painting, or startup, + rethink the design before polishing the code. +- **Repo conventions:** if the repo has established patterns for ownership, + signals and slots, widgets vs. QML, testing, or Qt version support, follow + them unless they create a correctness problem. +- **Narrowness vs. quality:** implement the narrowest change that solves the + problem. When narrowness conflicts with correctness or lifecycle safety, + prefer correctness. When it conflicts with style alone, prefer narrowness + unless the task is explicitly a cleanup. +- **Refactor boundary:** outside explicit refactor work, fix at most one small + adjacent issue while you are in the file. +- **Abstraction threshold:** three similar widget handlers, signal-wiring paths, + model-shaping steps, or dialog flows is a pattern; before extracting, check + whether a small helper, adapter, presenter, or model object is the simpler + move. +- **Qt vs. plain C++:** if logic does not need the event loop, QObject + identity, or Qt containers, keep it as plain testable C++ instead of forcing + Qt into the core domain. + +## Validation + +A change is done when: + +- the code builds without new compiler, moc, or Qt-specific warnings +- existing tests pass +- new or changed behavior has test coverage, or the lack of coverage is called + out with a concrete reason +- changed signal, layout, model, or thread-hop behavior has a deterministic + validation path +- UI-facing changes have at least a narrow smoke path on the affected platform +- Qt5/Qt6 compatibility changes were validated on each claimed build variant +- resource paths, generated-code inputs, and translation-sensitive changes were + verified when touched +- review findings at `Critical` and `Important` severity are addressed + +## Examples + +- `Review this Qt dialog and layout refactor for ownership, size-policy, and accessibility regressions` +- `Refactor this Qt widget controller so business logic moves out of slots and the UI stays responsive` +- `Fix this Qt CMake setup so the repo can build cleanly against both Qt5 and Qt6` diff --git a/.agents/skills/coding-guidance-qt/references/qt-build-compatibility.md b/.agents/skills/coding-guidance-qt/references/qt-build-compatibility.md new file mode 100644 index 0000000..5acf130 --- /dev/null +++ b/.agents/skills/coding-guidance-qt/references/qt-build-compatibility.md @@ -0,0 +1,52 @@ +# Qt Build Compatibility + +Open this reference only when the task touches CMake, generated Qt build steps, +or real Qt5/Qt6 compatibility requirements. + +## Use when + +- the repo claims support for both Qt5 and Qt6 +- `CMakeLists.txt` contains hard-coded `Qt5::` or `Qt6::` targets +- generated-code inputs such as moc, uic, or qrc are part of the failure +- a build works on one Qt version and fails on the other + +## Core patterns + +- Prefer version-driven discovery over hard-coded target families: + +```cmake +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core Widgets) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets) +``` + +- Prefer version-driven targets: + +```cmake +target_link_libraries(myapp + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets +) +``` + +- In Qt6-first repos that are not already standardized on a stable local + pattern, prefer Qt's helper commands such as + `qt_standard_project_setup()` and `qt_add_executable()` over ad hoc Qt target + setup. + +- Treat moc, uic, and qrc changes as build-contract changes, not local cleanup. + +## Review hotspots + +- hard-coded `Qt5::` / `Qt6::` targets in a repo that claims both +- new hand-rolled CMake setup in a Qt6-first repo where Qt helper commands + would be clearer and less error-prone +- generated headers or sources not regenerated after class-shape changes +- stale `Q_OBJECT` additions that compile only because one platform cached old + generated files +- resource lookups that depend on the current working directory + +## Validation + +- configure and build each claimed Qt variant +- verify generated-code inputs are part of the build graph +- smoke-test the changed UI path on at least one affected platform diff --git a/.agents/skills/coding-guidance-qt/references/qt-debugging-checklist.md b/.agents/skills/coding-guidance-qt/references/qt-debugging-checklist.md new file mode 100644 index 0000000..4e26bd1 --- /dev/null +++ b/.agents/skills/coding-guidance-qt/references/qt-debugging-checklist.md @@ -0,0 +1,88 @@ +# Qt Debugging Checklist + +Open this reference when the task is primarily diagnosis rather than ordinary +implementation. + +## Use when + +- the failure class is still unclear and you need to categorize before editing +- the bug looks like ownership, signal/slot, layout, thread-affinity, or style + breakage +- the change is mostly diagnosis rather than feature or refactor work + +## Fast categorization + +Classify the symptom before changing code: + +- invisible widget +- zero-size widget or collapsed layout +- deleted-object access +- cross-thread QObject misuse +- pre-`QApplication` GUI object construction +- frozen event loop / blocked GUI thread +- signal connected but never fires +- style or QSS mismatch + +## High-value checks + +### Invisible or collapsed widget + +- check `isVisible()`, `isHidden()`, and actual size +- verify parent visibility for child widgets +- verify a real layout is attached +- check `QSizePolicy`, stretch, minimum size, margins, and accidental + `setFixedSize(0, 0)` + +### Deleted-object or lifecycle bug + +- check whether the object is owned by a parent that is already gone +- check `deleteLater()` timing and queued callbacks +- prefer `QPointer` for observing objects with unstable lifetime +- in C++, use ASan before guessing + +### Thread-affinity bug + +- look for cross-thread parent/child creation +- verify where the receiver lives, not only where the signal was emitted +- make queued delivery explicit if the hop matters + +### Signal path bug + +- verify sender lifetime +- verify exact signal/slot signature compatibility +- verify `Q_OBJECT` is present and moc reran after the last change + +### Frozen UI + +- find the blocking call on the GUI thread +- move I/O or heavy work off-thread +- treat `processEvents()` as diagnosis only, not the final fix + +### Style or QSS bug + +- inspect the effective stylesheet +- use local `unpolish()` / `polish()` and `update()` to confirm rule + application before changing rendering logic + +## Review hotspots + +- code changes made before the failure class was identified +- `processEvents()` used as a production fix instead of diagnosis +- guessed lifecycle or thread explanations without checking object ownership or + affinity +- layout or style fixes applied without verifying the actual geometry or active + stylesheet state + +## Useful C++ diagnostics + +```cpp +qDebug() << "size" << widget->size(); +qDebug() << "class" << widget->metaObject()->className(); +qWarning() << "unexpected state" << state; +``` + +## Validation + +- the root failure class is identified +- the fix removes the cause instead of hiding the symptom +- the relevant test or smoke path reproduces the fix deterministically diff --git a/.agents/skills/coding-guidance-qt/references/qt-designer-ui-files.md b/.agents/skills/coding-guidance-qt/references/qt-designer-ui-files.md new file mode 100644 index 0000000..e2051eb --- /dev/null +++ b/.agents/skills/coding-guidance-qt/references/qt-designer-ui-files.md @@ -0,0 +1,29 @@ +# Qt Designer UI Files + +Open this reference when the task touches `.ui` forms, Qt Widgets Designer, +`uic`, custom Designer widgets, or generated `ui_*.h` headers. + +## Core rules + +- Treat `.ui` files as source and generated `ui_*.h` files as build outputs +- Do not hand-edit generated UI headers; make the change in the form, the + wrapper widget, or the code that consumes the generated UI class +- When a form change affects margins, spacing, or custom widget includes, treat + the Designer form settings as behavior-affecting inputs, not editor metadata + +## Review hotspots + +- generated `ui_*.h` checked in with manual edits instead of regenerating +- `.ui` changes that silently alter layout defaults, spacing, or margins +- custom widgets declared in Designer without the includes or build wiring they + require +- wrapper code that bypasses `setupUi()` assumptions and fights the generated + layout or object naming + +## Validation + +- rebuild after every `.ui` or Designer custom-widget change so `uic` reruns +- verify the changed screen through the affected interaction path, not only by + compiling +- if the repo uses Designer heavily, keep layout ownership in the form unless a + code-side override is clearly intentional diff --git a/.agents/skills/coding-guidance-qt/references/qt-layouts-and-desktop-ux.md b/.agents/skills/coding-guidance-qt/references/qt-layouts-and-desktop-ux.md new file mode 100644 index 0000000..b3a73da --- /dev/null +++ b/.agents/skills/coding-guidance-qt/references/qt-layouts-and-desktop-ux.md @@ -0,0 +1,49 @@ +# Qt Layouts And Desktop UX + +Open this reference when the task is mainly widget composition, dialog design, +panel layout, or desktop ergonomics. + +## Layout defaults + +- layouts own geometry; do not hand-place widgets unless there is a real custom + rendering need +- prefer `QFormLayout` for forms, `QGridLayout` for true grids, and `QSplitter` + for user-resizable panel balance +- be deliberate with margins, spacing, stretch factors, and `QSizePolicy` + +## Useful patterns + +### Forms + +- use `QFormLayout` for label-field alignment +- use `QDialogButtonBox` for accept/reject flows + +### Panels + +- use `QDockWidget` only for real dockable panels +- use `QGroupBox` when visual grouping materially improves scanability +- persist `QSplitter` state for long-lived multi-panel screens + +### Accessibility and keyboard flow + +- set accessible names for important controls +- keep tab order sensible +- make important actions keyboard reachable + +### Native desktop conventions + +- prefer `QDialogButtonBox` standard roles and platform-native button ordering + over custom accept/cancel layouts +- prefer Qt standard shortcuts, icons, and dialogs before inventing custom + desktop conventions +- use Qt-provided standard paths and file dialogs instead of hard-coded + platform-specific locations + +## Layout debugging + +- if a widget is zero-size, check minimum size, size hint, attached layout, and + size policy +- if the layout ignores size changes, inspect stretch factors and whether the + widget is `Fixed` when it should expand +- if the screen looks cramped, inspect margins and spacing before rewriting the + hierarchy diff --git a/.agents/skills/coding-guidance-qt/references/qt-model-view-checklist.md b/.agents/skills/coding-guidance-qt/references/qt-model-view-checklist.md new file mode 100644 index 0000000..ea9e8e0 --- /dev/null +++ b/.agents/skills/coding-guidance-qt/references/qt-model-view-checklist.md @@ -0,0 +1,33 @@ +# Qt Model View Checklist + +Open this reference when the task touches `QAbstractItemModel`, +`QAbstractProxyModel`, selection models, custom roles, resets, or view/model +interaction bugs. + +## Core rules + +- Treat `data()`, `flags()`, `headerData()`, role names, and index validity as + compatibility-facing contracts +- Use the correct `begin*/end*` pair for structural changes; do not emit data + change signals as a substitute for inserts, removes, or moves +- Use model reset only when the model contract truly resets; prefer narrower + notifications when the structure is still meaningfully stable +- Keep selection state, current index, and persistent index assumptions explicit + when rows move, reset, or disappear + +## Review hotspots + +- `dataChanged` emitted where rows were inserted, removed, or moved +- indexes created or consumed without validating parent, row, column, or model +- custom roles added without stable names or without updating the view path that + depends on them +- view code caching model-derived state that becomes stale after reset or move +- delegates or views depending on side effects in `data()` or paint-time logic + +## Validation + +- verify the affected view path with inserts, removes, updates, and empty-model + cases +- confirm selection/current-index behavior after reset, move, or deletion +- add deterministic model tests where the contract is subtle or previously + broken diff --git a/.agents/skills/development-contract-process/SKILL.md b/.agents/skills/development-contract-process/SKILL.md new file mode 100644 index 0000000..d795dc4 --- /dev/null +++ b/.agents/skills/development-contract-process/SKILL.md @@ -0,0 +1,69 @@ +--- +name: development-contract-process +description: Portable workflow for repos that require tracked change contracts, verifier evidence, and smallest-proof validation. Use when a repo has a contract policy file or enforced feature-plan checker. +--- + +# Development Contract Process + +Find the repo's contract policy file and use it as the source of truth for repo-specific paths, plan locations, lanes, and validation profiles. +Treat any separate repo guidance as secondary unless it contradicts policy; if it does, fix the mismatch instead of guessing. + +This is a process overlay, not a thinking aid. Pair it with the repo's implementation skill for the touched code and any repo-local contract overlay that names the actual policy path and helper commands. + +## Use this skill when + +- work may trigger a tracked change contract +- a repo requires a plan update for substantive changes +- a checker validates plan structure, ownership, or evidence +- you need to choose the smallest proving validation set for a substantive change + +## Core workflow + +1. Read the touched files and the repo contract policy file before editing. +2. Decide whether the change is substantive using policy data rather than guesswork. +3. If the change is substantive, create or update a non-template plan in the policy-defined plan directory. +4. Keep the plan aligned with the repo's enforced template, required evidence lanes, and lifecycle-directory rules. +5. Keep implementation ownership and verification ownership explicit. +6. Record verifier commands, observed results, and contract mismatches concretely. +7. Run the smallest validation profile that proves the change, then extend only when the surface justifies it. +8. Before closing work, run the repo's checker command and any additional checks implied by the chosen validation profile. + +## Operator quickstart + +Use this compact path unless the repo overlay says otherwise: + +1. Read the touched files. +2. Read the repo policy file. +3. Decide whether the touched paths are substantive under policy. +4. If substantive, update the existing non-template record or create one from the repo template. +5. Implement narrowly. +6. Record verifier commands, observed results, and mismatches in the record. +7. Run the smallest proving validation profile plus the checker command. +8. If lifecycle state changed, use the repo's lifecycle helper instead of a manual move. + +## Decision rules + +- Treat the policy file as the single source of truth for substantive-path detection, plan location, section requirements, lane names, and default validation commands. +- If the repo ships a lifecycle transition helper, prefer it over manual file moves so path and lifecycle state stay synchronized. +- Do not duplicate repo literals across the skill, docs, checker, and template when policy can express them once. +- Keep the schema stable by default; use policy for repo-level variation and only change the schema when portability or correctness requires it. +- Prefer small repo overlays over forking the core skill. +- If a repo needs extra instructions that policy cannot express, add them in a thin overlay skill rather than bloating the core. +- Prefer updating an existing active record over creating scattered new notes for the same change. +- Keep the operator path lightweight: policy decides what is substantive, and the checker enforces the contract. + +## Output expectations + +When this skill applies, the final work should leave behind: + +- code or docs aligned with repo guidance and policy +- a plan update when the change is substantive +- explicit verifier evidence +- a concise report of what was validated and what could not be validated + +## References + +- `references/policy-reference.md` for the portable policy surface and adoption rules +- `references/operator-quickstart.md` for the compact day-to-day usage path +- `references/repo-overlay-template.md` for the expected shape of a repo-local overlay +- `references/run-release-checklist.example.sh` for a CMake-first pre-release runner scaffold example diff --git a/.agents/skills/development-contract-process/references/operator-quickstart.md b/.agents/skills/development-contract-process/references/operator-quickstart.md new file mode 100644 index 0000000..fdf7253 --- /dev/null +++ b/.agents/skills/development-contract-process/references/operator-quickstart.md @@ -0,0 +1,22 @@ +# Development Contract Operator Quickstart + +Use this when the repo already has a contract system and you are applying it during normal work. + +## Minimal path + +1. Read the touched files. +2. Read the repo policy file. +3. Decide whether the change is substantive from policy, not intuition. +4. If substantive, update the existing non-template record or create one from the repo template. +5. Implement narrowly and keep ownership explicit. +6. Record verifier commands, observed results, and any mismatches concretely. +7. Run the smallest proving validation profile. +8. Run the checker command before closing work. +9. If the record's state changed, use the lifecycle helper instead of moving files by hand. + +## Practical notes + +- Prefer one maintained record per substantive change slice instead of scattering notes. +- Let the policy file define plan paths, lanes, required headings, and validation profiles. +- Keep the contract record factual. It should show what changed, who implemented it, who verified it, what was run, and what remains uncertain. +- If repo docs and policy disagree, fix the mismatch rather than guessing which one is current. diff --git a/.agents/skills/development-contract-process/references/policy-reference.md b/.agents/skills/development-contract-process/references/policy-reference.md new file mode 100644 index 0000000..636b354 --- /dev/null +++ b/.agents/skills/development-contract-process/references/policy-reference.md @@ -0,0 +1,39 @@ +# Development Contract Policy Reference + +Use a small repo-local policy file as the source of truth for contract enforcement. + +## Minimum policy surface + +- plan directory +- template basename +- substantive path patterns +- substantive top-level files +- required section headings +- allowed lifecycle values +- allowed uncertainty/cost values +- allowed yes/no values when evidence lines encode impact +- allowed implementation/verification status values when ownership lanes are enforced +- allowed evidence statuses +- evidence lane names +- checker command + +Prefer a repo-neutral path such as `config/change-contract-policy.sh`, when the repository itself, CI, or shell scripts depend on the policy. + +## Recommended additions + +- named validation profiles such as `docs`, `code`, and `release` +- comments that explain the repo's substantive surface and why a path is included +- repo-specific examples for install or smoke-test commands +- a release-runner example kept as a skill reference, while the runnable repo copy lives under `scripts/` +- a repo-owned lifecycle helper when records live in state-specific subdirectories +- a policy variable for the policy file path itself when the repo wants wrappers to export it explicitly + +## Portability rules + +- keep policy data repo-local and declarative +- keep the core skill generic +- keep the checker reading the same policy file that humans read +- keep template and docs aligned with policy names +- keep lifecycle folder rules and any transition helper aligned with the checker +- prefer extending policy over cloning the core skill +- keep examples honest about ecosystem scope; if an example is CMake- or language-specific, say so directly diff --git a/.agents/skills/development-contract-process/references/repo-overlay-template.md b/.agents/skills/development-contract-process/references/repo-overlay-template.md new file mode 100644 index 0000000..9a55a1f --- /dev/null +++ b/.agents/skills/development-contract-process/references/repo-overlay-template.md @@ -0,0 +1,33 @@ +# Repo Overlay Template For Development Contract + +Use this as the shape of the repo-local overlay that sits on top of `development-contract-process`. + +## Responsibilities of the repo overlay + +- name the actual repo policy file path +- name the actual checker command +- name the lifecycle helper command if the repo has one +- call out repo-specific validation profiles when they exist +- identify any repo-specific substantive paths or human workflow rules that policy alone cannot express + +## Recommended structure + +- Start by telling the agent to read the repo policy file, then apply `development-contract-process`. +- Keep repo-specific instructions thin and operational. +- Treat the policy file as the source of truth for contract mechanics. +- Prefer changing policy data first, then docs, instead of duplicating literals in several places. + +## Example overlay flow + +1. Read the touched files. +2. Read the repo policy file. +3. Apply `development-contract-process`. +4. If the change is substantive under policy, update a non-template record in the repo's plan directory. +5. Use the lifecycle helper when changing record state. +6. Run the smallest proving validation profile and then the checker command. + +## Anti-patterns + +- Do not write the overlay as if every repo uses the same policy path, plan directory, or script names unless this is actually true. +- Do not restate schema details already enforced by policy and checker. +- Do not let the overlay drift away from the generated repo docs, template, or checker behavior. diff --git a/.agents/skills/development-contract-process/references/run-release-checklist.example.sh b/.agents/skills/development-contract-process/references/run-release-checklist.example.sh new file mode 100644 index 0000000..6e109c1 --- /dev/null +++ b/.agents/skills/development-contract-process/references/run-release-checklist.example.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +set -euo pipefail + +usage() { + cat <<'EOF_USAGE' +Usage: bash scripts/run-release-checklist.sh [--build-dir DIR] [--help] [-- ] + +Runs the automated portion of RELEASE_CHECKLIST.md up to, but not including, +manual release review. +EOF_USAGE +} + +die() { + printf 'ERROR: %s\n' "$*" >&2 + exit 1 +} + +note() { + printf '==> %s\n' "$*" +} + +run_cmd() { + note "$*" + "$@" +} + +run_build_target() { + shift + "$@" +} + +build_dir="" +declare -a extra_cmake_args=() + +while [[ $# -gt 0 ]]; do + case "$1" in + --build-dir) + [[ $# -ge 2 ]] || die "--build-dir requires a value" + build_dir="$2" + shift 2 + ;; + --help) + usage + exit 0 + ;; + --) + shift + extra_cmake_args=("$@") + break + ;; + *) + die "Unknown argument: $1" + ;; + esac +done + +if [[ -z "$build_dir" ]]; then + build_dir="$(mktemp -d /tmp/project-release-build-XXXXXX)" +fi + +declare -a generator_args=() +if command -v ninja >/dev/null 2>&1 || command -v ninja-build >/dev/null 2>&1; then + generator_args=(-G Ninja) +fi + +note "Release checklist build directory: $build_dir" +run_cmd bash scripts/check-release-hygiene.sh +run_cmd bash scripts/check-change-contracts.sh +run_cmd cmake -S . -B "$build_dir" "${generator_args[@]}" -DCMAKE_BUILD_TYPE=Debug "${extra_cmake_args[@]}" +run_build_target "$build_dir" cmake --build "$build_dir" -j"$(nproc)" +run_cmd ctest --test-dir "$build_dir" --output-on-failure +if command -v valgrind >/dev/null 2>&1; then + run_cmd bash scripts/run-valgrind.sh "$build_dir" +else + note "Skipping Valgrind because valgrind is not installed" +fi +if command -v clang-tidy >/dev/null 2>&1; then + run_build_target "$build_dir" cmake --build "$build_dir" --target clang-tidy +else + note "Skipping clang-tidy because clang-tidy is not installed" +fi +if command -v doxygen >/dev/null 2>&1; then + run_build_target "$build_dir" cmake --build "$build_dir" --target docs +else + note "Skipping docs because doxygen is not installed" +fi + +cat < ` +- optionally accept `--repo-root` +- require `--superseded-by ` for `superseded` +- validate that the record exists +- validate that it lives under the feature-records tree +- reject the root `README.md` and `TEMPLATE.md` +- update the `Lifecycle` `State` +- update `Superseded by` +- move the file into the correct lifecycle directory + +Good default transition usage: + +```bash +bash scripts/set-feature-record-lifecycle.sh feature_records/planned/.md active +bash scripts/set-feature-record-lifecycle.sh feature_records/active/.md done +bash scripts/set-feature-record-lifecycle.sh \ + --superseded-by feature_records/done/.md \ + feature_records/active/.md superseded +``` + +## Phase 7: Add tests + +Add direct tests for both the checker and the lifecycle helper. + +Checker tests should cover: + +- valid record passes +- missing required section fails +- invalid uncertainty/status values fail +- missing verifier fails +- waived without rationale fails +- superseded without pointer fails +- mismatched lifecycle folder and `State` fails +- substantive change without record update fails +- policy override with a different plan directory still works + +Lifecycle helper tests should cover: + +- moving `planned -> active` +- moving `active -> done` +- moving `active -> superseded` with replacement +- rejecting `superseded` without replacement +- checker still passes after helper-driven transitions + +Prefer shell tests when the checker/helper are shell scripts. + +## Phase 8: Add a repo-local process overlay when the repo uses skills + +If the target repository keeps project-local skills, generate a thin overlay +that: + +- names the concrete policy file path +- tells the agent to apply `development-contract-process` +- names the checker command and lifecycle helper command +- points at the repo policy's validation profiles +- avoids restating schema details already enforced by policy and checker + +Do not generate this overlay when the repo does not use local skills. The repo +must remain usable for humans and scripts without any skill dependency. + +## Phase 9: Update docs + +Update the repo docs so a human maintainer can use the system without the skill: + +- main README +- AGENTS-style maintainer guidance +- release checklist or hygiene docs +- feature-records README + +The main README should include a readable lifecycle diagram, for example: + +```text + start work complete + verify + +-----------+ ----------> +----------+ -----------------> +--------+ + | planned/ | | active/ | | done/ | + +-----------+ +----------+ +--------+ + | + | replace with newer record + v + +---------------+ + | superseded/ | + +---------------+ + + rule: records in `superseded/` must set `Superseded by` to the replacement record +``` + +Also document the lifecycle helper command explicitly. + +## Decision rules + +- Prefer repo-owned files under `config/`, `scripts/`, and `feature_records/` + over agent-specific locations. +- Keep the policy file as the single source of truth for checker behavior. +- Keep the checker and lifecycle helper deterministic and local-first. +- Prefer a small explicit schema over a flexible but vague document format. +- Keep feature records as Markdown so they are easy to review in git. +- Keep lifecycle visibility obvious from the directory tree. +- Seed each lifecycle folder with an example record unless the repo already has + real records. +- When the repo uses local skills, keep the repo-local process overlay thin and aligned + with the policy, checker, template, and docs. +- If the repo has a release checklist, point it at the checker and lifecycle + docs. + +## Final acceptance criteria + +The system is complete when: + +- the repo has a neutral policy file +- `feature_records/` exists with root docs/template and lifecycle subdirectories +- the checker enforces lifecycle and evidence rules +- the helper script performs lifecycle transitions deterministically +- direct tests exist for checker and helper +- if the repo uses local skills, the repo-local process overlay points at the concrete + policy/checker/helper without duplicating schema literals +- repo docs explain the lifecycle model and helper commands +- the repo's hygiene or validation path includes the checker + +## Output expectations + +When using this skill, leave behind: + +- the full repo-owned contract system +- example lifecycle records or migrated real records +- tests that prove checker and helper behavior +- docs aligned with the system +- a concise summary of what was validated and what remains manual diff --git a/.agents/skills/documenter-coauthoring/SKILL.md b/.agents/skills/documenter-coauthoring/SKILL.md new file mode 100644 index 0000000..23c630d --- /dev/null +++ b/.agents/skills/documenter-coauthoring/SKILL.md @@ -0,0 +1,48 @@ +--- +name: documenter-coauthoring +description: Companion overlay for multi-round collaborative drafting of large specs, proposals, decision docs, and similar documents. Use when the workflow needs structured context gathering, explicit outline approval, section-by-section iteration, and reader-testing rather than a direct documentation pass. +--- + +# Documenter Coauthoring + +Structured coauthoring workflow for large docs. Pair this with `documenter` +when the task needs sustained collaboration instead of a direct draft/update. + +## Core Workflow + +1. Gather context efficiently: + - ask for audience, desired outcome, constraints, deadline, and template + - invite a raw context dump; do not force the user to pre-organize it + - read linked local files and existing docs before asking avoidable questions +2. Propose a structure before drafting the full doc when scope is still fuzzy + or the document is large. +3. Draft the sections with the most uncertainty first. Summary sections usually + come last. +4. Refine with surgical edits instead of reprinting the whole document on every + iteration. +5. Before finishing, do a reader test: + - check whether a reader without hidden context can follow the decision, + procedure, or reference entry + - look for missing assumptions, undefined terms, and filler that adds little + value + +## Decision Rules + +- prefer this skill only for substantial docs; small edits should stay with + `documenter` alone +- defer baseline doc-type, hygiene, style, and validation rules to + `documenter`; this skill adds collaboration workflow +- when a template exists, align to it early instead of drafting against a + guessed structure +- ask for approval on the outline when the document shape materially affects the + content +- keep summary sections until late, after the decision and evidence are clear +- capture user preference from feedback and apply it to later sections + +## Exit Criteria + +- the full document has a coherent structure +- section order matches reader needs +- important assumptions are stated explicitly +- repeated or low-value text has been removed +- a fresh reader can follow the document without hidden context diff --git a/.agents/skills/documenter/SKILL.md b/.agents/skills/documenter/SKILL.md index d6a4bad..df81c4f 100644 --- a/.agents/skills/documenter/SKILL.md +++ b/.agents/skills/documenter/SKILL.md @@ -1,42 +1,129 @@ --- name: documenter -description: Documentation skill for README, API docs, code comments, release docs, and AI-friendly project documentation. +description: "Baseline overlay for substantial documentation authoring or restructuring: README, specs, ADRs, tutorials, how-to guides, reference docs, explanations, API docs, code comments, changelogs, and agent-facing docs. Use when the agent should classify doc type, ground claims in repo truth, and validate examples before finishing." --- # Documenter -Read `AGENTS.md` first. This skill adds documentation-specific guidance. +Documentation workflow for repo docs, technical writing, and inline API comments. ## Priorities - keep docs accurate, scannable, and current -- prefer examples over vague prose +- identify audience, document type, and source of truth before drafting +- prefer examples and concrete structures over vague prose - match README/docs to actual build, test, install, and release behavior -- keep Doxygen-facing docs API-focused and release-facing docs user-focused +- keep public API comments complete enough for generated docs +- keep one document one job; link to neighboring docs instead of mixing modes + +## Not For + +- binary document manipulation such as `.docx`, `.pdf`, `.pptx`, or `.xlsx` +- regulatory document-control systems, compliance programs, or quality records +- repo-specific doc-site pipelines unless the repo already contains them +- intensive coauthoring sessions for large specs or proposals + use `documenter-coauthoring` for that mode ## Core Workflow -1. Identify the audience: user, contributor, maintainer, or agent. -2. Read the current docs and the source of truth in code/build scripts. -3. Update only the sections affected by the change. -4. Keep structure compact: title, one-line purpose, quick start, key commands, - important constraints. -5. If public headers change, update API comments immediately. +1. Classify the request before writing: + - audience: user, contributor, maintainer, reviewer, or agent + - document type: README, spec, ADR, tutorial, how-to, reference, explanation, + API doc, code comment, changelog, release note + - output target: existing file, new file, or inline content +2. Read the current doc plus local source of truth in code, config, build + scripts, tests, release files, and existing repo guidance. +3. Pick the structure that fits the job: + - small edit: update only affected sections + - large or new doc: outline first, then draft section by section +4. Draft in compact Markdown with active voice, present tense, and direct + wording. Explain before code when the reader needs context. +5. Validate every claim you can: + - run or inspect commands and examples when feasible + - check links, paths, identifiers, and filenames + - if examples cannot be validated, say so instead of implying they were + checked +6. Tighten before finishing: remove duplication, filler, and mixed-purpose + sections. Cross-link instead of repeating background. + +## Bundled Reference + +Load [references/doc-templates.md](references/doc-templates.md) when the task +needs a compact starting structure for README sections, ADRs, endpoint docs, +public API comments, or changelog entries. +## Document Type Rules + +Use Diataxis when the request is general documentation rather than a repo +convention with its own fixed format. + +- tutorial: for first-time learning by doing; every step should produce a + visible result +- how-to: for solving one known task; assume baseline knowledge and skip theory +- reference: for facts, options, endpoints, flags, or API contracts; optimize + for fast lookup +- explanation: for trade-offs, concepts, rationale, and "why" + +Keep each document a single dominant type. Link to related docs instead of +mixing tutorial steps, reference tables, and conceptual background in one page. -## README Rules +## README And Project Docs Rules - answer what it is, how to build it, how to test it, and how to release it - keep quick start runnable in minutes +- keep top-level structure compact: title, one-line purpose, quick start, key + commands, important constraints - avoid stale feature claims and aspirational behavior presented as shipped +- use tables for config, support matrices, or command summaries when they make + scanning faster + +## Specs, ADRs, And Change Docs Rules + +- specs and proposals should state audience, problem, constraints, decision, and + open questions +- ADRs should separate context, decision, and consequences +- changelogs and release notes should emphasize user-visible changes, breaking + changes, and upgrade action +- if a decision depends on local politics or history, state the consequence + plainly instead of hinting at it ## Code Comment Rules - comment why, contracts, and non-obvious behavior - do not narrate obvious statements line by line - keep public API comments complete enough for Doxygen/docs generation +- include params, return values, errors, and examples when the API surface needs + them +- do not invent API behavior that code does not implement + +## Documentation Hygiene Rules + +- put durable documentation where the repo already expects it; do not force a + generic `docs/` layout onto repos that use a different structure +- make docs discoverable: link new durable docs from the nearest index, README, + sidebar, or parent doc when the repo has one +- prefer contextual links over vague text such as "click here" +- use relative links for repo-local docs unless the repo clearly prefers another + pattern +- keep time-sensitive status, progress snapshots, and point-in-time test output + out of durable docs unless the file is explicitly meant to record history, as + in changelogs or ADRs +- when writing docs ahead of implementation, mark planned interfaces clearly and + replace placeholders with real behavior once the code exists + +## Style Rules + +- prefer simple, concrete words: `use`, `add`, `run`, `because` +- prefer active voice; passive is acceptable when the actor is irrelevant +- keep paragraphs short; split when a reader would need to re-parse the sentence +- use direct address in tutorials and how-to guides; use neutral voice in + references +- avoid throat-clearing such as "this section describes" unless it adds meaning -## Project Docs Rules +## Validation Rules +- examples should be runnable, inspectable, or clearly marked illustrative +- if public headers or external APIs change, update API comments immediately - keep checklists actionable -- prefer concise tables and commands over long prose where possible -- keep agent-facing docs aligned with `AGENTS.md` and local skills +- keep agent-facing docs aligned with repo guidance and local skills +- for AI-facing docs, prefer clear heading hierarchy, self-contained sections, + and direct file/path references diff --git a/.agents/skills/documenter/references/doc-templates.md b/.agents/skills/documenter/references/doc-templates.md new file mode 100644 index 0000000..eb6a27e --- /dev/null +++ b/.agents/skills/documenter/references/doc-templates.md @@ -0,0 +1,94 @@ +# Documentation Templates + +Use these as starting points when the repo does not already provide a stronger +local format. + +## README + +```md +# Project Name + +One-line purpose. + +## Quick Start + +[short runnable steps] + +## Key Commands + +| Command | Purpose | +|---------|---------| +| `...` | ... | + +## Configuration + +| Variable | Description | Default | +|----------|-------------|---------| +| `...` | ... | ... | +``` + +## ADR + +```md +# ADR-001: Title + +## Status +Accepted + +## Context +[why a decision is needed] + +## Decision +[what was chosen] + +## Consequences +[trade-offs and follow-up] +``` + +## API Endpoint + +```md +## GET /resource/:id + +Short purpose. + +### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| `id` | `string` | yes | Resource identifier | + +### Responses + +- `200`: success payload +- `404`: not found +``` + +## Public API Comment + +```ts +/** + * Brief purpose. + * + * @param input - Meaning of the input. + * @returns Meaning of the result. + * @throws ErrorName - When it fails. + * @example + * const value = fn("x") + */ +``` + +## Changelog Entry + +```md +## [Unreleased] + +### Added +- ... + +### Changed +- ... + +### Fixed +- ... +``` diff --git a/.agents/skills/documenter/references/fusion-notes.md b/.agents/skills/documenter/references/fusion-notes.md new file mode 100644 index 0000000..07a74d4 --- /dev/null +++ b/.agents/skills/documenter/references/fusion-notes.md @@ -0,0 +1,40 @@ +# Documenter Fusion Notes + +Use these notes when revising `documenter` or adjacent documentation skills. + +## Current Boundary + +`documenter` is the baseline documentation overlay. Keep it focused on: + +- document-type selection +- repo-truth verification +- durable documentation hygiene +- concise structure and style rules +- API comment expectations + +Do not keep optional heavy workflows in the baseline if they can live in a +companion skill. + +Prefer moving presentation-level preferences and optional metadata conventions +out of the baseline before moving core verification or hygiene rules. + +## Companion Skill Boundary + +Use `documenter-coauthoring` for: + +- large specs, proposals, or decision docs +- sessions that need explicit context gathering and staged drafting +- iterative reader-testing and section-by-section collaboration + +If future edits reintroduce that workflow into `documenter`, move it back out. + +## Rejected Additions + +These were reviewed and intentionally excluded from the baseline skill: + +- hard `docs/` directory conventions +- mandatory doc-site indexing or GitHub Pages workflows +- Office/PDF/PowerPoint/Excel manipulation guidance +- regulatory document-control and compliance-management material + +Keep these concerns in separate skills or repo-local overlays. diff --git a/.agents/skills/documenter/references/trigger-evals.md b/.agents/skills/documenter/references/trigger-evals.md new file mode 100644 index 0000000..bb25392 --- /dev/null +++ b/.agents/skills/documenter/references/trigger-evals.md @@ -0,0 +1,29 @@ +# Documenter Trigger Evals + +Use these prompts to spot over-triggering and boundary drift between +`documenter` and `documenter-coauthoring`. + +## Expected `documenter` + +- "Update the README install steps to match the current CLI flags." +- "Write API docs for these new endpoints." +- "Turn this rough markdown into a clear how-to guide." +- "Add missing public API comments to these headers." +- "Clean up this changelog entry and remove stale claims." + +## Expected `documenter` + `documenter-coauthoring` + +- "Help me co-author a design doc for the new caching layer." +- "I need to draft a proposal and want to iterate section by section." +- "Let's build this ADR together. Start by helping me shape the outline." +- "I have a lot of context for a spec. Ask questions, then help me draft it." + +## Expected Neither + +- "Merge these PDFs." +- "Build a docs website with MkDocs and GitHub Pages." +- "Set up a compliance document-control workflow for regulated releases." +- "Summarize this existing markdown file." + +If the expected skill choice stops looking obvious, tighten frontmatter before +adding more behavior. diff --git a/.agents/skills/project-config-and-tests/SKILL.md b/.agents/skills/project-config-and-tests/SKILL.md index d1d006e..2aa454a 100644 --- a/.agents/skills/project-config-and-tests/SKILL.md +++ b/.agents/skills/project-config-and-tests/SKILL.md @@ -1,19 +1,32 @@ --- name: project-config-and-tests -description: Generic overlay for config contracts, defaults, path helpers, and deterministic test coverage. +description: Overlay for config contracts, defaults, path helpers, and deterministic test coverage. Use alongside the repo's principle skill when the main task is config behavior or test coverage. --- # Project Config And Tests -Read `AGENTS.md` first. Use this skill when the main task is config behavior or -small deterministic test coverage. +This is a composable overlay, not a standalone workflow. +Use alongside the repo's principle skill (e.g. **coding-guidance-cpp**) when the +main task is config behavior or test coverage. -## Focus +## When to use + +The task involves config parsing, defaults, path resolution, normalization, or +adding deterministic test coverage around these seams. + +## Not for + +General feature work (use **project-core-dev**), vendored dependency changes +(use **project-vendor-boundary**), or release/packaging work (use +**project-release-maintainer**). + +## Rules - keep config parsing non-fatal where that preserves recovery/help paths - keep defaults, example config, and docs aligned - prefer deterministic tests around parsing, normalization, and helper seams - using `frame_test.h` macros + using the repo's test framework - keep WHAT/HOW/WHY commentary current in repo-owned tests -- add benchmarks for performance-sensitive helpers using `frame_bench.h` -- use the `coverage` preset and target to verify test coverage for new code +- add benchmarks for performance-sensitive helpers using the repo's benchmark + framework when available +- use the repo's coverage tooling to verify test coverage for new code diff --git a/.agents/skills/project-core-dev/SKILL.md b/.agents/skills/project-core-dev/SKILL.md index 52a81ed..0f9869e 100644 --- a/.agents/skills/project-core-dev/SKILL.md +++ b/.agents/skills/project-core-dev/SKILL.md @@ -5,7 +5,7 @@ description: Overlay for day-to-day feature work and bug fixes in repo-owned cod # Project Core Dev -Read `AGENTS.md` first. This is a composable overlay, not a standalone workflow. +This is a composable overlay, not a standalone workflow. Use alongside the repo's principle skill (e.g. **coding-guidance-cpp**) for normal feature work and bug fixes in repo-owned code. diff --git a/.agents/skills/project-platform-diagnose/SKILL.md b/.agents/skills/project-platform-diagnose/SKILL.md index 0de4356..766627e 100644 --- a/.agents/skills/project-platform-diagnose/SKILL.md +++ b/.agents/skills/project-platform-diagnose/SKILL.md @@ -5,7 +5,7 @@ description: Overlay for environment-sensitive diagnosis — service startup, in # Project Platform Diagnose -Read `AGENTS.md` first. This is a diagnostic overlay, not a standalone workflow. +This is a diagnostic overlay, not a standalone workflow. Use alongside the repo's implementation skill when debugging environment-sensitive issues. diff --git a/.agents/skills/project-release-maintainer/SKILL.md b/.agents/skills/project-release-maintainer/SKILL.md index 3139337..7724014 100644 --- a/.agents/skills/project-release-maintainer/SKILL.md +++ b/.agents/skills/project-release-maintainer/SKILL.md @@ -5,7 +5,7 @@ description: Overlay for release-facing docs, install layout, workflows, license # Project Release Maintainer -Read `AGENTS.md` first. This is a composable overlay, not a standalone workflow. +This is a composable overlay, not a standalone workflow. Use alongside the repo's implementation skill for publication-facing and packaging-sensitive changes. diff --git a/.agents/skills/project-vendor-boundary/SKILL.md b/.agents/skills/project-vendor-boundary/SKILL.md index e269300..192ad8c 100644 --- a/.agents/skills/project-vendor-boundary/SKILL.md +++ b/.agents/skills/project-vendor-boundary/SKILL.md @@ -5,7 +5,7 @@ description: Overlay for app-owned versus vendored dependency boundaries. Portab # Project Vendor Boundary -Read `AGENTS.md` first. This is a composable overlay, not a standalone workflow. +This is a composable overlay, not a standalone workflow. Use alongside the repo's implementation skill when work touches vendored dependencies or their integration boundary. diff --git a/.agents/skills/security-identity-access/SKILL.md b/.agents/skills/security-identity-access/SKILL.md new file mode 100644 index 0000000..6948c91 --- /dev/null +++ b/.agents/skills/security-identity-access/SKILL.md @@ -0,0 +1,67 @@ +--- +name: security-identity-access +description: Companion overlay for the local `security` workflow skill when the task centers on authentication, sessions, identity recovery, or tenant-scoped access boundaries. Use with `security` for session handling, verification and reset flows, MFA, invitation logic, callback-origin trust, and organization or tenant boundary enforcement. +--- + +# Security Identity Access + +Use this companion overlay with `security` when the task involves auth stacks, +session systems, identity flows, invitation models, or multi-tenant +organization boundaries. + +## Focus areas + +- session creation, storage, refresh, invalidation, and revocation behavior +- password reset, email verification, recovery, and callback URL trust +- MFA enablement, verification, backup-code storage, and trusted-device flows +- invitation, membership, role, active-organization, and tenant-scoping logic +- origin checks, CSRF defenses, trusted origins, and cross-domain auth flows + +## Not For + +- generic user-model changes where auth or tenant boundaries are not the main risk +- routine login or signup implementation work with no security review or hardening goal +- generic RBAC discussions detached from actual session, identity, or tenant behavior + +## Workflow + +1. Map the auth surface: + session transport, cookies or tokens, reset and verification endpoints, MFA + state, invitation paths, active-org or tenant context, and privileged roles. +2. Identify trust assumptions: + which origins are trusted, which callbacks are accepted, who can invite, + promote, switch orgs, revoke sessions, or recover accounts. +3. Review boundary failures: + account takeover paths, authz gaps, tenant-boundary leaks, stale-session + risks, missing session revocation, insecure reset flows, and MFA bypasses. +4. Check secure defaults: + absolute callback URLs or strict origin validation, bounded invitation + lifetime, email verification where appropriate, session revocation on + password reset, org or membership limits, and encrypted or hashed MFA + recovery material when supported. +5. Report by boundary: + state the impacted identity or tenant boundary, required attacker capability, + and whether the issue leads to takeover, privilege escalation, or + cross-tenant access. + +## Review rules + +- require explicit authorization on role changes, tenant switches, invitation + acceptance, and privileged member-management actions +- inspect whether active-organization or tenant context is server-enforced, not + only client-selected +- prefer short-lived, single-use recovery artifacts and invalidate older + sessions after password reset when the platform supports it +- verify callback and redirect handling with absolute URLs or trusted-origin + checks; do not trust inferred origins in split frontend/backend deployments +- treat MFA backup codes, OTP storage, and trusted-device markers as sensitive + credentials + +## False-positive guards + +- do not flag a client-selected org or tenant switch if the server re-derives + and enforces tenant scope on every sensitive action +- do not flag every redirect or callback as unsafe when the code enforces a + strict allowlist or trusted-origin validation +- do not treat session persistence itself as a flaw when rotation, revocation, + and transport protections match the deployment model diff --git a/.agents/skills/security/SKILL.md b/.agents/skills/security/SKILL.md index 35a1da4..52d32c4 100644 --- a/.agents/skills/security/SKILL.md +++ b/.agents/skills/security/SKILL.md @@ -1,17 +1,90 @@ --- name: security -description: Security skill for threat modeling, secure defaults, and security-focused code review in generic software projects. +description: Security workflow skill for repo-grounded threat modeling, exploit-focused security review, and secure-by-default implementation guidance. Use when the user explicitly asks for security work, or when security properties are the primary concern in a high-risk change. Do not trigger for ordinary code review, routine endpoint work, or general backend implementation just because a repo contains APIs, auth, or secrets. --- # Security -Read `AGENTS.md` first. This skill adds security-specific guidance. +This skill adds security-specific guidance. ## Default Stance -- prioritize realistic attacker goals and concrete impact -- ground claims in actual code, entrypoints, data flows, and deployment shape -- prefer secure defaults that do not silently break intended behavior +- prioritize realistic attacker goals, attacker-controlled input, and concrete impact +- ground claims in actual code, entrypoints, data flows, trust boundaries, and deployment shape +- research the broader repo before reporting a vulnerability; do not flag pattern matches in isolation +- report high-confidence exploit paths first and separate them from lower-confidence follow-up checks +- prefer secure defaults that do not silently break intended behavior; call out meaningful tradeoffs +- separate runtime risk from CI/build/dev/test-only concerns + +## Use This Skill For + +- security reviews, vulnerability audits, OWASP-style review requests, and secure-by-default coding help +- high-risk changes where the main question is whether a boundary is secure: authz, untrusted input, external fetches, uploads, secrets handling, sensitive data, or tenant isolation +- threat modeling a repo, service, or path + +## Not For + +- ordinary code review with no security angle +- routine endpoint work where security is not the main task or risk +- generic checklist dumping without repo evidence +- reporting hypothetical findings when exploitability is unclear + +For auth-heavy systems, load this skill with `security-identity-access`. + +## Workflow + +### 1. Scope the job + +Identify which mode applies: + +- `security review`: find concrete vulnerabilities in code or changes +- `threat model`: map assets, boundaries, abuse paths, and mitigations +- `secure implementation`: write or revise code with secure defaults while preserving intended behavior + +Clarify in-scope paths, runtime surfaces, and any known deployment or auth assumptions. If material context is missing for a threat model, ask a small number of targeted questions before finalizing. + +### 2. Build the system view + +1. Identify languages, frameworks, entrypoints, external integrations, and storage layers. +2. Distinguish runtime behavior from tests, examples, and build tooling. +3. Enumerate concrete trust boundaries, assets, attacker goals, and attacker capabilities. +4. For web apps, inspect both frontend and backend surfaces. + +### 3. Investigate before reporting + +For each suspected issue: + +- trace whether the input is attacker-controlled or operator-controlled +- check framework protections, middleware, schema validation, sanitization, and parameterization already in place +- confirm whether the code path is reachable and whether auth or environment assumptions materially reduce impact + +Do not report a finding based only on a risky-looking API. Confirm exploitability first. + +### 4. Review the highest-value risk areas + +Prioritize these categories as applicable: + +- authn/authz gaps, IDOR, privilege escalation, tenant-boundary failures +- injection: SQL, NoSQL, command, template, deserialization, path traversal +- XSS, CSRF, unsafe HTML rendering, unsafe redirects +- SSRF and unsafe external requests +- secrets exposure, weak crypto, insecure token/session handling, sensitive-data logging +- uploads, parsers, decoder surfaces, and denial-of-service pressure points +- misconfiguration with real security impact: unsafe defaults, debug exposure, dangerous CORS, missing isolation + +Treat framework-safe defaults as safe unless repo evidence shows they were bypassed. Example: ORM parameterization, templating auto-escaping, and config-derived URLs are not findings by themselves. + +### 5. Apply secure-by-default implementation rules + +When writing or fixing code: + +- validate untrusted input with explicit schemas or strict allowlists +- use parameterized queries and typed APIs instead of string-built commands or queries +- store secrets in environment or secret-management systems, never in source +- keep auth tokens in safer storage mechanisms for the deployment model; avoid browser-accessible storage for session secrets when httpOnly cookies fit the design +- redact secrets and sensitive fields from logs and user-facing errors +- add rate limits, size bounds, and fail-closed validation on expensive or dangerous operations +- preserve functionality intentionally; if a fix changes behavior, state the tradeoff before or while making the change ## Threat-Model Workflow @@ -20,6 +93,7 @@ Read `AGENTS.md` first. This skill adds security-specific guidance. 3. Enumerate a small set of high-quality abuse paths. 4. Rank findings by likelihood and impact with explicit assumptions. 5. Recommend mitigations tied to concrete boundaries or components. +6. If key context is missing, summarize the assumptions that drive ranking and ask the user to confirm or correct them before finalizing. ## Secure-Review Workflow @@ -27,6 +101,8 @@ When reviewing code for security: - look for auth/authz gaps, unsafe parsing, command execution, path traversal, injection, secrets exposure, weak validation, and denial-of-service risks +- verify whether attacker-controlled input actually reaches the sink +- distinguish exploitable issues from "needs verification" follow-ups - note where types/contracts could make misuse harder - distinguish critical findings from hygiene improvements @@ -34,5 +110,8 @@ When reviewing code for security: - findings first, ordered by severity - include concrete file references and impacted asset/boundary +- for reviews, default to reporting only high-confidence vulnerabilities; keep lower-confidence items clearly labeled or omit them +- for threat models, keep the threat set small, explicit, and tied to concrete assets and boundaries - make assumptions explicit - avoid generic checklist noise when the repo evidence does not support it +- if the user asked for a report file, write concise Markdown with line references and a short executive summary diff --git a/.agents/skills/ui-design-guidance/SKILL.md b/.agents/skills/ui-design-guidance/SKILL.md new file mode 100644 index 0000000..1ff02a1 --- /dev/null +++ b/.agents/skills/ui-design-guidance/SKILL.md @@ -0,0 +1,156 @@ +--- +name: ui-design-guidance +description: Canonical overlay for graphical UI and web frontend code that need strong design quality and UX discipline without breaking repo conventions. Use alongside the repo's implementation skill when implementing or reviewing UI changes, redesigns, frontend polish work, or UX-heavy UI updates. +--- + +# UI Design Guidance + +This is a composable overlay, not a standalone workflow. +Use alongside the repo's implementation skill when the change touches graphical +UI or web frontend code. + +This is the stronger UI overlay in this repo. +Prefer it over `ui-guidance` when the task is redesign-heavy, polish-heavy, or +needs explicit UX review beyond basic UI hygiene. + +## When to use + +- the repo includes graphical UI or web frontend code +- the task asks for UI implementation, redesign, beautification, styling, or + frontend polish +- the task changes how a feature looks, feels, moves, or is interacted with +- the work includes new pages, components, forms, navigation, responsive layout, + animation, or charts/data display +- the task asks for UX review or quality improvement, not just visual changes +- the change touches web views, desktop UI, embedded panels, dashboards, pages, + landing screens, or rendering layers + +## Not for + +- terminal UIs unless the repo explicitly treats them as product UI +- pure data visualization or plotting libraries without product-interface work +- backend-only changes with no UI surface + +## Core workflow + +1. Read the touched UI files and nearby components first. +2. Determine the mode: + - preserve mode when the repo already has a clear design language and the + user did not ask for redesign + - redesign mode when the user explicitly wants a new visual direction or the + current UI is intentionally being reworked + - UX-review-heavy mode when the main risk is usability, interaction quality, + responsiveness, forms, navigation, or data presentation +3. In preserve mode, derive tokens, spacing, interaction patterns, breakpoints, + and component structure from the nearest existing screens or components. +4. In redesign mode, choose one intentional aesthetic direction before coding: + define the interface purpose, audience, tone, and one memorable visual idea. +5. In UX-review-heavy mode, evaluate the change in this order: + - accessibility + - interaction and feedback + - layout and responsiveness + - typography and color clarity + - forms, navigation, and data presentation when they apply +6. Implement real working UI code that fits the chosen mode: + - preserve mode should feel native to the repo + - redesign mode should feel distinctive, cohesive, and production-grade + - UX-review-heavy mode should strengthen usability without drifting away from + the repo's design language unless redesign is requested +7. Verify accessibility, keyboard behavior, responsive layout stability, and + visual output with the strongest evidence the repo supports. +8. When the repo lacks UI docs or automated checks, record the fallback + evidence: files inspected, viewport sizes tested, and screenshots or manual + checks used. + +## Decision rules + +- Preserve the existing design language unless the task explicitly calls for + redesign. +- Accessibility, layout stability, and responsive behavior are part of done, + not follow-up work. +- UI changes must not bypass the repo's build, test, or review hygiene. +- Match implementation complexity to the visual goal. Refined minimalism needs + precision and restraint; bold maximalism needs deliberate structure and + stronger visual systems. +- Before adding a new visual element, grep for a similar existing element and + reuse its patterns unless redesign mode justifies divergence. +- Prefer concise, durable heuristics over giant style catalogs. Use repo + context first, not generic design-library sprawl. + +## UX priorities + +### 1. Accessibility + +- interactive elements must be keyboard-navigable +- icon-only controls need labels +- visible focus states must remain intact +- color cannot be the only carrier of meaning +- reduced-motion preferences should be respected when animation is present + +### 2. Interaction and feedback + +- touch and click targets should be comfortably hittable +- loading, success, and error states must be explicit +- primary interactions must not depend on hover alone +- destructive or async actions need clear user feedback + +### 3. Layout and responsiveness + +- layout must stay stable across supported viewports +- avoid horizontal scroll and fragile fixed-width assumptions +- spacing should follow the repo's existing scale or the nearest local pattern +- fixed or overlay UI should not obscure essential content + +### 4. Typography and color + +- body text should remain readable without tiny type or weak contrast +- use semantic tokens or shared variables instead of scattered one-off values +- hierarchy should come from spacing, weight, scale, and contrast, not color + alone + +### 5. Forms, navigation, and data + +- inputs need visible labels and local error messages +- navigation state and back-path should be predictable +- charts and data views must remain readable without relying on color alone +- empty, loading, and error states should explain what the user can do next + +## Aesthetic rules + +- Choose typography intentionally. Avoid default stacks and overused safe + choices unless the repo already standardizes on them. +- Commit to a cohesive palette and define reusable tokens or variables instead + of scattering one-off colors. +- Use motion deliberately. Prefer a few meaningful transitions or reveal + sequences over noisy micro-interactions everywhere. +- Build atmosphere with backgrounds, texture, layering, contrast, shadows, or + pattern where the design direction benefits from it. +- Avoid generic AI-UI habits: purple-on-white defaults, interchangeable hero + sections, timid palettes, and cookie-cutter dashboard layouts. +- Keep distinctive choices consistent across the whole surface so the UI feels + designed rather than decorated. + +## Validation + +A UI change is done when, in addition to the base implementation skill's +validation: + +- visual output matches the existing design language or the requested redesign +- interactive elements are keyboard-navigable and labeled appropriately +- layout is stable across supported viewports or the nearest documented + fallbacks +- forms, navigation, and feedback states are explicit where they apply +- the evidence names the files, screenshots, snapshots, or manual checks used + when automated UI verification is absent + +## Examples + +- `Polish this React settings screen without changing the product style`: + stay in preserve mode, inspect nearby screens, reuse tokens and spacing, and + verify keyboard and viewport behavior. +- `Redesign this marketing landing page so it feels memorable`: + switch to redesign mode, pick one clear aesthetic direction, then implement a + cohesive page with stronger typography, layout, and motion choices. +- `Review this dashboard for UX issues before release`: + switch to UX-review-heavy mode, walk the priority list from accessibility + through data presentation, and report concrete issues with evidence. diff --git a/.agents/skills/ui-guidance/SKILL.md b/.agents/skills/ui-guidance/SKILL.md index e2ccfe2..9ec5e64 100644 --- a/.agents/skills/ui-guidance/SKILL.md +++ b/.agents/skills/ui-guidance/SKILL.md @@ -5,10 +5,14 @@ description: Overlay for graphical UI and web frontend code. Use alongside the r # UI/Frontend Guidance -Read `AGENTS.md` first. This is a composable overlay, not a standalone workflow. +This is a composable overlay, not a standalone workflow. Use alongside the repo's implementation skill (e.g. **coding-guidance-cpp**, **project-core-dev**) when the change touches UI or frontend code. +Use this as the thin default overlay for ordinary UI work. +If the task is redesign-heavy, frontend-polish heavy, or needs a stronger UX +review checklist, prefer `ui-design-guidance`. + ## When to use The repo includes graphical UI or web frontend code — web views, desktop UI, diff --git a/skills-lock.json b/skills-lock.json new file mode 100644 index 0000000..65fb3a0 --- /dev/null +++ b/skills-lock.json @@ -0,0 +1,105 @@ +{ + "version": 1, + "skills": { + "backend-guidance": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "35a395395f78ca06cefc7259d13dbbd025459fb9c9957cb25e923e119a16315a" + }, + "backend-systems-guidance": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "c3c5e1ec416705f8dfe7984b69aab8d949b0a80ad9434222941454a240012235" + }, + "coding-guidance-bash": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "e02e2afd93a45a008f5b24f57692572b50497bdd2a5db41f6c32ea500ed00813" + }, + "coding-guidance-cpp": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "9657a2ba9eecdbee8f7619f74055bd77a15ea2ab2b19e6a074bfe632f5781710" + }, + "coding-guidance-python": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "3f655dede236a2d2b6abb26f3c49cd05b77d1552360ea2e566f5ccd5659b64e0" + }, + "coding-guidance-qt": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "45a7bd1da45e9d6d1365db3879e581689c7e8921248848e5b1691478376613f5" + }, + "development-contract-process": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "1542bb3350811ffa6d87813361895c912e55fdd9aaf147fc7a65a9541b9fd607" + }, + "development-contract-repo-overlay-template": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "09e41b5a232f45f272f50b45c406fbb14f23c33e1773760d1b86f65937069441" + }, + "development-contract-system": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "c07ea5e25b574fb1a1e1c5798a43fcfe655111f7205428331111354a79c71e12" + }, + "documenter": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "f27b835841ffe3d6f547f0d828ece8bd3fe31bffb13c09e3c680f54a618fe120" + }, + "documenter-coauthoring": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "2a2fb5658df28ce4729a1bd8745282e21cdfa64d208f2e576324fb1c7fd0e71f" + }, + "project-config-and-tests": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "032f2ac48f8083475e2094c46972a062ccae8e66964560bf899956233c205a71" + }, + "project-core-dev": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "29141b6f6a036b914da32efaa67cb03be2a17e3b80726fbef5217102287fa443" + }, + "project-platform-diagnose": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "0552bc432011c0c2fda9717748afbae3f3abd5777917187cbceb81befa2324a2" + }, + "project-release-maintainer": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "f4d738ad86e3de7a4c63195fe18c6d3eff7290ca3d760bc865400a6ea82d0ba0" + }, + "project-vendor-boundary": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "9611aa73ad324c6845d5806e106aabfd747c3c767645dad7e8270fdc4d0b3e78" + }, + "security": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "70c78877b61d1f68fab99845ceef006cd22a52c061d970aeb41a1ae2a17ea745" + }, + "security-identity-access": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "2a2a6d98441be15f0762bc68f1cca19ebd68186ef80f7c06e4510283a805bb2b" + }, + "ui-design-guidance": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "961d3f37322a70a5b16e5d27df6b9e593df3bf6cd6ce03ad43180760c2eb5dbc" + }, + "ui-guidance": { + "source": "n-n-code/n-n-code-skills", + "sourceType": "github", + "computedHash": "e7218040779e9de25399ec7831769234b767b473b93b2296fa97b4fca98502dd" + } + } +}