Harden swarm design-lens integration (0.5.1)#41
Merged
Conversation
Two UX bugs where kind:"design" findings interact badly with the --fix/--loop paths, which were written for defects: - --fix re-confirm was defect-shaped: a design suggestion has no line-local defect to re-find, so an agreed (✅) design fix got silently reported skipped-stale and never applied. Step 1 now branches on kind — for kind:"design" it re-confirms the suggestion still applies (reuse target/duplication/simpler form/waste still present), only skipping when that target is genuinely gone. - --loop never converged on design churn: the tally made no defect/design distinction, so once only design suggestions remained (F>0 ∧ A>0 ∧ C>0 every round, each simplification spawning a fresh one) it ran to the cap. loop-closeout.py step gains --defects D and a new design-only reason (fixed order: after no-change, before cap); --pending is now defect-scoped (design never holds the loop open). Omitting --defects disables the reason (legacy callers unaffected). test_loop_closeout.py extended for the design-only ordering, pending-suppression, and range-check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
In default per-cluster mode a design-cluster finder that dropped its [lens] prefix fell back to 'unspecified' → kind:"defect", so a real design suggestion rendered in the defect table, skipped applicability verify, and (since P1b) inflated the --loop defect tally that drives convergence — reintroducing the churn P1b closes. The old guard rejected inference because "guessing lenses[0] could stamp a design kind on an off-lens defect". That collapsed a real distinction: a Claude finder reviews through ONE kind-homogeneous cluster, so its kind is recoverable even when the exact lens isn't; externals carry the full 11-lens (kind-mixed) set or none, so they stay 'unspecified'/defect and keep NOT voting. - pool: untagged finding from a homogeneous Claude unit inherits that unit's kind and is marked kindTrusted; lens stays 'unspecified' (we recover the kind, not a lens we can't know). - cluster kind vote uses kindTrusted members; untaggedOnly stays lens-tagged-based, so the consensus/auto-accept invariant is untouched — only design/defect routing is corrected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
render_body unconditionally prepended "[lens] " to design rows. The workflow doesn't strip a finder's own "[lens] " self-tag from the summary, and a merge can leave the representative summary tagged with a different design lens than the cluster's resolved lens — so a row could post as "[reuse] [reuse] …" or "[reuse] [simplification] …". Add an idempotency guard keyed on a DESIGN_LENS_TAGS tuple (mirrored from LENS_CLUSTERS.design, sync-checked by test_lens_sync.py): if the cell already opens with a known design-lens tag, keep it and don't add a second. The tuple is NOT a kind fallback (the retired DESIGN_LENSES was) — it runs only inside the already-decided design branch and can never move a row between tables. A non-lens bracket ([TODO] …) is not mistaken for a self-tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
- P3: the in-session Design table gains a [lens] Befund prefix, matching the PR-comment path so lens attribution reads identically on both. - P3: document the cluster-default's loss of per-lens failure isolation as an accepted tradeoff (--max restores it; a crash is a visible backendError). - Update the swarm-review-pipeline knowledge entry for the 0.5.1 design-lens hardening (P1 --fix/--loop, P2 kind inference, P3 guard + attribution + isolation tradeoff). - CHANGELOG 0.5.1 entry; bump plugin.json + marketplace.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
External-only (codex+grok) review of this branch's own diff: - #1: pr-post's design double-prefix guard required trailing whitespace after "[lens]", so a valid but unspaced self-tag ([reuse]text, bare [reuse]) — which the workflow parser accepts — slipped past and got re-prefixed to "[reuse] [reuse]…". Align the regex to the workflow parser (/^\s*\[([\w-]+)\]/, no trailing-space requirement). - #2: the SKILL in-session Design-table skip rule suppressed the prefix only for the row's OWN lens, while pr-post suppresses any known design-lens tag — so a merged row opening with a different member's tag rendered differently on the two surfaces, contradicting the "read identically" claim. Align the wording to the pr-post guard. - #4: the "cap wins over design-only" test used defects=2, so design-only was never eligible and it never exercised the ordering. Replace with the real precedence (design-only wins over cap at the last round, defects=0) + a correctly-named cap-with-defects case. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
The branch's own external-only self-review flagged that inferring a design kind from cluster homogeneity is unsafe: a design finder is invited to report defects too, so an untagged finding from a design cluster may be a real off-lens bug. Inferring 'design' routed that bug to applicability verify (wrong rubric → can silently REFUTE/drop a real defect) and excluded it from the --loop defect tally (loop could converge design-only with a real defect still open). Dropping a real bug is the cardinal sin for a review tool and outweighs the benefit (keeping a rarer-but-lower-severity untagged design suggestion out of the defect table). Revert to the pre-0.5.1 safe default: untagged multi-lens findings fall to 'unspecified' → defect. Restores the original pool-level fallback and lens-tagged cluster-kind vote; drops kindTrusted/voters. The P3 double-prefix guard, in-session lens prefix, and P1 --fix/--loop changes are unaffected. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
The branch's second external-only self-review (CONFIRMED codex+grok) flagged that `--loop` design-only convergence terminates right after applying that round's design fixes, before any re-review — so a simplification that introduces a real defect this round is never caught. Forcing a re-review would re-open the churn design-only exists to close (design findings diverge), so the fix is explicit disclosure, not a behavior change: the SKILL close-out, loop-closeout.py's REASONS label + docstring, and the knowledge entry now state the last design edits were applied but NOT re-reviewed and recommend a fresh /swarm:review to confirm — same honesty as the cap caveat. (Round-2 finding B — the double-prefix guard keeping a self-tag that differs from the resolved cluster lens — was declined: the shown tag matches the shown text, so rewriting to the resolved lens would mislabel it; it's the deliberate anti-double-prefix tradeoff.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jo5yGBLmefV64HN26hxV8n
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
kind:"design"findings first-class: the--fix/--loop/fan-out/rendering paths were written for defects and never fully generalized to suggestion-shaped findings./code-review highon PR Extend swarm lens set to 11 lenses in 4 clusters #35.Changes
--fixre-confirm is kind-aware. Akind:"design"finding has no line-local defect to re-find, so an agreed (✅) design fix was silently reported skipped-stale. Step 1 now re-confirms the suggestion still applies for design findings (reuse target / duplication / simpler form / waste still present).--loopconverges on design churn.loop-closeout.py stepgains--defects Dand a newdesign-onlyreason (fixed order: after no-change, before cap);--pendingis now defect-scoped. Design suggestions are advisory and no longer run the loop to the cap. Omitting--defectsdisables the reason (legacy-safe).kindTrusted) even when the[lens]prefix is dropped; externals (kind-mixed 11-lens unit) stayunspecified/defect and keep not voting — the consensus/auto-accept invariant is untouched, only design/defect routing is corrected.[lens]double-prefix guard (DESIGN_LENS_TAGS, sync-checked); in-session Design table gains a[lens]prefix (matches the PR path); per-lens failure-isolation loss documented as an accepted tradeoff of the cluster default.swarm-review-pipeline.md), CHANGELOG, version bump; tests extended (test_loop_closeout.py,test_pr_post.py,test_lens_sync.py).Readiness
test_loop_closeout/test_pr_post/test_lens_syncall passcheck-structure.py: 0 errors (2 pre-existing description-length warnings, unrelated)Test plan
--loopon a diff whose only remaining findings are design suggestions terminates withdesign-only, not at the cap--fixis applied (not reported skipped-stale)[lens]prefix renders in the Design table, not the defect table[reuse]posts once, not[reuse] [reuse]🤖 Generated with Claude Code