Skip to content

Deletion-guard PR-body marker, BotId::Oikosbot, rhodibot link fix#298

Merged
hyperpolymath merged 1 commit into
mainfrom
claude/determined-cerf-s4zaob
Jun 20, 2026
Merged

Deletion-guard PR-body marker, BotId::Oikosbot, rhodibot link fix#298
hyperpolymath merged 1 commit into
mainfrom
claude/determined-cerf-s4zaob

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Follow-ups after the sustainabot→oikosbot extraction (#297). Companion PR: hyperpolymath/oikosbot branch claude/determined-cerf-s4zaob.

Matter 1 — Repo Integrity Guard

When #297 deleted the 98 vendored files, the guard fired and the PR was merged via override. Root cause (besides not knowing the marker): the guard's own comment promises [mass-delete-ok] works in "a commit message or the PR title/body", but the code only grepped commit messages.

  • Implement the documented PR-title/body escape hatch (via env: + grep -F, injection-safe — untrusted PR text is never eval'd). Accidental stale-base gut-merges are still blocked; only explicitly-marked intentional removals pass. The guard is not weakened — threshold and critical-file checks are unchanged.
  • CLAUDE.md invariant chore(deps): bump notify from 7.0.0 to 8.2.0 in /shared-context #7 documents the tripwire + marker convention so future cleanups are marked, not force-merged.

Matter 2b — fix rhodibot's broken sibling link

bots/rhodibot/README.adoc linked the non-existent hyperpolymath/sustainabot repo. Repointed to the in-repo slot bots/sustainabot/ and clarified it's the reserved fleet slot, not the standalone OikosBot (avoids re-creating the conflation).

Matter 2c (fleet side) — distinct identity for OikosBot

  • Add BotId::Oikosbot to shared-context so the optional oikosbot-fleet bridge can publish under its own identity instead of borrowing BotId::Sustainabot. Modelled on Custom: deliberately excluded from BotId::all(), so the bot roster and coordinator dispatch are unchanged — OikosBot is an external publisher, not a managed roster bot. (+22/−1 in bot.rs; 84 shared-context tests pass.)

Notes

  • robot-repo-automaton has a pre-existing, unrelated build error in src/detector.rs (regex is_match wants &str, gets &Vec<u8>) — present on main before this change, out of scope here.
  • I deliberately avoided running cargo fmt (the crate has pre-existing rustfmt drift); the diff is the minimal bot.rs change only.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RozeeLxpJsd3WWFngaZWz3


Generated by Claude Code

…t link fix

Follow-ups after the sustainabot→oikosbot extraction (#297).

Matter 1 — Repo Integrity Guard:
- Implement the documented-but-missing escape hatch: the guard now honours
  `[mass-delete-ok]` in the PR title/body (via env + grep -F, injection-safe),
  not only in commit messages. Accidental stale-base gut-merges are still
  blocked; only explicitly-marked intentional removals pass. The guard is NOT
  weakened (threshold and critical-file checks unchanged).
- CLAUDE.md: new invariant #7 documenting the tripwire + marker convention.

Matter 2b — fix rhodibot's broken sibling link:
- `bots/rhodibot/README.adoc` linked the non-existent `hyperpolymath/sustainabot`
  repo. Repoint to the in-repo slot `bots/sustainabot/` and clarify it is the
  reserved fleet slot, NOT the standalone OikosBot (avoids re-conflation).

Matter 2c (fleet side) — distinct fleet identity for OikosBot:
- Add `BotId::Oikosbot` to shared-context so the optional `oikosbot-fleet`
  bridge can publish under its own identity instead of borrowing
  `BotId::Sustainabot`. Modelled on `Custom`: it is deliberately excluded from
  `BotId::all()`, so the 11-bot roster and coordinator dispatch are unchanged —
  OikosBot is an external publisher, not a managed roster bot.
- shared-context: 84 tests pass.

Note: robot-repo-automaton has a pre-existing, unrelated build error in
src/detector.rs (regex `is_match` wants &str, gets &Vec<u8>); out of scope here.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RozeeLxpJsd3WWFngaZWz3
@hyperpolymath hyperpolymath marked this pull request as ready for review June 20, 2026 07:29
@hyperpolymath hyperpolymath merged commit f39d3d5 into main Jun 20, 2026
16 checks passed
@hyperpolymath hyperpolymath deleted the claude/determined-cerf-s4zaob branch June 20, 2026 07:29
hyperpolymath added a commit that referenced this pull request Jun 20, 2026
Fixes the pre-existing `robot-repo-automaton` build error noted (out of
scope) in #298.

## The bug
`Detector::detect_content_match` read file contents with `std::fs::read`
(→ `Vec<u8>`) and passed `&content` to a **string**
`regex::Regex::is_match`, which wants `&str`:

```rust
let re = regex::Regex::new(regex_str).ok()?;     // string Regex
...
if let Ok(content) = std::fs::read(file_path) {  // Vec<u8>
    if re.is_match(&content) {                   // ❌ expects &str, got &Vec<u8>
```

So the crate **never compiled**, and the entire
`DetectionMethod::ContentMatch` detection path (dispatched at
`detector.rs:149`) was dead. CI didn't catch it because the rust CodeQL
job runs build-mode `none` (buildless) — nothing in CI did a full `cargo
build`/`test` of this crate.

## The fix (one line)
Switch to `std::fs::read_to_string`. This both fixes the type error
**and** implements the *"skip non-UTF8"* intent already written in the
comment directly above the read (`read_to_string` returns `Err` on
non-UTF8 bytes, which the existing `if let Ok` skips). It matches the
sibling content scan in `hypatia.rs:433-435`, which already uses
`read_to_string` + `is_match(&content)`.

I considered `regex::bytes::Regex` instead, but that changes detection
semantics and contradicts the stated non-UTF8-skipping intent —
`read_to_string` is the smaller, intent-preserving fix.

## Regression test
Added `test_content_match_detects_and_skips_non_utf8` (this path had
**zero** coverage since it never compiled): asserts a positive regex
match is detected, a non-match yields nothing, and a non-UTF8 file is
skipped without panicking.

## Verification
- `OPENSSL_NO_VENDOR=1 cargo build` — clean.
- `cargo test` — **101 passed, 0 failed** (was 100; +1 new test).
- `cargo fmt --check` — `detector.rs` is clean. (Pre-existing rustfmt
drift in `catalog.rs`/`confidence.rs` is untouched and out of scope,
consistent with #298.)

Scope is `detector.rs` only (+58/−1, no file deletions).

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

https://claude.ai/code/session_01RozeeLxpJsd3WWFngaZWz3

---
_Generated by [Claude
Code](https://claude.ai/code/session_01RozeeLxpJsd3WWFngaZWz3)_

Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants