analyze-project-architecture
LLM-based architectural analysis that transforms raw project data into meaningful structure
Best use case
analyze-project-architecture is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
LLM-based architectural analysis that transforms raw project data into meaningful structure
Teams using analyze-project-architecture should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/analyze-project-architecture/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How analyze-project-architecture Compares
| Feature / Agent | analyze-project-architecture | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
LLM-based architectural analysis that transforms raw project data into meaningful structure
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Analyze Project Architecture Skill
## Enforcement Rules
### Script Execution
1. Run scripts EXACTLY as documented - no improvisation
2. All scripts use: `python3 .plan/execute-script.py {notation} ...`
### Workflow Behavior
1. Complete all steps in sequence
2. After each module enrichment → proceed to next module
3. Only stop when all modules are enriched
### Prohibited Actions
- Skipping modules without enrichment
- Leaving `responsibility` or `key_packages` empty
- Omitting `--reasoning` parameters (traceability is required)
- Summarizing what you're about to do instead of doing it
---
## What This Skill Provides
**Discovery**: Run extension API to collect raw module data
**Enrichment**: LLM analyzes documentation and code to add semantic understanding
**Persistence**: Store enriched data for solution-outline consumption
---
## Scripts
| Script | Notation | Purpose |
|--------|----------|---------|
| architecture | `plan-marshall:analyze-project-architecture:architecture` | Main CLI for all operations |
### Command Groups
| Group | API | Purpose |
|-------|-----|---------|
| `discover`, `init` | [manage-api](standards/manage-api.md) | Setup commands |
| `derived`, `derived-module` | [manage-api](standards/manage-api.md) | Read raw discovered data |
| `enrich *` | [manage-api](standards/manage-api.md) | Write enrichment data |
| `info`, `module`, `modules`, `commands`, `resolve` | [client-api](standards/client-api.md) | Consumer queries |
---
## Step 1: Discover Modules
Run extension API discovery:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture discover --force
```
**Output**: `.plan/project-architecture/derived-data.json`
Always overwrites existing data to ensure fresh discovery.
---
## Step 1.5: Review Build Profiles (Maven Only)
**Condition**: Only if any module has `build_systems` containing `maven`.
Check derived-data.json for NO-MATCH-FOUND profiles in `modules.*.metadata.profiles`.
**If Maven modules exist AND unmatched profiles found**:
Load skill `pm-dev-java:manage-maven-profiles` and follow its workflow to:
1. Ask user about each unmatched profile (Ignore/Skip/Map)
2. Apply configuration via `run_config` commands
3. Re-run discovery to apply changes
**If no Maven modules OR no unmatched profiles** → Skip to Step 2.
---
## Step 2: Initialize Enrichment File
Check if `llm-enriched.json` already exists:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture init --check
```
**If file exists**, ask user:
```yaml
AskUserQuestion:
question: "llm-enriched.json already exists. What do you want to do?"
header: "Enrichment"
options:
- label: "Skip"
description: "Keep existing enrichments, continue to next step"
- label: "Replace"
description: "Discard existing enrichments, start fresh"
multiSelect: false
```
**Based on user choice**:
| Choice | Command |
|--------|---------|
| Skip | Proceed to Step 3 |
| Replace | `architecture init --force` |
**If file does not exist**:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture init
```
This creates empty enrichment structure for each module found in derived-data.json.
---
## Step 3: Load Discovered Data
Load the raw discovered data in TOON format:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture derived
```
**Output (TOON)**:
```toon
project:
name: {project-name}
root: {project-root}
modules[N]{name,path,build_systems,readme,description}:
module-a,module-a,maven,module-a/README.adoc,Description from pom
module-b,module-b,maven,,
module-c,module-c,maven+npm,module-c/README.md,
```
The output shows raw extension API discovery results:
- Module names and paths
- Build systems (joined with `+` for hybrid)
- README paths (if detected)
- Descriptions (from build files, if available)
Read referenced READMEs for modules that have them:
```bash
Read {readme path from derived output}
```
---
## Step 4: Enrich Project Description
Based on the README and module descriptions, write a 1-2 sentence project description.
**Always provide reasoning** to document the source:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich project --description "{extracted project description}" \
--reasoning "{source: README.md introduction | inferred from module names | pom.xml description}"
```
**Reasoning examples**:
- "From README.md first paragraph"
- "Inferred from module structure and pom.xml descriptions"
- "Aggregated from child module responsibilities"
---
## Step 5: Get Module List
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture modules
```
**Output (TOON)**:
```toon
modules[N]:
- module-a
- module-b
- ...
```
---
## Step 6: Enrich Each Module
**For each module in the list**, execute Steps 6a-6e:
### Step 6a: Read Module Documentation
Get raw discovered data for the module:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture derived-module --name {module-name}
```
**Output (TOON)**:
```toon
module:
name: {module-name}
path: {module-path}
build_systems: maven
paths:
readme: {module}/README.adoc
sources[N]:
- src/main/java
tests[N]:
- src/test/java
metadata:
description: {from build file if available}
packaging: jar
packages[N]{name,path,package_info}:
com.example.core,src/main/java/com/example/core,src/main/java/com/example/core/package-info.java
com.example.util,src/main/java/com/example/util,
dependencies[N]:
- groupId:artifactId:scope
```
Read the referenced documentation:
```bash
Read {paths.readme}
Read {package_info path} # for packages with package_info
```
If no documentation available, sample 2-3 source files from packages.
### Step 6b: Determine Module Purpose
Analyze to determine `purpose` value:
| Signal | Purpose Value |
|--------|---------------|
| packaging=jar, no runtime deps | `library` |
| Quarkus extension annotations | `extension` |
| Build-time processor, deployment | `deployment` |
| Main class, application entry | `runtime` |
| packaging=pom at root | `parent` |
| Only test files | `integration-tests` |
| JMH benchmarks | `benchmark` |
### Step 6c: Write Module Responsibility
Write 1-3 sentences describing what the module does.
**Good examples**:
- "Validates JWT tokens from multiple identity providers using a pipeline approach"
- "Provides Quarkus CDI integration for the core validation library"
- "Coordinates build configuration for all child modules"
**Bad examples** (avoid):
- "Core module" (too vague)
- "Main package for processing" (says nothing)
**Always provide reasoning** for traceability:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich module --name {module-name} \
--responsibility "{1-3 sentence description}" \
--responsibility-reasoning "{source: README overview | package-info.java | inferred from class names}" \
--purpose {purpose-value} \
--purpose-reasoning "{signal: packaging=jar with no main class | Quarkus extension annotations}"
```
**Reasoning examples**:
- Responsibility: "From module README.adoc overview section"
- Responsibility: "Inferred from package-info.java and primary class names"
- Purpose: "packaging=jar, no runtime dependencies, no main class"
- Purpose: "Contains @BuildStep annotations indicating Quarkus deployment module"
### Step 6d: Identify Key Packages
Select 2-4 architecturally significant packages per module.
For each key package, write 1-2 sentence description:
**Good examples**:
- "Provides the token validation pipeline with pluggable validators"
- "Contains domain models for tokens, claims, and validation results"
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich package --module {module-name} \
--package {full.package.name} \
--description "{1-2 sentence description}"
```
Repeat for each key package (2-4 packages).
### Step 6d-2: Identify Key Dependencies
From the derived-module output (Step 6a), analyze the `dependencies` list to identify architecturally significant dependencies.
**Selection criteria** - Include dependencies that:
- Define the module's core technology (frameworks, runtime libraries)
- Provide essential APIs the module builds upon
- Define the runtime contract (provided-scope dependencies like `quarkus-core`, `servlet-api`)
- Are unique to this module's purpose (not ubiquitous across all modules)
**Exclude from key dependencies**:
- Ubiquitous utilities (commons-lang, guava, slf4j) unless central to module purpose
- Pure code-generation tools (lombok) that don't define architecture
- Standard test frameworks (junit, mockito) - implied by testing profile
- Transitive dependencies not directly used
**Include despite scope**:
- Provided-scope framework APIs (these define the runtime contract)
- Test-scope if architecturally distinctive (testcontainers, wiremock, arquillian)
- Compile-scope annotation libraries that define contracts (jspecify, checker-qual)
**For multi-module projects**, also identify `internal_dependencies`:
- Other modules in this project that this module depends on
- Look for dependencies with same groupId as the project
**Good examples**:
- `io.quarkus:quarkus-core` (provided) - Defines runtime framework contract
- `jakarta.servlet-api` (provided) - Defines servlet container contract
- `org.eclipse.microprofile.jwt:microprofile-jwt-auth-api` - Core API this module implements
- `org.jspecify:jspecify` - Defines null-safety contract
- `org.testcontainers:testcontainers` (test) - Architecturally distinctive testing approach
**Bad examples** (exclude):
- `org.junit.jupiter:junit-jupiter-api` - Standard test framework, implied by profile
- `org.projectlombok:lombok` - Code generation tool, doesn't define architecture
- `org.slf4j:slf4j-api` - Ubiquitous logging facade
- `org.apache.commons:commons-lang3` - Generic utility, not distinctive
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich dependencies --module {module-name} \
--key "{comma-separated list of groupId:artifactId}" \
--internal "{comma-separated list of internal module names}" \
--reasoning "{why these dependencies are architecturally significant}"
```
**Example**:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich dependencies --module oauth-sheriff-core \
--key "io.quarkus:quarkus-core,org.eclipse.microprofile.jwt:microprofile-jwt-auth-api" \
--reasoning "Quarkus runtime and MicroProfile JWT API define the module's integration contract"
```
For single-module projects or leaf modules with no internal dependencies, omit `--internal`.
### Step 6e: Determine Skills by Profile
Assign skills organized by execution profile (implementation, unit-testing, integration-testing, benchmark-testing, documentation).
**Step 6e.1: List Available Domains**
Get all configured skill domains:
```bash
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
skill-domains list
```
**Output (TOON)**:
```toon
status: success
domains:
- system
- java
- javascript
- plan-marshall-plugin-dev
count: 4
```
**Step 6e.2: Determine Applicable Domain**
Based on the module analysis from Steps 6a-6d, determine which domain applies.
**Signals to consider** (from derived-module output and documentation):
- Source file extensions (`.java`, `.kt`, `.js`, `.ts`)
- Dependencies (groupId/artifactId patterns, npm packages)
- Framework annotations in code
- Build file configurations
- Module description and purpose
**Examples of domain applicability**:
| Signal | Domain |
|--------|--------|
| Java sources, javax/jakarta imports | `java` |
| Kotlin sources, kotlin-stdlib | `java` (or future `kotlin`) |
| JavaScript/TypeScript sources | `javascript` |
| plugin.json, marketplace structure | `plan-marshall-plugin-dev` |
| Quarkus dependencies | `java` + CUI-specific if CUI deps present |
| `doc/` or `docs/` with `.adoc` files | `documentation` (as additional profile) |
**Step 6e.3: Get Skills by Profile**
For the applicable domain, get the pre-assembled skills by profile:
```bash
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
get-skills-by-profile --domain {domain-key}
```
**Output (TOON)**:
```toon
status: success
domain: java
skills_by_profile:
implementation:
- pm-dev-java:java-core
- pm-dev-java:java-null-safety
- pm-dev-java:java-lombok
- pm-dev-java:java-cdi
- pm-dev-java:java-maintenance
unit-testing:
- pm-dev-java:java-core
- pm-dev-java:java-null-safety
- pm-dev-java:java-lombok
- pm-dev-java:junit-core
- pm-dev-java:junit-integration
integration-testing:
- pm-dev-java:java-core
- pm-dev-java:java-null-safety
- pm-dev-java:java-lombok
- pm-dev-java:junit-core
- pm-dev-java:junit-integration
benchmark-testing:
- pm-dev-java:java-core
- pm-dev-java:java-null-safety
- pm-dev-java:java-lombok
- pm-dev-java:junit-core
- pm-dev-java:junit-integration
```
**Step 6e.4: Filter Skills Based on Module Signals**
Optionally filter the skills based on module signals:
| Module Signal | Action |
|---------------|--------|
| No CDI annotations | Remove `java-cdi` from implementation |
| No Lombok annotations | Remove `java-lombok` from all profiles |
| No integration tests (*IT.java) | Remove integration-testing profile entirely |
| No benchmarks (*Benchmark.java) | Remove benchmark-testing profile entirely |
**Step 6e.4b: Add Documentation Profile (Cross-Domain)**
If module has AsciiDoc documentation, add `documentation` profile from `documentation` domain:
**Detection**: Check if module has `doc/` or `docs/` directory with `.adoc` files.
```bash
# Check for AsciiDoc docs in module
ls {module-path}/doc/*.adoc 2>/dev/null || ls {module-path}/docs/*.adoc 2>/dev/null
```
**If `.adoc` files found**:
1. Get documentation skills:
```bash
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
get-skills-by-profile --domain documentation
```
2. Add `documentation` profile to the module's `skills_by_profile`:
```json
{
"implementation": [...],
"module_testing": [...],
"documentation": ["pm-documents:ref-documentation", "pm-documents:manage-adr", ...]
}
```
**Key principle**: Documentation is a separate task type (like testing), not a variant of implementation. A module can have both `implementation` AND `documentation` profiles.
**Step 6e.5: Apply Skills by Profile**
**Include reasoning** about filtering decisions:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich skills-by-profile --module {module-name} \
--skills-json '{"implementation": ["pm-dev-java:java-core", "pm-dev-java:java-cdi"], "module_testing": ["pm-dev-java:java-core", "pm-dev-java:junit-core"]}' \
--reasoning "{filtering applied: removed java-lombok (no @Data annotations found), kept java-cdi (CDI beans present)}"
```
**Reasoning examples**:
- "Base java domain, no filtering applied"
- "Removed java-cdi (no CDI annotations), removed integration_testing (no *IT.java files)"
- "Added cui-testing-http based on MockWebServer test dependency"
- "Added documentation profile (module has doc/*.adoc files)"
The `skills_by_profile` structure flows to:
1. **solution-outline**: Copies to deliverable as `skills-implementation`, `skills-testing`, etc.
2. **task-plan**: Uses pre-resolved skills when creating tasks (no runtime lookup)
---
## Step 7: Verify Enrichment
After all modules are enriched, verify completeness:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture info
```
Check that:
- [ ] Every module has non-empty `responsibility`
- [ ] Every module has valid `purpose`
- [ ] Every module has 2-4 `key_packages` with descriptions
- [ ] Every module has `key_dependencies` identified (unless module has no compile-scope deps)
- [ ] Every module has `skills_by_profile` with at least `implementation` and `unit-testing` profiles
If any module is incomplete → return to Step 6 for that module.
---
## Step 8: Output Summary
Display completion summary:
```
Architecture analysis complete.
Project: {project name}
Modules enriched: {count}
Files created:
- .plan/project-architecture/derived-data.json
- .plan/project-architecture/llm-enriched.json
Next steps:
- Solution outline will use this data for placement decisions
- Run 'architecture.py module --name X' to query module details
```
---
## Error Handling
### Extension API Not Available
```
Error: Extension API not found.
Resolution:
1. Verify domain bundles installed (pm-dev-java, pm-dev-frontend)
2. Run /marshall-steward to configure project
3. Re-run this skill
```
### No Modules Discovered
```
Error: No modules found in project.
Resolution:
1. Verify project has build files (pom.xml, package.json, build.gradle)
2. Check that domain bundle matches project type
3. Re-run discovery
```
### Documentation Not Found
If module has no README or package-info:
1. Analyze source code directly
2. Check parent module for context
3. Note in responsibility: "Inferred from source analysis"
---
## Deferred Loading
For detailed specifications, load on demand:
| Reference | When to Load |
|-----------|--------------|
| [manage-api.md](standards/manage-api.md) | Manage commands (setup, read raw, enrich) |
| [client-api.md](standards/client-api.md) | Client commands (merged data for consumers) |
| [architecture-persistence.md](standards/architecture-persistence.md) | Field schemas and formats |
| [architecture-workflow.md](standards/architecture-workflow.md) | Workflow phase details |
| [documentation-sources.md](standards/documentation-sources.md) | Reading strategy details |
| `pm-dev-java:manage-maven-profiles` | Maven profile classification (Step 1.5) |
---
## Integration
This skill is invoked by:
- **marshall-steward wizard** Step 6b (after discovery)
- **Direct activation** when regenerating project structure
Output is consumed by:
- **solution-outline** Step 0 (module placement)
- **task-plan** (command resolution)
---
## Post-Implementation Enrichment
During verification phase or after implementation, capture learnings:
### Add Implementation Tip
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich tip --module {module-name} --tip "Use @ApplicationScoped for singleton services"
```
### Add Learned Insight
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich insight --module {module-name} --insight "Heavy validation happens in boundary layer"
```
### Add Best Practice
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
enrich best-practice --module {module-name} --practice "Always validate tokens before extracting claims"
```
These accumulate over time and are included in module output for future reference.Related Skills
analyze-rust-optimizations
This skill performs thorough analysis of Rust libraries to find optimization opportunities. It should be used when reviewing Rust code for performance improvements, memory efficiency, or when profiling indicates bottlenecks. Focuses on runtime performance and memory usage through dynamic profiling tools and static code analysis.
analyze-pr-performance
Analyze code review pipeline performance for a specific PR. Use when investigating slow PRs, identifying bottlenecks, or debugging performance issues in code reviews.
analyze
Deep analysis and investigation
analyze-m1-module-for-migration
Systematically analyze a Magento 1 module to determine its purpose, usage, and migration requirements for Magento 2. Use when you need to decide whether to migrate a M1 module, find alternatives, or skip it.
analyze-function
Deep line-by-line analysis of a function or method. Explains what each line does, why it's written that way, performance implications, edge cases, and design patterns. Use when user says "analyze-function", "analyze {function}", "deep dive on {function}", or "explain {function} line by line".
analyze-friction
Orchestrate 3-stage friction analysis workflow across conversations. Extracts raw friction, abstracts patterns, and presents for approval. Use when user wants to analyze conversation history for improvement opportunities.
analyze-codebase
Analyze a codebase to generate a comprehensive architecture and structure report. Use when user wants to understand a codebase, explore project structure, or generate analysis.
analyze-code
Deep code analysis using consultant agent. Identifies technical debt, risks, and improvement opportunities.
analyze-code-structure
Examine code organization and identify structural patterns. Use when reviewing module design.
analyze-architecture
Comprehensive brownfield architecture analysis for existing codebases. Discovers structure, identifies patterns, assesses quality, calculates production readiness, and provides actionable recommendations. Use when analyzing existing codebases to understand architecture, assess quality, or prepare for modernization.
aidb-architecture
Comprehensive architectural reference for AIDB core and MCP integration. Covers 6-layer architecture (MCP, Service, Session, Adapter, DAP Client, Protocol), component organization, data flow patterns, and design decisions. Use when explaining overall system design or understanding how layers interact.
agentic_architecture
Enforces high-level architectural thinking, separation of concerns, and scalability checks before coding.