Skip to content

fix(cli): remove duplicate Evidence import that broke the workspace build - #78

Merged
hyperpolymath merged 3 commits into
mainfrom
fix/restore-workspace-build
Sep 15, 2026
Merged

hyperpolymath merged 3 commits into
mainfrom
fix/restore-workspace-build

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

main has not compiled for five days

crates/squabble-cli/src/fight.rs imports Evidence twice:

use squabble_core::polarity::Evidence;                                   // line 16
use squabble_core::outcome::Outcome;
use squabble_core::polarity::{Applicability, Evidence, RepoDeclaration}; // line 18 -- removed
error[E0252]: the name `Evidence` is defined multiple times
  --> crates/squabble-cli/src/fight.rs:18:46

Line 18 was re-added by 327fb24 ("Apply rustfmt across Rust sources", #73, merged
2026-09-09 17:00 +0100). Every commit on main since then fails to build.

Why the whole line goes, not just the duplicate name

rustc reports all three names on that line as unused, and Applicability and
RepoDeclaration appear nowhere else in the file. Removing only the duplicated
Evidence would leave an unused_imports warning, which fails clippy -D warnings.

Why CI did not stop this

Worth recording, because the obvious reading is wrong. Rust CI did report
conclusion: failure on the breaking commit itself — run at 2026-09-09T16:00:56Z on
main. The gate was working and the failure was visible; it simply was not acted on.

From 2026-09-10T22:06 onward, every Rust CI run on this repo is a startup failure
with jobs.total_count == 0 — the run exists, no job is created, no check run is
emitted
, and so the gate stops reporting entirely. An unrepaired repo therefore looks
greener than a working one.

That is a repo-level GitHub Actions allow-list problem
(allowed_actions: "selected" with an empty patterns_allowed, which refuses the
third-party actions reached transitively through standards/rust-ci-reusable.yml), it
is not a problem with any file in this repository, and it is not addressed by
this PR. It needs a settings change, which is the owner's call.

Verification

All three run on this branch, unfiltered:

Command Result
cargo check --workspace --all-features clean
cargo test --workspace --all-features 128 passed, 0 failed
cargo clippy --workspace --all-features --all-targets -- -D warnings clean

Confirmed red before the change (E0252) and green after — one line deleted, nothing else
touched.

⚠ Because the Rust CI gate is currently startup-dead, this PR will not get a green
Rust check from CI
. The evidence above is local. Merging it restores the build; it
does not restore the gate.

🤖 Generated with Claude Code

https://claude.ai/code/session_0178nN4Nm3neFRy5K9StZKnB

…uild

