Skip to content

fix(discovery): constrain applies_to in the research-sweep schemas and synthesis - #10815

Merged
melodic-automation-lanes[bot] merged 2 commits into
mainfrom
work-resolve-issue/issue-9810-40792526956-1
Oct 29, 2026
Merged

melodic-automation-lanes[bot] merged 2 commits into
mainfrom
work-resolve-issue/issue-9810-40792526956-1

Conversation

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor

Closes #9810

Summary

Opened by the work-resolve-issue lane. The run's own summary:

The research-sweep workflow typed every applies_to as a bare string, so free-text values reached the deep-tier artifact and failed criterion 13. Each applies_to field in the read, consolidate and synthesis schemas now carries the grammar as a pattern. A new appliesToOk() mirrors check-source-applicability.py's APPLIES_TO and applies_to(), including the low-to-high range check. Synthesis checks each surviving finding and cited source. A non-conforming value is re-asked of the synthesizer once, with the grammar named, and a value that still fails is recorded unstated with its raw text appended to the finding's qualifiers, per the recorded decision.

Not verified

  • plugins/discovery/tests/research-sweep.test.mjs was not executed in this run (the lane runs no node; check-affected's output does not name it), so the new and changed cases are left to the PR's CI.
  • Replay check from the issue (a full deep-tier sweep transcribed per deep-tier.md step 5, then check-source-applicability.py exits 0) is a person's check per the recorded decision: it is a large model spend.
  • Tidy pass 4 (ai-slop fix) ran as a rubric read only: detect.sh, the semantic-diff verify subagent and the findings file were not run, because this lane's Bash permits only the named wrappers. Tidy passes 1 to 3 ran: no code edits or comment deletions were warranted, and the fragment got one passive-
  • Review residue not changed: JS trim()/\s treat U+FEFF as whitespace where Python does not, and Number() loses precision above 2^53, so a few exotic values could pass appliesToOk() and still fail the gate. The re-ask also swallows cap or budget errors (keeping round one) where the first synthesize ca
  • Untracked placeholder files appeared in the checkout root during the run (.bash_profile, .bashrc, .gitconfig, .idea, .mcp.json, .profile, .ripgreprc, .vscode, .zprofile, .zshrc). This run did not create them; they look like sandbox mount points. They are not part of this change and should be left ou

Fix

  • plugins/discovery/workflows/research-sweep.js: APPLIES_TO_RULE prompt text (DATED now reuses it); APPLIES_TO_FIELD schema with a pattern on the five applies_to fields; appliesToOk() mirroring the Python gate's grammar; offGrammar() and a single synthesize:r2 re-ask naming the grammar and the offendi
  • plugins/discovery/tests/research-sweep.test.mjs: the fetch-entries fixture now uses conforming applies_to values, since the new check reaches it (the invented c99 'x' stays as is); new cases cover the schema patterns, conforming values passing through with no re-ask, the free-text re-ask plus unstat
  • .changes/discovery/fix-9810-research-sweep-applies-to-4c7e19a2.md: patch changelog fragment for discovery (written by hand: new-changelog-fragment refuses a detached HEAD).

Verification

The runner ran each check from the base copy against 78b9964:

  • scripts/check-changelog-fragments.sh --check: passed

The run reports:

  • check-changelog-fragments: all 2 fragments valid (run before and after tidy and review fixes)
  • check-affected: 11 passed, 7 skipped, no failures over the 3 changed files (run before and after tidy and review fixes)
  • fresh-context review subagent (opus) over the whole diff: it confirmed the regex and version compare match the Python gate and that no existing test breaks. It found a junk qualifier on an already-unstated value and that a partial re-ask dropped first-round findings, and both are fixed with tests. I
  • The lane run: https://github.com/melodic-software/claude-code-plugins/actions/runs/40792526956

Left out: the items under Not verified.

Related

#9810

Lane-Activity: work-resolve-issue/resolve-issue
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 329f63201cd1c4086c20f68c85f7db02a7c34f81: 0 finding(s), 0 as inline comments.

No security issues found in the incremental change (plugins/discovery/workflows/research-sweep.js and its test).

The change keeps a first-round applies_to that fits the grammar when the round-two re-ask returns one that doesn't, for the finding and for each of its sources matched by url. It is pure in-memory data handling over the synthesizer's output.

  • It adds no command execution, file or network access, token or secret handling, or template injection.
  • It touches no trust control, trusted path, gate or plugin manifest.
  • The Map is keyed by model-supplied urls and the object spread copies model output into a plain object. Neither reaches a privileged sink, and the spread assigns own properties only, so there is no prototype-pollution path.
  • The re-ask still runs the same schema and appliesToOk checks as before, so this change cannot loosen validation of what reaches the deep-tier artifact.

critical-findings: 0

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

claude-review: 1 inline finding(s) on 78b996480a2fcfa2a4e87792a47c4704d4e8276e; the summary is in this lane's pull request comment.

claude-lane: claude-review

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed 329f63201cd1c4086c20f68c85f7db02a7c34f81: 0 finding(s), 0 as inline comments.

Incremental review of research-sweep.js and research-sweep.test.mjs since 78b9964. I found nothing to flag.

What changed. After the synthesize:r2 re-ask, a first-round applies_to that is in the grammar is now kept over a round-two value that is outside it. This applies to each finding and to each of its sources, matched by url.

What I checked.

  • first is only read when off.length > 0. That implies synthesis is non-null and synthesis.findings is an array, so line 758 cannot throw.
  • conforming(v, was) returns the round-two value unless it is off-grammar and the first-round value is in the grammar. When both are off-grammar, the round-two value goes on to settled(), which records unstated and appends the raw text to qualifiers.
  • Sources the first round did not have, and findings with no first-round counterpart, pass through unchanged.
  • I traced the new test through the code. c1 triggers the re-ask and takes round two's version-independent. c2 keeps x 1+ at the finding level and x 2.1 at the source level, and ['q'] is the expected qualifier. The assertions match what the code does.

Not run. I did not run the tests; this lane has no shell. Whether the test file passes is left to CI.

Spend. The re-ask costs at most one extra synthesizer call per sweep. It draws on prepaid or subscription usage only, so it is not a hold.

Closing issue #9810. The criteria about the schema pattern, the appliesToOk check, and a fixture feeding a free-text value through synthesis were reviewed in the earlier pass. This increment adds a test for the partial-conformance case. The replay check is left to a person, as the issue's recorded decision says.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

pr-unblock / address-feedback finished round 1 of max 4 on 78b9964.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The pr-unblock lane stopped address-feedback on this pull request: a fix the lane recorded did not reach the branch, so none of its review replies was posted. The lane sets no label: the run ends in a failing pr-unblock/address-feedback status on the head the lane gated.

When a retry on this head can change the outcome, the lane runs one on its own, up to its per-head cap, and edits this comment if it stops again; a run that does not stop clears the status. When no retry can (a review thread the lane does not take or settle, or a failing check after the retries are spent), a person resolves the threads or gets the checks green, then dispatches the workflow below: that run finds the cause gone and clears the status. On a pull request the lanes App opened, the dispatchers start that run once per stop; on any other, a person does. A new commit to the branch starts clean.

To run it again on this head now, dispatch the pr-unblock workflow:

gh workflow run pr-unblock.yml -R melodic-software/claude-code-plugins -f pr-number=10815 -f activity=address-feedback

Lane-Activity: pr-unblock/address-feedback
Lane-Thread: PRRT_kwDOTCGFQM6xYGaF
@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

pr-unblock / address-feedback finished round 2 of max 4 on 329f632.

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

Unattended merge: native auto-merge leaves this pull request unarmed at head 329f63201cd1c4086c20f68c85f7db02a7c34f81. The lanes clear this reason on their own; the next scheduled run judges it again.

pr-merge's gate refuses its verifier verdict (verify:missing)

@melodic-automation-lanes

Copy link
Copy Markdown
Contributor Author

The unattended merge path armed native auto-merge at head 329f63201cd1c4086c20f68c85f7db02a7c34f81.

@melodic-automation-lanes
melodic-automation-lanes Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 2d8e5b1 Oct 29, 2026
40 checks passed
@melodic-automation-lanes
melodic-automation-lanes Bot deleted the work-resolve-issue/issue-9810-40792526956-1 branch October 29, 2026 03:52
@github-actions

Copy link
Copy Markdown
Contributor

Post-merge mutation testing

Killed 6, survived 1, timeout 0, no coverage 0, invalid 0, not run 0.
Covered-code score 86%; mutation score 86%.

File Killed Survived Timeout No coverage Invalid Not run
plugins/discovery/workflows/research-sweep.js 6 1 0 0 0 0

Surviving mutants

Location Operator Disposition Cause
plugins/discovery/workflows/research-sweep.js:759 LCR productive input-gap

The run's summary has the full report.

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.

fix(discovery): constrain applies_to in the research-sweep schemas so deep-tier artifacts pass criterion 13

0 participants