feat(ops): PR Hedge Trim skill — automated CodeRabbit thread resolution - #941
Conversation
- Coverage: 96.6% (down from 100%) - New commands added without parity updates: chit:review-sweep, chit:sign-trail, docs:reconcile, tac:review - Timestamp updated from 2026-02-28 to 2026-03-13 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… tree **PMOVES-a0-plugins Submodule:** - Adds POWERFULMOVES/PMOVES-a0-plugins as submodule - Tracks PMOVES.AI-Edition-Hardened branch for security hardening - Enables curated plugin ecosystem for Agent Zero customizations - README includes PMOVES.AI-specific integration patterns: - TensorZero Gateway (port 3030/3000) for all LLM calls - NATS (nats://nats:pmoves@nats:4222) for event coordination - Hi-RAG v2 (port 8086/8087) for knowledge retrieval - Archon (port 8091) for prompt management - Security: non-root containers, healthchecks, metrics, CHIT **Agent Zero Customization TAC Tree:** - 50 checks across 9 phases for comprehensive review - 100% pass rate validates: - TensorZero integration and model naming format - Extension system proper use (23 extension points) - PMOVES.AI service leverage (not duplication) - Docker hardening (tier-agent-hardened anchor) - Observability (healthz/metrics endpoints, NATS heartbeat) - 4-tier context loading strategy - Plugin ecosystem integration - Subordinate agent model - Tools & prompts customization patterns Related: Agent Zero customization documentation and integration patterns
- PMOVES.AI_INTEGRATION.md: Complete service integration reference - QUICKSTART.md: 15-minute getting started guide This documentation provides: - Service connection details (TensorZero, NATS, Hi-RAG, Archon, Neo4j) - MCP API usage examples - Extension system guide (23 lifecycle hooks) - Security hardening patterns - Troubleshooting section Related: Agent Zero TAC tree (50/50 checks passing) Related: PMOVES-a0-plugins submodule initialization
**Plugin Added:** pmoves-notes-integration - Repository: https://github.com/POWERFULMOVES/a0-plugin-pmoves-notes - Branch: PMOVES.AI-Edition-Hardened **Plugin Features:** - Auto-save conversation summaries (message_loop_end extension) - Save reasoning traces to memory (monologue_end extension) - Manual tools: save_note, search_notes - NATS events: agent.notes.saved.v1, agent.notes.searched.v1 - Open Notebook integration (SurrealDB knowledge base) **TAC Review Results:** - Agent Zero Customization Review: 50/50 passing (100%) - All 9 phases validated successfully Related: Agent Zero integration documentation Related: PMOVES-a0-plugins submodule initialization
- Simplify NATS subject pattern: agent\.task\.|agent\.subordinate\. → agent\.task|agent\.subordinate - Update description to explicitly state "across 9 phases (51 checks)" - Removes unnecessary escape before pipe operator - More robust pattern matching for NATS subjects Suggested by code review feedback - all 50 checks still passing.
- Fix playwright default port: 3100 → 4482 (matches docker-compose) - Fix base64url decoding in boot-jwt route (JWT uses -/_ instead of +/) - Add spawn error handler to with-env.mjs These fixes were applied to all UI Testing PRs (#908-#913). PR branches will rebase onto main to pick up these core fixes.
Keep v1.2.0 TAC tree (newer), adopt robust base64url padding for JWT decode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…w threads New /pr-trim skill with 4-way classification (actionable / design-decision / false-positive / nitpick), GraphQL resolveReviewThread mutation, Make targets, NATS event schema, FlOO$ chain integration, and agent registry entry. Tested: 36 threads resolved across PRs #935-938 in batch trim session. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughAdds a PR Hedge Trim feature: new CLI tool to classify/fix PR review threads, NATS topic and JSON schemas for trim completion, agent and skill registry entries, make targets, docs, and packaging for producing JSON/Markdown trim artifacts and publishing ops.pr.trim.completed.v1 events. Changes
Sequence DiagramsequenceDiagram
autonumber
participant User as "User"
participant Make as "Make Target\n(pr-trim)"
participant CLI as "PR Hedge Trim CLI\npr_hedge_trim.py"
participant GH as "GitHub GraphQL API"
participant NATS as "NATS Broker"
User->>Make: make pr-trim PR=123 REPO=org/repo
Make->>CLI: analyze --pr 123
CLI->>GH: Query unresolved review threads
GH-->>CLI: Threads + comments
CLI->>CLI: Classify threads
CLI-->>Make: Save JSON artifact / show summary
Make->>CLI: resolve --pr 123
CLI->>GH: Mutation: resolve selected threads
GH-->>CLI: Mutation responses
CLI-->>Make: Resolved count
Make->>CLI: report --pr 123
CLI->>CLI: Generate Markdown report
CLI-->>Make: Report output
CLI->>NATS: Publish ops.pr.trim.completed.v1 (JSON payload)
NATS-->>Make: Deliver event to subscribers
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pmoves/config/agent_registry.yaml`:
- Around line 720-723: Agent registry subscribes to the subject
ops.pr.monitor.completed.v1 but that subject is missing from the contracts
mapping; open pmoves/contracts/topics.json and add a new topic entry for
"ops.pr.monitor.completed.v1" following the same shape as other topics (subject
name, version, schema/description/owner fields used in your JSON contract
conventions) so the nats subscription in agent_registry.yaml (nats.subscribes
entry) is declared in the contracts mapping and passes validation.
In `@pmoves/contracts/schemas/ops/pr.trim.completed.v1.schema.json`:
- Around line 7-59: The schema
pmoves/contracts/schemas/ops/pr.trim.completed.v1.schema.json currently requires
agent_id and resolved and forbids extra fields, but _serialize_report in
pmoves/tools/pr_hedge_trim.py emits resolved_count, unresolved_threads, and
threads and omits agent_id; fix by aligning the serializer to the schema: modify
_serialize_report to emit "resolved" (map from resolved_count), include
"agent_id" (use the agent identity available in the function/context), and stop
emitting unknown fields "unresolved_threads" and "threads" (or if those fields
are required for consumers, instead add them to the schema and update "required"
and "properties"); ensure the final payload validates against the schema before
publishing via services/common/events.py.
In `@pmoves/contracts/topics.json`:
- Around line 222-226: The topic "ops.pr.trim.completed.v1" lists
"publisher-discord" as a subscriber but that subject is not included in the
default DISCORD_SUBJECTS used by the publisher-discord service; either add
"ops.pr.trim.completed.v1" to the default DISCORD_SUBJECTS list used in the
publisher-discord startup (ensure the DISCORD_SUBJECTS env var or DEFAULT list
in publisher-discord main.py includes this string and that docker-compose.yml
sets the matching default), or remove "publisher-discord" from the subscriber
array for "ops.pr.trim.completed.v1" in topics.json so the config and defaults
stay consistent.
In `@pmoves/tools/pr_hedge_trim.py`:
- Around line 336-345: The resolve_thread function currently assumes
result["data"]["resolveReviewThread"] is always a dict and will crash when
GraphQL returns null; update resolve_thread to check that result is a dict, then
that data.get("resolveReviewThread") is not None before accessing
.get("thread"), log the full result/error including thread_id when
resolveReviewThread is null or the mutation failed, and return False on any
failure; then update cmd_resolve to inspect the boolean returned by
resolve_thread (instead of treating the subprocess as success) and exit non-zero
when resolve_thread returns False so batch jobs can detect failed mutations;
reference symbols: resolve_thread, cmd_resolve, _run_json, thread_id.
- Around line 162-181: The default branch in classify_comment always returns
"nitpick" because it never knows whether the author is a bot; change the
classify_comment signature to accept an is_bot: bool (e.g., def
classify_comment(body: str, is_bot: bool) -> str), preserve the existing token
checks using FALSE_POSITIVE_TOKENS, DESIGN_TOKENS, NITPICK_TOKENS,
ACTIONABLE_TOKENS, and replace the final return with return "nitpick" if is_bot
else "actionable"; update all call sites to pass the caller's is_bot value so
human comments default to "actionable".
- Around line 236-250: The loop currently uses `break` when `_run_json(cmd)` or
nested keys (`payload`, `data`, `repository`, `pr`, `review_threads`) are
missing, which masks errors as "0 threads"; instead, fail fast by replacing
those `break` statements with raising a descriptive exception (e.g.,
RuntimeError or ValueError) that includes the `cmd` and the malformed
`payload`/missing-key name; apply the same change in the second occurrence (the
block around `review_threads` at the later location) so both pagination checks
surface malformed GraphQL responses or auth issues immediately.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 74c5651c-d421-4cf0-a5d1-e32a9cdbe8a9
📒 Files selected for processing (9)
.claude/commands/pr-trim.md.claude/context/nats-subjects.md.gitignorepmoves/config/agent_registry.yamlpmoves/configs/skill-pairings.yamlpmoves/contracts/schemas/ops/pr.trim.completed.v1.schema.jsonpmoves/contracts/topics.jsonpmoves/mk/preflight.mkpmoves/tools/pr_hedge_trim.py
…g, classification context - Add is_bot parameter to classify_comment() so unclassified human comments default to actionable instead of nitpick (thread 4) - Fail fast with RuntimeError on malformed/null GraphQL responses instead of silently returning empty results (thread 5) - Guard resolveReviewThread null result, track failed resolutions, exit code 1 when target threads remain unresolved (thread 6) - Align schema with serializer: rename resolved → resolved_count, add unresolved_threads and threads fields, add agent_id to serializer output (thread 2) - Add ops.pr.monitor.completed.v1 topic and schema (thread 1) - Remove publisher-discord from trim subscriber list — Discord routing is opt-in via DISCORD_SUBJECTS env override (thread 3) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
pmoves/tools/pr_hedge_trim.py (1)
311-313:⚠️ Potential issue | 🟠 MajorRaise on missing
pageInfo.Most of
fetch_threads()now fails fast on malformed GraphQL responses, but this lastbreakstill turns a bad payload into a partial-success analysis/report.🛠️ Proposed fix
page_info = review_threads.get("pageInfo") if not isinstance(page_info, dict): - break + raise RuntimeError("unexpected GraphQL response: missing 'pageInfo'")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@pmoves/tools/pr_hedge_trim.py` around lines 311 - 313, fetch_threads currently breaks out of the loop when page_info is not a dict, turning a malformed GraphQL response into a silent partial success; replace the break with an explicit exception (e.g., raise ValueError or RuntimeError) so callers fail fast. In the fetch_threads function, where page_info = review_threads.get("pageInfo") and the code checks isinstance(page_info, dict), raise a descriptive error that includes context (e.g., the offending review_threads or its keys) instead of using break so upstream code can handle/log the malformed payload.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pmoves/contracts/schemas/ops/pr.trim.completed.v1.schema.json`:
- Around line 62-68: The "threads" array items are currently unconstrained
(items: { "type": "object" }), allowing malformed thread objects; update
pmoves/contracts/schemas/ops/pr.trim.completed.v1.schema.json to precisely
validate the shape emitted by the serializer in pmoves/tools/pr_hedge_trim.py:
replace the loose items schema with an object schema that lists the exact
per-thread properties (and types), marks required fields, and validates nested
comment fields (with their properties) so downstream consumers get strict
contract protection. Ensure property names and nesting match the fields produced
by pr_hedge_trim.py and include any enums/format constraints used by the
serializer.
In `@pmoves/tools/pr_hedge_trim.py`:
- Around line 595-599: The post-check treats any remaining targeted threads as a
failure even during a dry run; update the return logic in the block that calls
cmd_resolve so that when args.dry_run is True the function returns 0 (success)
even if target_threads exist; specifically modify the code using cmd_resolve,
fetch_threads and target_threads to return 1 only when not args.dry_run and
target_threads is non-empty, otherwise return 0.
---
Duplicate comments:
In `@pmoves/tools/pr_hedge_trim.py`:
- Around line 311-313: fetch_threads currently breaks out of the loop when
page_info is not a dict, turning a malformed GraphQL response into a silent
partial success; replace the break with an explicit exception (e.g., raise
ValueError or RuntimeError) so callers fail fast. In the fetch_threads function,
where page_info = review_threads.get("pageInfo") and the code checks
isinstance(page_info, dict), raise a descriptive error that includes context
(e.g., the offending review_threads or its keys) instead of using break so
upstream code can handle/log the malformed payload.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 96548749-40be-4762-be60-48eb3581fa3e
📒 Files selected for processing (4)
pmoves/contracts/schemas/ops/pr.monitor.completed.v1.schema.jsonpmoves/contracts/schemas/ops/pr.trim.completed.v1.schema.jsonpmoves/contracts/topics.jsonpmoves/tools/pr_hedge_trim.py
Document the full pr-monitor-graphiti-chit FlOO$ pipeline in CLAUDE.md, wire existing hooks into settings.json, and resolve all remaining CodeRabbit threads from the #934-941 merge session. Changes: - CLAUDE.md: Add "PR Review & Merge Workflow" section with skill chain, usage guide, FlOO$ validation commands, and NATS subjects - CLAUDE.md: Fix skill pairing table (3-step → 4-step pipeline) - settings.json: Wire UserPromptSubmit hook for PR skill awareness - settings.json: Wire post-review-chit.sh to Skill PostToolUse - hooks/pr-skill-reminder.sh: New lightweight PR context reminder - .gitignore: Add runtime graphiti/CGP log patterns - Resolve 14 unresolved CodeRabbit threads on PRs #940 and #941 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: refresh CODEX_CLAUDE_PARITY_GAPS coverage report to 2026-03-13 - Coverage: 96.6% (down from 100%) - New commands added without parity updates: chit:review-sweep, chit:sign-trail, docs:reconcile, tac:review - Timestamp updated from 2026-02-28 to 2026-03-13 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(submodules): add PMOVES-a0-plugins plugin index + Agent Zero TAC tree **PMOVES-a0-plugins Submodule:** - Adds POWERFULMOVES/PMOVES-a0-plugins as submodule - Tracks PMOVES.AI-Edition-Hardened branch for security hardening - Enables curated plugin ecosystem for Agent Zero customizations - README includes PMOVES.AI-specific integration patterns: - TensorZero Gateway (port 3030/3000) for all LLM calls - NATS (nats://nats:pmoves@nats:4222) for event coordination - Hi-RAG v2 (port 8086/8087) for knowledge retrieval - Archon (port 8091) for prompt management - Security: non-root containers, healthchecks, metrics, CHIT **Agent Zero Customization TAC Tree:** - 50 checks across 9 phases for comprehensive review - 100% pass rate validates: - TensorZero integration and model naming format - Extension system proper use (23 extension points) - PMOVES.AI service leverage (not duplication) - Docker hardening (tier-agent-hardened anchor) - Observability (healthz/metrics endpoints, NATS heartbeat) - 4-tier context loading strategy - Plugin ecosystem integration - Subordinate agent model - Tools & prompts customization patterns Related: Agent Zero customization documentation and integration patterns * docs(submodule): update Agent Zero with integration guide and quickstart - PMOVES.AI_INTEGRATION.md: Complete service integration reference - QUICKSTART.md: 15-minute getting started guide This documentation provides: - Service connection details (TensorZero, NATS, Hi-RAG, Archon, Neo4j) - MCP API usage examples - Extension system guide (23 lifecycle hooks) - Security hardening patterns - Troubleshooting section Related: Agent Zero TAC tree (50/50 checks passing) Related: PMOVES-a0-plugins submodule initialization * feat(submodules): add PMOVES.Notes plugin to a0-plugins index **Plugin Added:** pmoves-notes-integration - Repository: https://github.com/POWERFULMOVES/a0-plugin-pmoves-notes - Branch: PMOVES.AI-Edition-Hardened **Plugin Features:** - Auto-save conversation summaries (message_loop_end extension) - Save reasoning traces to memory (monologue_end extension) - Manual tools: save_note, search_notes - NATS events: agent.notes.saved.v1, agent.notes.searched.v1 - Open Notebook integration (SurrealDB knowledge base) **TAC Review Results:** - Agent Zero Customization Review: 50/50 passing (100%) - All 9 phases validated successfully Related: Agent Zero integration documentation Related: PMOVES-a0-plugins submodule initialization * refactor(tac): simplify NATS regex pattern and update description - Simplify NATS subject pattern: agent\.task\.|agent\.subordinate\. → agent\.task|agent\.subordinate - Update description to explicitly state "across 9 phases (51 checks)" - Removes unnecessary escape before pipe operator - More robust pattern matching for NATS subjects Suggested by code review feedback - all 50 checks still passing. * fix(ui): apply PR review fixes to main - Fix playwright default port: 3100 → 4482 (matches docker-compose) - Fix base64url decoding in boot-jwt route (JWT uses -/_ instead of +/) - Add spawn error handler to with-env.mjs These fixes were applied to all UI Testing PRs (#908-#913). PR branches will rebase onto main to pick up these core fixes. * feat(ops): PR review skill chain integration + thread resolution Document the full pr-monitor-graphiti-chit FlOO$ pipeline in CLAUDE.md, wire existing hooks into settings.json, and resolve all remaining CodeRabbit threads from the #934-941 merge session. Changes: - CLAUDE.md: Add "PR Review & Merge Workflow" section with skill chain, usage guide, FlOO$ validation commands, and NATS subjects - CLAUDE.md: Fix skill pairing table (3-step → 4-step pipeline) - settings.json: Wire UserPromptSubmit hook for PR skill awareness - settings.json: Wire post-review-chit.sh to Skill PostToolUse - hooks/pr-skill-reminder.sh: New lightweight PR context reminder - .gitignore: Add runtime graphiti/CGP log patterns - Resolve 14 unresolved CodeRabbit threads on PRs #940 and #941 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Shaela Bello <slbello@uncg.edu> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
/pr-trimskill with 4-way thread classification (actionable / design-decision / false-positive / nitpick) and GraphQLresolveReviewThreadmutationpmoves/tools/pr_hedge_trim.py) withanalyze,resolve, andreportsubcommandspr-trim-analyze,pr-trim-resolve,pr-trim-report,pr-trim-batchops.pr.trim.completed.v1), FlOO$ chain integration, agent registry entryTest plan
py -3 pmoves/tools/pr_hedge_trim.py --help— CLI parsesmake -C pmoves -n pr-trim-analyze PR=1— Make target resolvespy -3 -c "import json; json.load(open('pmoves/contracts/topics.json'))"— Topics valid JSONpy -3 -c "import yaml; yaml.safe_load(open('pmoves/configs/skill-pairings.yaml'))"— FlOO$ chain valid🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores