codeprobe-architecture
Standalone Mode
If invoked directly (not via the orchestrator), you must first:
- Read
../codeprobe/shared-preamble.mdfor the output contract, execution modes, and constraints. - Load applicable reference files from
../codeprobe/references/based on the project's tech stack. - Default to
fullmode unless the user specifies otherwise.
Architecture & Structure Analyzer
Domain Scope
This sub-skill detects architectural and structural issues across these categories:
- Layer Violations — Business logic in controllers, presentation logic in models, database access in views
- Circular Dependencies — Direct or transitive circular imports between modules
- God Objects — Oversized files and classes that do too much
- Anemic Domain Model — Entity classes with no behavior, all logic in service classes
- Missing Boundaries — No clear module/domain separation, cross-feature coupling
- Directory Structure — Framework convention violations, flat directory anti-patterns
- Config/Environment — Hardcoded environment values, missing config abstraction
What It Does NOT Flag
- Small projects/scripts with fewer than 5 files — flat structure is appropriate for small codebases and adding layers would be over-engineering.
- Microservices that intentionally have thin layers — a microservice with a single controller, single service, and single repository is fine by design.
- Framework-standard monolith patterns that are idiomatic — e.g., Laravel's default structure for small-to-medium apps, Rails convention-over-configuration patterns, Next.js app directory conventions.
- Prototypes and proof-of-concept code clearly marked as such.
- Generated code directories (e.g.,
dist/,build/,.next/,__pycache__/).
Detection Instructions
Layer Violations
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
Controllers containing business logic | Scan files in controller directories (controllers/, Controllers/, routes/, api/). Flag controllers that contain: database queries (SQL, ORM query builders beyond simple find()/findById()), complex conditionals with business rules (3+ branches), calculations, data transformations, or validation logic beyond simple field presence checks. Controllers should delegate to services/actions. |
Major |
ARCH |
Models/entities containing presentation logic | Scan model/entity files. Flag models that contain: HTML generation, string formatting for display (e.g., toHtml(), formatForDisplay()), view-specific transformations, CSS class computation, or response formatting. Models should contain domain logic, not presentation. |
Major |
ARCH |
Views/components calling database directly | Scan view files (.blade.php, .vue, .jsx/.tsx components, .ejs, .pug, Jinja templates). Flag views that contain: direct database queries, ORM calls, raw SQL, or repository method calls. Views should receive data from controllers/props, never fetch it themselves. |
Critical |
Circular Dependencies
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
Module A imports B, B imports A (direct or transitive) | Prefer the pre-loaded dependency graph (see "Dependency Graph" subsection below). When present, the graph includes a circular_dependencies array with each cycle's full file-path chain — report one ARCH finding per cycle with that chain as evidence. When the graph is absent (degraded mode), fall back to tracing import/require/use statements across files and looking for direct cycles (A→B→A) and transitive cycles (A→B→C→A). Focus on module-level (directory-level) cycles which are more architecturally significant than file-level cycles within the same module. |
Major |
Dependency Graph (pre-loaded)
When invoked via /codeprobe audit or /codeprobe architecture, the orchestrator pre-computes the import graph by running scripts/dependency_mapper.py and provides the JSON in-context between === DEPENDENCY_GRAPH === and === END DEPENDENCY_GRAPH === markers. The JSON schema:
graph:{file_path: [files it imports]}— the full dependency graph.circular_dependencies: list of cycle objects, each with the full file-path chain (e.g.,["a.py", "b.py", "c.py", "a.py"]).summary:{total_files, total_cycles, most_imported, most_dependencies}— aggregate stats.
When the graph is present, treat it as ground truth: every cycle in circular_dependencies becomes an ARCH finding. Do NOT attempt your own cycle detection — the script runs deterministic DFS and is more reliable than LLM import-tracing.
When the graph is absent (script failed, Python 3 missing, or degraded mode), fall back to LLM-based import tracing as described in the Circular Dependencies row above.
God Objects
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
File exceeds 500 LOC | Count total lines in each source file (excluding blank lines and comments). Flag files exceeding 500 LOC. For files exceeding 1000 LOC, escalate to critical. | Major |
ARCH |
Class with 20+ methods | Count public, protected, and private methods in each class. Flag classes with 20+ methods. List the method groups to suggest how the class could be split. | Major |
ARCH |
Single file handling request-to-response lifecycle | Look for files that handle the full request lifecycle: receiving/parsing the request, validating input, executing business logic, performing persistence, formatting the response, and logging — all in one file or class. Flag when 4+ of these concerns are in a single file. | Major |
Anemic Domain Model
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
Entity/model classes with only getters/setters, zero behavior | Scan model/entity classes. If a class has only property declarations, getters, setters, and constructor assignment — with no business logic methods (no validation, no calculations, no state transitions, no domain rules) — it is an anemic entity. | Minor |
ARCH |
All logic in "Service" classes operating on dumb data bags | Check if the codebase has a pattern where entity classes are pure data containers and all behavior (validation, calculation, state transitions) lives in separate *Service classes that manipulate the entity externally. Flag when this pattern is pervasive (3+ services operating on the same entity). |
Minor |
Missing Boundaries
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
No clear module/domain separation in medium+ projects | For projects with 20+ source files, check whether the code is organized into modules, domains, or bounded contexts. If all source files live in a single flat directory or are only separated by technical layer (controllers/, models/, services/) with no domain grouping, flag it. | Major |
ARCH |
Shared database tables accessed directly across unrelated features | Search for the same database table name, model, or entity being imported/queried from multiple unrelated modules or feature directories. If users table is accessed from billing/, notifications/, reports/, and admin/ without going through a shared user module, flag it. |
Major |
ARCH |
Cross-feature direct imports instead of events/interfaces | Check whether feature modules import directly from other feature modules' internal files. For example, billing/InvoiceService importing shipping/ShippingCalculator directly instead of through an interface or event system. Flag tight inter-feature coupling. |
Minor |
Directory Structure
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
Framework conventions violated | Check whether the project follows its framework's expected directory structure. Examples: business logic classes in a Controllers/ directory, SQL queries in view templates, route definitions scattered across non-route files, test files mixed with source files without naming convention. |
Minor |
ARCH |
No separation between layers for 20+ files | For projects with 20+ source files, check whether there is any directory-based separation between layers (controllers, services, models, views) or domains. If everything lives in one flat directory, flag it. | Major |
Config/Environment
| ID Prefix | What to Detect | How to Detect | Severity |
|---|---|---|---|
ARCH |
Hardcoded environment-specific values in source code | Search for hardcoded URLs (http://localhost, https://api.example.com), port numbers (:3000, :8080, :5432), hostnames, IP addresses, and file system paths in source code files (not config files). These should come from environment variables or config. |
Major |
ARCH |
Missing environment abstraction | Check whether the project has an environment abstraction layer (.env file + config loader, environment variables, config service). If source files read process.env.X or os.environ['X'] directly in 5+ places without a centralized config module, or if there is no .env/config layer at all, flag it. |
Minor |
Using file_stats.py
When available, run the file_stats.py script via Bash to get LOC, class count, and method count per file. The script is located in the review skill's scripts/ directory (resolve relative to the skill installation, not the user's project):
python3 scripts/file_stats.py <target_path>
Note: The orchestrator typically runs this script and passes results. If invoked standalone, locate the script in the sibling codeprobe/scripts/ directory.
Use this data to:
- Identify god objects (files > 500 LOC, classes with 20+ methods)
- Find the largest files in the project
- Get accurate LOC counts for the summary
If Python 3 or the file_stats.py script is unavailable, estimate from reading files directly using Read. Do not fail the analysis — proceed with manual counting.
ID Prefix & Fix Prompt Examples
All findings use the ARCH- prefix, numbered sequentially: ARCH-001, ARCH-002, etc.
Fix Prompt Examples
- "Move the pricing calculation logic from
OrderController@store(lines 40-75) into a newPricingServiceclass underapp/Services/. The controller should injectPricingServiceand call$this->pricingService->calculate($order). The controller should only handle request parsing, service delegation, and response formatting." - "Break
UserManager(850 LOC) into focused services: extract authentication methods (lines 50-200) intoUserAuthService, profile management (lines 201-450) intoUserProfileService, and notification methods (lines 451-700) intoUserNotificationService.UserManagerbecomes a thin facade that delegates to these three services." - "Resolve the circular dependency between
billing/InvoiceServiceandshipping/ShippingCalculator: extract the shared interfaceShippingCostProviderinto ashared/contracts/directory. HaveShippingCalculatorimplementShippingCostProvider, and haveInvoiceServicedepend on the interface instead of the concrete class." - "Replace the hardcoded URL
http://localhost:3000/apiat line 23 ofsrc/services/ApiClient.tswith an environment variable: useprocess.env.API_BASE_URLloaded through the config module. AddAPI_BASE_URL=http://localhost:3000/apito.env.example." - "Create a domain-based directory structure: move
UserController,UserService,UserRepository, andUserPolicyinto aapp/Domains/User/directory. Repeat forOrder,Payment, andNotificationdomains. Each domain directory should contain its own controllers, services, models, and policies."