mustflow 2.108.3 → 2.112.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,499 @@
1
+ ---
2
+ mustflow_doc: skill.java-code-change
3
+ locale: en
4
+ canonical: true
5
+ revision: 3
6
+ lifecycle: mustflow-owned
7
+ authority: procedure
8
+ name: java-code-change
9
+ description: Apply this skill when Java source, Spring Boot or JPA transaction code, Maven or Gradle metadata, JVM toolchains, bytecode targets, binary compatibility surfaces, modules, nullability, Optional, records, sealed classes, reflection, serialization, final-field mutation, virtual threads, executors, ThreadLocal or ScopedValue context, structured concurrency, dependency resolution, multi-module boundaries, HTTP clients, applets or legacy desktop APIs, GC choice, allocation pressure, JVM flags, JFR, JMH, container memory or CPU behavior, tests, benchmarks, public APIs, or Java/JDK version-gated features are created or changed.
10
+ metadata:
11
+ mustflow_schema: "1"
12
+ mustflow_kind: procedure
13
+ pack_id: mustflow.core
14
+ skill_id: mustflow.core.java-code-change
15
+ command_intents:
16
+ - changes_status
17
+ - changes_diff_summary
18
+ - lint
19
+ - build
20
+ - test_related
21
+ - test
22
+ - docs_validate_fast
23
+ - mustflow_check
24
+ ---
25
+
26
+ # Java Code Change
27
+
28
+ <!-- mustflow-section: purpose -->
29
+ ## Purpose
30
+
31
+ Preserve Java API, JVM runtime, concurrency, reflection, serialization, module, build-tool,
32
+ container, observability, GC, and performance boundaries while making a focused change.
33
+
34
+ Java changes fail when the patch treats the JDK as only language syntax. The real contract includes
35
+ the JDK track, bytecode target, framework reflection behavior, class loading, native memory, thread
36
+ lifecycle, GC pause and throughput tradeoffs, and evidence from JFR, GC logs, or JMH.
37
+
38
+ Modern-looking Java can still lie when `null`, `Optional`, records, sealed hierarchies, Maven, or
39
+ Gradle hide domain states and module boundaries instead of making them explicit contracts.
40
+
41
+ Spring and open-source Java changes also fail when a clean patch betrays already deployed users:
42
+ transaction proxies, existing database flows, already compiled consumers, service provider loading,
43
+ test discovery, and serialized payloads are compatibility contracts, not implementation details.
44
+
45
+ <!-- mustflow-section: use-when -->
46
+ ## Use When
47
+
48
+ - `.java`, `.kt` Java interop surfaces, `pom.xml`, `build.gradle`, `build.gradle.kts`,
49
+ `gradle.properties`, Maven or Gradle wrapper files, toolchains, module descriptors, public Java
50
+ APIs, tests, benchmarks, generated code, serialization shapes, reflection, bytecode targets,
51
+ annotation processors, JVM flags, or deployment runtime metadata change.
52
+ - The task touches virtual threads, thread pools, `ThreadLocal`, `ScopedValue`, structured
53
+ concurrency, cancellation, blocking I/O, CPU-bound work, locks, request context propagation,
54
+ servlet or HTTP client behavior, nullability, `Optional`, final fields, reflection, records,
55
+ sealed classes, modules, applets or legacy Swing APIs, native images, AOT caches, GC, JFR, JMH,
56
+ container memory, CPU limits, or startup and warmup behavior.
57
+ - The task touches Spring `@Transactional`, JPA entity or repository behavior, Spring Security
58
+ matchers, Actuator exposure, OSIV, request binding, async execution, transactional events, bulk
59
+ updates, locking, pagination, exports, or mass-assignment-sensitive request models.
60
+ - The task changes public or protected Java members, constants, interfaces, generic bounds, service
61
+ providers, SPI files, module descriptors, test framework baselines, Surefire or Failsafe discovery
62
+ patterns, binary compatibility checks, serialized classes, or consumer-facing library artifacts.
63
+ - The task changes Maven or Gradle dependency declarations, `api` versus `implementation`, Maven
64
+ scopes, parent or aggregator POMs, BOM or dependency management, version catalogs, convention
65
+ plugins, exclusions, dynamic versions, publishing metadata, or multi-module boundaries.
66
+ - Code or docs use Java-version-gated features such as module import declarations, compact source
67
+ files, instance main methods, flexible constructor bodies, `ScopedValue`, structured concurrency,
68
+ primitive pattern matching, final-field reflection restrictions, applet API removal, HTTP/3 in
69
+ `java.net.http.HttpClient`, AOT cache or method profiling, Compact Object Headers, Generational
70
+ Shenandoah, JFR method timing, KDF APIs, PEM APIs, Vector API, or other preview/incubator APIs.
71
+
72
+ <!-- mustflow-section: do-not-use-when -->
73
+ ## Do Not Use When
74
+
75
+ - Java or JVM files are read-only context and no Java, build, test, runtime, or documentation surface
76
+ changes.
77
+ - A generated Java file should be regenerated by a declared command rather than edited.
78
+ - The task only compares runtime targets without changing Java surfaces; use
79
+ `runtime-target-selection` first.
80
+
81
+ <!-- mustflow-section: required-inputs -->
82
+ ## Required Inputs
83
+
84
+ - Maven or Gradle metadata, wrapper versions, toolchain declarations, source and target release,
85
+ annotation processors, generated-code markers, test configuration, benchmark configuration, and
86
+ CI or container runtime hints.
87
+ - The minimum supported Java version, intended JDK vendor, current GA versus LTS policy, bytecode
88
+ compatibility target, repository runtime matrix, and whether preview or incubator APIs are allowed.
89
+ - Relevant modules, packages, public exports, serialized forms, reflection entry points, framework
90
+ adapters, generated bindings, tests, benchmarks, and docs examples.
91
+ - Spring context when present: proxy mode, transaction owner, propagation, rollback rules, async
92
+ boundaries, event listener phase, JPA persistence context, OSIV policy, entity exposure, security
93
+ filter chains, CORS, CSRF, Actuator, and request DTO mapping.
94
+ - Public-library compatibility context: supported source and runtime floor, old consumer binaries,
95
+ previous released jar, japicmp or Revapi availability, ServiceLoader or SPI discovery, test
96
+ discovery pattern, and serialized payload compatibility expectations.
97
+ - Domain meanings for absent values, such as not loaded, not found, forbidden, deleted, lookup
98
+ failed, backend unavailable, defaulted, redacted, or intentionally empty.
99
+ - Dependency graph and module-boundary evidence: Maven parent versus aggregator role, Gradle
100
+ project boundaries, public dependency surface, runtime scopes, transitive dependency expectations,
101
+ lockfiles, BOMs, version catalogs, and publication metadata.
102
+ - Runtime and deployment context when the change touches server startup, HTTP clients, thread
103
+ pools, virtual threads, containers, GC, memory flags, JFR, JMH, native memory, class loading,
104
+ direct buffers, or CPU limits.
105
+ - Runtime pressure evidence when performance is involved: allocation rate, TLAB and outside-TLAB
106
+ allocation, humongous objects, boxed primitive churn, collection resizing, string or regex churn,
107
+ executor queue length, rejection behavior, downstream pool limits, and cancellation propagation.
108
+ - Configured verification intents.
109
+
110
+ <!-- mustflow-section: preconditions -->
111
+ ## Preconditions
112
+
113
+ - Inspect build metadata before using newer Java syntax, APIs, preview features, or JVM flags.
114
+ - Determine whether the change affects public API, binary compatibility, serialized shape,
115
+ reflection, module access, thread ownership, shutdown, resource cleanup, performance, or
116
+ deployment runtime behavior.
117
+ - If a Java release, latest Java, latest LTS, support status, JEP status, JVM flag, GC behavior,
118
+ preview or incubator feature, framework minimum Java version, or toolchain claim is written
119
+ durably, use `version-freshness-check` with official Java, OpenJDK, vendor, or build-tool sources.
120
+
121
+ <!-- mustflow-section: allowed-edits -->
122
+ ## Allowed Edits
123
+
124
+ - Preserve repository bytecode, source, and runtime compatibility unless the task explicitly asks
125
+ for a migration and the affected surfaces can be synchronized.
126
+ - Keep public API, serialized forms, and module exports compatible unless a breaking-change plan is
127
+ explicit.
128
+ - Use virtual threads for blocking I/O concurrency, not as CPU parallelism. Do not pool virtual
129
+ threads.
130
+ - Prefer immutable scoped context through `ScopedValue` when the supported Java version allows it
131
+ and the context is truly scoped and read-only.
132
+ - Keep JFR, GC logs, JMH, or representative runtime evidence ahead of JVM flag tuning or performance
133
+ claims.
134
+ - Do not add preview, incubator, vendor-specific, or experimental JVM features to public APIs or
135
+ durable examples without an explicit support policy and fallback.
136
+
137
+ <!-- mustflow-section: procedure -->
138
+ ## Procedure
139
+
140
+ 1. Read build metadata, wrapper files, toolchain declarations, module descriptors, generated-file
141
+ markers, public API entry points, tests, benchmarks, and deployment hints.
142
+ 2. Classify the change as source syntax, public API, binary compatibility, serialized form, build
143
+ metadata, dependency, reflection, module access, concurrency, HTTP, startup, GC or JVM tuning,
144
+ container behavior, observability, benchmark, or test-only.
145
+ 3. Review null and absence semantics:
146
+ - do not use one `null` or `Optional.empty()` bucket for not loaded, not found, forbidden,
147
+ deleted, lookup failed, backend unavailable, redacted, or intentionally empty;
148
+ - validate required values before writes, events, cache updates, or other side effects;
149
+ - reject `null` elements inside collections unless a legacy boundary explicitly documents them;
150
+ - prefer domain result types for meaningful absence and failure states.
151
+ 4. Review `Optional` boundaries:
152
+ - use `Optional` mainly as a return protocol, not as DTO, entity, or long-lived object state;
153
+ - remember an `Optional` field can itself be `null` and can complicate JSON, ORM, and framework
154
+ mapping;
155
+ - treat `Optional` as a value-based class: avoid identity equality, identity hash, and
156
+ synchronization on it;
157
+ - distinguish `Optional.of()` as a non-null assertion from `Optional.ofNullable()` at uncertain
158
+ boundaries;
159
+ - reject `isPresent()` plus `get()` null-check cosplay, eager `orElse(expensive())`, and
160
+ `map()` paths that silently convert buggy mapper `null` results into empty values.
161
+ 5. Review records and sealed classes as contracts:
162
+ - records are shallowly immutable; mutable components need defensive copies in constructors and
163
+ accessors;
164
+ - a record header is public API for construction, accessors, equality, hashing, and string output;
165
+ - array record components use reference equality in generated `equals` and `hashCode`;
166
+ - do not leak secrets through generated `toString()` or parse it as a stable format;
167
+ - sealed classes control inheritance, not plugin extension; `non-sealed` reopens the hierarchy;
168
+ - check package or module placement, permitted subclasses, and exhaustive switch behavior when a
169
+ hierarchy changes without every consumer recompiling.
170
+ 6. Build the Java version ledger before changing code:
171
+ - current repository source and target release;
172
+ - minimum supported runtime;
173
+ - CI and container runtime versions;
174
+ - current GA, latest LTS, and vendor-support track when the patch mentions "latest",
175
+ "current", "recommended", "LTS", "deprecated", or "removed";
176
+ - preview, incubator, experimental, product, and default-enabled status for every JDK feature
177
+ mentioned.
178
+ 7. Do not collapse JDK tracks:
179
+ - latest GA is not automatically the production baseline;
180
+ - latest LTS is not automatically the repository runtime;
181
+ - a JEP being delivered, preview, incubator, product, or removed changes how safe it is to write
182
+ code or docs;
183
+ - vendor support and licensing can matter for deployment even when OpenJDK source status is clear.
184
+ 8. Check source and bytecode compatibility:
185
+ - use `--release` or the build tool equivalent when compiling for older runtimes;
186
+ - avoid APIs unavailable on the target runtime even if the local JDK compiles them without
187
+ `--release`;
188
+ - treat records, sealed classes, pattern matching, module imports, compact source files, instance
189
+ main methods, flexible constructor bodies, and primitive patterns as version-gated features.
190
+ 9. Treat preview and incubator APIs as migration-sensitive:
191
+ - do not expose structured concurrency preview types in public APIs unless the project explicitly
192
+ accepts preview churn;
193
+ - keep Vector API, Lazy Constants, primitive patterns, and other preview or incubator features
194
+ behind tests, flags, internal adapters, or fallback paths;
195
+ - report the exact JDK floor and preview flag requirement when used.
196
+ 10. Preserve public Java contracts:
197
+ - exported classes, interfaces, methods, fields, annotations, exceptions, generic signatures,
198
+ module exports, service providers, records, sealed hierarchy members, enum constants, and
199
+ serialized forms can be compatibility surfaces;
200
+ - adding a method to an interface can break implementers;
201
+ - changing `equals`, `hashCode`, `compareTo`, nullability, exception types, or annotation
202
+ retention can break callers without changing signatures.
203
+ 11. Review binary compatibility for already compiled consumers:
204
+ - do not trust repository search to prove a public or protected member, constructor, field,
205
+ interface method, class modifier, or constant is safe to remove or change;
206
+ - use `--release` or equivalent toolchain checks to protect the library's minimum runtime API,
207
+ not only source and target class-file versions;
208
+ - distinguish the JDK that runs Maven or Gradle from the JDK that compiles, tests, and runs the
209
+ published artifact;
210
+ - treat test dependencies such as JUnit majors as contributor baseline changes even when runtime
211
+ artifacts are unaffected;
212
+ - verify Surefire, Failsafe, JUnit Platform, nested tests, integration-test phases, and naming
213
+ patterns so added tests actually run;
214
+ - keep deprecated wrappers, adapters, sub-interfaces, or major-version boundaries when changing
215
+ public/protected methods, fields, constructors, `static`, `final`, access levels, return types,
216
+ generic bounds, bridge-sensitive signatures, or compile-time constants;
217
+ - test ServiceLoader, `META-INF/services`, module `provides` and `uses`, public no-arg provider
218
+ constructors, reflection entry points, and sample consumer jar loading when SPI behavior moves;
219
+ - protect `Serializable`, exception classes, enum shapes, record shapes, `serialVersionUID`, and
220
+ golden serialized payloads when stored or cross-version data may exist.
221
+ 12. Review reflection and final fields:
222
+ - treat deep reflection into private or final fields as a framework, serializer, test, or module
223
+ contract;
224
+ - if code mutates `final` fields reflectively, check JDK final-field restriction status, required
225
+ flags, warnings, serializer behavior, and test helpers;
226
+ - prefer constructors, builders, factories, records, or explicit deserialization hooks over
227
+ mutating finals after construction;
228
+ - when modules are present, keep `exports`, `opens`, and command-line open flags deliberate and
229
+ narrow.
230
+ 13. Check legacy API removal before migrating runtime:
231
+ - scan direct and transitive legacy surfaces when raising to a newer JDK, especially `java.applet`
232
+ and `javax.swing.JApplet` dependencies;
233
+ - direct use, generated code, old vendor SDKs, classroom code, or legacy Swing helpers can fail
234
+ even when the application no longer has browser applets.
235
+ 14. Design concurrency by workload:
236
+ - use virtual threads for high-concurrency blocking I/O paths, not CPU-bound parallelism;
237
+ - do not hide CPU work behind virtual threads when a bounded executor, work queue, or
238
+ parallelism limit is the real policy;
239
+ - do not pool virtual threads; create them per task through the supported executor or framework
240
+ integration;
241
+ - keep pinning risks visible for native calls, foreign functions, class initialization, monitor
242
+ usage, and blocking sections that cannot unmount.
243
+ 15. Review executor and backpressure behavior:
244
+ - treat virtual-thread-per-task executors as cheap thread creation, not unlimited downstream
245
+ capacity;
246
+ - put concurrency limits at the scarce resource boundary: database pools, HTTP clients, Redis,
247
+ file descriptors, rate limits, semaphores, bounded queues, or bulkheads;
248
+ - do not send blocking I/O to `CompletableFuture` default async methods, `ForkJoinPool`
249
+ `commonPool`, or `parallelStream` without an explicit executor decision;
250
+ - remember fixed thread pools can hide overload behind unbounded queues and cached thread pools
251
+ can create unbounded platform threads;
252
+ - review `ThreadPoolExecutor` core size, max size, queue type, timeout, rejection policy, and
253
+ `CallerRunsPolicy` or abort behavior as one saturation contract;
254
+ - keep parent ownership, timeout, cancellation, and result-write rules explicit when `Future`,
255
+ `CompletableFuture`, executor submissions, or structured concurrency fan-out are used.
256
+ 16. Review scoped context:
257
+ - treat `ThreadLocal` as a memory and lifecycle risk in virtual-thread-heavy paths;
258
+ - use `ScopedValue` for immutable request, auth, tenant, tracing, or audit context only when the
259
+ JDK support matrix allows it;
260
+ - do not use scoped context as dependency injection or a mutable configuration bag;
261
+ - clear or bound `ThreadLocal` values in platform-thread pools and framework callbacks.
262
+ 17. Structure task lifetimes:
263
+ - when using structured concurrency, name the owner, failure policy, cancellation rule, timeout,
264
+ and join boundary;
265
+ - do not leak preview structured-concurrency types into public library contracts without an
266
+ explicit compatibility plan;
267
+ - avoid fire-and-forget threads unless a long-lived owner starts, stops, joins, and reports them.
268
+ 18. Check HTTP clients and server behavior:
269
+ - reuse clients and connection pools instead of creating them per request;
270
+ - set connect, request, read, and overall operation timeouts at the owner boundary;
271
+ - treat Java `HttpClient` HTTP/3 support as client-side and opt-in unless current official docs
272
+ say otherwise;
273
+ - do not imply Java HTTP/3 provides a generic QUIC API, server API, or automatic protocol change.
274
+ 19. Review Spring Boot, JPA, and security boundaries when present:
275
+ - verify `@Transactional` is reached through the proxy; self-invocation such as `this.save()`
276
+ does not prove a transaction boundary;
277
+ - make rollback rules explicit for checked exceptions when rollback, not commit, is required;
278
+ - treat `REQUIRES_NEW` as a connection-pool and deadlock risk, especially inside loops or
279
+ request-per-item auxiliary writes;
280
+ - keep external API calls, S3, email, Kafka sends, payment providers, and blocking network waits
281
+ outside long database transactions; prefer outbox or after-commit handoff with clear semantics;
282
+ - do not assume `@Async`, `CompletableFuture`, executor work, or `parallelStream` inherits the
283
+ transaction context; pass IDs and value objects rather than live entities;
284
+ - treat `@TransactionalEventListener(AFTER_COMMIT)` database writes as requiring an intentional
285
+ new transaction or an outbox record created before commit;
286
+ - after JPA bulk update or delete, decide whether to flush and clear the persistence context
287
+ before reusing loaded entities;
288
+ - protect inventory, points, coupons, credits, balances, and ownership changes with optimistic
289
+ locking, conditional updates, pessimistic locks, idempotency keys, or database constraints;
290
+ - avoid returning entities directly when OSIV or lazy loading can move queries into controller
291
+ rendering or JSON serialization;
292
+ - cap page sizes, `IN` lists, exports, offsets, and request-driven repository reads; use jobs,
293
+ cursors, fetch sizes, timeouts, and rate limits for heavy paths;
294
+ - bind external requests to DTOs or allowlisted fields, not entities with privileged fields;
295
+ - review Spring Security filter-chain matchers, unprotected paths, Actuator, Swagger, H2 console,
296
+ CORS ordering, and CSRF decisions instead of assuming URL patterns protect everything.
297
+ 20. Separate AOT cache from native image:
298
+ - Java AOT cache and method profiling reduce JVM startup or warmup by recording JVM-visible
299
+ state from training runs;
300
+ - do not describe JVM AOT cache as producing a standalone native binary;
301
+ - check training-run representativeness, classpath stability, CDS or AOT cache invalidation, GC
302
+ compatibility, and deployment reproducibility before enabling it.
303
+ 21. Tune GC only from evidence:
304
+ - G1 pause targets are goals, not SLAs. Lowering `MaxGCPauseMillis` can reduce young-gen size,
305
+ increase GC frequency, and hurt throughput;
306
+ - inspect humongous objects, allocation rate, evacuation failures, remembered sets, Full GC, and
307
+ old-region growth before changing G1 flags;
308
+ - ZGC and Shenandoah trade CPU and headroom for lower pauses; they are not free latency switches;
309
+ - Generational Shenandoah, Compact Object Headers, and similar features may be product features
310
+ without being default-enabled;
311
+ - explicit `System.gc()` calls, `DisableExplicitGC`, and concurrent explicit GC flags are
312
+ observable runtime policy, not formatting.
313
+ 22. Reduce allocation pressure from evidence, not folklore:
314
+ - optimize allocation rate, live set, peak memory, and object lifetime before chanting "avoid
315
+ `new`";
316
+ - inspect JFR allocation events such as new-TLAB, outside-TLAB, and thread allocation statistics
317
+ before rewriting hot paths;
318
+ - avoid pooling ordinary short-lived DTOs, builders, lists, or event objects when that only
319
+ promotes them into longer-lived state and adds locks or stale-data cleanup risk;
320
+ - prefer primitive arrays, packed values, primitive-specialized collections, or structure-of-array
321
+ layouts for dense hot-loop data where object headers and pointer chasing dominate;
322
+ - watch boxed primitives, generic callbacks, varargs, `Stream<Integer>`, and `Optional<Integer>`
323
+ on hot paths;
324
+ - size collections from realistic p95 counts rather than defaults or oversized guesses;
325
+ - cache or reuse regex `Pattern`s and avoid repeated string split, case conversion, substring,
326
+ JSON-path construction, and concat loops in request hot paths;
327
+ - treat large arrays and buffers as G1 humongous-object risks and prefer chunking, streaming,
328
+ paging, buffer caps, or region-size review over simply raising heap;
329
+ - do not pin G1 young-generation sizing unless evidence shows that overriding pause-time control
330
+ is the intended tradeoff;
331
+ - consider compressed-oops thresholds, multiple JVMs versus one large heap, and compact object
332
+ header experiments only with JFR, GC log, RSS, CPU, and latency evidence.
333
+ 23. Budget container memory and CPU explicitly:
334
+ - heap is only part of RSS. Account for direct buffers, metaspace, code cache, thread stacks, JNI,
335
+ native allocations, GC native memory, memory-mapped files, and libc allocator behavior;
336
+ - do not set `-Xmx` equal to the container limit without headroom;
337
+ - review `MaxRAMPercentage`, `InitialRAMPercentage`, `MaxDirectMemorySize`, metaspace, code
338
+ cache, and thread-count effects together;
339
+ - review `ActiveProcessorCount`, CPU quota, cpuset, ForkJoinPool sizing, GC thread counts, and
340
+ multiple JVMs per node before explaining throughput or latency changes.
341
+ 24. Keep performance measurement honest:
342
+ - use JMH for microbenchmarks instead of hand-rolled `System.nanoTime` loops;
343
+ - include warmup, forks, dead-code elimination guards, representative data, and allocation
344
+ metrics when benchmark claims matter;
345
+ - use JFR, GC logs, native memory tracking, heap dumps, thread dumps, async-profiler or
346
+ equivalent profiler evidence according to the symptom;
347
+ - do not call a JVM flag or GC change successful from a local warm-cache run, empty dataset,
348
+ debug logging path, or startup-only timing unless that is the actual product metric.
349
+ 25. Review serialization and data compatibility:
350
+ - Java serialization, Jackson, Gson, Kryo, protobuf, Avro, Hibernate, and reflection-heavy
351
+ frameworks can depend on constructors, final-field mutation, modules, annotations, records,
352
+ parameter names, sealed classes, default values, and no-arg constructors;
353
+ - keep unknown-field, defaulting, enum, and schema evolution behavior explicit when data crosses
354
+ process or storage boundaries.
355
+ 26. Keep build tooling synchronized:
356
+ - Maven compiler plugin, Gradle toolchains, wrapper versions, annotation processors, test
357
+ engines, bytecode instrumentation, shading, jlink, jpackage, and native-image tasks can each
358
+ have their own JDK support boundary;
359
+ - do not raise a toolchain, source level, target release, dependency bytecode floor, or plugin
360
+ major without checking CI, container, IDE, and downstream consumers.
361
+ 27. Review Maven, Gradle, and multi-module dependency boundaries:
362
+ - treat modules as compile, dependency, and deploy boundaries, not folder cleanup;
363
+ - reject `common`, `shared`, `core`, or `util` sink modules that erase ownership and import
364
+ direction;
365
+ - keep Maven parent inheritance separate from aggregator reactor membership;
366
+ - avoid Gradle `allprojects` and `subprojects` cross-project magic for real build policy; prefer
367
+ convention plugins or `build-logic` when shared behavior is intentional;
368
+ - use Gradle `api` only for public types and `implementation` for internal dependencies;
369
+ - remember Maven `dependencyManagement` manages versions but does not add dependencies and does
370
+ not govern plugin transitive dependencies;
371
+ - account for Maven nearest-wins resolution, optional dependencies, and path-local exclusions;
372
+ - do not treat a Gradle version catalog as a BOM or enforced constraint;
373
+ - use `force`, broad excludes, and `transitive = false` only as last-resort masking tools;
374
+ - check `compileOnly`, `provided`, `runtimeOnly`, and `testImplementation` against the runtime
375
+ provider, not just local test success;
376
+ - lock or avoid dynamic versions and snapshots when reproducible builds matter;
377
+ - check Gradle variant-aware resolution versus Maven POM publication metadata when publishing
378
+ Java libraries.
379
+ 28. Choose configured verification intents that cover compilation, tests, docs, package output,
380
+ benchmarks, runtime flags, and template or release metadata when available.
381
+
382
+ <!-- mustflow-section: rejection-criteria -->
383
+ ## Review Rejection Criteria
384
+
385
+ Reject or revise the patch when any of these appear without strong local justification:
386
+
387
+ - A latest-GA or LTS Java claim written without a current source ledger.
388
+ - New preview, incubator, or vendor-specific APIs in public APIs or durable examples without a
389
+ support policy.
390
+ - Public or protected API, `static`, `final`, access, return type, generic-bound, constant, SPI,
391
+ `ServiceLoader`, test-baseline, or serialized-form changes without old-consumer or compatibility
392
+ review.
393
+ - Spring self-invoked `@Transactional` methods, checked-exception rollback assumptions,
394
+ `REQUIRES_NEW` fan-out, external calls inside transactions, async transaction-context assumptions,
395
+ after-commit DB writes, stale persistence-context reuse after bulk updates, or entity request
396
+ binding.
397
+ - Security config that narrows Spring Security matchers while leaving Actuator, internal, Swagger,
398
+ H2, CORS, or CSRF behavior unreviewed.
399
+ - Executor changes that hide overload in unbounded queues, send blocking work to common pools, lack
400
+ rejection policy, or miss downstream backpressure.
401
+ - One `null` or `Optional.empty()` path standing for multiple domain states such as not found,
402
+ forbidden, deleted, lookup failed, or backend unavailable.
403
+ - `Optional` stored as DTO, entity, or mutable state, `isPresent()` plus `get()`, eager
404
+ `orElse(expensive())`, or `Optional.map()` hiding a mapper `null` bug.
405
+ - Record components with mutable collections or arrays and no defensive-copy or equality decision.
406
+ - Sealed hierarchy changes that ignore `non-sealed`, package or module restrictions, permitted
407
+ subclasses, or exhaustive switch compatibility.
408
+ - Maven or Gradle module changes that create sink modules, hidden cross-project configuration,
409
+ accidental `api` leakage, Maven nearest-wins surprises, version-catalog-as-BOM confusion, or
410
+ runtime scope gaps.
411
+ - New virtual-thread use for CPU-bound work, virtual-thread pooling, or unbounded task fan-out.
412
+ - New `ThreadLocal` request context in high-concurrency or virtual-thread paths without cleanup,
413
+ memory accounting, or a scoped alternative.
414
+ - New structured-concurrency preview types exported from a library boundary.
415
+ - New reflective mutation of final fields, broad module `opens`, or serializer magic without a JDK
416
+ compatibility plan.
417
+ - New JVM flags that change GC, heap, direct memory, CPU count, explicit GC, or AOT behavior without
418
+ JFR, GC log, benchmark, or runtime evidence.
419
+ - Allocation rewrites based on `new` folklore instead of allocation rate, live set, TLAB, humongous
420
+ object, boxing, collection sizing, or string/regex evidence.
421
+ - New `-Xmx` or `MaxRAMPercentage` settings that ignore native memory, direct buffers, metaspace,
422
+ code cache, stacks, and container headroom.
423
+ - New G1, ZGC, Shenandoah, Compact Object Headers, or AOT claims that treat opt-in or goal-based
424
+ behavior as default or guaranteed.
425
+ - New hand-rolled microbenchmarks that can be optimized away by the JIT.
426
+ - New applet, removed API, or legacy `javax.swing.JApplet` dependency on a runtime where the API is
427
+ gone.
428
+ - Public API, serialized form, module exports, annotation contracts, or bytecode floor changes
429
+ without compatibility review.
430
+
431
+ <!-- mustflow-section: postconditions -->
432
+ ## Postconditions
433
+
434
+ - Java version, source target, runtime target, and preview/incubator status are explicit where
435
+ relevant.
436
+ - Public API, bytecode, module, reflection, serialization, and framework compatibility are preserved
437
+ or the breaking-change requirement is reported.
438
+ - Spring transaction, JPA persistence, security matcher, request binding, pagination, and entity
439
+ exposure risks are explicit where touched.
440
+ - Binary compatibility, old compiled consumers, test discovery, SPI, ServiceLoader, and serialized
441
+ payload compatibility are preserved or the breaking-change requirement is reported.
442
+ - Absence semantics, nullability, `Optional`, record, and sealed hierarchy contracts are explicit
443
+ where touched.
444
+ - Maven or Gradle dependency, scope, module, and publication boundaries are explicit where touched.
445
+ - Virtual-thread, `ThreadLocal`, `ScopedValue`, structured-concurrency, cancellation, and thread
446
+ ownership choices are explicit where touched.
447
+ - Executor saturation, downstream backpressure, allocation rate, object lifetime, GC choice, JVM
448
+ flags, AOT cache, container memory, CPU count, JFR, JMH, and profiling claims are evidence-backed
449
+ or downgraded.
450
+ - Missing runtime matrix, JMH, JFR, GC-log, native-memory, container, or framework verification is
451
+ reported.
452
+
453
+ <!-- mustflow-section: verification -->
454
+ ## Verification
455
+
456
+ Use configured oneshot command intents when available:
457
+
458
+ - `lint`
459
+ - `build`
460
+ - `test_related`
461
+ - `test`
462
+ - `docs_validate_fast`
463
+ - `mustflow_check`
464
+
465
+ For Java-version-gated features, report whether the repository has a configured JDK matrix, bytecode
466
+ target check, preview-enabled check, or framework compatibility check. For performance or JVM flag
467
+ changes, report whether configured JMH, JFR, GC-log, container-smoke, native-memory, startup, or load
468
+ verification exists.
469
+
470
+ <!-- mustflow-section: failure-handling -->
471
+ ## Failure Handling
472
+
473
+ - If the supported Java version is unclear, do not use newer APIs or claims; preserve the existing
474
+ code style and report the missing version policy.
475
+ - If a build passes locally but bytecode target, runtime image, or CI runtime is lower, treat the
476
+ change as unverified until the target runtime is checked.
477
+ - If reflection, serialization, or module access fails after a JDK change, inspect framework
478
+ compatibility before broadening `opens` or adding command-line escapes.
479
+ - If virtual-thread changes hang, leak, or slow CPU work, revisit workload classification and owner
480
+ cancellation before adding pools or timeouts.
481
+ - If JVM tuning worsens tests or benchmarks, do not loosen assertions or invent flags; revert or
482
+ narrow the tuning decision unless the behavior change is intentional.
483
+ - If generated code must change but no generator intent exists, report the missing command contract.
484
+
485
+ <!-- mustflow-section: output-format -->
486
+ ## Output Format
487
+
488
+ - Java boundary checked
489
+ - Version, toolchain, source target, runtime target, and preview/incubator notes
490
+ - Public API, module, reflection, serialization, and bytecode impact
491
+ - Nullability, Optional, record, sealed hierarchy, Maven, Gradle, dependency, and multi-module impact
492
+ - Spring transaction, JPA, security, binary compatibility, SPI, test discovery, executor, allocation,
493
+ and backpressure notes when relevant
494
+ - Virtual-thread, scoped context, structured concurrency, HTTP, GC, JVM flag, AOT, container, JFR,
495
+ JMH, and profiling notes when relevant
496
+ - Files changed
497
+ - Command intents run
498
+ - Skipped checks and reasons
499
+ - Remaining Java risk
@@ -36,6 +36,12 @@ route_type = "primary"
36
36
  priority = 40
37
37
  applies_to_reasons = ["code_change", "behavior_change"]
38
38
 
39
+ [routes."split-refactor-residual-path-review"]
40
+ category = "architecture_patterns"
41
+ route_type = "adjunct"
42
+ priority = 79
43
+ applies_to_reasons = ["unknown_change", "code_change", "behavior_change", "test_change", "public_api_change", "performance_change", "ui_change", "data_change"]
44
+
39
45
  [routes."composition-over-inheritance"]
40
46
  category = "architecture_patterns"
41
47
  route_type = "primary"
@@ -456,6 +462,12 @@ route_type = "primary"
456
462
  priority = 78
457
463
  applies_to_reasons = ["unknown_change", "code_change", "behavior_change", "migration_change", "package_metadata_change", "release_risk"]
458
464
 
465
+ [routes."technology-stack-selection"]
466
+ category = "architecture_patterns"
467
+ route_type = "primary"
468
+ priority = 79
469
+ applies_to_reasons = ["unknown_change", "code_change", "behavior_change", "docs_change", "product_change", "cross_cutting_code_change", "data_change", "migration_change", "performance_change", "security_change", "privacy_change", "package_metadata_change", "release_risk"]
470
+
459
471
  [routes."structure-first-engineering"]
460
472
  category = "general_code"
