AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified Apache-2.0 Self-run

Axon4to5 Migrate Code

skill-axoniq-agent-skills-axon4to5-migrate-code · by AxonIQ

>-

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-axoniq-agent-skills-axon4to5-migrate-code

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-axoniq-agent-skills-axon4to5-migrate-code)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
24d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Axon4to5 Migrate Code? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

axon4to5-migrate-code

Goal

> Fully (or as most as possible) compiling, green-test codebase on AF5, same architecture as AF4. > No DCB. No new patterns. Legacy event storage preserved. > > Scope: code and configuration only. This skill migrates source code and wiring. It does NOT > migrate stored data — the event store contents (stored events) and tracking tokens are left untouched. > Migrating to AF5 with the legacy event-storage layout keeps those stores compatible as-is; moving data > to a new storage layout (e.g. DCB) is out of scope. > The migration preserves the project's existing configuration style: a Spring Boot > project stays on Spring auto-config (recipes use @Component / @Bean > idioms); a plain framework-configuration project stays on the direct > Configurer API (recipes use EventSourcingConfigurer / > MessagingConfigurer / CommandHandlingModule / EventSourcedEntityModule).

Available recipes (auto-listed)

Run bash scripts/list-recipes.sh from the skill root directory. Output format:

- file: references/recipes//RECIPE.md
  id: 
  title: 
  description: 
  applicable: |
    

Inputs

  • framework (required): which Axon flavor to migrate. Currently supported values: axon, axoniq. Any other

value → STOP.

  • configuration (required): how the application wires Axon. Currently supported values: native, spring. Any

other value → STOP.

  • mode (required): what gets migrated in one invocation.
  • single — one element (a class, e.g. an Aggregate). Requires source.
  • project — the whole application (default: current working directory). source ignored.
  • execution (optional, default inline): how the orchestrator runs its steps. Only meaningful for mode=project

for mode=single it has no observable effect.

  • inline — main session does discovery + recipe runs sequentially. No Agent tool use.
  • subagent — orchestrator MAY dispatch via the Agent tool: discovery → Explore subagent, recipe sub-flow per

