| name | exeris-tooling-codegen-determinism-review |
| description | Codegen determinism review for exeris-tooling. Use for every PR that touches `*Generator` emission surfaces, scaffold helpers, or text-stable iteration. Catches timestamps, randoms, hash-iteration leakage, and locale-dependent formatting before they reach committed `src/main/generated/`. |
Exeris Tooling Codegen Determinism Review
Purpose
Enforce: same DomainMetadata input → byte-identical emitted output, across runs / machines / locales.
This skill is mandatory for PR reviews touching exeris-codegen-java/*Generator.java, exeris-codegen-ts/src/**, or shared scaffold/iteration helpers in exeris-codegen-core.
When to Use
- Any PR review in
exeris-codegen-{core,java,ts}.
- Any change that adds a generator or modifies scaffold extraction.
- Any change to
OutputWriter or filesystem write path.
- Any PR proposing iteration over a
Map/Set whose iteration order leaks into emitted text.
Required Inputs
- PR diff or changed file list scoped to
exeris-codegen-*.
- Affected
*Generator classes.
- Stated intent of the change (new shape / refactor / scaffold / parity).
Review Procedure
- Scan emitted-text producers — any
String.format, text block, JavaPoet.JavaFile, or StringBuilder.append chain that produces text written to disk.
- Time-of-day audit — reject any
Instant.now(), LocalDate.now(), System.currentTimeMillis(), or new Date() reachable from emission paths. The 0.1.0 OutputWriter timestamp drop is canonical.
- Randomness audit — reject
UUID.randomUUID() and Random in emission paths. Test fixtures are OK.
- Iteration-order audit — flag iteration over
HashMap, HashSet, ConcurrentHashMap when the output is text-stable-sensitive. Require sort or LinkedHashMap/TreeMap upstream.
- Locale audit — flag
String.format/String.toLowerCase/String.toUpperCase without Locale.ROOT when emitting language-like output.
- Path-separator audit — flag
File.separator in emitted text paths (use forward slash for source paths).
- Determinism harness reachability — if the change is non-trivial, require a "regenerate twice,
diff -r, expect empty" check on at least one representative entity.
- Decision and report — produce one of:
APPROVE, CONDITIONAL, REJECT.
Decision Logic
- APPROVE: No timestamp / random / hash-iteration / locale leak; existing
KernelCodegenE2ETest substring assertions or KernelCodegenCompileTest cover the changed surface.
- CONDITIONAL: Fixable determinism gap with named remediation; suggest the minimum harness or sort addition.
- REJECT: Active reintroduction of a known determinism regression (timestamps, randoms in emission, hash-order leakage).
Completion Criteria
- Every emitted-text producer in the change was scanned.
- A "regenerate twice" check was proposed or already covered.
- A verdict and remediation list were provided.
Review Output Template
- Scope analysed (generators / scaffolds touched)
- Determinism findings (timestamps / randoms / iteration / locale / path)
- Coverage (which existing test catches what; what the change exposes)
- Verdict (
APPROVE / CONDITIONAL / REJECT)
- Required actions (precise and minimal)
Non-Negotiable Rules
- Never let a timestamp into committed generated artefacts.
- Never trust default-
HashMap iteration in text-stable emission.
- Never claim "low-risk" without naming the test that catches the regression.