Repository navigation
Conversation
Reimplement GitHub #12 / Linear RM-127 in Rust after the Python orchestrator was removed. The store is a separate file from job-status watched.json, with add/remove/list/check/check-all, atomic writes, quarantine of corrupt state, and allowlisted check-all. Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 19 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (29)
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. Comment |
There was a problem hiding this comment.
This PR successfully implements persistent multi-owner PR watchlist state in Rust. The implementation shows strong attention to detail with atomic file operations, proper error quarantining, POSIX file mode security (600), comprehensive test coverage, and well-structured error types.
Key strengths:
- Atomic temp-file + rename pattern prevents partial writes
- Corrupt files are quarantined rather than silently overwritten
- Schema versioning with forward compatibility checks
- Comprehensive test coverage including edge cases
- Proper security with file mode 600 for sensitive PR titles
Critical issue identified:
One security vulnerability requires attention: the quarantine operation has a TOCTOU (time-of-check-time-of-use) race condition between checking file existence and renaming. This should be fixed to use atomic operations.
All tests pass (cargo test, cargo clippy, cargo fmt), and the feature is well-documented in SKILL.md and watchlist-schema.md.
You can now have the agent implement changes and create commits directly on your pull request's source branch. Simply comment with /q followed by your request in natural language to ask the agent to make changes.
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Security | 1 high |
🟢 Metrics 0 complexity · 53 duplication
Metric Results Complexity 0 Duplication 53
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
…ding Address independent review of the watchlist store: empty status rollups are pending, each check is saved before the next gh call, Windows replaces an existing file, filtered check of a disallowed owner is rejected, and stack identity walks the parent chain regardless of add order. Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
|
You have reached your Codex usage limits for security reviews. Please try again later. |
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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: befd6761f3
ℹ️ 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".
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
Bugbot Autofix prepared fixes for all 3 issues found in the latest run.
- ✅ Fixed: Check succeeds for missing entries
- select_check_targets now validates --repo and returns NOT_FOUND when a requested number is not on the watchlist.
- ✅ Fixed: Repo identity is case-sensitive
- Repo identity and --repo filters now compare owner/name slugs with eq_ignore_ascii_case so mixed-case GitHub slugs match one row.
- ✅ Fixed: Startup failures mark PRs healthy
- classify_snapshot treats STARTUP_FAILURE and STALE conclusions as failing checks instead of falling through to healthy.
You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit befd676. Configure here.
`watchlist check --repo` now returns NOT_FOUND for absent identities and rejects malformed slugs instead of succeeding on an empty target set. Repo identity compares owner/name case-insensitively so mixed-case GitHub slugs cannot duplicate or miss a row. STARTUP_FAILURE and STALE rollup conclusions classify as failed rather than healthy. Agent: Cursor Grok 4.6 Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
Address substantive bot review findings on PR #190: - store: crash-safe Windows replace_file (backup/restore, never zero copies) - store: create temp file with mode 0600 at creation time on Unix - store: quarantine_corrupt uses a rename loop instead of exists() precheck - ops: treat empty CheckRun conclusion/state/status as absent (in-progress no longer looks healthy) - ops: classify mergeable UNKNOWN/empty and draft PRs as Pending - ops: bounded gh probe via SafeGhCommand::run_with_timeout mapped to WatchlistError::Timeout (self-contained, no async supervisor rewrite) - ops: import_pr_babysit rejects malformed repo identities and refreshes existing entry source fields while preserving fix_count Adds unit tests for each; fmt/clippy/test gates green.
…st biomarkers - write_add takes a command name so import-pr-babysit emits watchlist.import_pr_babysit instead of watchlist.add - entry_json now includes stack_type (additive, v1-compatible) - detect_stacks picks the lowest PR number on head-branch collisions for deterministic parent inference (cycle-safe walk preserved) - extract classify_readiness/checks/review, compute_parents/ assign_positions/walk_to_root, insert_or_refresh_entry (AddContext), CheckScope/validate_check_scope, is_valid_slug, accept_parsed/ quarantine_and_report, and CLI run_add/add_report_is_empty to cut CodeScene complexity/arg-count/bumpy-road biomarkers, behavior intact - dedupe watchlist_cli tests via run_json/write_sample helpers
|
🤖 Review skipped: Repository rate limit exceeded. Free accounts are limited to 2 reviews per 4 hours per repository. Upgrade to a paid plan for unlimited reviews. |
Bot comments addressed (45 inline across 5 reviewers)Substantive fixes (persistence, classification, gh probe)
Already fixed at HEAD (cursor[bot], verified present)
codescene-access (26 biomarkers)Addressed by behavior-preserving extraction: Not applicable
Verification (Linux)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18e0a46c53
ℹ️ 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".
Keep the watchlist persistence work together with main's hook, lease, and fork-PR import changes. Conflicts were resolved by preserving both sides. Agent: Cursor Grok 4.6 Co-authored-by: Grok <noreply@x.ai> Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Raul Montoya Cardenas <montoyaraul34@gmail.com>
Add writ-core and in-crate CLI unit tests for error display, import/probe paths, reset/timeout refresh, and gh run_with_timeout fast-fail. Split watchlist CLI dispatch and pr-babysit import helpers for maintainability. Use target/ scratch dirs in tests instead of system temp_dir. Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
|
RM-127 owner direction (2026-09-21) retargets this as a view over Continuation after rebase onto current main (#199/#197): #200 ( This PR (#190) is left in place; I am not merging or closing it from this session. Agent: Cursor Grok 4.6 |
Retarget RM-127 / PR #190 as a consumer of the shared SQLite lease store instead of a competing watchlist.json. list/check/check-all compose lease ownership, optional coord_claims/messages, recovery, and live GitHub PR overlay. add/remove do not persist. Local collab_status is independent of GitHub check_status and is not a merge gate. Coord tables are read when present and skipped when absent (RM-825 owns that schema). Refs: Linear RM-127, RM-825, RM-116 Agent: Cursor Grok 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
Retarget RM-127 / PR #190 as a consumer of the shared SQLite lease store instead of a competing watchlist.json. list/check/check-all compose lease ownership, optional coord_claims/messages, recovery, and live GitHub PR overlay. add/remove do not persist. Local collab_status is independent of GitHub check_status and is not a merge gate. Coord tables are read when present and skipped when absent (RM-825 owns that schema). Refs: Linear RM-127, RM-825, RM-116 Agent: Cursor Grok 4.6 Co-authored-by: Cursor <cursoragent@cursor.com>
…istent-state-81d0 Amp-Thread-ID: https://ampcode.com/threads/T-01a1014a-23d3-721b-adf3-ff6fe4f0f31b # Conflicts: # AGENTS.md # README.md # REVIEW.md # SKILL.md # crates/writ-core/src/git_safe.rs # crates/writ-core/src/lib.rs # crates/writ-core/src/state.rs # crates/writ-core/src/watchlist/classify.rs # crates/writ-core/src/watchlist/mod.rs # crates/writ/src/main.rs # crates/writ/src/watchlist.rs # crates/writ/tests/watchlist_cli.rs # docs/examples/README.md # docs/status-schema.md # docs/watchlist-schema.md # docs/workflows/safe-issue-verified-commit.md # docs/workflows/safe-verified-commit-to-pr.md
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 108a912a0b
ℹ️ 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".
| .iter() | ||
| .enumerate() | ||
| .filter(|(j, other)| { | ||
| *j != i && repos_match(&other.repo, &entry.repo) && other.branch == base |
There was a problem hiding this comment.
Distinguish fork heads when inferring stack parents
When two watched PRs target the same repository, this predicate treats any matching head branch name as the parent even if that head belongs to a fork. For example, a fork PR whose head is release is falsely made the parent of an unrelated PR based on the upstream repository's release branch, corrupting the persisted group and bottom-up check order. The replaced probe retained headRepositoryOwner, and gh pr view --help confirms that field is available; request and store it so only a head in the base repository can satisfy this parent match.
AGENTS.md reference: AGENTS.md:L24-L24
Useful? React with 👍 / 👎.
Amp-Thread-ID: https://ampcode.com/threads/T-01a1014a-23d3-721b-adf3-ff6fe4f0f31b Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a1014a-23d3-721b-adf3-ff6fe4f0f31b Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
Amp-Thread-ID: https://ampcode.com/threads/T-01a1014a-23d3-721b-adf3-ff6fe4f0f31b Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Security | 1 high |
🟢 Metrics 0 complexity · 53 duplication
Metric Results Complexity 0 Duplication 53
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Amp-Thread-ID: https://ampcode.com/threads/T-01a1014a-23d3-721b-adf3-ff6fe4f0f31b Co-authored-by: Raul Cardenas Montoya <montoyaraul34@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a10fb7603
ℹ️ 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".
| Err(err) if err.kind() == io::ErrorKind::NotFound => { | ||
| if !recover_replacement_backup(path)? { | ||
| return Ok(Watchlist::default()); |
There was a problem hiding this comment.
Avoid backup recovery during an active Windows replacement
On Windows, a read-only list can hit this NotFound branch after replace_file has renamed the destination to .bak-replace but before it installs the temporary file. Because reads do not acquire the sidecar lock, the reader restores the backup to the canonical path and removes the backup; the writer's subsequent fs::rename(from, to) then fails because the destination exists, causing an otherwise valid concurrent mutation to return IO_ERROR. Coordinate recovery with the writer lock or use a replacement scheme whose transient missing path cannot be mistaken for crash recovery.
Useful? React with 👍 / 👎.
| if parent[i].is_none() && !has_child[i] { | ||
| list.prs[i].stack_id = None; | ||
| list.prs[i].stack_type = None; | ||
| list.prs[i].stack_position = None; |
There was a problem hiding this comment.
Preserve imported stack annotations across later refreshes
When an import contains a partial or otherwise non-inferable stack, the import path now restores its source stack_id and stack_position, but every subsequent add, remove, or check calls detect_stacks again and this branch clears those annotations whenever no watched parent/child relation is currently visible. ordered_identities then falls back to repository/PR-number sorting, so later check cycles can lose the imported bottom-up order. Fresh evidence after the earlier import fix is that these later detection calls have no corresponding restoration step; retain explicit annotations until a complete inferred chain supersedes them.
AGENTS.md reference: AGENTS.md:L24-L24
Useful? React with 👍 / 👎.
| let github_state = snapshot.state.to_ascii_uppercase(); | ||
| if github_state == "MERGED" || github_state == "CLOSED" { | ||
| report | ||
| .skipped | ||
| .push((repo.to_owned(), number, snapshot.state.clone())); | ||
| return; |
There was a problem hiding this comment.
Remove an existing entry when add finds it closed
When add is used to refresh an identity already on the watchlist and GitHub now reports it as MERGED or CLOSED, this early return records the PR as skipped but leaves the existing entry untouched. The command can therefore report that the closed PR was skipped while list continues to expose its stale pre-closure status until a separate check cycle happens to prune it; remove a matching existing entry here and recompute its stack metadata.
Useful? React with 👍 / 👎.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Gates Failed
New code is healthy
(2 new files with code health below 10.00)
Enforce critical code health rules
(1 file with Low Cohesion)
Enforce advisory code health rules
(2 files with Excess Number of Function Arguments, Large Method, String Heavy Function Arguments, Large Assertion Blocks)
Our agent can fix these. Install it.
Gates Passed
3 Quality Gates Passed
Reason for failure
| New code is healthy | Violations | Code Health Impact | |
|---|---|---|---|
| ops_tests.rs | 4 rules | 7.45 | Suppress |
| ops.rs | 1 rule | 9.69 | Suppress |
| Enforce critical code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| ops_tests.rs | 1 critical rule | 7.45 | Suppress |
| Enforce advisory code health rules | Violations | Code Health Impact | |
|---|---|---|---|
| ops_tests.rs | 3 advisory rules | 7.45 | Suppress |
| ops.rs | 1 advisory rule | 9.69 | Suppress |
Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

Important
Current owner direction (2026-09-21): this PR is a view/consumer, not a second coordination authority. RM-825 owns shared Rust/SQLite coordination state. Preserve useful watchlist/status work, but remove or avoid duplicate state/schema that competes with RM-825. Harnesses own checkouts; writ registers/coordinates them. Normal assigned-branch local integration is allowed. Linear/RM-116 is current task steering; do not revive Python orchestration, GitHub issue mirroring, or a new merge gate.
User description
Update (RM-116 alignment + CI fixes)
Session
bc-f3cdb75foncursor/watchlist-persistent-state-81d0.Scope preserved:
writ watchlistremains a visibility surface for multi-owner PR state (watchlist.json), not a scheduler, permission store, or merge gate. Coordinated on Linear with RM-825 (lease/message contract consumer only) and RM-145 (status shape alignment — watchlist stays external PR visibility, separate from lease/job rows).Head:
f0138da— focused coverage + maintainability without silencing checks:watchlist::run(list/add error/remove human paths)WatchlistErrordisplay/codes, import/probe edge paths,--reset, timeout refresh,run_with_timeoutfast-failtarget/instead oftemp_dirwhere flaggedLocal patch coverage (merge-base diff,
cargo llvm-cov): 87.26% (was ~77.7% on Codecov report).Not in this PR: RM-825 shared inbox schema, RM-145 AGENTS simplification, GitHub settings/merge.
Linear Issue: RM-127
Summary by cubic
Implements Linear RM-127 by persisting the multi-owner PR watchlist in a separate versioned
watchlist.json(distinct fromwatched.json), sowrit statusandwrit jobskeep their JSON-array read path. The watchlist is external GitHub PR visibility only, never coordination authority.New Features
writ watchlist add|remove|list|check|check-all|import-pr-babysit; import refreshes source fields and preservesfix_count.(repo, number)identity with case-insensitive repo comparison and includestack_type;adduses allowlistedgh pr view, skips MERGED/CLOSED, and preservesfix_countunless--reset.check-allrequiresWRIT_ALLOWED_OWNERS(orWH_ALLOWED_OWNERS), refreshes status/residuals/check count, prunes MERGED/CLOSED, and never incrementsfix_countor spawns babysit workers.ghcall.{user_data}/writ/watchlist.jsonwith legacy fallback andWRIT_WATCHLIST_PATH/WH_WATCHLIST_PATHoverrides.Written for commit ff6c874. Summary will update on new commits.
CodeAnt-AI Description
Add persistent multi-owner PR watchlist commands
What Changed
writ watchlistcommands to add, remove, list, check, check all, and import pull requests from existing babysit state.watchlist.json, support owner and repository filters, preserve stacked PR relationships, and recognize case-insensitive repository identities.Impact
✅ Persistent PR tracking across check cycles✅ Safer multi-owner check-all scope✅ Clearer pending, failure, conflict, and timeout status✅ Recovery from corrupt watchlist files💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.