marketplace/bundles/plan-marshall/skills/marshall-steward/SKILL.md
Project configuration wizard for planning system. Manages executor generation, health checks, build systems, and skill domains.
npx skillsauth add cuioss/plan-marshall marshall-stewardInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Project configuration wizard for the planning system.
/marshall-steward # Interactive menu or first-run wizard
/marshall-steward --wizard # Force first-run wizard
At command start, emit the following banner verbatim to the user:
╔═══════════════════════════════════════════════════════════════════════╗
║ : ║
║ .;:;. ║
║ :;:::;: ║
║ ... .;:::::::::;. ... ║
║ .::;:::::::::::::;:::::::::;:::::::::::::;::. ║
║ :;:::::::::::::::::::::::::::::::;: ║
║ .;:::::::::::::::::::::::::::::;. ║
║ ║
║ █▀█ █ █▀█ █▄ █ ║
║ █▀▀ █▄▄ █▀█ █ ▀█ ║
║ █▀▄▀█ █▀█ █▀█ █▀ █ █ █▀█ █ █ ║
║ █ ▀ █ █▀█ █▀▄ ▄█ █▀█ █▀█ █▄▄ █▄▄ ║
║ ║
║ .;:::::::::::::::::::::::::::::;. ║
║ :;:::::::::::::::::::::::::::::::;: ║
║ .::;:::::::::::::;:::::::::;:::::::::::::;::. ║
║ ... .;:::::::::;. ... ║
║ :;:::;: ║
║ .;:;. ║
║ : ║
╚═══════════════════════════════════════════════════════════════════════╝
Execution mode: Run scripts exactly as documented; return to Main Menu after each operation.
Prohibited actions:
Constraints:
python3 .plan/execute-script.py {notation} ...Wizard Mode: Sequential setup for new projects (executor generation, marshal.json init, build detection, skill domains)
Menu Mode: Interactive maintenance for returning users (regenerate executor, health check, configuration)
| Script | Notation | Purpose |
|--------|----------|---------|
| determine_mode | plan-marshall:marshall-steward:determine_mode | Determine wizard vs menu mode; also exposes check-working-prefixes for the project.working_prefixes presence/drift surfacing |
| gitignore_setup | plan-marshall:marshall-steward:gitignore_setup | Configure .gitignore for .plan/ |
| bootstrap_plugin | (direct Python call) | Detect plugin root, cache in .plan/local/marshall-state.toon |
| Script | Notation | Purpose |
|--------|----------|---------|
| generate-executor | plan-marshall:tools-script-executor:generate_executor | Executor generation. Both surfaces (wizard Step 4 and maintenance "Regenerate Executor") detect whether they are running inside a git worktree (path under .plan/local/worktrees/) and, when so, pass --marketplace-root <worktree-absolute-path> so the generated executor's script mappings resolve against the worktree's marketplace/bundles/ instead of the main checkout or the plugin cache. |
| manage-config | plan-marshall:manage-config:manage-config | Project-level marshal.json CRUD |
| run_config | plan-marshall:manage-run-config:run_config | Clean temp, logs, archived-plans, memory |
| ci_health | plan-marshall:tools-integration-ci:ci_health | CI provider detection |
| permission_doctor | plan-marshall:tools-permission-doctor:permission_doctor | Permission analysis |
| permission_fix | plan-marshall:tools-permission-fix:permission_fix | Permission fixes |
| extension_discovery | plan-marshall:extension-api:extension_discovery | Extension config defaults |
| credentials | plan-marshall:manage-providers:credentials | External tool provider management |
The /marshall-steward command must locate bootstrap_plugin.py and detect the plugin root before loading this skill. bootstrap_plugin.py is the single deterministic resolver for every other bootstrap script path — locate it once, then route all post-get-root path lookups through its resolve verb instead of hand-globbing each script.
Locate bootstrap_plugin.py (the one unavoidable glob). Resolve its path with the Glob tool against the layout-agnostic pattern **/marshall-steward/scripts/bootstrap_plugin.py and capture the first match as ${BOOTSTRAP}. The recursive ** prefix matches both deploy layouts — the flat target/claude/plan-marshall/skills/… tree and the versioned cache …/plan-marshall/{version}/skills/… tree — without a hand-placed * version level.
Detect the plugin root and cache it:
python3 "${BOOTSTRAP}" get-root
Read plugin_root from the TOON output and set ${PLUGIN_ROOT} to it. The plugin root is cached in .plan/local/marshall-state.toon for subsequent calls.
Resolve every other bootstrap script path through bootstrap_plugin resolve — version-aware, layout-agnostic. For any script X.py under a bundle, run:
python3 "${BOOTSTRAP}" resolve --bundle plan-marshall --path skills/{skill}/scripts/X.py
and read resolved_path from the TOON. Never hand-glob a ${PLUGIN_ROOT}/plan-marshall/*/skills/… pattern to find a post-get-root script — resolve already iterates the version dirs deterministically.
Determine whether to run wizard or menu based on existing files.
BOOTSTRAP: Since execute-script.py may not exist yet, use a DIRECT Python call. Resolve the script path deterministically via bootstrap_plugin resolve (${BOOTSTRAP} was located in Prerequisites) and read resolved_path from the TOON as {DETERMINE_MODE}:
python3 "${BOOTSTRAP}" resolve --bundle plan-marshall --path skills/marshall-steward/scripts/determine_mode.py
Then invoke the resolved script directly:
python3 "{DETERMINE_MODE}" mode
Output (TOON):
mode wizard
reason executor_missing
| mode | reason | Action |
|------|--------|--------|
| wizard | executor_missing | Load: Read references/wizard-flow.md → Execute wizard |
| wizard | marshal_missing | Load: Read references/wizard-flow.md → Execute wizard |
| menu | both_exist | Show Main Menu below |
--wizard FlagIf --wizard flag provided, force wizard regardless of determine_mode result:
Read references/wizard-flow.md
Execute the wizard flow from that file.
Display menu when both executor and marshal.json exist.
The Main Menu has 5 options, which exceeds the AskUserQuestion 4-option cap. It is presented as a paginated menu following the "More actions..." pattern documented in plan-marshall/workflow/planning.md (§ Action: list): each page presents at most 4 options, and every non-final page reserves its 4th slot for a "More..." continuation that triggers the next page's AskUserQuestion.
Page 1 — first 3 options plus the "More..." continuation:
AskUserQuestion:
question: "What would you like to do?"
header: "Main Menu"
options:
- label: "1. Maintenance"
description: "Regenerate executor, clean logs"
- label: "2. Health Check"
description: "Verify setup, diagnose issues"
- label: "3. Configuration"
description: "Build systems, skill domains"
- label: "More..."
description: "Show remaining Main Menu options"
multiSelect: false
Page 2 — shown only when the user selects "More..." on Page 1 — the remaining options:
AskUserQuestion:
question: "What would you like to do?"
header: "Main Menu (continued)"
options:
- label: "4. Effort"
description: "Configure per-role model levels (variant routing)"
- label: "5. Quit"
description: "Exit plan-marshall"
multiSelect: false
| User Selection | Action |
|----------------|--------|
| "1. Maintenance" | Load: Read references/menu-maintenance.md → Execute |
| "2. Health Check" | Load: Read references/menu-healthcheck.md → Execute |
| "3. Configuration" | Load: Read references/menu-configuration.md → Execute |
| "More..." | Present Main Menu Page 2 AskUserQuestion |
| "4. Effort" | Load: Read standards/effort-menu.md → Execute |
| "5. Quit" | Output "Good bye!" → STOP |
After any menu option completes, return to Main Menu Page 1 (except Quit).
This skill uses progressive disclosure to minimize context usage:
references/wizard-flow.md (~250 lines)When routing indicates to load a reference:
Read references/{file}.md
Then execute the workflow described in that file. Each reference file is loaded in full when its menu path is chosen — only one reference is active at a time.
| Reference | Purpose | Load When |
|-----------|---------|-----------|
| wizard-flow.md | First-run wizard steps 1-15 (bootstrap 1-4, configuration 5 onwards) | mode=wizard or --wizard flag |
| provider-setup.md | Provider discovery/activation, CI detection, credential setup (extracted from wizard-flow.md) | Linked from wizard-flow.md (provider/CI/credential steps) |
| architecture-setup.md | Extension defaults, module discovery, build commands, Maven profiles, LLM analysis + architecture_refresh tier knobs (extracted from wizard-flow.md) | Linked from wizard-flow.md Step 8 |
| build-map-setup.md | Build-map seed/read workflow — build.map file-to-build contract, write-once seed, menu re-seed operation | Linked from wizard-flow.md Step 8b and menu-configuration.md (Project Structure) |
| skill-domains-setup.md | Skill-domain configuration, profile activation, execute-task/recipe registration (extracted from wizard-flow.md) | Linked from wizard-flow.md Step 9 |
| menu-maintenance.md | Regenerate executor, cleanup | Menu option 1 |
| menu-healthcheck.md | Verify setup, diagnose issues | Menu option 2 |
| menu-configuration.md | Build systems, skill domains, architecture refresh tier knobs | Menu option 3 |
| standards/effort-menu.md | Per-phase effort configuration (Effort submenu) | Menu option 4 |
| menu-recipes.md | Built-in recipes available in the wizard | Linked from menu-configuration.md |
| menu-terminal-title.md | Two-action sub-menu: install render-hook wiring; override active-plan for the current session | Linked from menu-configuration.md (Terminal Title) |
| error-handling.md | Error types and recovery | On error conditions |
The wizard seeds phase-6-finalize.steps in marshal.json from the
authoritative BUILT_IN_FINALIZE_STEPS list defined in
manage-config/scripts/_config_defaults.py. The list intentionally
covers only steps that are sensible defaults for any plan-marshall
consumer (pre-push-quality-gate, commit-push, create-pr, ci-verify,
automated-review, sonar-roundtrip, lessons-capture, branch-cleanup,
record-metrics, archive-plan). pre-push-quality-gate is a built-in
default like the rest; its activation is derived from
build.map — it activates whenever the live footprint
touches a glob registered in the build_map. Those globs are
tree-derived from each extension's classify_globs() vocabulary
(complete-by-construction over the real tree), not author-shipped
static literals.
Steps that are meta-project-only — e.g. running the multi-target
generator and pushing the host plugin cache — are NOT in
BUILT_IN_FINALIZE_STEPS. They live as project-local skills under
.claude/skills/finalize-step-{name}/SKILL.md in the meta-project that
needs them, and that meta-project's marshal.json registers them
explicitly with project:finalize-step-{name} references. Consumer
projects don't see them and don't have them seeded.
Missing-default detection. When the wizard runs against an existing
project, determine_mode.py compares the existing
marshal.json::plan["phase-6-finalize"]["steps"] array against the
current BUILT_IN_FINALIZE_STEPS list. Any built-in step missing from
the project's array is surfaced as missing_default_finalize_steps so
the wizard can prompt the user to add it. This protects existing
projects from quietly missing newly-added consumer-applicable defaults
when their marshal.json predates the additions.
The blocking-finding gate is governed by a fixed, hardcoded actionable-vs-knowledge rule in plan-marshall/scripts/_invariants.py — there is no per-phase configuration partition, no marshal.json key, and no wizard seed step. ACTIONABLE types (build-error, test-failure, lint-issue, sonar-issue, qgate, pr-comment) block when pending at a guarded boundary; KNOWLEDGE types (insight, tip, best-practice, improvement) never block. The wizard does not write any blocking-finding configuration. See plan-marshall:plan-marshall/references/phase-handshake.md § pending_findings_blocking_count resolution for the full rule.
project.working_prefixes holds the canonical closed set of allowed
working-branch prefixes as the transparent, operator-editable source of truth in
marshal.json. It is seeded from DEFAULT_PROJECT['working_prefixes'] (defined
in manage-config/scripts/_config_defaults.py) on init and back-filled into an
existing marshal.json by sync-defaults. The default value is:
| Key | Default |
|-----|---------|
| working_prefixes | ["feature/", "fix/", "chore/"] |
The docs/ prefix is explicitly retired and must not be re-admitted — it is not
CI-triggered, so a docs/-prefixed branch makes its PR structurally unmergeable
(see CLAUDE.md "Branch Naming"). The CI push-trigger allowlist is owned by
.github/workflows/python-verify.yml (not mirrored here); a structural test
(test_branch_prefix_allowlist.py) asserts every working_prefix is covered by
a workflow push trigger.
Missing-default / drift detection. When the wizard runs against an existing
project, determine_mode.py check-working-prefixes compares the live
marshal.json::project["working_prefixes"] list against
DEFAULT_PROJECT['working_prefixes']. It surfaces missing when the key is
entirely absent, or a drift signal when a default entry is missing, so the wizard
can prompt the user to add or update it. This protects projects whose
marshal.json predates the key, since sync-defaults is not auto-run in the
interactive menu flow.
Idempotent and non-clobbering. The detection performs no writes. An
operator's customized list — including a superset that adds prefixes beyond
the defaults — is returned as ok and never flagged or overwritten; only
genuine absence or a missing default entry is surfaced.
Wizard step (runs against an existing project to surface presence/drift):
python3 .plan/execute-script.py plan-marshall:marshall-steward:determine_mode \
check-working-prefixes
Output (TOON) when the list is present and current (or operator-customized):
status ok
When the working_prefixes key is absent:
status missing
detail absent
missing_keys working_prefixes
When the key is present but a default entry has drifted out (e.g. chore/
dropped):
status missing
detail drift
missing_keys working_prefixes
CRITICAL — Restart Claude Code session before dispatching against newly-emitted agents or notations. Claude Code's agent registry is session-pinned at session start: it scans the plugin cache exactly once when the session boots and never re-scans mid-session. Any steward operation that materially alters the agent set — executor regeneration that adds new notations, a
/sync-plugin-cacherun that emits newexecution-context-{level}variants from the dynamic-level executor extension point — produces files the already-running session cannot see. Dispatching against a freshly emitted variant from the same session fails withAgent type 'plan-marshall:execution-context-{level}' not foundeven though the file exists on disk in the cache.Operational guardrail: after running steward operations from the Maintenance menu (Regenerate Executor) or the wizard's executor- generation step, surface a prominent "Restart Claude Code session before next dispatch" warning to the user when the operation regenerated the executor OR changed the agent set. The restart is the only mechanism that refreshes the registry. The same WHY rationale (registry is session-pinned at startup) is documented at the sister surfaces —
/sync-plugin-cache,variant_emitter.py, andext-point-dynamic-level-executor.md— and MUST stay convergent across all four surfaces.
The wizard and the maintenance Configuration submenu both expose two architecture_refresh tier knobs that drive the phase-6-finalize architecture-refresh step. The canonical schema, defaults, and value contract are owned by plan-marshall:manage-run-config (see manage-run-config/standards/run-config-standard.md and the architecture-refresh get-tier-0/get-tier-1/set-tier-0/set-tier-1 subcommands documented in manage-run-config/SKILL.md).
| Knob | Subcommand | Default | Allowed values |
|------|------------|---------|----------------|
| architecture_refresh.tier_0 | manage-run-config architecture-refresh set-tier-0 --value {value} | enabled | enabled, disabled |
| architecture_refresh.tier_1 | manage-run-config architecture-refresh set-tier-1 --value {value} | prompt | prompt, auto, disabled |
Surfaces inside this skill:
| Surface | Reference | Section |
|---------|-----------|---------|
| First-run wizard | references/architecture-setup.md | Architecture Refresh Tier Knobs (reached via wizard-flow.md Step 8) |
| Maintenance menu (returning users) | references/architecture-setup.md | Architecture Refresh Tier Knobs (reached via Configuration → Full Reconfigure, which re-runs the wizard from Step 5 onwards) |
Both surfaces share the same architecture-setup.md tier-knob question set, and both delegate persistence to the manage-run-config architecture-refresh set-tier-* subcommands — this skill never edits run-config.json directly.
The steward exposes the following built-in recipes (registered via provides_recipes() in plan-marshall-plugin/extension.py). Recipes are loaded by phase-3-outline when a plan's status metadata sets plan_source=recipe and recipe_key=<key>.
| Recipe key | Recipe skill | Default change_type | Scope |
|------------|--------------|---------------------|-------|
| refactor-to-profile-standards | plan-marshall:recipe-refactor-to-profile-standards | tech_debt | codebase_wide |
| lesson_cleanup | plan-marshall:recipe-lesson-cleanup | derived from lesson kind (see below) | single_lesson |
lesson_cleanup derived change_type:
| Lesson kind | change_type |
|-------------|-------------|
| bug | bug_fix |
| improvement | enhancement |
| anti-pattern | tech_debt |
The lesson_cleanup recipe is auto-suggested by phase-1-init Step 5c when source == lesson and the lesson body is doc-shaped (no code-touching fences, no code-action verbs as primary subject). See references/menu-recipes.md for the wizard-facing description and marketplace/bundles/plan-marshall/skills/recipe-lesson-cleanup/SKILL.md for the recipe contract.
Note:
shared-doc-check.mdcontent has been inlined intowizard-flow.mdandmenu-maintenance.md. For TOON output format, seeplan-marshall:ref-toon-format.
If an error occurs during execution:
Read references/error-handling.md
Apply the recovery guidance for the specific error type.
The canonical argparse surface for the three entry-point scripts this skill registers: determine_mode.py, bootstrap_plugin.py, and gitignore_setup.py. The plugin-doctor analyzer (_analyze_manage_invocation.py) reads this section as source-of-truth for the manage-invocation-invalid and missing-canonical-block rules. Consuming docs xref this section by name instead of restating the command inline. See pm-plugin-development:plugin-script-architecture cross-skill-integration.md § "Script invocation in documentation".
python3 .plan/execute-script.py plan-marshall:marshall-steward:determine_mode mode [--plan-dir PLAN_DIR]
python3 .plan/execute-script.py plan-marshall:marshall-steward:determine_mode check-docs [--project-root PROJECT_ROOT]
python3 .plan/execute-script.py plan-marshall:marshall-steward:determine_mode fix-docs [--project-root PROJECT_ROOT]
python3 .plan/execute-script.py plan-marshall:marshall-steward:determine_mode check-structure [--plan-dir PLAN_DIR]
python3 .plan/execute-script.py plan-marshall:marshall-steward:determine_mode check-missing-finalize-steps [--plan-dir PLAN_DIR]
python3 .plan/execute-script.py plan-marshall:marshall-steward:bootstrap_plugin get-root [--refresh]
python3 .plan/execute-script.py plan-marshall:marshall-steward:bootstrap_plugin resolve --bundle BUNDLE --path PATH
python3 .plan/execute-script.py plan-marshall:marshall-steward:gitignore_setup [--project-root PROJECT_ROOT] [--dry-run]
development
The single append-only change-ledger — one worktree_sha-stamped substrate for kind=build and kind=change entries — plus the first-class worktree-sha freshness API
development
Authoring standards for ASCII box diagrams in skill and doc source — box-drawing conventions, right-border alignment, and a deterministic check/fix validator over fenced/literal code blocks in .md and .adoc files
testing
Recipe for verifying and fixing alignment of ASCII box diagrams across .md skill source and .adoc documentation, one deliverable per offending file
development
Pure platform-agnostic terminal-title composition consumed by platform-runtime via PYTHONPATH