item → general-purpose subagent (parallel batches). Useful for project mode on large codebases.

  • source (required for mode=single): hint identifying the thing to migrate (class name, file path, FQN).
  • skip-openrewrite (optional, default false): when true, the orchestrator SKIPS Pre-step 2 (the OpenRewrite bulk pass) and goes straight to the mode-specific producer. Use this when (a) OpenRewrite Phase 1 has already been run separately on the tree, (b) the caller is exercising a recipe in isolation, or (c) the project is not built with Maven/Gradle so the OpenRewrite plugin is unreachable. Values: true / false. Any other value → STOP. The downstream recipe must still tolerate both AF4-shaped and partially-migrated sources (see each recipe's # Applicable predicates).
  • max-subagents (optional, default 0): max parallel general-purpose subagents for item processing in the drain loop. mode=project only — ignored for mode=single. 0 = inline (no subagents, sequential). N > 0 = dispatch up to N items simultaneously as subagents; BLOCKER_RESOLUTION always runs in main session regardless of this value. Any non-integer or value ` so the log stays auditable.

| Decision point | Auto action | |---|---| | Ambiguous recipe match (mode=single) | Pick first candidate by applicable score. | | Blocker | Auto-select the Option the recipe marked (Recommended); if none is marked, skip. A recommended migration path (e.g. saga stateful-rewrite) re-enters the recipe with that option id; skip/revert resolve in-place. See BLOCKER_RESOLUTION.md § Auto mode. | | Resume + selection-args mismatch | Args identical → auto-resume. Args differ → auto-start-over. | | Working tree mismatch on resume | Proceed; record ⚠️ auto: tree mismatch ignored in progress.md. | | OpenRewrite step completes | Immediately continue to mode-specific producer. Do NOT pause or end session. |

Durability

Load order — see § Recipe sub-flow. FLOW.md first, then DURABILITY.md (second). Defines state files under .axon4to5-migration/, hooks across pre-steps + queue + recipe results + caller decisions, and commit protocol. Reads progress.md on entry to decide resume vs fresh.

Pre-steps (common to every mode)

These run before any mode-specific logic — independent of whether mode=single, project, or anything added later.

  1. Parse — read framework, configuration, mode, execution, skip-openrewrite, max-subagents, auto from $ARGUMENTS.
  • If framework is missing or ∉ {axon, axoniq} → STOP and report unsupported framework.
  • If configuration is missing or ∉ {native, spring} → STOP and report unsupported configuration.
  • If mode is missing or ∉ {single, project} → STOP and report unsupported mode.
  • execution defaults to inline if missing. If present and ∉ {inline, subagent} → STOP and report unsupported execution.
  • skip-openrewrite defaults to false if missing. If present and ∉ {true, false} → STOP and report unsupported value.
  • max-subagents defaults to 0 if missing. If present and not a non-negative integer → STOP.
  • auto defaults to false if missing. If present and ∉ {true, false} → STOP.
  1. OpenRewriteskipped entirely when skip-openrewrite=true. Otherwise, internally invoke

axon4to5-openrewrite via the Skill tool, passing --framework $framework --commit false. Do NOT pass --commit true or omit --commit; DURABILITY's on:openrewrite-done hook owns the single combined commit. This is a step of this orchestrator, not a separate command. Idempotent — safe even on a partially-migrated tree. If it fails → STOP and report the failure (no gap-filling on a broken bulk pass). When skipped, surface that fact in the eventual report (Notes or Learnings) so the caller knows the queue ran against unprocessed AF4 (or already-partially-migrated) sources and the recipes did all the work themselves. auto=true: after this step returns (success or skip), immediately continue to the mode-specific producer — do NOT end the session or pause.

Only after pre-steps complete does the mode-specific producer below run.

Modes

single

Migrate ONE element (one aggregate, one event processor, etc.) using exactly one recipe from the list above.

Steps (after the common pre-steps):

  1. Match — map user's request + source to ONE recipe in the auto-listed set. Primary signal: the catalog's

applicable block (surface predicates against $SOURCE — annotations / type markers). Fallback signal: id + title + description. If ambiguous → ask user via AskUserQuestion to pick (show title to the user; dispatch by id). If no applicable block matches and description is also unclear → STOP and report.

  1. ExecuteRead the chosen recipe file under [references/recipes/](references/recipes/) (/RECIPE.md)

and execute it per the Recipe sub-flow ([FLOW.md](references/recipes/FLOW.md), already loaded). Recipe-local auxiliary files (examples, fixtures, supporting docs) live alongside it in the same / directory.

  1. Verify — behavior is preserved (no DCB, keep AggregateBasedEventStorageEngine, etc.).
  2. Report — render the report (see Queue flow § Render report).

MUST NOT:

  • Run without all required parameters resolved to a supported value.
  • Run multiple recipes in one invocation.
  • Migrate more than the single source named by the user.
  • Migrate anything outside the supported (framework, configuration) matrix — the rest of the codebase stays untouched.
  • Introduce DCB or swap event storage engine.

project

Migrate everything in the working directory that any recipe in the catalog declares applicable. source is ignored.

Steps (after the common pre-steps):

Recipe loop — iterate recipes in discovery order. For each recipe:

  1. Discover — evaluate the recipe's applicable predicates across the codebase to produce candidate sources.
  • execution=inline → orchestrator scans inline using Grep / Glob / Read.
  • execution=subagent → dispatch one Explore subagent for this recipe. Read-only — no edits.
  • Scan .java AND .kt, across all source roots. JVM projects are mixed and Kotlin files often sit under src/main/java/ (and vice-versa) — never filter candidates by extension or source directory. Key on the recipe's Axon annotations, not on path. See DEFAULT.md § Source file conventions (the Explore subagent must be told this too).
  1. Enqueue — add (recipe, source) candidates. Deduplication is recipe's concern.
  2. Drain — exhaust all pending items for this recipe before advancing to the next:
  • max-subagents=0 (default) → inline, main session, sequentially.
  • max-subagents=N → main session acts as coordinator. Dispatches up to N pending items simultaneously as general-purpose subagents (single Agent message per batch). Each subagent executes ONE recipe sub-flow and returns a result block (RESULT: line + Notes + a Learnings field — complete authored entries, or an explicit none — ). The subagent authors the learning prose (it witnessed the run) but MUST NOT write learnings.md itself — the coordinator is the single safe writer under parallelism and stamps the date + commit sha, relaying each entry verbatim (see DURABILITY § Proactive Learnings).
  • ✅ Success / ⏭ Rejected / ❌ Failure → main records result, immediately dispatches next pending item. No pause.
  • 🚧 Blocker → BLOCKER_RESOLUTION in main session: AskUserQuestion if auto=false; auto-skip if auto=true. Resolved → re-dispatch same item to a new subagent. Not resolved → mark blocked, dispatch next pending item.
  • Main session never pauses unless waiting for user input on a blocker (auto=false).
  • Fallback — if a subagent cannot be spawned, process inline and continue.
  1. Mark recipe doneon:recipe-done hook records status in progress.md Recipe status table.

After all recipes drained → Debugging loopFinalizeReport.

Context hygiene — after every 5 items drained, emit this tip once (then reset counter):

> 💡 Context is growing. Run /clear and re-invoke the skill — it resumes automatically from .axon4to5-migration/progress.md, no work is lost.

MUST NOT:

  • Spawn a subagent under execution=inline.
  • Pass anything beyond (recipe path, source, framework, configuration) to a recipe subagent — context bloat defeats

the parallelism win.

  • Cross repository boundaries during discovery.
  • Halt the queue on a single Failure — record and drain the rest.
  • Introduce DCB or swap event storage engine.

Queue flow

$SOURCE is referenced throughout the recipe sub-flow as the argument passed to the skill from source.

> [[Execute recipe sub-flow]] = [references/recipes/FLOW.md](references/recipes/FLOW.md), loaded at skill start. [[Resolve blocker]] = [references/recipes/BLOCKER_RESOLUTION.md](references/recipes/BLOCKER_RESOLUTION.md), budget = 1 attempt per item; on exhaustion item is marked blocked and drain continues.

Single mode flow

flowchart TD
    A[Skill invoked] --> PARSE["Parseframework, configuration, source"]
    PARSE --> ORW[["OpenRewrite(internal Skill, idempotent)"]]
    ORW -- fail --> XORW[STOP: bulk-rewrite failed]
    ORW -- ok --> B["list-recipes (catalog)"]
    B --> MATCH{"Matchrequest + source → recipe"}
    MATCH -- ambiguous --> ASK["AskUserQuestion(show titles, dispatch by id)"]
    ASK --> EXEC
    MATCH -- "no match" --> XNOMATCH[STOP: no applicable recipe]
    MATCH -- matched --> EXEC[["Execute recipe sub-flow(FLOW.md)"]]
    EXEC --> R{RESULT?}
    R -- "Blocker (first attempt)" --> BR[["Resolve blocker(BLOCKER_RESOLUTION.md)"]]
    BR --> BRQ{"Resolved?budget = 1"}
    BRQ -- yes --> EXEC
    BRQ -- "no / exhausted" --> BLK["mark blocked(🚧 caller must resolve)"]
    R -- "Blocker (already retried)" --> BLK
    R -- "Success / Rejected / Failure" --> VER["Verifybehavior preservedsame architecture as AF4"]
    VER --> RPT["Report & END"]
    BLK --> RPT

Project mode flow

flowchart TD
    A[Skill invoked] --> PARSE["Parseframework, configuration, execution"]
    PARSE --> ORW[["OpenRewrite(internal Skill, idempotent)"]]
    ORW -- fail --> XORW[STOP: bulk-rewrite failed]
    ORW -- ok --> B["list-recipes (catalog)"]
    B --> RL{"Next recipein order?"}
    RL -- "yes: <recipe>" --> DISC["Discoverexecution=inline: Grep/Globexecution=subagent: 1 Explore→ Enqueue items"]
    DISC --> Q[(Recipe queue)]
    Q --> L{"Drainpending?"}
    L -- yes --> INP["pick next → in-progress"]
    INP --> W[["Execute recipe sub-flowexecution=inline: main sessionexecution=subagent: general-purpose (parallel batch)"]]
    W --> R{RESULT?}
    R -- "Blocker (first attempt)" --> BR[["Resolve blocker(BLOCKER_RESOLUTION.md)"]]
    BR --> BRQ{"Resolved?budget = 1"}
    BRQ -- yes --> W
    BRQ -- "no / exhausted" --> BLK["mark blocked(🚧 caller must resolve)"]
    R -- "Blocker (already retried)" --> BLK
    R -- "Success / Rejected / Failure" --> VER["Verifybehavior preservedsame architecture as AF4"]
    VER --> DONE["mark done in queue"]
    DONE --> Q
    BLK --> Q
    L -- "no (recipe drained)" --> RDONE["on:recipe-doneupdate Recipe status table"]
    RDONE --> RL
    RL -- "no more recipes" --> DBG_COMP

    subgraph DEBUG ["🔍 Debugging — all recipes applied, build still red"]
        direction TB
        DBG_COMP["Full compilemvn compile / gradle classes"]
        DBG_REDISC["Re-discoverre-scan applicable predicatesany recipe match remaining errors?"]
        DBG_COMP -- "⚠️ errors" --> DBG_REDISC
    end

    DBG_COMP -- "✅ green" --> FIN["Finalizeremove isolated-* scaffoldingfinal compile · count by recipe"]
    DBG_REDISC -- "new candidates" --> REENQ["re-enqueue as pending"]
    REENQ --> Q
    DBG_REDISC -- "nothing newrecipes exhausted" --> FIN
    FIN --> RPT["Report & END"]

Discovery order — Discover scans recipes in this fixed sequence. Aggregates first: they define the events and commands consumed by downstream types.

| # | Recipe (id per frontmatter order:) | |---|----------------------------------------| | 1 | aggregate | | 2 | event-processor | | 3 | command-gateway | | 4 | query-gateway | | 5 | query-handler | | 6 | interceptors | | 7 | saga | | 8 | event-store |

Debugging loop (project mode only)

Entered when drain empties but build is still red. All known recipes have been applied — this phase asks: "is there still something a recipe can fix?"

Before the first full compile: Scan for application classes in subdirectories that OpenRewrite does NOT process by default — e.g., a microservices/ tree or separately deployable modules at the same repo root. These classes often use the same AF4 patterns (AF4 ConfigurationEnhancer, SagaEntry, DeadlineManager) as the main modules but are missed by the recipe drain because discovery only scanned the main source sets. Add any found classes to the queue and drain them before running the full compile.

  1. Full compilemvn compile / gradle classes (Java + Kotlin). Green → exit loop → Finalize.
  2. Errors remain:
  • Re-discover — re-scan every recipe's applicable predicates against current codebase. Sources mutated during drain may now match recipes that rejected earlier.
  • New (recipe, source) pairs not already terminal → re-enqueue as pending, resume drain (loop repeats).
  • Nothing new → all applicable recipes exhausted → Finalize.

Finalize (project mode only)

  1. Cleanup scaffoldingGrep all pom.xml / build.gradle(.kts) for isolated-* Maven profiles and isolated* Gradle source-sets added by axon4to5-isolatedtest. Edit each build file to remove found blocks. Commit: `chore

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.