Skip to content

srcmorph: extract core+CLI, rename plugin, bump to 1.1.0, fix reactor CI - #144

Merged
bernardladenthin merged 9 commits into
mainfrom
claude/llm-wiki-architecture-plan-0nvriu
Jul 15, 2026
Merged

srcmorph: extract core+CLI, rename plugin, bump to 1.1.0, fix reactor CI#144
bernardladenthin merged 9 commits into
mainfrom
claude/llm-wiki-architecture-plan-0nvriu

Conversation

@bernardladenthin

Copy link
Copy Markdown
Owner

Summary

  • Completes the srcmorph migration on top of the previously-merged reactor-ify step (Migrate indexer logging from Maven Log to SLF4J #143): extracts the framework-free srcmorph core library (config/document/engine/indexer/prompt/provider/support) and the standalone srcmorph-cli (JSON/YAML-driven CLI with a fat jar), renames the Maven plugin to net.ladenthin:srcmorph-maven-plugin (goal prefix srcmorph, srcmorph.* properties), and adds a minimal relocation-stub module for the retired net.ladenthin:llamacpp-ai-index-maven-plugin coordinates (<distributionManagement><relocation> only, pinned independently at 1.0.4).
  • Bumps the reactor (srcmorph-parent, srcmorph, srcmorph-cli, srcmorph-maven-plugin) to release version 1.1.0.
  • Fixes a reactor CI bug: the code-style job's spotless:check/spotbugs:check steps used bare plugin prefixes, which Maven resolves against the invoking (pom-packaging root) project — neither plugin is declared there, only in each child's own pluginManagement/build, so both steps failed with "No plugin found for prefix" as soon as the previous merge turned this into a multi-module reactor. Switched both to fully-qualified groupId:artifactId:goal invocations scoped to the three modules that actually declare the plugins.

Test plan

  • mvn clean verify from repo root — BUILD SUCCESS across all 4 reactor projects
  • Regenerated srcmorph-maven-plugin's plugin.xml — goal prefix srcmorph, every parameter's property reads srcmorph.*
  • Ran the renamed srcmorph-selftest profile with the mock provider — produced real .ai.md output through the new srcmorph:generate goal
  • Release dry-run (mvn -P release verify -DskipTests -Dgpg.skip=true) — all modules produce expected jars; relocation stub installs as a standalone .pom with the intended relocation content
  • Reproduced the exact failing CI command lines locally (mvn -pl srcmorph,srcmorph-cli,srcmorph-maven-plugin com.diffplug.spotless:spotless-maven-plugin:check and the spotbugs equivalent) — both pass
  • publish.yml re-validated as parseable YAML after edits
  • CI green on this branch (pending — this PR triggers it)
  • Docs updated: root README.md/CLAUDE.md, per-module README.mds, TODO.md, CHANGELOG.md

Related issues / PRs

Follow-up to #143 (which merged only the initial single-module reactor-ify step).

Checklist

  • I have read CONTRIBUTING.md and CODE_OF_CONDUCT.md
  • My commits follow Conventional Commits
  • No security-sensitive changes

Generated by Claude Code

claude added 9 commits July 15, 2026 20:48
Moves the six non-mojo packages (config, document, indexer, prompt,
provider, support) out of llamacpp-ai-index-maven-plugin into a new
sibling reactor module net.ladenthin:srcmorph — a framework-free
library with no Maven plugin API dependency. The plugin module now
depends on srcmorph and keeps only the Mojo entry points.

- New srcmorph/pom.xml (jar packaging), module-info.java (module
  net.ladenthin.srcmorph), and spotbugs-exclude.xml carrying the
  suppressions scoped to the moved classes (plus two new
  OPM_OVERLY_PERMISSIVE_METHOD suppressions on ProjectIndexer's
  constructor and SourceFileIndexer.classify, which only surfaced
  once their sole caller moved to a different SpotBugs analysis
  unit). net.ladenthin:llama and the gpu-cuda/gpu-vulkan classifier
  profiles moved to srcmorph, since only the provider package touches
  the JNI binding.
- New CoreArchitectureTest (srcmorph) carries the internal layered
  architecture (Mojo layer removed), noPackageCycles,
  loggersArePrivateStaticFinal, jniConfinedToProvider, and a new
  coreIsMavenFree rule. PluginArchitectureTest is slimmed to
  mojo-relevant rules only.
- PIT's 100%-mutation-parity targetClasses list (all config/document/
  indexer/prompt/provider/support classes) moved to srcmorph's pom;
  the plugin pom drops its now-empty PIT execution with a comment.
