jade-core-change-collector
Collects Java version breaking-change rules from user-supplied sources. Uses LLM reading comprehension to extract rules from fetched text — never regex. A schema-validating write_manifest.py enforces
SKILL.md.claude/skills/jade-core-change-collector/SKILL.md
GitHubJADE Change Collector — LLM-as-Extractor
Objective
Produce artifacts/01-breaking-changes-manifest.json where every rule is extracted
by the agent's reading comprehension from actual fetched source text. Never regex.
Never fabricate.
Strict-mode constraint
It is forbidden to emit a rule unless the agent read it directly from a fetched
source file. Every rule must cite a source_label and evidence_ref that the
agent just read. Confidence scores below 0.7 MUST NOT appear in the manifest.
Required input
artifacts/00-run-config.json- User-supplied source list (URLs, file paths, or local
.mdKB files)
Produced artifacts
| Artifact | Purpose |
|---|---|
artifacts/01-source-index.json |
Every source with fetch status, snippet, hash |
artifacts/01-source-content-{label}.txt |
Clean, readable text extracted from each source — the LLM reads THIS |
artifacts/01-source-fetch-errors.json |
Written only when all sources fail |
artifacts/01-breaking-changes-manifest.json |
Final rule list, schema-validated |
artifacts/01-evidence-map.json |
Rejected candidates, extraction notes |
artifacts/01.5-precision-sample-{rule_id}.json |
Deterministic rank-ordered pattern-hit sample (precision gate, opt-in) |
artifacts/01.5-precision-verdicts-{rule_id}.json |
Agent's TRUE/FALSE_POSITIVE/UNDECIDABLE judgments — the only hand-written file in the precision gate |
artifacts/01.5-precision-report.json |
Scored precision per rule, with Wilson interval and counterexamples |
artifacts/PRECISION_ACTION_REQUIRED.md |
Written only when a rule needs a pattern rewrite, a larger sample, or a human decision |
Workflow
Phase A — Source Ingestion
- Read
artifacts/00-run-config.jsonto obtainrun_idandartifacts_path. - Accept the user's source list. Sources are URLs, local files, or KB paths.
- For each source, invoke
scripts/fetch_source.py:
python scripts/fetch_source.py \
--run-config artifacts/00-run-config.json \
--source-url "<URL_OR_PATH>" \
--source-label "<HUMAN_READABLE_LABEL>"
The script:
- Fetches URL content (handles 200, 404, timeout, paywall detection)
- Strips HTML tags to produce clean readable text
- Writes
artifacts/01-source-content-{label}.txt - Updates
artifacts/01-source-index.json
If zero sources succeed (all 404/timeout/paywall): write 01-source-fetch-errors.json,
set AWAITING_SOURCE_INPUT in 00-run-state.json, and halt.
Phase B — LLM Extraction (the agent does this)
The agent MUST NOT invent rules from prior knowledge. Every rule MUST come from text the agent explicitly read.
Read each source file with the
Readtool:- Read
artifacts/01-source-content-{label}.txt - Scan for breaking changes between
source_versionandtarget_version - Identify rule candidates: new language features, deprecated APIs, removed components, behavioral changes
- Read
For each candidate rule, cite evidence:
evidence_ref—source-label::line-range(e.g.,mock-sources::lines 15-28)evidence_hash— SHA-256 from01-source-index.jsonfor that source
Build a JSON array of rules. Each rule MUST have:
id— unique ID, e.g.,GENERICS_UPGRADE,LOOP_MODERNIZATIONname— human-readable namefix_strategy—"recipe:jade-recipe-{version}-{id}"formatseverity—HIGH,MEDIUM,LOW,WARNING,INFOcategory—LANGUAGE_CHANGE,API_REMOVAL,DEPRECATION,BEHAVIOR_CHANGE, etc.match_pattern— valid regex to find instances in sourcepatterns[]— array with{type: "regex", pattern, target_extensions, reason, confidence}evidence_ref,evidence_hash,confidence(0.7–1.0)verification_hint— how to confirm the fix was applied correctly
Save the rules to a temp JSON file:
python -c "
import json
rules = [...] # your extracted rules
json.dump(rules, open('artifacts/01-extracted-rules.tmp.json', 'w'), indent=2)
"
Phase C — Validate and Write
- Invoke
write_manifest.pywith the temp file:
python scripts/write_manifest.py \
--input artifacts/01-extracted-rules.tmp.json \
--artifacts-dir artifacts/ \
--run-id <run_id> \
--source-version <source_version> \
--target-version <target_version>
write_manifest.pyvalidates:- Every rule has required fields (
id,name,severity,patterns) - Every rule has
evidence_refandevidence_hash(Anti-Hallucination gate) confidence >= 0.7fix_strategystarts with"recipe:"match_patterncompiles as valid regex- No duplicate
rule_idvalues severityandcategoryare valid values
- Every rule has required fields (
If validation fails → print errors, exit 2. DO NOT proceed with invalid manifest.
If validation passes →
01-breaking-changes-manifest.jsonis written atomically.
Phase D — Pattern-Precision Sampling (only when precision_gate.enabled is true)
When 00-run-config.json carries an enabled precision_gate block, the manifest is
not final at the end of Phase C — a garbage pattern (one that matches the right
syntax shape but almost never the actual construct the rule describes) must be
caught before the knowledge graph is built and the scanner injects
// JADE-FLAG: comments into the workspace, not after. This phase runs entirely
inside the same MANIFEST_READY agent pause as Phases A-C; there is no separate
pipeline stop for it.
For each rule in the just-written manifest:
- Sample the rule's population of regex hits:
python scripts/sample_pattern_hits.py \
--run-config artifacts/00-run-config.json \
--rule-id <rule_id>
This writes artifacts/01.5-precision-sample-<rule_id>.json — a deterministic,
rank-ordered sample computed via the scanner's own file-collection logic (never
re-implemented), so the sample's population is provably identical to what
scan_and_tag.py would flag. The script never touches the workspace.
Read every hit in the sample artifact and judge it against one question only:
For each hit, answer one question: is what the pattern caught on this line the construct that
rule_descriptiondescribes? You are not judging whether it needs fixing, or whether the change is risky. You are judging only whether the pattern caught what it claims to catch.Record one verdict per
hit_id—TRUE_POSITIVE,FALSE_POSITIVE, orUNDECIDABLE— each with areason(>= 20 characters). AFALSE_POSITIVEverdict additionally requires afalse_positive_class:NOT_THE_CONSTRUCT,RIGHT_CONSTRUCT_WRONG_CONTEXT,ALREADY_COMPLIANT,COMMENT_OR_STRING,TEST_ONLY,GENERATED_CODE, orOTHER.Save the verdicts to
artifacts/01.5-precision-verdicts-<rule_id>.json— the only artifact in this phase the agent writes by hand:
{
"schema_version": 1,
"rule_id": "<rule_id>",
"sample_artifact": "01.5-precision-sample-<rule_id>.json",
"sample_hash": "<sha256 of the sample artifact file>",
"verdicts": [
{"hit_id": "...", "verdict": "TRUE_POSITIVE", "reason": "..."},
{"hit_id": "...", "verdict": "FALSE_POSITIVE", "false_positive_class": "NOT_THE_CONSTRUCT", "reason": "..."}
]
}
Phase E — Scoring and Manifest Injection
- Score every rule that has both a sample and a verdicts artifact:
python scripts/score_pattern_precision.py --run-config artifacts/00-run-config.json
This writes artifacts/01.5-precision-report.json. There is deliberately no
--min-precision or --sample-size flag — the threshold and sample floor come
only from 00-run-config.json#precision_gate, so the agent cannot dodge a low
score by passing a laxer flag. Exit code 1 means at least one rule needs
attention (see artifacts/PRECISION_ACTION_REQUIRED.md, written only when that
happens); exit 2 means the verdicts violated the contract in step D2/D3 and
no report was written — fix the verdicts file and re-run.
If a rule comes back
REJECTED,INCONCLUSIVE, orABANDONED, readPRECISION_ACTION_REQUIRED.mdand act onnext_action:REWRITE_PATTERN— rewritepattern/patterns[]in01-extracted-rules.tmp.jsonusing the report'scounterexamplesandfalse_positive_classes, incrementpattern_revision, and repeat from Phase C (write_manifest.py) → step D1 → step D2 → step D3 → step E1. Each pattern rewrite draws an independent new sample (the seed mixes in the pattern text), so previous verdicts are never silently carried over to a changed pattern.ENLARGE_SAMPLE— re-run step D1 with the larger--sample-sizethe report suggests; nested sampling means already-judged hits keep theirhit_id, so only the newly-added hits need fresh verdicts.REJUDGE_WITH_MORE_CONTEXT— re-run step D1 with a larger--context-lines, then re-judge.HUMAN_DECISION(rule hitmax_revisions) — this is not the agent's call: either drop the rule from the manifest or ask the user for an explicitprecision_gate.overridesentry (reason+approved_by).
Re-run
write_manifest.py, now pointed at the report, to fold the score into the final manifest:
python scripts/write_manifest.py \
--input artifacts/01-extracted-rules.tmp.json \
--artifacts-dir artifacts/ \
--run-id <run_id> \
--source-version <source_version> \
--target-version <target_version> \
--precision-report artifacts/01.5-precision-report.json
01-extracted-rules.tmp.json itself must never contain a pattern_precision
or queue_eligible key — those are script-computed only and get rejected as
FORGED_PRECISION if present. The resulting manifest carries
pattern_precision (value, status, judged/true_positive/false_positive/
undecidable, Wilson interval, counterexamples) and queue_eligible per rule,
sourced only from the validated report.
- Resume the orchestrator exactly as in Phase C — it re-validates the manifest at
MANIFEST_READY, then walks the (now non-pass-through)PRECISION_GATE_READYgate, which re-checks the report against the manifest before sealing it and moving on toTOOLING_SCOUT_READY.
Halt conditions
| Condition | Action |
|---|---|
| All sources failed | Write 01-source-fetch-errors.json, set AWAITING_SOURCE_INPUT, halt |
| Agent cannot extract any rule from sources | Write empty manifest (rules: []), note in evidence map |
write_manifest.py validation fails |
Fix extracted JSON, re-run Phase C |
Constraints
- Never fabricate a rule from model priors — evidence MUST be in the read text.
confidencerated by the agent based on source quality:- Official JLS/Oracle docs → 0.90–1.0
- Secondary sources → 0.75–0.85
- Ambiguous wording → DON'T extract (reject it)
fix_strategyalways usesrecipe:prefix to enable the dispatcher.evidence_hashmust match a hash from01-source-index.json.- The agent writes the extracted rules to a temp file, then
write_manifest.pyvalidates and saves — the agent never directly writes the manifest.