structure-audit
Skill7 starsChanged 27 days agoMITView on GitHub
Codebase structure and organization audit across 13 dimensions (SA1-SA13): directory consistency, naming conventions, folder depth, colocation, barrel exports, separation of concerns, file size distribution, dead code, complexity distribution, duplication, root organization, documentation, hotspots. Tool-driven with CodeSift primary and CLI fallbacks (cloc, knip, dep-cruiser, jscpd, eslint, git mining). Flags: full (default), [path], --naming, --size, --dead-code, --duplication, --hotspots, --quick, --fix.
- Reads credentials
1 other project uses a version of this.
Adopted by
Most recently taken up by
- Yale-A11y/claude-skillstheir own version, first seen Oct 13, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- Yale-A11y/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository58 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- a11y-auditSkill
- agent-benchmarkSkill
- api-auditSkill
- architectureSkill
- backlogSkill
- benchmarkSkill
- brainstormSkill
- buildSkill
- canarySkill
- ci-auditSkill
- code-auditSkill
- container-auditSkill
- content-auditSkill
- content-expandSkill
- content-fixSkill
- content-migrationSkill
- context-auditSkill
- db-auditSkill
- debugSkill
- dependency-auditSkill
- deploySkill
- design-reviewSkill
- designSkill
- docsSkill
- env-auditSkill
- executeSkill
- fix-testsSkill
- geo-auditSkill
- geo-fixSkill
- incidentSkill
- infra-auditSkill
- leadsSkill
- mutation-testSkill
- pentestSkill
- performance-auditSkill
- planSkill
- presentationSkill
- profile-sessionSkill
- receive-reviewSkill
- refactor-radarSkill
- refactorSkill
- release-docsSkill
- retroSkill
- reviewSkill
- security-auditSkill
- seo-auditSkill
- seo-fixSkill
- shipSkill
- skill-evalSkill
- test-auditSkill
- tests-performanceSkill
- ui-design-teamSkill
- using-zuvoSkill
- worktreeSkill
- write-articleSkill
- write-e2eSkill
- write-testsSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
39 rules. About 0 are common, 22 are distinctive, and 17 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈22
Distinctive · estimate
This author's own choices. Worth a look.
17
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 67
Read these files before any work begins:
- Distinctive: line 90
If file 1, 2, 4, or 5 is missing, STOP.
- Very specific: line 94
Read ../../shared/includes/env-compat.md for agent dispatch patterns, path resolution, and progress tracking across all supported platforms.
- Very specific: line 98
Read ../../shared/includes/codesift-setup.md for the full initialization sequence.
- Very specific: line 100
Summary: Run the CodeSift setup from codesift-setup.md at skill start.
- Distinctive: line 102
Use the deterministic preload helper: Before issuing any ToolSearch, run:
- Distinctive: line 145
After the audit report is written and the Validity Gate block is printed, the audit is NOT complete until:
- Very specific: line 153
If you reach the Run line and stop without calling append-runlog: the audit is INVALID regardless of finding count.
- Very specific: line 263
Run external tools. Save all outputs to zuvo/audits/structure-audit-{YYYY-MM-DD}/.
- Very specific: line 277
Verify output: check for "SUM" key in JSON, not exit code.
- Very specific: line 304
Verify output: check for "modules.*cruised" or violation text.
- Very specific: line 320
Verify output: check statistics.total.sources > 0 in JSON.
- Very specific: line 333
Project ESLint config (preferred): Check for existing config.
- Distinctive: line 341
After all tools, print:
- Distinctive: line 359
FALLBACK (no CodeSift): Run git mining scripts directly.
- Very specific: line 386
Scope: All grep/glob commands target $CODE_SCOPE for SA1-SA10.
- Very specific: line 393
Check framework conventions (Next.js: no pages/ alongside app/)
- Very specific: line 400
Check type suffix consistency (.service.ts, .controller.ts)
- Very specific: line 413
Check type files: centralized types/ vs co-located *.types.ts
- Distinctive: line 414
Check constants/utils used by single module but stored centrally
- Very specific: line 422
Check for barrel chains (index.ts re-exporting from another index.ts)
- Distinctive: line 424
Check tsconfig paths vs actual usage
- Distinctive: line 430
Run fitness function rules:
- Distinctive: line 434
F4:: Test utility imports in production code
- Distinctive: line 445
Use cloc per-file data. Exclude non-code files from size analysis.
- Distinctive: line 457
Check for tracked temp files (.tmp-*, .env.local, *.log)
- Distinctive: line 458
Check .gitignore completeness for detected stack
- Distinctive: line 459
Check for scripts at root vs scripts/ directory
- Distinctive: line 465
Check for README.md with setup instructions
- Very specific: line 467
Check for docs/adr/ directory (if project >50 files)
- Distinctive: line 468
Check for OpenAPI/Swagger spec (if API project)
- Distinctive: line 469
Check for CONTRIBUTING.md (if >3 git contributors)
- Distinctive: line 545
Import pollution: SA5 god barrel + SA8 unused exports
- Very specific: line 563
Every HIGH and CRITICAL finding goes through backlog-add, one call per finding (../../shared/includes/backlog-protocol.md "Filing from a …
- Very specific: line 573
Only if
--fixargument was provided: After the report is saved, and before the 5.3 backlog calls: - Distinctive: line 585
Delete files with MEDIUM confidence
- Distinctive: line 606
Before printing the final output block, verify every item.
- Distinctive: line 658
Run: <ISO-8601-Z> structure-audit <project> <N-critical> <N-total> <VERDICT> - <N>-dimensions <NOTES> <BRANCH> <SHA7> <INCLUDES> <TIER>
- Distinctive: line 676
If the wrapper exits non-zero: do NOT manually append to runs.log.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
zuvo:structure-audit — Codebase Structure & Organization Audit
Quantitative structural health assessment across 13 measurable dimensions. Every finding is backed by tool output or grep evidence -- no subjective opinions without data. Generates a scored report with prioritized action items.
Scope: Periodic health checks, pre-refactor reconnaissance, onboarding orientation, post-sprint cleanup, release readiness.
Out of scope: Design patterns and SOLID (zuvo:architecture), per-file code quality (zuvo:code-audit), test quality (zuvo:test-audit), runtime performance (zuvo:performance-audit).
Mandatory File Loading
Read these files before any work begins:
Dispatch follows ../../shared/includes/execution-policy.md through env-compat. Reuse existing
authorization within that policy; session restrictions take precedence. Run each required gate
and report its actual independence or an unmet requirement.
../../shared/includes/codesift-setup.md-- CodeSift discovery and tool selection../../shared/includes/env-compat.md-- Agent dispatch and environment adaptation../../rules/file-limits.md-- Size limits for SA7 file categorization../../shared/includes/run-logger.md-- Run logging contract../../shared/includes/retrospective.md-- Retrospective protocol
Print the checklist:
CORE FILES LOADED:
1. codesift-setup.md -- [READ | MISSING -> STOP]
2. env-compat.md -- [READ | MISSING -> STOP]
3. file-limits.md -- [READ | MISSING -> use defaults: 300L service, 200L component]
4. run-logger.md -- [READ | MISSING -> STOP]
5. retrospective.md -- [READ | MISSING -> STOP]If file 1, 2, 4, or 5 is missing, STOP. File 3 has a documented fallback.
Environment Compatibility
Read ../../shared/includes/env-compat.md for agent dispatch patterns, path resolution, and progress tracking across all supported platforms.
CodeSift Integration
Read ../../shared/includes/codesift-setup.md for the full initialization sequence.
Summary: Run the CodeSift setup from codesift-setup.md at skill start. CodeSift tools are the primary analysis engine for SA8 (dead code), SA9 (complexity), SA10 (duplication), and SA13 (hotspots). If unavailable, fall back to CLI tools and grep heuristics.
Use the deterministic preload helper. Before issuing any ToolSearch, run:
~/.zuvo/compute-preload structure-audit "$PWD"Copy the printed [CodeSift matching trace] block verbatim and issue the printed ToolSearch(query="select:...") line without modification. Math gate: [CodeSift loaded] tools=N must equal [Expected after load] tools=N from the helper. If they differ → [PRELOAD MATH MISMATCH] and abort before Phase 1.
MANDATORY TOOL CALLS — Audit Validity Gate
This audit is INVALID if any tool below is skipped when its trigger condition holds. "DEFERRED", "N/A", "no diff vs prior audit" are NOT valid reasons. The presence of trigger artifacts (a code file list, language detection, dep manifest) is what dictates the call — never delta or risk.
Required tool list
| Tool | Trigger | Reason | Skip allowed? |
detect_communities | Always (any project with code files) | SA6 separation of concerns — module boundary discovery | NO |
check_boundaries | Always | SA8 boundary violations between detected communities | NO |
classify_roles | Always | Hub/leaf/bridge symbol classification — needed for SA1+SA6 evidence | NO |
fan_in_fan_out | Always | SA8 coupling distribution; flags god modules and orphans | NO |
architecture_summary | Always | High-level project shape — required for executive summary section | NO |
analyze_complexity | Always | SA9 cyclomatic complexity distribution (CRITICAL GATE if outliers) | NO |
analyze_hotspots | Always | SA13 churn × complexity (last 90 days by default) | NO |
find_dead_code | Always | SA8 unused exports across the symbol graph | NO |
find_clones | Always | SA10 duplication ≥0.7 similarity | NO |
find_unused_imports | Always | SA5 barrel-export hygiene | NO |
audit_scan | Always | Compound CQ-pattern check covering several SA gates in one call | NO |
detect_hono_modules | Hono framework detected | SA6 Hono-specific module discovery | NO when Hono |
nest_audit | NestJS framework detected | SA6 NestJS module + DI graph | NO when NestJS |
| Stack-specific tools (python_audit, php_project_audit, kotlin trace_*) | Language detected | Language-specific structural patterns | NO when language matches |
Forbidden escape hatches
| Value | Forbidden when | Required value instead |
detect_communities: DEFERRED | EVER | detect_communities: <community_count> communities |
analyze_complexity: skipped (no diff vs prior) | EVER | analyze_complexity: <max_cc> max, <count_above_20> outliers |
find_dead_code: N/A | EVER | find_dead_code: <count> unused exports |
codesift: unavailable | mcp__codesift__* was in deferred-tools session-start banner | codesift: deferred-not-preloaded (FAILURE: skill required preload) |
retrospective: skipped | EVER | retrospective: appended (retros.log + retros.md) |
Required POSTAMBLE — retrospective + verify-audit gates
After the audit report is written and the Validity Gate block is printed, the audit is NOT complete until:
zuvo/audits/structure-audit-<date>.mdis on disk — at the project root (zuvo/resolves viagit rev-parse --show-toplevel; override$ZUVO_OUTPUT_DIR. See../../shared/includes/report-output-location.md).~/.zuvo/append-runlogis called with the Run line — this triggers BOTH gates:- retro-gate: requires a matching
RETRO:entry in~/.zuvo/retros.logforskill=structure-audit project=<this>. If missing → exit 2, runs.log NOT appended. Loadretrospective.md, fill 9 fields, run the bash append commands, then re-runappend-runlog. - audit-content gate: runs
~/.zuvo/verify-auditon the report. Every finding section must contain at least onepath/to/file.ext:LINEcitation that resolves in the current tree. Findings without citations get rejected. If rejected → fix the report (add file:line per finding), re-runappend-runlog.
- retro-gate: requires a matching
- Print
RETRO_APPENDED: retros.log=YES retros.md=YES (verified)and confirm exit 0 fromappend-runlog.
If you reach the Run line and stop without calling append-runlog: the audit is INVALID regardless of finding count. The Validity Gate's gate_status flips to FAIL — postamble incomplete and the verdict overrides to INCOMPLETE.
Mandatory acknowledgment (REQUIRED — print verbatim before Phase 0)
Mandatory-tools-acknowledgment: I will run detect_communities + check_boundaries + classify_roles + fan_in_fan_out + architecture_summary + analyze_complexity + analyze_hotspots + find_dead_code + find_clones + find_unused_imports + audit_scan + stack-specific structural tools (detect_hono_modules/nest_audit/python_audit/etc. when language/framework is detected) in this audit. Each finding will cite a `path/to/file.ext:LINE` resolving in the current tree.Phase 0: Parse $ARGUMENTS and Detect Stack
0.1 Arguments
| Argument | Behavior | Dimensions |
full | Audit entire project (all 13 dimensions) | SA1-SA13 |
[path] | Scope to specific directory | SA1-SA13 (scoped) |
--naming | Naming conventions only | SA2 |
--size | File size distribution only | SA7 |
--dead-code | Dead code and barrel analysis | SA5 + SA8 |
--duplication | Code duplication only | SA10 |
--hotspots | Git-based hotspot analysis only | SA13 |
--quick | Skip external tooling and git mining | SA1-SA8, SA11-SA12 (SA9/SA10/SA13 = N/A) |
--fix | Auto-fix after audit: delete unused (high confidence), .gitignore, rename | All + fix phase |
Default: full
0.2 Stack Detection
Detect language, framework, and project type from config files. Be restrictive -- a few stray .ts files in a non-JS project do not make it TypeScript.
| Stack | Required signals | SA Impact |
| TypeScript | package.json AND (tsconfig.json OR >10 .ts/.tsx files) | Full JS/TS tooling (knip, dep-cruiser, madge, eslint) |
| JavaScript | package.json AND >10 .js/.jsx files AND no tsconfig.json | JS tools (knip, dep-cruiser, madge, eslint) |
| Next.js | JS/TS AND next in package.json deps | SA1: App Router conventions, SA3: deep routes expected |
| NestJS | TypeScript AND (nest-cli.json OR @nestjs/core in deps) | SA2: suffix conventions, SA1: module structure |
| Python | pyproject.toml OR requirements.txt AND >5 .py files | SA9: radon, SA8: vulture, no knip/madge |
| PHP | composer.json AND >5 .php files | SA9: phpmd, SA10: phpcpd |
| Monorepo | turbo.json OR nx.json OR pnpm-workspace.yaml | SA1: per-package evaluation |
| Generic | None of above | Grep-only analysis, JS/TS tools = N/A |
Ignore for detection: files in dist/, node_modules/, coverage/, .next/, __pycache__/, .venv/, .git/.
0.3 Source Root and Code Scope
Two separate concepts:
$REPO_ROOT-- always.(project root). Used for SA11 (root org), SA12 (docs), .gitignore checks.$CODE_SCOPE-- directories containing source code to analyze. Used for SA1-SA10, SA13, and all tools.
Detect $CODE_SCOPE:
| Signal | CODE_SCOPE |
src/ exists with >5 code files | src/ |
app/ exists with code (Next.js, no src/) | app/ |
lib/ exists as main source dir | lib/ |
backend/ + frontend/ | Per-app: backend/src/ and frontend/src/ |
packages/*/src/ (monorepo) | Per-package |
| None of above but code files at root | . (project root) |
0.3.1 Build Code File List (ALWAYS)
Build a canonical file list as the single source of truth for all tools and analyses. Never let tools decide what to scan independently.
CODE_FILE_LIST="/tmp/structure-audit-code-files.txt"
find "$CODE_SCOPE" -type f \( \
-name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \
-o -name "*.py" -o -name "*.php" -o -name "*.go" -o -name "*.rs" \
-o -name "*.java" -o -name "*.rb" -o -name "*.swift" \) \
-not -path "*/node_modules/*" -not -path "*/dist/*" -not -path "*/.next/*" \
-not -path "*/coverage/*" -not -path "*/__pycache__/*" -not -path "*/.venv/*" \
-not -path "*/.git/*" \
> "$CODE_FILE_LIST"
CODE_FILE_COUNT=$(wc -l < "$CODE_FILE_LIST" 2>/dev/null || echo 0)Derive unique directories for tools that need directory arguments:
CODE_DIR_LIST="/tmp/structure-audit-code-dirs.txt"
while IFS= read -r file; do
dirname "$file"
done < "$CODE_FILE_LIST" | sort -u | head -20 > "$CODE_DIR_LIST"0.4 Code Density Check
| Condition | Mode |
CODE_FILE_COUNT >= 10 | FULL AUDIT -- all SA1-SA13 |
CODE_FILE_COUNT = 1-9 | LIMITED AUDIT -- SA1-SA4, SA11-SA12 only. Print: "Scope has <10 code files. Running limited audit." |
CODE_FILE_COUNT = 0 | NO-CODE MODE -- only markdown/config/docs. Run SA11 + SA12 only. Print: "No source code files. Running documentation audit only." |
Print:
Stack: [detected] | Framework: [detected] | Monorepo: [yes/no]
Code scope: [path] | Code files: [N] | Mode: [FULL/LIMITED/NO-CODE]
Dimensions: [which SA dimensions will run]Phase 1: Tool Execution
Run external tools. Save all outputs to zuvo/audits/structure-audit-{YYYY-MM-DD}/.
Skip if: --quick mode (SA9/SA10/SA13 = N/A), LIMITED/NO-CODE mode, or code density < 10.
CodeSift is the primary engine. Tools 1.2 (dead code), 1.4 (duplication), 1.5 (complexity) try CodeSift first. Phase 2 (hotspots) also uses CodeSift analyze_hotspots first. Fall back to CLI tools only if CodeSift is unavailable.
JS/TS tool gate (fallback tools only): Fallback tools 1.2 (knip) and 1.3 (dep-cruiser) require BOTH: (a) package.json exists, AND (b) stack detected as JavaScript or TypeScript. Tool 1.1 (cloc) and 1.4 fallback (jscpd) are stack-agnostic.
1.1 cloc (ALWAYS -- uses code file list)
npx cloc --json --by-file --list-file="$CODE_FILE_LIST"Feeds: SA7 (file size distribution), SA13 (hotspot LOC component).
Verify output: check for "SUM" key in JSON, not exit code.
1.2 Dead Code Detection (SA5, SA8)
PRIMARY (CodeSift):
find_dead_code(repo, file_pattern="*.{ts,tsx}")Parse: unused exports count, unused files list, confidence per entry.
FALLBACK (no CodeSift) -- knip (JS/TS only):
npx knip --reporter jsonFallback: grep-based export tracing (MEDIUM confidence).
1.3 dependency-cruiser (JS/TS only -- fallback tool)
Gate: package.json exists AND JS/TS stack detected. Otherwise: N/A.
tr '\n' '\0' < "$CODE_DIR_LIST" | xargs -0 npx --yes dependency-cruiser \
--no-config --output-type err \
--do-not-follow "node_modules" \
--exclude "^(dist|docs|coverage|\.next)"Feeds: SA6 (layer violations), SA8 (circular deps, orphans).
Verify output: check for "modules.*cruised" or violation text. 0 modules cruised = TOOL_EMPTY.
1.4 Code Duplication (SA10)
PRIMARY (CodeSift):
find_clones(repo, min_similarity=0.7, file_pattern="*.{ts,tsx}")FALLBACK (no CodeSift) -- jscpd (all languages):
tr '\n' '\0' < "$CODE_DIR_LIST" | xargs -0 npx --yes jscpd \
--min-lines 10 --reporters json \
--ignore "**/node_modules/**,**/dist/**,**/*.md,**/*.json" \
--output zuvo/audits/Verify output: check statistics.total.sources > 0 in JSON.
1.5 Complexity Distribution (SA9)
PRIMARY (CodeSift):
analyze_complexity(repo, top_n=20, file_pattern="*.{ts,tsx}")FALLBACK (no CodeSift) -- ESLint complexity (JS/TS only):
Try in order, stop at first success:
- Project ESLint config (preferred): Check for existing config. Use it with
--rule 'complexity: [warn, 15]'. - Standalone (plain JavaScript only):
--no-config-lookupon.js/.jsxfiles. - Grep heuristic (last resort): nesting depth via indentation analysis.
Never use --no-config-lookup on .ts/.tsx files -- it cannot parse TypeScript without a parser config.
Tool Summary
After all tools, print:
Tools: cloc [OK/SKIP] | dead-code [CodeSift/knip/SKIP] | dep-cruiser [OK/SKIP] | duplication [CodeSift/jscpd/SKIP] | complexity [CodeSift/eslint/SKIP]
Code files scanned: [N] | Non-code excluded: [dirs]Phase 2: Git Mining (SA13)
Skip if: --quick mode, LIMITED/NO-CODE mode, git history < 3 months, or non-git repository. Mark SA13 as N/A.
PRIMARY (CodeSift):
analyze_hotspots(repo, since_days=180)Parse: hotspot files (change frequency x complexity), temporal coupling pairs, churn scores.
FALLBACK (no CodeSift): Run git mining scripts directly.
2.1 Change Frequency
git log --since="6 months ago" --name-only --format="" -- $CODE_SCOPE | sort | uniq -c | sort -rn | head -30Top 30 most-changed files. Combine with cloc LOC for hotspot score.
2.2 Temporal Coupling
Analyze co-change patterns among top 100 most-changed files. Flag pairs with >50% co-change rate in different modules.
2.3 Shotgun Surgery
Count unique directories per commit. Median > 3 directories indicates shotgun surgery.
2.4 Developer Congestion
For each hotspot file from 2.1, count unique authors. >5 authors on a low-health file is a congestion finding.
Phase 3: Structural Analysis
Grep and Read based analysis for dimensions that do not need external tooling. Two-step detection: grep finds CANDIDATES, Read VERIFIES. Never score from grep alone.
Scope: All grep/glob commands target $CODE_SCOPE for SA1-SA10. SA11-SA12 use $REPO_ROOT.
3.1 SA1 -- Directory Pattern Consistency
- List top-level directories under
$CODE_SCOPE - Classify each as LAYER, FEATURE, INFRASTRUCTURE, or FRAMEWORK
- Mixed patterns at same level = finding
- Check framework conventions (Next.js: no pages/ alongside app/)
3.2 SA2 -- File Naming Conventions
- Glob all source files. Classify filename case (kebab, camel, pascal, snake).
- Mixed case in same directory = finding
- Count .test.ts vs .spec.ts. Both > 10% = mixed convention.
- Check type suffix consistency (.service.ts, .controller.ts)
3.3 SA3 -- Folder Depth and Nesting
- Compute max and average depth from file tree (code files only)
- Filter out framework-deep paths (Next.js App Router routes)
- Directories with >50 source files = flat explosion
- Single-file directories = unnecessary nesting
3.4 SA4 -- Colocation
- For each test file, determine co-located (same dir) or centralized (tests/)
20% in each category = mixed colocation
- Check type files: centralized types/ vs co-located *.types.ts
- Check constants/utils used by single module but stored centrally
3.5 SA5 -- Barrel Exports and Import Hygiene
Skip if: LIMITED or NO-CODE mode.
- Count index.ts files. >30 exports = god barrel
- Merge with dead code detection output for unused export counts
- Check for barrel chains (index.ts re-exporting from another index.ts)
- Grep for deep relative imports (>3 levels of ../)
- Check tsconfig paths vs actual usage
3.6 SA6 -- Separation of Concerns (CRITICAL GATE)
Skip if: LIMITED or NO-CODE mode.
Run fitness function rules:
- F1: ORM imports in .tsx/.vue files (CRITICAL if in components)
- F2: Controller-to-controller imports
- F3: Service importing from controller
- F4: Test utility imports in production code
- F5: fetch/axios in component files (not hooks)
- F6: process.env outside config layer
- F7: Module envy (>60% imports from single other module)
Each grep hit is a CANDIDATE. Read surrounding context to verify.
3.7 SA7 -- File Size Distribution (CRITICAL GATE)
Skip if: LIMITED or NO-CODE mode.
- Use cloc per-file data. Exclude non-code files from size analysis.
- Classify each file by type (component, service, hook, util)
- Apply 1.2x tolerance factor, compare to category limit from file-limits.md
- 3x+ = CRITICAL, 2-3x = HIGH, 1-2x = MEDIUM
- Compute distribution: median, P90, P99, max
- God module detection: >3x median files + generic name + high coupling
3.8 SA11 -- Configuration and Root Organization
Uses $REPO_ROOT.
- Count root-level files. Categorize (essential, dotfiles, stale, artifacts)
- Check for tracked temp files (.tmp-*, .env.local, *.log)
- Check .gitignore completeness for detected stack
- Check for scripts at root vs scripts/ directory
3.9 SA12 -- Documentation Structure
Uses $REPO_ROOT.
- Check for README.md with setup instructions
- Check for CHANGELOG.md
- Check for docs/adr/ directory (if project >50 files)
- Check for OpenAPI/Swagger spec (if API project)
- Check for CONTRIBUTING.md (if >3 git contributors)
Phase 4: Scoring
4.1 Per-Dimension Scoring
For each SA1-SA13:
- Apply scoring rubric (0 = violated, 1 = weak, 2 = acceptable, 3 = strong)
- Note N/A dimensions (exclude from denominator)
- Provide 1-line evidence for each score
- In LIMITED mode: SA5-SA10, SA13 are all N/A
- In NO-CODE mode: SA1-SA10, SA13 are all N/A
4.2 Critical Gate Check
| Gate | Trigger | Result |
| SA6 = 0 | ORM in UI components, no service layer | FAIL |
| SA7 = 0 | 3+ production files exceed 3x category limit | FAIL |
| SA8 = 0 | Circular deps in core production modules (confirmed) | FAIL |
Any gate = 0 means overall grade = FAIL regardless of total score. In LIMITED/NO-CODE mode, gates are N/A.
4.3 Total Score
raw_score = sum of all scored dimensions
available_max = 100 - sum of N/A dimension weights
normalized_score = (raw_score / available_max) * 1004.4 Grade Assignment
| Range | Grade |
| >= 85 | A |
| 70-84 | B |
| 50-69 | C |
| < 50 | D |
| Any gate = 0 | FAIL |
4.5 SQALE Debt Ratio (secondary metric)
remediation_minutes = sum(LOW:5 + MEDIUM:15 + HIGH:30 + CRITICAL:60 per finding)
debt_ratio = remediation_minutes / (total_LOC * 30)| Debt Ratio | Rating |
| 0-5% | A |
| 6-10% | B |
| 11-20% | C |
| 21-50% | D |
| 51%+ | E |
Phase 5: Report and Action Plan
REQUIRED: emit the Tool Availability Block (template in ../../shared/includes/codesift-setup.md) at the top of the report, after the title and before findings. Auditing degraded runs depends on this — do NOT skip it. The standard table replaces ad-hoc "tools used" prose in META.
5.1 Report Sections
- META -- date, stack, scope, code files count, mode (FULL/LIMITED/NO-CODE), tools used, LOC count
- Score Table -- SA1-SA13 with scores, max, gate status
- Critical Gates -- PASS/FAIL with evidence for SA6, SA7, SA8
- Grade -- letter grade + debt ratio
- Tool Outputs Summary -- key numbers from each tool
- Findings -- sorted by severity, with fix and effort estimates
- Cross-Cutting Patterns -- compound risk patterns:
- Structural bottleneck: SA7 god file + SA8 circular + SA13 hotspot
- Hidden coupling: SA13 temporal coupling + SA6 module envy
- Import pollution: SA5 god barrel + SA8 unused exports
- Untestable hotspot: SA13 hotspot + SA7 oversized + SA4 no co-location
- Missing abstraction: SA10 high duplication + SA13 shotgun surgery
- Abandoned attic: SA8 dead code + SA11 stale config + SA11 temp files
- Hotspot Analysis -- SA13 table (if applicable)
- Top 5 Action Items -- sorted by Impact/Effort ratio
- Recommended Next Skills -- based on findings
5.2 Save Report
mkdir -p audit-resultsSave to: zuvo/audits/structure-audit-YYYY-MM-DD.md — at the project root (zuvo/ resolves via git rev-parse --show-toplevel; override $ZUVO_OUTPUT_DIR. See ../../shared/includes/report-output-location.md).
5.3 Backlog Integration
Every HIGH and CRITICAL finding goes through backlog-add, one call per finding (../../shared/includes/backlog-protocol.md "Filing from a skill"; the checkout the helper writes to, the bars and the dedupe are the protocol's, so compute no fingerprint and restate nothing).
A Generic write per finding: ~/.zuvo/backlog-add --repo "$R" --class <C> --conf <N> --source structure-audit --file "$F" --line <n> [--anchor "$A"] --severity <level> --title "$T". <level> is critical or high, the finding's own severity. <N> is 85 for a HIGH-confidence finding (tool-confirmed, or read and verified) and 60 for a MEDIUM-confidence one (a grep-based fallback, as 1.2 labels it). <C> is the finding's own class: SIZE (SA7, a file over its size limit), DUP (SA10), CPLX (SA9, SA13), DEAD (unused exports and dead files, SA5), and CQ for every other dimension: SA1-SA4, SA6 (layer violations, a critical gate), SA8 (circular dependencies, a critical gate), SA11 and SA12. None of these takes an --anchor. Where the finding sits: a layer violation (SA6) cites the file and line of the offending import; a cycle (SA8) cites the first file of the cycle in path order and lists the others in --evidence "$E"; a directory-level finding (SA1-SA4, SA11, SA12) cites the first affected path in path order, --line 1, with a "Whole file: ..." or "Directory: ..." title ("The location rule"). A finding that is a defect with a wrong output rather than a structure problem is a BUG, which takes --anchor "$A", copied from the line that shows it. Assign "$R", "$F" and "$T" before each call, "$A" only when you pass --anchor and "$E" only when you pass --evidence, as "Free text goes through a variable" in that section says; an empty value you pass is a bug, and backlog-add refuses a missing required field (REFUSED missing-field:<f>). Report the B- or F-id each call prints and Recorded: N (backlog: a, ledger: b) ("The report line" in backlog-protocol.md), plus each NOT PERSISTED (<reason>) by name; on a non-zero exit act on the protocol's exit table, and never append by hand.
Resolved entries (Closing, not removing): with --fix, run 5.4 BEFORE these calls and file only the findings it left unresolved (the calls need the cited file to exist, and a file 5.4 deleted or renamed would leave an entry pointing nowhere). An open entry from an earlier audit that this run re-read and found fixed is closed, never removed. --fix does not commit, so there is no <sha7> to write: leave such an entry open, note the fix in the report, and let whoever commits the fix close it (backlog-protocol.md "How to Persist Findings" step 3: tick the box - [x] and append [FIXED <sha7>], the one hand edit the protocol sanctions; no helper ticks). When the fix is already committed, that tick is a single edit, it is not a wrote= path, this audit does not stage it, and the report names each ticked entry. Moving a closed entry to the archive is the helper's job (~/.zuvo/backlog-archive.py archive, which append-runlog runs at the end of the run), never done by hand.
This audit does not commit: it stages nothing. It lists the wrote= paths backlog-add printed as Backlog writes: <path>, ... (Backlog writes: none when there are none), in its report for the user when it runs standalone, and in its report for the calling skill's closing commit to carry when another skill runs it (backlog-protocol.md "Filing from a skill", Committing what backlog-add wrote).
5.4 Auto-Fix Mode (--fix)
Only if --fix argument was provided. After the report is saved, and before the 5.3 backlog calls:
| Fix Type | Condition | Action |
| Delete unused files | Dead code detection with HIGH confidence only | rm with confirmation |
| Add .gitignore patterns | Missing stack-specific patterns | Append to .gitignore |
| Rename convention violations | Clear case mismatch (1-3 files) | git mv with import updates |
NEVER auto-fix:
- Split oversized files (requires
zuvo:refactor) - Restructure directories (requires design decisions)
- Fix circular dependencies (requires
zuvo:architectureanalysis) - Delete files with MEDIUM confidence
Confirm each fix with the user before executing.
Next-Action Routing
| Finding | Action | Command |
| SA5 Dead code CRITICAL | Remove dead code | zuvo:structure-audit [path] --fix |
| SA8 Circular dependencies | Architecture review | zuvo:architecture --mode review [path] |
| SA10 Excessive duplication | Extract shared code | zuvo:refactor [file] |
| SA13 Hot file (high churn + complexity) | Refactor hot file | zuvo:refactor [file] |
| SA7 God module detected | Split oversized file | zuvo:refactor [file] |
| SA6 Layer violations | Architecture analysis | zuvo:architecture --mode review |
Completion Gate Check
Before printing the final output block, verify every item. Unfinished items = pipeline incomplete.
COMPLETION GATE CHECK
[ ] Code density mode printed (FULL/LIMITED/NO-CODE)
[ ] Tool summary printed: cloc/dead-code/dep-cruiser/duplication/complexity
[ ] SA6 fitness functions ran
[ ] SA7 file size uses cloc data with category classification
[ ] Critical gates printed: SA6, SA7, SA8
[ ] Report saved to zuvo/audits/
[ ] Run: line printed and appended to logSTRUCTURE-AUDIT COMPLETE
Grade: [A/B/C/D/FAIL] | Score: [N] / [MAX] Mode: [FULL/LIMITED/NO-CODE] | Stack: [detected] Dimensions: [N scored] | Critical gates: [PASS/FAIL] Findings: [N critical] / [N total]
Validity Gate (REQUIRED — print BEFORE Run line, AFTER retro append)
VALIDITY GATE
triggers_held:
code_files: yes(<count>)
language: <typescript|python|php|kotlin|javascript|...>
framework: <nextjs|nestjs|astro|hono|react|django|flask|...|none>
required_tool_calls:
detect_communities: [<N> communities | NOT_CALLED — VIOLATES_TRIGGER]
check_boundaries: [<N> violations | NOT_CALLED — VIOLATES_TRIGGER]
classify_roles: [<hub>/<leaf>/<bridge> distribution | NOT_CALLED — VIOLATES_TRIGGER]
fan_in_fan_out: [<max_in>/<max_out> outliers | NOT_CALLED — VIOLATES_TRIGGER]
architecture_summary: [<modules>/<files> | NOT_CALLED — VIOLATES_TRIGGER]
analyze_complexity: [<max_cc> max, <outliers_above_20> outliers | NOT_CALLED — VIOLATES_TRIGGER]
analyze_hotspots: [<top_N> hotspots in 90d | NOT_CALLED — VIOLATES_TRIGGER]
find_dead_code: [<N> unused exports | NOT_CALLED — VIOLATES_TRIGGER]
find_clones: [<N> clone clusters ≥0.7 | NOT_CALLED — VIOLATES_TRIGGER]
find_unused_imports: [<N> unused imports | NOT_CALLED — VIOLATES_TRIGGER]
audit_scan: [<N> compound findings | NOT_CALLED — VIOLATES_TRIGGER]
stack_specific (nest_audit/detect_hono_modules/python_audit/etc.): [<result> | not_required | NOT_CALLED — VIOLATES_TRIGGER]
postamble:
retros_log_appended: [yes(bytes_added=N) | NOT_APPENDED — VIOLATES_REQUIRED_POSTAMBLE]
retros_md_appended: [yes(entry_count=N) | NOT_APPENDED — VIOLATES_REQUIRED_POSTAMBLE]
verify_audit_pass: [yes(<verified>/<total> findings) | NOT_RUN | REJECTED]
gate_status: [PASS | FAIL — <which gates missing>]If gate_status = FAIL, override the VERDICT below to INCOMPLETE regardless of finding count, append [VALIDITY GATE FAIL] to the Run line NOTES column, and record the incomplete Process item (backlog-protocol.md "Filing from a skill"): ~/.zuvo/backlog-add --repo "$R" --class PROCESS --conf 90 --source structure-audit --target subject:structure-audit-incomplete --title "$T", with T the fixed title structure-audit run INCOMPLETE: validity gate failed, the same words on every run and no date; this run's reason goes in the report, never in the title. Assign "$R" and "$T" before the call, as "Free text goes through a variable" in that section says; an empty value is a bug, and backlog-add refuses a missing required field (REFUSED missing-field:<f>). It is kept in the findings ledger, not ticketed. File it before the report's Backlog writes: line is printed, so its wrote= paths are on that line: decide gate_status from every field the report can already fill (all but postamble) before the report is written, and file the item then. Only a postamble field that fails after the report is saved files it at this gate (a repeat bumps the same record); the Validity Gate block then carries its F-id on a line incomplete-item: <F-id> and its paths on a line Backlog writes (gate): <path>, … | none.
The Validity Gate must be printed AFTER the retro append and ~/.zuvo/append-runlog call (so postamble fields can be filled with yes(verified)). Printing it before guarantees NOT_APPENDED.
Run: <ISO-8601-Z> structure-audit <project> <N-critical> <N-total> <VERDICT> - <N>-dimensions <NOTES> <BRANCH> <SHA7> <INCLUDES> <TIER>
Retrospective (REQUIRED — load + fill BEFORE the Run line append)
Load ../../shared/includes/retrospective.md if not already loaded. Follow the retrospective protocol: gate check → 9 structured questions → TSV emit → markdown append to ~/.zuvo/retros.md AND ~/.zuvo/retros.log.
Then append the Run line via the retro-gated wrapper:
printf '%b\n' "$RUN_LINE" | ~/.zuvo/append-runlogThe wrapper:
- Verifies the matching
RETRO:entry inretros.log(skill+project). Missing → exit 2, runs.log NOT appended. - Runs
~/.zuvo/verify-auditon the audit report. Findings withoutfile:linecitations → exit 2, audit REJECTED. - On both pass: appends to
runs.logand prints confirmation.
If the wrapper exits non-zero: do NOT manually append to runs.log. Fix the cause (add retro, add file:line citations, etc.) and re-run.
VERDICT: PASS (0 critical findings), WARN (1-3 critical), FAIL (4+ critical), INCOMPLETE (Validity Gate FAIL).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

