| name | structure-audit |
| description | 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.
|
| codesift_tools | {"always":["analyze_project","index_status","index_folder","index_file","plan_turn","get_file_tree","get_file_outline","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","search_text","search_symbols"],"by_stack":{"typescript":["get_type_info"],"javascript":[],"python":["python_audit","analyze_async_correctness"],"php":["php_project_audit","php_security_scan","resolve_php_namespace"],"kotlin":["analyze_sealed_hierarchy","find_extension_functions","trace_flow_chain","trace_suspend_chain","trace_compose_tree","analyze_compose_recomposition","trace_hilt_graph","trace_room_schema","analyze_kmp_declarations","extract_kotlin_serialization_contract"],"nestjs":["nest_audit"],"nextjs":["framework_audit","nextjs_route_map"],"astro":["astro_audit","astro_actions_audit","astro_hydration_audit","astro_middleware","astro_svg_components"],"hono":["analyze_hono_app","audit_hono_security","detect_hono_modules"],"express":[],"fastify":[],"react":["react_quickstart","analyze_hooks","analyze_renders","analyze_context_graph"],"django":["analyze_django_settings","effective_django_view_security","taint_trace"],"fastapi":["trace_fastapi_depends","get_pydantic_models"],"flask":["find_framework_wiring"],"jest":[],"yii":["resolve_php_service"],"prisma":["analyze_prisma_schema"],"drizzle":[],"sql":["sql_audit"],"postgres":["migration_lint"]}} |
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:
../../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
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 or 2 is missing, STOP.
Environment Compatibility
Read ../../shared/includes/env-compat.md for agent dispatch patterns, path resolution, and progress tracking across Claude Code, Codex, and Cursor.
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>.md is on disk — at the project root (zuvo/ resolves via git rev-parse --show-toplevel; override $ZUVO_OUTPUT_DIR. See ../../shared/includes/report-output-location.md).
~/.zuvo/append-runlog is called with the Run line — this triggers BOTH gates:
- retro-gate: requires a matching
RETRO: entry in ~/.zuvo/retros.log for skill=structure-audit project=<this>. If missing → exit 2, runs.log NOT appended. Load retrospective.md, fill 9 fields, run the bash append commands, then re-run append-runlog.
- audit-content gate: runs
~/.zuvo/verify-audit on the report. Every finding section must contain at least one path/to/file.ext:LINE citation that resolves in the current tree. Findings without citations get rejected. If rejected → fix the report (add file:line per finding), re-run append-runlog.
- Print
RETRO_APPENDED: retros.log=YES retros.md=YES (verified) and confirm exit 0 from append-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 json
Fallback: 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-lookup on .js/.jsx files.
- 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 -30
Top 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) * 100
4.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-results
Save 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
For HIGH and CRITICAL findings, persist to memory/backlog.md — at the MAIN checkout root, resolved per ../../shared/includes/backlog-protocol.md "Where the Backlog Lives" (never a worktree-local copy):
- Fingerprint format:
file|SA-dimension|check-id
- Deduplicate against existing entries
5.4 Auto-Fix Mode (--fix)
Only if --fix argument was provided. After report generation:
| 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:architecture analysis)
- 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 log
STRUCTURE-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 add a backlog item B-structure-audit-incomplete-<date>.
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: structure-audit - -dimensions
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-runlog
The wrapper:
- Verifies the matching
RETRO: entry in retros.log (skill+project). Missing → exit 2, runs.log NOT appended.
- Runs
~/.zuvo/verify-audit on the audit report. Findings without file:line citations → exit 2, audit REJECTED.
- On both pass: appends to
runs.log and 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).