cuioss

manage-architecture

LLM-based architectural analysis that transforms raw project data into meaningful structure

cuioss 5 Updated 2mo ago

Resources

2
GitHub

Install

npx skillscat add cuioss/plan-marshall/manage-architecture

Install via the SkillsCat registry.

SKILL.md

Manage Architecture Skill

Scope: hybrid means this skill manages both project-level data (.plan/project-architecture/) and integrates with plan-scoped workflows (solution-outline, task-plan).

Enforcement

Base contract: See manage-contract.md for shared enforcement rules, TOON output format, and error response patterns.

Skill-specific constraints:

  • Execute all steps in sequence; only stop when all modules are enriched
  • Do not leave responsibility or key_packages empty after enrichment
  • Do not skip --reasoning parameters (traceability is required)
  • Enrichment must cover every discovered module before completion
  • Discovery must run before enrichment (Step 1 before Steps 4-8)

Migration completeness — enumerate every read path before declaring a derivation migration done. This skill exposes derived structures (the build_map behind derive-verification, the resolve command envelope, the files/graph inventories) that multiple consumers read. When a change reshapes any such derivation — its schema, its command mapping, or the canonical accessor — the migration is NOT complete until EVERY read path of that derivation has been enumerated and updated. An incomplete fix that migrates the primary accessor while leaving a parallel raw-read consumer on the old shape is a defect, not a partial success: the unmigrated read path silently returns the old structure and corrupts its downstream branch. Before declaring such a migration done, enumerate every reader of the derivation (architecture find first, grep fallback for sub-module call sites) and confirm each one was migrated — a single surviving raw read of the pre-change shape fails the gate.


Scripts

Script Notation Purpose
architecture plan-marshall:manage-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
suggest-domains — Suggest applicable skill domains for a module
info, module, modules, commands, resolve client-api Consumer queries
derive-verification resolve-command Derive the deterministic verification command set for a changed-artifact list (single build_map consumer)
files, which-module, find, search client-api Files-inventory readers (categorised paths, reverse lookup over a four-rung ladder ending in the Axis-D path-attribution seam, then the two search verbs: find is a path glob that never opens a file, search --content is the file-content reader)
graph, path, neighbors, impact client-api Dependency graph queries (full graph, shortest path, n-hop neighborhood, reverse-dep closure)
capabilities client-api Envelope capability report — which query capabilities are answerable right now (module edges, path attribution, content search), distinguishing cannot-derive from derived-nothing
lsp hover, lsp references, lsp workspace-symbol, lsp definition client-api Additive LSP-shaped facade over module / impact / find / resolve — addresses the query surface in editor/agent vocabulary; renames nothing (see client-api § "LSP-shaped query facade")
overview client-api Token-bounded markdown summary of the project architecture
diff-modules client-api Drift detection vs a pre-snapshot (added/removed/changed/unchanged buckets)

Step 1: Discover Modules

Run extension API discovery:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture discover --force

Output: .plan/project-architecture/_project.json plus per-module
{module}/derived.json and an empty {module}/enriched.json stub for every
discovered module. The whole tree is staged under
.plan/project-architecture.tmp/ and swapped into place atomically — an
interrupted run leaves either the old layout or the new layout intact.

Always overwrites the existing tree to ensure fresh discovery.


Step 2: Review Build Profiles (Maven Only)

Condition: Only if any module has build_systems containing maven.

Check each module's derived.json for NO-MATCH-FOUND profiles in
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 3.


Step 3: Initialize Enrichment

Check whether per-module enriched.json stubs already exist:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture init --check

init --check reports how many modules already carry an enriched.json
file under their per-module directory.

If stubs exist, ask user:

AskUserQuestion:
  question: "Per-module enriched.json stubs already exist. 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
Choice Command
Skip Proceed to Step 4
Replace architecture init --force --reset (destructive — blanks all existing enrichment back to the empty stub)