461
473
  route_type = "adjunct"
@@ -534,6 +546,12 @@ route_type = "primary"
534
546
  priority = 85
535
547
  applies_to_reasons = ["code_change", "public_api_change", "test_change"]
536
548
 
549
+ [routes."java-code-change"]
550
+ category = "general_code"
551
+ route_type = "primary"
552
+ priority = 85
553
+ applies_to_reasons = ["code_change", "behavior_change", "public_api_change", "test_change", "docs_change", "data_change", "performance_change", "security_change", "privacy_change", "package_metadata_change", "release_risk"]
554
+
537
555
  [routes."python-code-change"]
538
556
  category = "general_code"
539
557
  route_type = "primary"
@@ -738,6 +756,18 @@ route_type = "primary"
738
756
  priority = 86
739
757
  applies_to_reasons = ["code_change", "data_change", "migration_change", "behavior_change", "public_api_change", "test_change", "docs_change", "security_change", "performance_change"]
740
758
 
759
+ [routes."clickhouse-code-change"]
760
+ category = "data_external"
761
+ route_type = "primary"
762
+ priority = 86
763
+ applies_to_reasons = ["code_change", "data_change", "migration_change", "behavior_change", "public_api_change", "test_change", "docs_change", "security_change", "performance_change"]
764
+
765
+ [routes."duckdb-code-change"]
766
+ category = "data_external"
767
+ route_type = "primary"
768
+ priority = 86
769
+ applies_to_reasons = ["code_change", "data_change", "migration_change", "behavior_change", "public_api_change", "test_change", "docs_change", "security_change", "performance_change"]
770
+
741
771
  [routes."search-index-integrity-review"]
742
772
  category = "data_external"
743
773
  route_type = "primary"
@@ -990,6 +1020,12 @@ route_type = "adjunct"
990
1020
  priority = 80
991
1021
  applies_to_reasons = ["ui_change", "behavior_change", "code_change", "performance_change", "data_change", "test_change", "public_api_change"]
992
1022
 
1023
+ [routes."ui-state-resurrection-review"]
1024
+ category = "ui_assets"
1025
+ route_type = "adjunct"
1026
+ priority = 83
1027
+ applies_to_reasons = ["unknown_change", "ui_change", "behavior_change", "code_change", "performance_change", "data_change", "test_change", "public_api_change", "docs_change", "package_metadata_change", "release_risk"]
1028
+
993
1029
  [routes."frontend-stress-layout-review"]
994
1030
  category = "ui_assets"
995
1031
  route_type = "adjunct"
@@ -1176,6 +1212,12 @@ route_type = "primary"
1176
1212
  priority = 60
1177
1213
  applies_to_reasons = ["docs_change", "copy_change", "product_change"]
1178
1214
 
1215
+ [routes."writing-elegance"]
1216
+ category = "docs_release"
1217
+ route_type = "primary"
1218
+ priority = 62
1219
+ applies_to_reasons = ["docs_change", "copy_change", "workflow_change", "release_risk", "unknown_change"]
1220
+
1179
1221
  [routes."docs-prose-review"]
1180
1222
  category = "docs_release"
1181
1223
  route_type = "adjunct"