Skip to content

docs(adr): record that the Gradle exclude residue was measured, not assumed - #93

Merged
rodrigorjsf merged 3 commits into
mainfrom
docs/adr-0007-gradle-residue-measured
Aug 5, 2026
Merged

rodrigorjsf merged 3 commits into
mainfrom
docs/adr-0007-gradle-residue-measured

Conversation

@rodrigorjsf

@rodrigorjsf rodrigorjsf commented Aug 5, 2026 •

Copy link
Copy Markdown
Owner

Closes #91 once merged, by taking its option 1 — accept the residue — with the measurement its
acceptance criteria required.

What #91 left open

The Gradle exclude recognizer shipped in #68 keeps two residual holes: an unclosed exclude( with
an orphan ) and no brace between them, and a Groovy exclude line whose trailing comma is followed
by a declaration. Both blank a real langchain4j-…shell… declaration — a false negative, the failure
#45 exists to prevent.

#91's acceptance criteria let the issue close as accepted only with ADR 0007 amended to say the
residue was measured and kept. Nothing had measured it: #88's survey read 262 build files for
refusal spellings, not for these two shapes.

What was measured

Both shapes were first re-verified against shell_artifact_declarations on current main
(d5e9682), each with a control, so the mechanism is isolated rather than assumed:

input result
shape A {}
shape A, exclude( line deleted ShellDeclaration(line=2, langchain4j-experimental-skills-shell)
shape B {}
shape B, trailing comma dropped ShellDeclaration(line=3, langchain4j-experimental-skills-shell)

Then the shipped _GRADLE_EXCLUDE_CALL was run over #88's downloaded population — all 262 files —
looking for the hazard both shapes share, shape-agnostically: a match that spans lines and swallows a
line opening a dependency declaration (implementation, api, testImplementation, …).

files scanned: 262
multi-line exclude matches: 4
matches swallowing a declaration line: 0
control A: detector fires = True
control B: detector fires = True

The four multi-line matches are the four wrapped exclude( calls #88 already classified as file
filters. The two controls prove the zero is not vacuous.

What this PR changes

One paragraph in docs/adr/0007-l4j-shell-survives-the-graduation-rename.md, plus one Applied
Learning bullet in CLAUDE.md recording that #88's population is still on disk — the fact that made
this measurement free. No code, no test, no
snapshot — tests/behavior/snapshots/langchain4j_gradle_skill.json is untouched, as #91's third
acceptance criterion requires.

The amendment says rarity, not impossibility: the population is filtered to build files naming
both langchain4j and exclude, so a zero there bounds how often the shapes occur near the code
this Rule reads — it does not prove they cannot exist.

Deliberately not done

Options 2–4 of #91. Two of them trade one residue for another (an arbitrary line cap; a vocabulary of
Gradle configuration names to keep true), and the third reverses the no-brace-parsing decision
signals.py is built on. Zero observed instances does not buy any of that.

Validation

  • make lint — passed
  • make format-check — 204 files already formatted
  • make test-unit — 2639 passed, 12 skipped, 4 xfailed
  • make update-snapshots — tree clean afterwards (git status empty)
  • CI green on 8734c2c: test-unit, lint, DCO Check, changes all pass
  • prose-only diff; no snapshot regeneration needed

…ssumed

Issue #91 documents two malformed Gradle exclude shapes that still blank a
real shell declaration. ADR 0007 named them as accepted; it could not say
they were rare, because nothing had looked.

Issue #88's population -- the 262 build files fetched for the spelling
survey -- was re-run through the shipped recognizer, searching for the
hazard both shapes share: a match spanning lines that swallows a line
opening a dependency declaration. Four matches span lines, all file
filters, none swallowing a declaration. The detector fires on both shapes
when fed them, so the zero is not vacuous.

The population is filtered rather than universal, so the ADR says rarity,
not impossibility.

Refs: #91
Signed-off-by: Rodrigo França <rodrigo_rjsf@hotmail.com>
Measuring #91 against that population cost nothing because the 262 files
were still in a prior session's scratchpad. Refetching them would have
been ~300 API calls for the same answer.

Signed-off-by: Rodrigo França <rodrigo_rjsf@hotmail.com>
The previous wording pointed at a session-scoped scratchpad path, which is
reaped -- a future session would follow it, find nothing, and learn only to
waste a search. #88's survey comment carries the query, the pagination and
the filter, which is the part that stays true.

Signed-off-by: Rodrigo França <rodrigo_rjsf@hotmail.com>
@rodrigorjsf
rodrigorjsf merged commit 71042d6 into main Aug 5, 2026
5 checks passed
@rodrigorjsf
rodrigorjsf deleted the docs/adr-0007-gradle-residue-measured branch August 5, 2026 15:50
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.

L4J-SHELL: two malformed Gradle exclude shapes still blank a real declaration

1 participant