fix(harness-ops): score a built-in plugin surface a filtered entry named first - #5792
Conversation
…med first native_surfaces() added a name to `seen` before dropping an empty or `internal` entry, so a later built-in plugin or plugin component of the same name was skipped as a duplicate and never scored. Mark a name seen only when its entry is kept. Closes #5766 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 41s —— View job Security review —
|
|
Claude finished @kyle-sexton's task in 2m 9s —— View job Reviewing PR #5792
SummaryReviewed the diff against The fix (overlap.py#L465-L471) moves
The test ( Changelog/version bump: 1.0.1 → 1.0.2 (patch) with an accurate description of the fix and its (lack of) impact on the 2.1.287 extraction — consistent with the fix. Nothing else in the 4 changed files stood out as a correctness or maintainability concern. Not independently verified: I was not able to execute the test suite, ruff, or |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ff5bd2b2cb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
A name dropped as internal or empty no longer claims a built-in plugin's name, but it must still keep the plugin_backed fallback from fabricating an unmarked surface for it. Track filtered names separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 48s —— View job Security review —
|
|
Claude finished @kyle-sexton's task in 2m 14s —— View job Code review —
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 33090d1812
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
build_native_index kept the first lane's entry with setdefault even when it was internal or empty, so a seeded pair or dismissal for a name a built-in plugin component rescued read the filtered registration. Share one is_filtered rule between the index and native_surfaces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep it up! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…r-filter-5766 # Conflicts: # plugins/harness-ops/.claude-plugin/plugin.json # plugins/harness-ops/CHANGELOG.md
|
@codex review |
|
Claude finished @kyle-sexton's task in 48s —— View job Security review —
|
|
Claude finished @kyle-sexton's task in 3m 27s —— View job Code review —
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf7919a773
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Resolve version and CHANGELOG conflicts with #5781, #5789, #5765 and #5792: harness-ops stays 2.0.0 and work-items 0.44.0; harness-config moves to 1.2.1, instruction-placement to 0.18.2 and source-control to 0.71.6 so this branch's entries sit above main's released ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…scores (#5820) Closes #5799 ## Summary `overlap.py detect` reads seeded pairs and dismissal drift from `build_native_index()`, but discovery scores the surfaces `native_surfaces()` emits. The two picked different registrations in two cases: 1. **The #5799 case.** The index replaced a filtered (empty or `internal`) held entry only with a built-in plugin component. With an internal bundled skill, a valid built-in command and a built-in plugin component of one name, the index ended on the plugin component while `native_surfaces()` scored the command. 2. **A second divergence found while confirming the rules.** The index walked lanes as workflow, skill, command, agent, tool, plugin; scoring walks `LANE_ORDER` (command, skill, workflow, agent, tool, plugin). `native_surfaces()` scores every unfiltered ordinary-lane entry, and `keyed()` in `cmd_detect` collapsed same-name pairs last-wins. So a name valid in two lanes read its score from the last lane while the index held the first. On 2.1.287 this applies to `fork`: it is both a built-in command and a built-in agent, and the seeded `fork` pair took its score from the agent surface while its class and verdict name the command. ## Fix - `build_native_index()` walks `LANE_ORDER`, skipping `plugin_backed`. It holds the first unfiltered entry for each name; a name with only filtered entries keeps its first entry. The `plugin_backed` override at the end is unchanged. It already reclassifies whatever entry is held, which matches `native_surfaces()` scoring an enriched name under the plugin-backed class with that lane's registrations. - `keyed()` keeps the first surface's pair for each `(name, component)` key. That is the earliest lane, the same registration the index holds. - harness-ops 1.2.0 -> 1.2.1, with a CHANGELOG entry. ## Verification - New tests in `test_overlap.py`: - `test_a_filtered_entry_yields_to_a_later_ordinary_lane`: internal bundled skill, valid built-in command and built-in plugin component; asserts index lane == scored lane. - `test_the_index_holds_the_surface_scored_first_in_every_lane_mix`: table over every absent/valid/internal mix of the six scored lanes; asserts index lane == lane of the first surface scored for the name (the first lane present when none is scored). - `test_a_name_scored_in_two_lanes_reports_the_indexed_surface`: a detect run with one name in the command and agent lanes; asserts the discovered candidate's class equals the index class. - Fail before: run against origin/main's `overlap.py`, all three fail (466 failures counting subtests). Pass after: all 195 tests pass. - `overlap.py detect` on a fresh `inventory.py --binary-only` extraction (2.1.287), before and after: discovered 0/0, resurfaced 0/0, orphaned 0/0, seeded 29/29, existing 34/34, suppressed 111/111. No candidate was added or removed. The only change is the seeded `fork` -> `session-flow:continue-in-background` pair: its score goes from 0.0448 to 0.057 and its matched tokens become `background, agent`. - `overlap.py generate` and `node scripts/generate-catalog.mjs` leave the tree unchanged. `overlap.py self-check` is degraded only because of its existing version and upstream-SHA advisories. - `scripts/run-ruff.sh check` passes. `format --check` reports nothing in the changed files; the 85 files it does flag repo-wide were already unformatted on main. - `scripts/check-changelog-parity.sh --check-bump origin/main` and `--check-order` pass, as does `node scripts/validate-plugin-contracts.mjs`. ## Related - #5792 (introduced the plugin-component replacement this generalizes) - #5766 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Closes #5766
Summary
overlap.py'snative_surfaces()added a name toseenbefore dropping an empty orinternalentry. A later built-in plugin or plugin component with the same name was then skipped as a duplicate, so that name had no scorable surface and its overlap candidates were silently missed.Fix
seen.add(name)below the empty/internalfilter inplugins/harness-ops/skills/audit-native-overlap/scripts/overlap.py, so only a kept entry claims its name.test_a_filtered_earlier_entry_does_not_claim_a_plugin_nameintest_overlap.py: an internal and an emptybuiltin_commandsentry nameddiff, plus the same-named built-in plugin command, and asserts thebuiltin_pluginssurface is scored.Verification
overlap.test.sh);test_native_drift40 OK.overlap.py detectbefore/after, identical reports on both inventories:.work/cc-2.1.287/inv-final.json(nobuiltin_pluginslane): discovered 0, resurfaced 0, orphaned 14, seeded 24, suppressed 97, surfaces 238.builtin_plugins): discovered 0, resurfaced 0, orphaned 0, seeded 24, suppressed 111, surfaces 256.overlap.py generateandnode scripts/generate-catalog.mjs: no changes.overlap.py self-check: degraded (2 pre-existing version/upstream-SHA advisories).scripts/run-ruff.sh checkandformat --check,node scripts/validate-plugin-contracts.mjs,typos: clean.Related
🤖 Generated with Claude Code