If file does not exist:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture init

Step 4: Load Data & Enrich Project

Load the raw discovered data:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture derived

Read referenced READMEs for modules that have them. Based on the README and module descriptions, write a 1-2 sentence project description:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich project --description "{extracted project description}" \
  --reasoning "{source: README.md introduction | inferred from module names}"

Get the module list:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture modules

Steps 5-8: Per-Module Enrichment

For each module in the list, execute Steps 5-8 in order (dependencies: Step 5 feeds Steps 6-7, Step 8 runs last):

Get raw discovered data for the module:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture derived-module --module {module-name}

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.

Analyze to determine purpose value (see also architecture-persistence.md for full list):

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
Bill of Materials POM bom
Only test files integration-tests
JMH benchmarks benchmark

Step 6: Write Responsibility

Write 1-3 sentences describing what the module does, with reasoning:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich module --name {module-name} \
  --responsibility "{1-3 sentence description}" \
  --responsibility-reasoning "{source}" \
  --purpose {purpose-value} \
  --purpose-reasoning "{signal}"

Step 7: Key Packages & Dependencies

Select 2-4 architecturally significant packages per module (choose packages that represent the module's core abstractions, public API, or key implementation concerns):

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich package --module {module-name} \
  --package {full.package.name} \
  --description "{1-2 sentence description}"

Identify key dependencies (both --key and --internal are optional — omit either when not applicable):

# External + internal dependencies
python3 .plan/execute-script.py plan-marshall:manage-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 are architecturally significant}"

# Internal dependencies only (no external deps)
python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich dependencies --module {module-name} \
  --internal "{comma-separated list of internal module names}" \
  --reasoning "{why these are architecturally significant}"

Step 8: Resolve Skill Domains

Get applicable domains for this module:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  suggest-domains --module {module-name}

Present suggestions to user for confirmation:

AskUserQuestion:
  question: "Which skill domains apply to '{module-name}'?"
  header: "Skill Domains"
  options: [{domain} ({confidence}) — {signals}]
  multiSelect: true

For each confirmed domain, add its default skills:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich add-domain --module {module-name} --domain {domain-key} \
  --reasoning "{domain}: {signals}"

For domains where optional skills also apply (e.g., CDI detected, Lombok used),
add with --include-optionals:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich add-domain --module {module-name} --domain {domain-key} \
  --include-optionals --reasoning "{domain}: all skills apply based on {signals}"

To override profile filtering for a specific module (e.g., force integration_testing on a module
that lacks automatic signals), use --profiles:

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture \
  enrich add-domain --module {module-name} --domain {domain-key} \
  --profiles implementation,module_testing,integration_testing \
  --reasoning "explicit IT profile for {reason}"

Profile resolution order: --profiles flag > marshal.json active_profiles > extension signal detection > all defined profiles.

Batch: enrich all

Purpose: Batch-populate skills_by_profile for every module × every applicable extension in one call. Useful when you want to initialize (or back-fill) skills across the entire project without iterating enrich add-domain per module/domain pair.

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich all

Flags:

Flag Purpose
--include-optionals Include optional skills in addition to defaults
--reasoning Shared rationale appended to every enriched module

Notes:

  • Idempotent — safe to re-run. Only new (module, domain) pairs increment pairs_applied; already-present skills are not duplicated.
  • Returns a summary with modules_enriched, pairs_applied, pairs_skipped, and errors for traceability.
  • The system domain is always skipped (reserved for internal use).
  • Prose may refer to this as the enrich-all command; CLI invocations always use the space-separated form enrich all (same shape as enrich add-domain).

Step 9: Verify & Summarize

After all modules are enriched, verify completeness:

python3 .plan/execute-script.py plan-marshall:manage-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 no compile-scope deps)
  • Every module has skills_by_profile with at least implementation and module_testing

If any module is incomplete → return to Steps 5-8 for that module.

Display completion summary:

Architecture analysis complete.

Project: {project name}
Modules enriched: {count}

Files created:
  - .plan/project-architecture/_project.json
  - .plan/project-architecture/{module}/derived.json    (per module)
  - .plan/project-architecture/{module}/enriched.json   (per module)

Next steps:
  - Solution outline will use this data for placement decisions
  - Run 'architecture.py module --module X' to query module details

Canonical invocations

The canonical argparse surface for architecture.py. The D4 plugin-doctor analyzer
(_analyze_manage_invocation.py) reads this section as source-of-truth for markdown
notation occurrences across the marketplace. Consuming skills xref this section by
name (e.g., "see manage-architecture Canonical invocations → files") instead of
restating the command inline.

All subcommands accept the mutually-exclusive routing pair --project-dir DIR (default
.) and --plan-id PLAN_ID; see `plan-marshall:tools-script-executor/standards/cwd-policy.md`
for the Bucket A/B two-state contract.

discover

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture discover \
  [--force]

init

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture init \
  [--check] [--force] [--reset]

derived

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture derived

derived-module

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture derived-module \
  --module MODULE

info

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture info

modules

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture modules \
  [--command FILTER_COMMAND]

module

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture module \
  [--module MODULE] [--full] [--budget LINES]

overview

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture overview \
  [--budget LINES]

commands

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture commands \
  [--module MODULE]

resolve

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture resolve \
  --command COMMAND [--module MODULE]

derive-verification

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture derive-verification \
  --changed-artifacts PATH1,PATH2,...

Derives the deterministic verification command set for a comma-separated changed-artifact list. Each path is classified to a build_class via the tree-derived build_map (longest-glob-wins), grouped by class, and resolved to the architecture-command set. The build_class value names the canonical command directly — there is no indirection map between the class and the command it resolves (build_class: compile resolves compile, build_class: verify resolves verify). A docs-only changed set derives zero Python builds. See resolve-command.md § "Build-class → verification command" for the canonical mapping and Output example.

graph

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture graph \
  [--full]

path

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture path \
  SOURCE TARGET

neighbors

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture neighbors \
  --module MODULE [--depth N]

impact

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture impact \
  --module MODULE

siblings

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture siblings \
  --module MODULE

suggest-domains

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture suggest-domains \
  --module MODULE

profiles

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture profiles \
  [--modules MODULE_LIST]

files

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture files \
  --module MODULE [--category CATEGORY]

--category is one of the declared file-inventory vocabulary: agent, build_file, command, doc, script, skill, skill_doc, source, standard, template, test. The vocabulary is declared once as FILE_CATEGORIES in scripts/_architecture_core.py; client-api.md is the authoritative client contract.

Coverage: inside a marketplace bundle, every file under skills/<skill>/ is inventoried regardless of its sub-directory name or its file extension — a file that is not a skill, script, standard, template, build_file or doc classifies as skill_doc. Outside a bundle, the generic classifier is extension-driven and inventories .md / .adoc / .asciidoc as doc.

Zero-result semantics: an unrecognised --category returns status: error, error: unknown_category carrying the valid vocabulary in valid_categories — it is never a confident empty list. A recognised category that this module does not populate returns status: success with files: [].

which-module

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture which-module \
  --path PATH

Resolves --path to its owning module over a four-rung ladder — exact-inventory
match, paths.sources ∪ paths.tests containment, the Axis-D path-attribution
seam, then the root module. Every response carries the fail-closed pairs
truncated / elided and attributors / attributor_count (plus
attributor_notes), so attributor_count: 0 with module: null ("no attributor
ran") stays distinguishable from attributor_count: N with module: null ("N
ran and none claimed this path"). See
client-api.md § which-module for the full response
contract.

find

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture find \
  --pattern PATTERN [--category CATEGORY]

--pattern is a path glob (fnmatch syntax, case-sensitive, anchored to the full path). find matches the PATH only and never opens a file, so a token that exists solely inside a file body is invisible to it — that is the verb behaving exactly as designed, not a defect. For content questions ("which file contains X?") use search --content below.

--category takes the same vocabulary and the same zero-result semantics as the files verb above: an unrecognised name returns status: error, error: unknown_category, while a recognised-but-unpopulated category returns status: success with count: 0.

search

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture search \
  --content --pattern PATTERN [--category CATEGORY] [--literal] [--ignore-case]

Searches inventoried file bodies and reports the module-attributed files containing --pattern. This is the sanctioned content-search path for a dispatched leaf whose Grep / Glob tools are unavailable and whose Bash file-search commands are refused by the PreToolUse enforcement hook.

--content is the mode selector and is argparse-required — a bare search --pattern X is rejected at parse time rather than defaulting to a mode, so the mode stays explicit at every call site.

--pattern is a Python regex by default; --literal matches it verbatim (re.escape), which is what makes a pattern full of shell metacharacters safe and exact. No caller input ever reaches a shell. A pattern that fails to compile returns status: error, error: invalid_pattern carrying the compile message.

--ignore-case adds re.IGNORECASE and composes with --literal: a metacharacter-bearing pattern can be matched verbatim AND case-insensitively at once — the one combination the inline (?i) regex marker cannot express under --literal (re.escape neutralises it). Regex-mode (?i) still works. The echoed ignore_case boolean names the population the match set was computed over.

--category takes the same vocabulary and the same unknown-category semantics as the files verb above.

The result carries both count (result ROWS — one per module/category/path hit) and file_count (DISTINCT paths); they diverge only for an unclaimed cross-module duplicate. Read file_count for "how many files contain this?".

capabilities

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture capabilities

Reports which query capabilities are answerable right now, in the executing envelope — module_edges (graph/path/neighbors/impact), path_attribution (which-module), and content_search (files/find/search) — each distinguishing cannot-derive (no producer ran) from derived-nothing. Read from producers that actually ran (never the declaration), recomputed per call (never cached across dispatches), and scoped to the executing --project-dir. See client-api.md § capabilities for the full contract.

lsp

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture lsp hover \
  --module MODULE [--full]
python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture lsp references \
  --module MODULE
python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture lsp workspace-symbol \
  --query QUERY [--category CATEGORY]
python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture lsp definition \
  --command COMMAND [--module MODULE]

The additive LSP-shaped facade: lsp hover → module, lsp references → impact, lsp workspace-symbol → find, lsp definition → resolve. Each returns the underlying verb's answer unchanged — the facade adds LSP vocabulary over the existing verbs and renames nothing; the four traversal/inventory residue verbs (path, impact, find, which-module) stay reachable under their own names. See client-api.md § "LSP-shaped query facade" for the per-verb mapping table.

Anchors are per line: the pattern is compiled with re.MULTILINE, so ^ matches at the start of every LINE and $ at the end of every line — the same semantics grep, ripgrep, and the harness Grep tool give them. An anchored sweep such as --pattern '^Skill: plan-marshall:manage-files' therefore finds a directive on any line of a file, not only one starting at byte 0, and match_count counts every such line. The engine is Python re, not POSIX: write \s for whitespace, never a POSIX bracket class like [[:space:]] — Python still compiles that (as a nested set, emitting a FutureWarning on stderr) and it then silently over-matches, so the failure arrives as spurious hits rather than as an error or a zero.

Payload boundary: a hit carries exactly module, category, path, and match_count — the response never carries matching line text. match_count (the number of non-overlapping matches in that file) is the ranking signal: use it to decide which few files are worth a Read. Do not expect to see the matched lines.

Inventory-scope boundary: the search covers the crawled file inventory, which by construction excludes always-ignored directories (.git, node_modules, target, caches), dotfile trees outside the .gitignore / .editorconfig allowlist (so .claude/** and .github/** are NOT searched), and anything a .gitignore rule excludes. A zero result therefore means "not in any inventoried file", which is not the same as "not in the tree".

Zero-result semantics: count: 0 is never confident on its own. Every response also carries files_scanned (so "nothing was searched" stays distinguishable from "N files searched, genuinely absent"), unreadable[{path,reason}] (files skipped for a decode or OS error, rather than silently dropped), and the fail-closed truncated / elided pair.

See client-api.md § search for the full pattern contract, the worked TOON payloads, and every edge case.

diff-modules

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture diff-modules \
  --pre PRE_SNAPSHOT_DIR

enrich project

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich project \
  --description TEXT [--reasoning TEXT]

enrich module

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich module \
  --name MODULE --responsibility TEXT \
  [--purpose VALUE] [--reasoning TEXT] \
  [--responsibility-reasoning TEXT] [--purpose-reasoning TEXT]

enrich package

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich package \
  --module MODULE --package PACKAGE --description TEXT \
  [--components LIST]

enrich skills-by-profile

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich skills-by-profile \
  --module MODULE --skills-json JSON [--reasoning TEXT]

enrich dependencies

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich dependencies \
  --module MODULE [--key LIST] [--internal LIST] [--reasoning TEXT]

enrich tip

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich tip \
  --module MODULE --tip TEXT

enrich insight

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich insight \
  --module MODULE --insight TEXT

enrich best-practice

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich best-practice \
  --module MODULE --practice TEXT

enrich add-domain

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich add-domain \
  --module MODULE --domain DOMAIN \
  [--include-optionals] [--reasoning TEXT] [--profiles PROFILE_LIST]

enrich all

python3 .plan/execute-script.py plan-marshall:manage-architecture:architecture enrich all \
  [--include-optionals] [--reasoning TEXT]

Error Handling

Error Resolution
Extension API not found Verify domain bundles installed, run /marshall-steward
No modules discovered Verify build files exist and domain bundle matches project
Documentation not found Analyze source code directly, note "Inferred from source analysis"
Partial discovery failure Some extensions may fail while others succeed — check which modules are missing and re-run discover --force after fixing the failing extension
Interrupted enrichment Safe to resume — enrich module overwrites per-module data; re-run Steps 5-8 for incomplete modules
manage-maven-profiles skill unavailable Skip Step 2 entirely; unmatched profiles will remain as NO-MATCH-FOUND in each module's derived.json

Post-Implementation Enrichment

During verification or after implementation, capture learnings:

Command Usage
enrich tip --module {name} --tip "Use @ApplicationScoped for singleton services"
enrich insight --module {name} --insight "Heavy validation happens in boundary layer"
enrich best-practice --module {name} --practice "Always validate tokens before extracting claims"

Deferred Loading

Load standards documents in the order listed — each builds on the previous:

# Reference When to Load
1 manage-api.md First — covers setup, raw data, enrich commands (Steps 1-8), and orchestration flow
2 architecture-persistence.md When you need field schemas, purpose values, skills_by_profile structure, module graph format, or documentation source priorities
3 client-api.md When consuming enriched data (Step 9 verification, or downstream skills)
4 arch-gate-fitness-functions.md When working with arch-gate — the architectural-fitness-function canonical command, its per-domain tool binding, and the arch-constraint findings/lesson lifecycle
5 pm-dev-java:manage-maven-profiles Only during Step 2, only for Maven projects with unmatched profiles

Integration

This skill is invoked by:

  • marshall-steward wizard Step 13 (Project Structure Analysis)
  • Direct activation when regenerating project structure

Output is consumed by:

  • solution-outline Step 0 (module placement)
  • task-plan (command resolution)

Related

  • manage-solution-outline — Consumes architecture data for placement decisions
  • manage-config — Project-level configuration used during analysis
  • manage-files — Generic file operations used during discovery