
analyze-project-architecture
by cuioss
An orchestration layer for AI coding assistants (currently Claude Code) that enforces consistency, reliability, and more predictable outputs.
SKILL.md
name: analyze-project-architecture description: LLM-based architectural analysis that transforms raw project data into meaningful structure allowed-tools: Read, Write, Edit, Glob, Grep, Bash
Analyze Project Architecture Skill
Enforcement Rules
EXECUTION MODE: Execute this skill immediately. Do not explain, summarize, or discuss these instructions.
Script Execution
- Run scripts EXACTLY as documented - no improvisation
- All scripts use:
python3 .plan/execute-script.py {notation} ...
Workflow Behavior
- Complete all steps in sequence
- After each module enrichment → proceed to next module
- Only stop when all modules are enriched
Prohibited Actions
- Skipping modules without enrichment
- Leaving
responsibilityorkey_packagesempty - Omitting
--reasoningparameters (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 | Setup commands |
derived, derived-module | manage-api | Read raw discovered data |
enrich * | manage-api | Write enrichment data |
info, module, modules, commands, resolve | client-api | Consumer queries |
Step 1: Discover Modules
Run extension API discovery:
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:
- Ask user about each unmatched profile (Ignore/Skip/Map)
- Apply configuration via
run_configcommands - 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:
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture init --check
If file exists, ask user:
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:
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:
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture derived
Output (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:
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:
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
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture modules
Output (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:
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture derived-module --name {module-name}
Output (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:
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:
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"
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 contractjakarta.servlet-api(provided) - Defines servlet container contractorg.eclipse.microprofile.jwt:microprofile-jwt-auth-api- Core API this module implementsorg.jspecify:jspecify- Defines null-safety contractorg.testcontainers:testcontainers(test) - Architecturally distinctive testing approach
Bad examples (exclude):
org.junit.jupiter:junit-jupiter-api- Standard test framework, implied by profileorg.projectlombok:lombok- Code generation tool, doesn't define architectureorg.slf4j:slf4j-api- Ubiquitous logging facadeorg.apache.commons:commons-lang3- Generic utility, not distinctive
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:
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:
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
skill-domains list
Output (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:
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
get-skills-by-profile --domain {domain-key}
Output (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.
# 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:
- Get documentation skills:
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
get-skills-by-profile --domain documentation
- Add
documentationprofile to the module'sskills_by_profile:
{
"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:
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:
- solution-outline: Copies to deliverable as
skills-implementation,skills-testing, etc. - task-plan: Uses pre-resolved skills when creating tasks (no runtime lookup)
Step 7: Verify Enrichment
After all modules are enriched, verify completeness:
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_packageswith descriptions - Every module has
key_dependenciesidentified (unless module has no compile-scope deps) - Every module has
skills_by_profilewith at leastimplementationandunit-testingprofiles
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:
- Analyze source code directly
- Check parent module for context
- Note in responsibility: "Inferred from source analysis"
Deferred Loading
For detailed specifications, load on demand:
| Reference | When to Load |
|---|---|
| manage-api.md | Manage commands (setup, read raw, enrich) |
| client-api.md | Client commands (merged data for consumers) |
| architecture-persistence.md | Field schemas and formats |
| architecture-workflow.md | Workflow phase details |
| 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
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
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
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.
スコア
総合スコア
リポジトリの品質指標に基づく評価
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
3ヶ月以内に更新がある
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
レビュー
レビュー機能は近日公開予定です