- The plugin's ai-index-selftest profile keeps invoking this
  plugin's own mojo goals (unchanged location) but its config/
  provider self-index subtrees now point across the reactor into
  ../srcmorph.
- REUSE.toml's GGUF resource annotation path updated to
  srcmorph/src/test/resources/.

Verified: reactor-wide `mvn clean verify` is green (spotless,
spotbugs 0 findings, 428 tests across both modules), and
`mvn test-compile org.pitest:pitest-maven:mutationCoverage -pl
srcmorph -am` reproduces the pre-extraction 100% mutation-kill
parity (565/565 mutations killed across the 38 gated classes). The
generated plugin.xml's 5 goals and every parameter name/required/
editable flag are unchanged from the pre-extraction baseline; only
the @see javadoc FQNs now point at net.ladenthin.srcmorph.*.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DByQrKSWzzpBt4iSRcmRP
Moves the orchestration bodies of GenerateMojo/AggregatePackagesMojo/
AggregateProjectMojo/CalibrateMojo into new framework-free engine classes
in the srcmorph core module (net.ladenthin.srcmorph.engine): GenerateEngine,
AggregatePackagesEngine, AggregateProjectEngine, CalibrateEngine, plus the
new checked SrcMorphException, the GenerateResult/CalibrationReport value
types, and a package-private EngineSupport for the logic shared by two or
more engines (subtree resolution, prompt/model-support construction,
LlamaCppJniConfig resolution).

Adds the shared root config.SrcMorphConfiguration JavaBean (field names
mirror today's @parameter names) and provider.LlamaCppJniConfigFactory (the
pure extraction of the old 26-arg buildLlamaCppJniConfig mapping). The five
mojos shrink to: skip check -> buildConfiguration() -> new XxxEngine(config)
.execute() -> wrap SrcMorphException/IOException into MojoExecutionException,
with the exact same log/exception-message shapes as before.

CoreArchitectureTest gains the new Engine layer on top of Indexer, plus the
Provider->Config and Config->Prompt edges the extraction introduced.
srcmorph's PIT targetClasses gains SrcMorphConfiguration,
LlamaCppJniConfigFactory, EngineSupport, GenerateResult, and
CalibrationReport(+ModelMeasurement) at the existing 100% mutation
threshold; the four orchestration engines are deliberately left out,
mirroring the plugin module's own mojo-PIT-exemption rationale.

Verified: full reactor `mvn verify` green, srcmorph PIT 100% (618/618
mutations killed across 43 target classes), plugin.xml parameter parity
confirmed for all 5 goals, and a real Maven CLI run of generate/
aggregate-packages/aggregate-project/calibrate against the mock provider
produced the expected .ai.md tree end-to-end.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DByQrKSWzzpBt4iSRcmRP
New net.ladenthin:srcmorph-cli module wrapping the core engines behind a
BitcoinAddressFinder-style cli.Main: single positional config-file argument,
.json/.js via Jackson ObjectMapper, .yaml/.yml via YAMLMapper (both strict,
FAIL_ON_UNKNOWN_PROPERTIES enabled), echo-back of the parsed configuration,
and a Java-8 switch over CCommand (Plan/GenerateFileIndex/AggregatePackages/
AggregateProject/All/Calibrate) with no System.exit anywhere. Plan forces
planOnly=true on a deep copy of SrcMorphConfiguration so it never mutates the
caller's object nor accidentally loads a model. Fat jar (jar-with-dependencies)
binds unconditionally to the package phase since it is this module's actual
deliverable artifact.

Adds MainTest/ConfigBindingTest/CliEndToEndTest/CliArchitectureTest plus a
private test-fixtures pair (minimal-generate.json/.yaml). Root pom.xml gains
the new module and jackson-databind/jackson-dataformat-yaml dependency
management entries.

Verified end-to-end via java -jar against both JSON and YAML configs (mock
provider): file/package/project .ai.md trees written correctly for both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DByQrKSWzzpBt4iSRcmRP
The indexer and engine packages log via SLF4J at runtime, but the module
descriptor never declared `requires org.slf4j` — a real gap masked by
Maven always loading these jars classpath-only. Adding the requires
clause is enough to flip Surefire's module-path auto-detection on for
this module (and transitively for the plugin module, which requires
net.ladenthin.srcmorph), which then fails patching test-only
dependencies (logback-classic, archunit-junit5) into the named module.
Both modules now pin useModulePath=false for tests, matching the same
setting already added to srcmorph-cli for the identical reason.
…nchanged)

Adds examples/ (config_Plan/GenerateFileIndex/All/Calibrate.json + a YAML twin, paired
run_*.sh/.bat launchers, logbackConfiguration.xml) covering every srcmorph-cli command with
the mock provider, plus a new ExamplesConfigBindingTest that sweeps every shipped fixture
through the CLI's strict Jackson mappers.

Rewrites the root README.md/CLAUDE.md for the 3-module reactor (srcmorph / srcmorph-cli /
llamacpp-ai-index-maven-plugin), adds per-module READMEs (srcmorph: API tour of
SrcMorphConfiguration + the four engines; srcmorph-cli: config-file reference + command
table; llamacpp-ai-index-maven-plugin: relocated plugin doc, now noting its srcmorph
dependency), and updates TODO.md/CHANGELOG.md for the current migration status. The Maven
plugin's own coordinates, package, goal prefix, and aiIndex.* properties are explicitly
documented as unchanged in this release -- the srcmorph-maven-plugin rename remains a
deferred, separate step (tracked in TODO.md).

Extends REUSE.toml for the new JSON/YAML example fixtures (and a pre-existing gap in the
CLI's private test fixtures); reuse lint is fully compliant.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DByQrKSWzzpBt4iSRcmRP
…adiness

publish.yml assumed the pre-reactor single-module layout in several places;
adapt it to the srcmorph / srcmorph-cli / llamacpp-ai-index-maven-plugin
reactor:

- build job uploads jars from all three modules (incl. the CLI's
  jar-with-dependencies fat jar), not just the plugin's.
- crash-dump upload globs are repo-wide (**/hs_err_pid*.log etc.) since a
  forked surefire JVM can crash in any module's own target/ tree.
- PIT step scoped to `-pl srcmorph -am` (the only module with a
  pitest-maven execution); report glob/upload path moved to
  srcmorph/target/pit-reports/.
- vmlens job scoped to `-pl llamacpp-ai-index-maven-plugin -am`, where
  VmlensInterleavingSmokeTest and the vmlens profile actually live (not
  relocated during the core extraction). Also adds
  -Dsurefire.failIfNoSpecifiedTests=false: -am pulls srcmorph into the
  build, and the pre-existing -DfailIfNoTests=false does not suppress the
  "-Dtest pattern matched nothing" failure that then occurs there
  (verified locally — this was a latent bug the reactor split introduced).
- jdeps step prints a package graph per module.
- Coveralls/Codecov point at srcmorph's jacoco report (the module with the
  bulk of the test suite and the only PIT gate), matching the
  single-primary-module precedent already used by the sibling
  java-llama.cpp reactor; documented as a gap for srcmorph-cli/plugin
  coverage in TODO.md.
- signed-artifact collection steps (snapshot + release) now cp jars/.asc
  from all three module target/ directories.

Verified locally (no deploy/tag/push):
- `mvn -q clean verify` — BUILD SUCCESS.
- `mvn -P release verify -DskipTests -Dgpg.skip=true` — BUILD SUCCESS for
  all 4 reactor projects; every module produced its expected jar/sources/
  javadoc (+ CLI fat jar, + plugin's plugin.xml), no .asc files (gpg
  skipped, as intended).
- publish.yml YAML re-validated after edits.

