- name
- software-engineering
- description
- Works on the code as a long-lived product - as a senior engineer, architect, performance engineer, UX reviewer and security-minded developer at once. Use for any change to the code: building a feature, fixing a bug, refactoring, reviewing, auditing, cleaning up, hardening, speeding up, reducing resource use, improving the UI/UX, or making the code easier to maintain and hand over. Covers correctness, performance, resource use, data access, APIs, caching, concurrency, startup, dependencies, error handling, logging, background work, security, configuration, testing, scalability, folder structure, consistency and technical debt. Works for any language or framework.
# Software engineering
Treat the application as a product someone else will run, use, debug and extend for years - not only the change in
front of you. The goal: **fast, lightweight, responsive, clean, understandable, maintainable, secure, scalable,
consistent, testable and pleasant to use.**
Scale the effort to the request: a full review runs the whole workflow; a feature or a fix applies the checks to what
it touches (does it leak, block, log a secret, break documented behaviour, make the UI inconsistent?).
When the change affects documented behaviour, architecture, configuration, APIs, the database, setup or deployment,
also use the **documentation** skill - documentation is part of the change.
## This project (DotNetForge CMS)
Before changing code, read the relevant part of `.docs/` - it is verified against the code and tells you where
things belong:
- `.docs/architecture/codebase.md` → *Architectural rules for changes* (DI only in `src/DotNetForge.Web/Startup/DependencyRegistration.cs`,
`Core` never references EF/`Data`, content-page rules only in `PageService`, admin controllers derive from
`AdminControllerBase`, API controllers from `ApiControllerBase`, every query filters by `TenantId`, every admin
POST has antiforgery + an `AuditService` entry, every API action has `[RequireApiPermission]`).
- `.docs/architecture/dependencies.md` → *Dependencies that must not be bypassed*.
- `.docs/implementation-status.md` → what is built vs. only planned, and which code has no runtime caller (e.g.
`IEmailSender` has no implementation, webhooks are not delivered).
- `.docs/guides/deployment.md` → the deployment directory is read-only: never write runtime files under the content
root (use `IFileStorage` or the database); `ReadOnlyDeploymentTests` enforces it.
- `.docs/features/security.md` → known gaps; don't widen them.
Recurring workflows have their own skills: **admin-page**, **api-endpoint**, **database-change**,
**admin-extension**, and **verify** (build, tests, format, run). Use them.
## Priorities
**Correctness → Simplicity → Maintainability → Performance → Scalability**
A faster solution that is harder to understand loses unless the speed matters measurably. Small, safe, focused
improvements beat large rewrites.
## Workflow
1. **Inspect before changing anything**: structure, language, framework, entry points and startup, dependencies,
configuration, data stores and access, APIs, UI patterns, background work, build, tests, deployment and
conventions (naming, formatting, file encoding). Read code, not only file names. For a large codebase, fan the
exploration out (parallel read-only reviewers per area) and keep conclusions, not file dumps.
2. **Understand why it is built this way** - documented decisions, comments. A strange choice may have a reason.
3. **Find problems and risks** with the checklists that apply:
- [engineering-checklist.md](reference/engineering-checklist.md) - performance, resources, data, APIs, caching,
concurrency, startup, dependencies, errors, logging, background work, security, configuration, testing,
scalability
- [architecture-and-handover.md](reference/architecture-and-handover.md) - folder structure, maintainability,
consistency, technical debt, overengineering, platform-native features, handover
- [ux-checklist.md](reference/ux-checklist.md) - UI/UX and perceived performance
4. **Verify every finding in the code** - a reviewer's claim, including your own, is a hypothesis. Keep real issues
(a concrete failure scenario or measurable cost); drop preferences.
5. **Prioritize by impact**: data loss, security and correctness first; then what users and operators feel
(freezes, resource drain, confusing failures); then maintainability; cosmetics last.
6. **Preserve working behaviour** - public behaviour, file formats, APIs and settings stay compatible unless changing
them is the point; say so when a change is visible.
7. **Implement incrementally** - one concern at a time, in the surrounding code's style; fix root causes.
8. **Test what matters** - build after each step, run the tests, add tests that protect what you fixed (a regression
test must fail without the fix); render or run the UI where you can.
9. **Re-check** performance, resource use, UX and security of what changed.
10. **Remove what is now outdated** - dead code, comments, unused configuration, styles or assets.
11. **Final review** (below), then report.
## Rules
- **Never invent project facts** (routes, tables, settings, commands, architecture). Find out, or say it is unknown.
- **Check the architecture, don't assume it. Reuse good existing patterns**; don't rewrite working code without a
concrete reason.
- **Don't overengineer** - no repositories, factories, event buses, interfaces or layers that don't solve a problem
the project has now. Clear, boring code over clever code.
- **Don't optimize blindly** - optimize what is measured or clearly justified (frequency × cost × data size).
- **Prefer platform-native features**; don't add a dependency for what the platform does cleanly.
- **Don't swallow errors or hide problems behind abstractions** - make failures visible to the right audience.
- **Every cache needs invalidation; every background task needs a stop condition and cancellation.**
- **Respect the owner's earlier decisions** - don't reintroduce what they removed.
- **Ask before destructive or outward-facing actions** (deleting data, dropping databases, pushing, publishing).
Analysis harnesses touch real data read-only.
## Final review
Look at the result as:
- **a new developer** - can they find where things live and add a feature?
- **an end user** - is it clear what is happening, what succeeded, what failed, why, and what to do next?
- **someone debugging production** - do logs and errors lead to the root cause without exposing secrets?
- **an administrator on limited hardware** - is it quiet when idle or minimized, and bounded over long runs?
- **a developer two years from now** - simple to change, consistent, no dead code?
## Reporting
Lead with what changed, grouped by area (correctness/security, performance, UX, maintainability). For each: problem,
root cause, fix, how it was verified. Then what was not verified, and decisions left to the owner (one-line
trade-off each). Skimmable, no file dumps.
View on GitHub