`crates/squabble-cli/src/fight.rs` has imported `Evidence` twice since
327fb24 ("Apply rustfmt across Rust sources", #73, merged 2026-09-09),
which re-added a `use squabble_core::polarity::{Applicability, Evidence,
RepoDeclaration};` line alongside the existing single-name import on the
line above it.

    error[E0252]: the name `Evidence` is defined multiple times
      --> crates/squabble-cli/src/fight.rs:18:46

The workspace has not compiled on main for five days. rustc reports all
three names on the removed line as unused, and `Applicability` and
`RepoDeclaration` appear nowhere else in the file, so the whole line goes
rather than just the duplicated name -- leaving an `unused_imports`
warning would break `clippy -D warnings`.

CI did not catch this: `Rust CI` reported `conclusion: failure` on the
breaking commit itself (run 2026-09-09T16:00:56Z), but from
2026-09-10T22:06 onward every run on this repo is a startup failure with
`jobs.total_count == 0`, so the gate stopped reporting at all. That is a
separate, repo-level Actions allow-list problem and is not addressed here.

Verified on this change:
  cargo check --workspace --all-features   -> clean
  cargo test  --workspace --all-features   -> 128 passed, 0 failed
  cargo clippy --workspace --all-features --all-targets -- -D warnings -> clean

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178nN4Nm3neFRy5K9StZKnB
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 47 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 389e3708-baa1-4d91-9990-fc3f6277ee96

📥 Commits

Reviewing files that changed from the base of the PR and between 1cdadc3 and 3626792.

📒 Files selected for processing (1)
  • crates/squabble-fight/src/gate_triage.rs

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: bb5355ab-8ae1-4a87-8380-797b0d3d4d0b

📥 Commits

Reviewing files that changed from the base of the PR and between 323940a and 1cdadc3.

📒 Files selected for processing (1)
  • crates/squabble-cli/src/fight.rs

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
⚠️ CI failures not shown inline (6)

GitHub Actions: Hypatia Security Scan / 0_scan _ Hypatia Neurosymbolic Analysis.txt: fix(cli): remove duplicate Evidence import that broke the workspace build

Conclusion: failure

View job details

##[group]Run set -euo pipefail
 �[36;1mset -euo pipefail�[0m
 �[36;1m# Exactly one JSON array, with a recognised severity on every finding.�[0m
 �[36;1m# Missing/truncated output is a scanner error, never an empty clean scan.�[0m
 �[36;1mif [ ! -s hypatia-findings.json ] || ! jq -e -s '�[0m
 �[36;1m  length == 1 and (.[0] | type == "array" and all(.[];�[0m
 �[36;1m    type == "object" and (.severity as $s |�[0m
 �[36;1m      ["critical", "high", "medium", "low", "info", "informational"] | index($s) != null)))�[0m
 �[36;1m' hypatia-findings.json >/dev/null; then�[0m
 �[36;1m  echo "::error::Hypatia did not produce one valid findings array"�[0m

GitHub Actions: Static Analysis Gate / 1_Hypatia neurosymbolic scan.txt: fix(cli): remove duplicate Evidence import that broke the workspace build

Conclusion: failure

View job details

##[group]Run set +e
 �[36;1mset +e�[0m
 �[36;1mHYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json�[0m
 �[36;1mHYP_EXIT=$?�[0m
 �[36;1mset -e�[0m
 �[36;1m�[0m
 �[36;1m# --exit-zero is Hypatia's own documented CI recipe (lib/hypatia/cli.ex),�[0m
 �[36;1m# for exactly this case: "use in CI when a downstream step gates on�[0m
 �[36;1m# severity counts". Findings go to stdout, the one-line summary to�[0m
 �[36;1m# stderr, and the process exits 0 unless the SCANNER itself failed.�[0m
 �[36;1m#�[0m
 �[36;1m# Do NOT redirect stderr into the payload with `2>&1`: that folds the�[0m
 �[36;1m# summary line into the JSON, so every parse fails, the old `[]`�[0m
 �[36;1m# fallback substituted a clean result, CRITICAL was always 0, and the�[0m
 �[36;1m# gate below could never fire on any input. Keep stderr on the log.�[0m
 �[36;1mif [ "$HYP_EXIT" -ne 0 ]; then�[0m
 �[36;1m  echo "::error::Hypatia scanner execution failed with exit ${HYP_EXIT}"�[0m

GitHub Actions: Hypatia Security Scan / scan _ Hypatia Neurosymbolic Analysis: fix(cli): remove duplicate Evidence import that broke the workspace build

Conclusion: failure

View job details

##[group]Run set -euo pipefail
 �[36;1mset -euo pipefail�[0m
 �[36;1m# Exactly one JSON array, with a recognised severity on every finding.�[0m
 �[36;1m# Missing/truncated output is a scanner error, never an empty clean scan.�[0m
 �[36;1mif [ ! -s hypatia-findings.json ] || ! jq -e -s '�[0m
 �[36;1m  length == 1 and (.[0] | type == "array" and all(.[];�[0m
 �[36;1m    type == "object" and (.severity as $s |�[0m
 �[36;1m      ["critical", "high", "medium", "low", "info", "informational"] | index($s) != null)))�[0m
 �[36;1m' hypatia-findings.json >/dev/null; then�[0m
 �[36;1m  echo "::error::Hypatia did not produce one valid findings array"�[0m

GitHub Actions: Static Analysis Gate / Hypatia neurosymbolic scan: fix(cli): remove duplicate Evidence import that broke the workspace build

Conclusion: failure

View job details

##[group]Run set +e
 �[36;1mset +e�[0m
 �[36;1mHYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json�[0m
 �[36;1mHYP_EXIT=$?�[0m
 �[36;1mset -e�[0m
 �[36;1m�[0m
 �[36;1m# --exit-zero is Hypatia's own documented CI recipe (lib/hypatia/cli.ex),�[0m
 �[36;1m# for exactly this case: "use in CI when a downstream step gates on�[0m
 �[36;1m# severity counts". Findings go to stdout, the one-line summary to�[0m
 �[36;1m# stderr, and the process exits 0 unless the SCANNER itself failed.�[0m
 �[36;1m#�[0m
 �[36;1m# Do NOT redirect stderr into the payload with `2>&1`: that folds the�[0m
 �[36;1m# summary line into the JSON, so every parse fails, the old `[]`�[0m
 �[36;1m# fallback substituted a clean result, CRITICAL was always 0, and the�[0m
 �[36;1m# gate below could never fire on any input. Keep stderr on the log.�[0m
 �[36;1mif [ "$HYP_EXIT" -ne 0 ]; then�[0m
 �[36;1m  echo "::error::Hypatia scanner execution failed with exit ${HYP_EXIT}"�[0m

GitHub Actions: Static Analysis Gate / Hypatia neurosymbolic scan: fix(cli): remove duplicate Evidence import that broke the workspace build

Conclusion: failure

View job details

##[group]Run # Findings carry no `.message` (keys: action,file,line,reason,rule_module,
 �[36;1m# Findings carry no `.message` (keys: action,file,line,reason,rule_module,�[0m
 �[36;1m# severity,type), so every annotation read "null". `.file` is an absolute�[0m
 �[36;1m# runner path, which GitHub cannot anchor to the diff, so it is made�[0m
 �[36;1m# workspace-relative here.�[0m
 �[36;1mjq -r --arg ws "$GITHUB_WORKSPACE" '.[] | select(.file != null) |�[0m
 �[36;1m  (.file | ltrimstr($ws + "/")) as $f |�[0m
 �[36;1m  (.reason // .message // .type // "finding") as $m |�[0m
 �[36;1m  if .severity == "critical" then�[0m
 �[36;1m    "::error file=\($f),line=\(.line // 1)::[hypatia] \($m)"�[0m

GitHub Actions: Static Analysis Gate / Hypatia neurosymbolic scan: fix(cli): remove duplicate Evidence import that broke the workspace build

Conclusion: failure

View job details

##[group]Run echo "::error::Hypatia found 1 critical security issue(s) — blocking merge"
🔇 Additional comments (1)
crates/squabble-cli/src/fight.rs (1)

17-17: LGTM!


📝 Summary

Summary by CodeRabbit

  • Chores
    • Cleaned up internal imports; no user-visible behaviour has changed.

Walkthrough

The CLI fight module reorders the Outcome import and removes unused Applicability and RepoDeclaration imports. The Evidence import remains.

Changes

CLI import cleanup

Layer / File(s) Summary
Remove unused polarity imports
crates/squabble-cli/src/fight.rs
The module removes unused Applicability and RepoDeclaration imports. It retains Evidence and reorders the Outcome import.

Priority: ⬇️ Low

Estimated code review effort: 1 (Trivial) | ~2 minutes

Change: Bug fix

Suggested reviewers: claude

Merge Risk: ⚪ Minimal · up to 1cdad

No current-head merge-blocking risk is identified.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: removing the duplicate Evidence import that broke the workspace build.
Description check ✅ Passed The description clearly explains the build failure, the import change, the separate CI issue, and local verification results. It does not use the template headings or include the checklist, but it pro…
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🛠️ Fix failing CI checks

❌ Error running CI fixer.

  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit reads each line,
The patch grows clear beneath the moon,
Small changes hop in place,
Tests guard the garden path,
Reviews bloom before the dawn.

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Sep 14, 2026
Removing the duplicate `polarity::{Applicability, Evidence, RepoDeclaration}`
line left `polarity::Evidence` sitting above `outcome::Outcome`, which rustfmt
sorts the other way. Swapping them makes fight.rs fmt-clean.

`cargo fmt --all --check` still exits 1 on this branch AND on origin/main, for
an unrelated diff at crates/squabble-core/src/polarity.rs:183. That predates
this branch and is deliberately left alone here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0178nN4Nm3neFRy5K9StZKnB
coderabbitai[bot]
coderabbitai Bot previously approved these changes Sep 14, 2026
…er (#79)

## What is wrong

`parse_signatures` splits the directive on the bare literal:

```rust
for chunk in raw.split(SIGNATURE_TABLE).skip(1) {
```

`SIGNATURE_TABLE` is `[[gate-triage.detection.signatures]]`. The split
matches that
text **anywhere** — in prose, and inside a `#` comment.

The directive this parser reads documents its own table name in a
comment:
`.machine_readable/bot_directives/gate_triage.a2ml:174`, inside the
`[gate-triage.detection]` section that opens at line 171 — well above
the three real
headers at 258 / 265 / 272.

## Two failures, both now covered by tests that are RED against the old
parser

Grafting the two new tests onto the current parser, unchanged:

```
test gate_triage::tests::a_prose_mention_of_the_table_name_does_not_open_a_scanner ... FAILED
  left: 2
 right: 1

test gate_triage::tests::a_commented_out_header_neither_opens_nor_closes_a_table ... FAILED
  left: 0
 right: 1

test result: FAILED. 43 passed; 2 failed
```

1. **A prose or commented mention opens a phantom scanner** — `left: 2,
right: 1`.
2. **A commented-out header deletes a real scanner** — `left: 0, right:
1`. This is the
serious one. The stray match *closes* the live table above it and opens
a body which
the section-header scan then discards, so **both halves are dropped**
and the scanner
   vanishes. It does not add noise; it silently removes enforcement.

## The fix

Line-oriented. `signature_bodies` walks `split_inclusive('\n')`, strips
each line's
trailing comment via `code_of`, and treats a line as a header only when
the **code**
part is exactly the table name. A comment can then neither open nor
close a table.

`until_next_header` is retained — `section_of` still calls it, so
removing it would
trip `unused_imports`/dead-code under `-D warnings`.

Two pre-existing `assert_eq!` calls in this file are reflowed by
`rustfmt`; that is the
only churn outside the new code.

### Not fixed here, but adjacent

`extract_array` in `crates/squabble-fight/src/context.rs:152` has the
same
comment-blindness: once `collecting`, it pushes quoted strings from
every subsequent
line, comments included, until `]`. Out of scope for this PR; worth a
follow-up.

## Verification

```
cargo test --workspace --all-features                                 130 passed, 0 failed
cargo clippy --workspace --all-features --all-targets -- -D warnings  rc=0
cargo fmt --all --check                                               gate_triage.rs clean
```

`cargo fmt --all --check` still exits 1 for three diffs in
`crates/squabble-core/src/polarity.rs` — those are **pre-existing on
`main`**, unrelated
to this change, and deliberately untouched.

## Two things a reviewer should know

- **Stacked on #78.** `main` does not compile (duplicate `Evidence`
import), so this
branch is based on the build repair. Base retargets to `main`
automatically when #78
  merges.
- **CI will not produce a green Rust check.** The `Rust CI` workflow in
this repo is
startup-dead — runs are created with `jobs.total_count == 0` and emit no
check run at
all, so the required context never reports. The evidence above is local.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_0178nN4Nm3neFRy5K9StZKnB

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

ℹ️ Nothing to fix from this PR. All 2 failing check(s) are already failing on main, so they aren't caused by your changes.

⏭️ 2 check(s) skipped — already failing on `main` (not caused by this PR)
  • GitHub Actions: Hypatia Security Scan / 0_scan _ Hypatia Neurosymbolic Analysis.txt
  • GitHub Actions: Static Analysis Gate / 3_Hypatia neurosymbolic scan.txt

These need to be addressed on main (or by whoever owns them), not in this PR.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Rate Limit Exceeded

@hyperpolymath have exceeded the limit for the number of chat messages per hour. Please wait 25 minutes and 8 seconds before sending another message.

@hyperpolymath
hyperpolymath merged commit 56eab36 into main Sep 15, 2026
24 of 26 checks passed
@hyperpolymath
hyperpolymath deleted the fix/restore-workspace-build branch September 15, 2026 12:04
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.

1 participant