Skip to content

docs(cursor-rules): fix the two live AI-context contradictions in .cursor/rules/ - #37590

Merged
fabrizzio-dotCMS merged 2 commits into
mainfrom
issue-37577-cursor-rules-contradictions
Sep 17, 2026
Merged

fabrizzio-dotCMS merged 2 commits into
mainfrom
issue-37577-cursor-rules-contradictions

Conversation

@fabrizzio-dotCMS

@fabrizzio-dotCMS fabrizzio-dotCMS commented Sep 17, 2026

Copy link
Copy Markdown
Member

What

Fixes the two contradictions still live in .cursor/rules/, and adds a script that measures whether one of them actually stops recurring.

.cursor/rules/*.mdc is the second entry point for AI context — Cursor loads a rule automatically when the file you are editing matches its globs. java-context.mdc fires on every *.java and pom.xml; test-context.mdc on every *Test.java. The Rock's M1–M3 (#37126, #37127, #37128) audited docs/ and root CLAUDE.md and left this directory untouched, because it sits in Scout's slice. Result: two of the four failure modes #37124 exists to stop are still being served to anyone working from Cursor.

Java version

java-context.mdc stated Core: Java 11 syntax. CLI: Java 21 ok. Runtime: Java 21.

CLAUDE.md:68 no longer pins a version at all — it defers to .sdkmanrc for the runtime, dotcms.core.compiler.release in parent/pom.xml for core modules, and maven.compiler.release in tools/dotcms-cli/pom.xml for the CLI. #37126 fixed this in the docs; the Cursor rule kept serving Java 11 idioms. It now points at the properties instead of restating a number, with a line saying not to hardcode one here again — that is what caused the drift.

Integration-test registration

MainSuite/Junit5Suite appeared nowhere under .cursor/rules/, while test-context.mdc did hand out a command for running integration tests. So the rule gave the "how to run" without the "how to make CI run it".

An integration test not listed in a @SuiteClasses array compiles, passes review, and is silently never run in CI — green build, zero coverage. That has been a Critical Rule in CLAUDE.md since #37127, and it is the opening example in #37124's own problem statement.

Per review feedback from @nollymar and @jcastro-dotcms, the rule states the consequence and defers the mechanics to docs/testing/INTEGRATION_TESTS.md, which #37583 rewrote the same day: the suite to pick is whichever MainSuite* currently has the shortest CI runtime, and the suite set is explicitly not fixed. The rule tells the reader not to hardcode suite names — the same drift the Java fix above addresses.

Measuring it

scripts/validate-integration-test-registration.sh reads the suite list from .github/test-matrix.yml — what CI actually runs, so a future MainSuite3b is picked up the day it lands, and QuickSuite (in the tree, not in the matrix) correctly does not count. It extracts the classes in each suite's @SuiteClasses block, cross-checks against the concrete *Test.java classes in dotcms-integration, and reports two different things: the standing backlog, and — the part that matters for the gate — the tests added in a recent window.

$ scripts/validate-integration-test-registration.sh 60
CI suites (from .github/test-matrix.yml):
  - MainSuite1a … MainSuite3a, Junit5Suite1, OpenSearchUpgradeSuite

Registered classes:  609
Concrete *Test.java: 673
Never run in CI:     87

Leak rate: 0 of 28 new tests unregistered.

The headline number is 0, and that is worth stating plainly: over the last 60 days, every new integration test was registered. The failure mode this Rock cites is not currently leaking in the flow. What remains is a standing backlog of 87 classes that exist and never run — separate work, not a regression.

An earlier revision of this PR quoted 1 of 28. That was wrong: the script's suite list was a hardcoded glob that missed OpenSearchUpgradeSuite, so a test registered there read as unregistered. Two further bugs were fixed in the same pass — the bot review's point that class extraction matched every X.class token rather than the @SuiteClasses block, and, once anchored, that MainSuite3a spells the annotation @Suite.SuiteClasses and was silently dropped entirely. The script now aborts if any CI suite yields zero classes, so that class of error fails loudly instead of inflating the count.

Caveat, documented in the script: matching is by simple class name, not fully-qualified. Two same-named classes in different packages, one registered and one not, read as registered. Fine for trending; verify by hand before quoting the number anywhere.

What this means for the gate

#37581's monitoring gate was premised on watching a leak stop. With a measured baseline of 0 leaks in 60 days, the gate's job changes: it confirms the rate stays at 0 now that Cursor users get the rule too, rather than demonstrating a drop. Worth a decision on whether that still warrants the full 1–2 week window.

Testing

Documentation and tooling only — no production code. The script was run against main at dfbe40f. Its 87-class backlog figure was reproduced independently, and five entries spot-checked by hand against every *Suite*.java in the module. The two .mdc edits were checked against real source: .sdkmanrc, parent/pom.xml, tools/dotcms-cli/pom.xml, .github/test-matrix.yml, and the suite files under dotcms-integration/src/test/java/com/dotcms/.

Refs #37577, #37581

🤖 Generated with Claude Code

This PR fixes: #37577

…rsor/rules/

`.cursor/rules/*.mdc` is the second entry point for AI context, loaded by glob
when a matching file is edited. The Rock's M1-M3 audited docs/ and CLAUDE.md but
never touched it, so two of the failure modes the Rock exists to stop are still
being served to anyone working from Cursor.

java-context.mdc claimed `Core: Java 11 syntax. CLI: Java 21 ok. Runtime: Java
21`. CLAUDE.md:68 no longer pins a version at all — it defers to `.sdkmanrc` for
the runtime and `dotcms.core.compiler.release` in `parent/pom.xml` for core
modules. #37126 fixed this in the docs; the Cursor rule was outside that slice
and kept serving Java 11 idioms. Now it points at both properties, and says not
to hardcode a version here again.

test-context.mdc had no mention of MainSuite/Junit5Suite registration anywhere,
while handing out a command for running integration tests. An unregistered test
compiles, passes review and is silently never run in CI. That rule has been in
CLAUDE.md's Critical Rules since #37127; it now exists in the Cursor rule too,
with the real suite names.

Also adds scripts/validate-integration-test-registration.sh, which measures the
failure mode instead of assuming it stopped: it cross-checks every @SuiteClasses
list against the concrete *Test.java classes in dotcms-integration, and reports
separately on tests added in a recent window. Current state: 100 classes never
run in CI, and 1 of the 28 added in the last 60 days went unregistered. That 1/28
is the baseline the monitoring gate in #37581 measures against.

Refs #37577, #37581

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@claude

claude Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Claude finished @fabrizzio-dotCMS's task in 2m 54s —— View job


Review

Docs + tooling only, no production code. I verified the two .mdc edits against real source and traced the new script's logic. The reviewer feedback from @nollymar / @jcastro-dotcms is addressed by 07d4c0e8.

New Issues

  • 🟡 Medium: scripts/validate-integration-test-registration.sh:60 — the class-extraction awk only recognizes @SuiteClasses / @Suite.SuiteClasses, but Junit5Suite1 (deliberately included via the matrix) registers its tests with JUnit 5's @SelectClasses (Junit5Suite1.java:34). The script produces correct numbers today only by coincidence: line 26 of that file mentions {@code @SuiteClasses} in a javadoc comment, which trips inblock=1, and since no }) appears before the real @SelectClasses({ … }) block, its 15 classes get captured anyway. If that javadoc is ever reworded/reordered, extraction returns 0 for Junit5Suite1 and the guard at line 66–68 hard-fails with the misleading message "unrecognized @SuiteClasses form?" (set -e → exit 1) — or, absent the guard, all ~15 JUnit 5 ITs (JobQueue*, BulkUpload*) would read as "never run in CI" and, being recent additions, as false leaks in the window (a false --strict exit 1 if wired to CI). The comment at line 56 ("both spellings occur … @SuiteClasses and @Suite.SuiteClasses") doesn't acknowledge @SelectClasses at all. Add @SelectClasses to the regex on line 60 so the coincidence becomes intent. Fix this →

Resolved

  • .cursor/rules/test-context.mdc:22@jcastro-dotcms / @nollymar's feedback (point IT docs at docs/testing/INTEGRATION_TESTS.md, don't hardcode a suite list) is handled: the rule now links the doc's "Registering Tests in a MainSuite (CI gate)" section (heading confirmed present) and drops the hardcoded suite names.

Verified

  • .cursor/rules/java-context.mdc:29-31 — properties resolve: .sdkmanrc (java=25.0.4+1-ms), parent/pom.xml (dotcms.core.compiler.release=25), tools/dotcms-cli/pom.xml (maven.compiler.release=11). No hardcoded version — matches CLAUDE.md.
  • Script sources exist: .github/test-matrix.yml and its test_class: entries, plus the abstract-class / concrete-*Test.java split and the loud-fail guard are sound for the @SuiteClasses families. --strict and the class-name caveat are documented.

Nice touch reading the suite set from .github/test-matrix.yml rather than hardcoding it — that keeps the script honest about what CI actually runs. The one gap is that the matrix now includes a JUnit 5 suite the extractor doesn't formally understand. Non-blocking.

Note: I couldn't execute the script in this environment (permission), so the trace above is by reading, not by run.
· issue-37577-cursor-rules-contradictions

Comment thread .cursor/rules/test-context.mdc Outdated
…te detection

Review feedback from @nollymar and @jcastro-dotcms on PR #37583: the Cursor rule
restated suite mechanics that had just changed, and any doc touching integration
tests should point at docs/testing/INTEGRATION_TESTS.md instead.

#37583 established that the suite to register in is whichever MainSuite* has the
shortest current CI runtime, and that the suite set is explicitly not fixed. The
rule now gives the consequence (unregistered = silently never run in CI) and
defers the choice to the doc, with a line telling the reader not to hardcode
suite names here — the same drift the Java-version fix in this PR addresses.

Two bugs in the script, found while acting on that feedback:

- The suite list was a hardcoded glob of MainSuite*/Junit5Suite*, which missed
  OpenSearchUpgradeSuite (a real CI suite, 19 classes) and would have counted a
  future MainSuite3b as nonexistent. It now reads the suite list from
  .github/test-matrix.yml, which is what CI actually runs — so QuickSuite, which
  exists in the tree but is not in the matrix, correctly does not count.

- Class extraction matched every X.class token in the file, per the bot review.
  Anchoring it to the @SuiteClasses block then silently dropped all of
  MainSuite3a, which spells the annotation @Suite.SuiteClasses. Both forms are
  now matched, and the script aborts if any CI suite yields zero classes rather
  than reporting its tests as unregistered.

Corrected figures: 609 registered, 673 concrete test classes, 87 never run in
CI, and 0 of the 28 added in the last 60 days unregistered. The 1-of-28 quoted
in the original PR body was an artifact of the missing OpenSearchUpgradeSuite.

Refs #37577, #37581

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fabrizzio-dotCMS fabrizzio-dotCMS added the Area : Documentation PR changes documentation files label Sep 17, 2026
@fabrizzio-dotCMS
fabrizzio-dotCMS added this pull request to the merge queue Sep 17, 2026
Merged via the queue into main with commit 496ccc7 Sep 17, 2026
59 checks passed
@fabrizzio-dotCMS
fabrizzio-dotCMS deleted the issue-37577-cursor-rules-contradictions branch September 17, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI: Safe To Rollback Area : Documentation PR changes documentation files

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

M1 — Fix Scout contradictions

3 participants