TODO.md/CHANGELOG.md updated to reflect the CI adaptation; the actual
1.1.0 tag + `mvn -P release deploy` is left for the user to trigger.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DByQrKSWzzpBt4iSRcmRP
…n + relocation stub

Renames the plugin module net.ladenthin:llamacpp-ai-index-maven-plugin ->
net.ladenthin:srcmorph-maven-plugin: goal prefix ai-index -> srcmorph, package
net.ladenthin.maven.llamacpp.aiindex(.mojo) -> net.ladenthin.maven.srcmorph(.mojo), and every
@parameter property aiIndex.* -> srcmorph.* across all 5 mojos. The reactor's own <version>
stays 1.1.0-SNAPSHOT (unchanged, per explicit instruction) and the new plugin coordinates
inherit it as usual.

Adds a new, independent 4th reactor module at the vacated llamacpp-ai-index-maven-plugin/ path:
a minimal relocation-stub POM (no <parent>, no dependencies, no source) pinned at
net.ladenthin:llamacpp-ai-index-maven-plugin:1.0.4 with a <distributionManagement><relocation>
pointing at net.ladenthin:srcmorph-maven-plugin:1.1.0, so existing consumers of the old
coordinates are transparently redirected once both are published. Documents, in the stub's own
pom.xml, in the root pom.xml module comment, in CLAUDE.md, and in TODO.md, that a reactor-wide
`mvn versions:set` must exclude this module (-Dexcludes=net.ladenthin:llamacpp-ai-index-maven-plugin)
so its frozen 1.0.4 is never accidentally bumped.

Updates CI (.github/workflows/publish.yml), the srcmorph-selftest profile (renamed from
ai-index-selftest), spotbugs-exclude.xml, module-info.java, and every cross-module doc
(README.md, CLAUDE.md, CHANGELOG.md, TODO.md, CONTRIBUTING.md, TEST_WRITING_GUIDE.md,
CODE_WRITING_GUIDE.md, REUSE.toml, .gitignore, srcmorph/srcmorph-cli READMEs and Javadoc) to
match the new coordinates/package/properties, while leaving historical docs/ benchmark write-ups
and the relocation stub's own old-coordinate literals untouched.

Verified: reactor-wide `mvn clean verify` and `-P release verify -DskipTests -Dgpg.skip=true`
both green (5 projects incl. the trivial pom-only stub); regenerated plugin.xml confirms
goalPrefix=srcmorph and every parameter's property reads srcmorph.*; the renamed
srcmorph-selftest profile run with the mock provider produced real .ai.md output via the new
srcmorph:generate goal; the relocation stub installs standalone with its relocation content
intact; publish.yml re-validated as parseable YAML.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016DByQrKSWzzpBt4iSRcmRP
Flips <version> in the parent pom and every child that inherits it
(srcmorph, srcmorph-cli, srcmorph-maven-plugin) via
`mvn versions:set -DnewVersion=1.1.0 -Dexcludes=net.ladenthin:llamacpp-ai-index-maven-plugin`,
leaving the relocation stub pinned at its own independent 1.0.4. Also
corrects now-stale 1.1.0-SNAPSHOT mentions in README.md, CLAUDE.md, and
the example launcher scripts' illustrative jar-name comments.

publish-release only fires on a v* tag via manual workflow_dispatch, but
the poms must already carry the release version before that tag is cut.
…eactor

spotless-maven-plugin and spotbugs-maven-plugin are declared only in each
child module's own pluginManagement/build, never in the pom-packaging
reactor root. Maven resolves a short plugin prefix (spotless:check,
spotbugs:check) against the invoking project, so from root neither
prefix has anywhere to resolve from and CI failed with "No plugin found
for prefix" before reaching any child module.

Switch both invocations to fully-qualified groupId:artifactId:goal
(bypasses prefix resolution; plugin version still resolves correctly via
each module's inherited pluginManagement pin), scoped via -pl to the
three modules that actually declare the plugin. Verified locally with
the exact CI command lines.
* pastes {@link CalibrationReport#renderXml()} onto the matching {@code <aiDefinition>} so the plan's time
* estimate reflects <em>this</em> machine instead of the built-in reference-CPU coefficients.</p>
*/
@ToString
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants