| name | deft-directive-review-cycle |
| description | Greptile bot reviewer response workflow. Use when running a review cycle on a PR -- to audit process prerequisites, fetch bot findings, fix all issues in a single batch commit, and exit cleanly when no P0 or P1 issues remain.
|
Deft Directive Review Cycle
Structured workflow for responding to bot reviewer (Greptile) findings on a PR.
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
Platform Requirements
! This skill requires GitHub as the SCM platform and the GitHub CLI (gh) to be installed and authenticated. PR comment fetching, check-run queries, and review submission all depend on gh.
When to Use
- User says "review cycle", "check reviews", or "run review cycle" on a PR
- A bot reviewer (Greptile) has posted findings on an open PR
- Dispatching a cloud agent to monitor and resolve PR review findings
Branch-Protection Policy Guard
! Before entering the review/fix loop, run the skill-level branch-policy guard documented in scripts/policy.py / scripts/preflight_branch.py (#746 / #747). Halt before any state mutation if the project's plan.policy.allowDirectCommitsToMaster is unresolvable AND the operator has not set DEFT_ALLOW_DEFAULT_BRANCH_COMMIT=1. Concretely:
uv run python scripts/preflight_branch.py --project-root . --quiet || exit 1
or invoke task verify:branch. The skill MUST NOT modify files, push, or comment on the PR until the guard passes -- this catches the case where a malformed PROJECT-DEFINITION quietly disabled the policy and the agent would have committed directly to master mid-review.
Deterministic Questions Contract
! Every numbered-menu prompt rendered in this skill (Phase 1 audit gates, Phase 2 Step 4 monitoring approach selection, Phase 5->6 ready-to-merge gate, Step 6 exit-condition prompts) MUST follow ../../contracts/deterministic-questions.md: the final two numbered options MUST be Discuss and Back, in that order. The Discuss-pause semantic is documented verbatim there -- on Discuss selection the agent MUST halt the in-progress sequence immediately, prompt What would you like to discuss?, and resume only on an explicit user signal (re-asking the original question, saying resume/continue, or re-issuing the prior selection). Implicit resumption is forbidden.
Pre-Flight Check
! Before entering the review/fix loop, verify the Greptile configuration supports it:
- !
triggerOnUpdates must be enabled (via Greptile dashboard or .greptile/config.json) — without this, Greptile only reviews the initial PR and never re-reviews after fix pushes, so the loop cannot reach the exit condition
- ~
statusCheck should be enabled so Greptile posts a "Greptile Review" check run on each commit — this is the signal the org ruleset uses to gate merges
- ? If Greptile does not re-review after a push despite
triggerOnUpdates being enabled, comment @greptileai on the PR as a manual re-trigger fallback
! Greptile posts check runs (GitHub Checks API), not commit statuses (Statuses API). To verify the check run is present on a commit:
gh api repos/<owner>/<repo>/commits/<sha>/check-runs --jq '.check_runs[] | select(.name == "Greptile Review")'
⊗ Use commits/<sha>/statuses to check for Greptile — that endpoint will always be empty.
~ See tools/greptile.md for recommended dashboard and per-repo settings.
Phase 1 — Deft Process Audit
! Before touching code, verify ALL prerequisites are satisfied. Fix any gaps first:
- ! Verify
skills/deft-directive-pre-pr/SKILL.md was run before PR creation -- the PR branch should have passed at least one full RWLDL cycle. If not, run it now before proceeding.
- !
PROJECT-DEFINITION.vbrief.json and vbrief/ lifecycle folders have scope vBRIEF coverage for all changes in the PR
- !
CHANGELOG.md has entries under [Unreleased] for the PR's changes
- !
task check passes fully (fmt + lint + typecheck + tests + coverage ≥75%)
- !
.github/PULL_REQUEST_TEMPLATE.md checklist is satisfied in the PR description
- ! If the PR touches 3+ files: verify a
/deft:change proposal.vbrief.json exists in history/changes/ for this branch and was explicitly confirmed by the user (affirmative response, not a broad 'proceed'), or document N/A with reason in the PR checklist
- ! Verify the PR is on a feature branch -- work MUST NOT have been committed directly to the default branch (master/main)
~ PR scope gate: If the PR spans 3+ unrelated surfaces (e.g. a skill, a tool doc, and a strategy -- with no shared issue or scope vBRIEF linking them), warn the user that broad PRs increase review churn and Greptile noise. Recommend splitting into focused PRs unless all changes trace to the same scope vBRIEF or issue bundle.
! Phase 1 audit gaps must be resolved before merging — but hold the fixes (do NOT commit or push them independently). Proceed to Phase 2 analysis to gather bot findings, then batch all Phase 1 + Phase 2 fixes into a single commit.
⊗ Commit or push Phase 1 audit fixes independently before gathering Phase 2 findings.
Phase 2 — Review/Fix Loop
Step 1: Fetch ALL bot comments
! Retrieve findings using BOTH methods — each catches different comment categories:
gh pr view <number> --comments
! Use do_not_summarize_output: true — summarizers silently drop the "Comments Outside Diff" section from large bot comments.
~ Oversized output fallback: If do_not_summarize_output: true produces output too large to process, extract the relevant section with:
- PowerShell (Windows):
gh pr view <number> --comments | Select-String "Outside Diff" -Context 50
- Unix/macOS:
gh pr view <number> --comments | grep -A 50 "Outside Diff"
Both commands extract the "Comments Outside Diff" section with surrounding context, avoiding the need to process the full output.
~ Windows + Grok Build (#1353): Avoid |, >, or 2>&1 in run_terminal_command strings -- use Python pathlib/subprocess or plain task commands instead.
! MCP capability probe (mirrors deft-directive-swarm Phase 3 pattern): Before attempting MCP get_review_comments, probe whether MCP GitHub tools are available in the current session. Detection: attempt a lightweight MCP call (e.g. list available tools or a no-op query) -- if it succeeds, MCP is available; if it errors or the tool is not in the available set, MCP is unavailable.
- MCP available: ! Use MCP
get_review_comments as the second source to catch Comments Outside Diff.
- MCP unavailable (e.g. non-MCP agents including
start_agent / spawn_subagent ("grok-build") dispatch, cloud agents, oz agent run): ! Use gh api repos/<owner>/<repo>/pulls/<number>/comments as the explicit fallback for the second review source. Document in the commit message or PR comment why MCP was skipped (e.g. "MCP unavailable in this session -- used gh api fallback for review comments"). The platform descriptor from runtime detection determines MCP availability independently of the dispatch primitive.
⊗ Report "all comments resolved" without verifying both sources.
⊗ Skip the second review source without probing for MCP capability and documenting the fallback used.
~ Late-arriving bot review re-check: If the initial dual-source fetch returns no bot review on the current HEAD SHA, wait ~60s and re-fetch before evaluating the Step 6 exit condition. Bot reviewers (Greptile) typically land within 3-7 min of PR creation/push; an empty first pass is more likely "review pending" than "review clean".
⊗ Declare the exit condition met based on a single fetch that returned no bot review — re-fetch at least once after a ~60s delay first.
~ This codifies a user-rule precedent on late-arriving bot reviews into the deft-internal deterministic tier. The templates/swarm-greptile-poller-prompt.md loop body already handles the same case for push-driven cycles via its per-poll fetch -- the rule above closes the orthogonal cold-start path where the one-shot review-cycle entry runs on a freshly-opened PR before any fix push has triggered the Step 4 polling loop.
Step 2: Analyze ALL findings before changing anything
! Before making any changes:
- Read every finding across all files
- Identify cross-file dependencies (a term, value, or field mentioned in multiple files)
- Categorize by severity (P0, P1, P2 — where P0 is critical/blocking, P1 is a real defect, P2 is a style or non-blocking suggestion)
- Plan a single coherent batch of fixes
⊗ Start fixing individual findings as you encounter them.
Step 3: Fix all findings in ONE batch commit
! Apply ALL fixes across all files before committing:
- ! For any fix that touches a value, term, or field appearing in multiple files: grep for it across the full PR file set and update every occurrence in the same commit
- ! Validate structured data files locally before committing (e.g.
python3 -m json.tool for JSON, YAML lint for YAML) — do not rely on the bot to catch syntax errors
- ! Before committing any Greptile fix, re-read the FULL current Greptile review and confirm all P0/P1 issues are addressed in the staged changes — this is the pre-commit gate that prevents per-finding fix commits
- ! Run
task check before committing
- ! Fail-loud completion claim (#1006): when reporting fix-batch completion (to the user, in the commit message, in a PR comment, or in a status message to a parent agent), MUST surface the OUTCOMES not the intent -- name the P0/P1 finding count addressed ("addressed 3/3 P0 findings, 2/2 P1 findings, 0 deferred" -- NOT "all findings addressed"), report the
task check result with the test-collection counts ("task check: 412 collected, 412 passed, 0 skipped, 0 xfailed" -- NOT "task check passed"), and explicitly call out any finding intentionally deferred with the reason. Apply coding/coding.md ## Fail Loud: Completion Claims Require Outcome Verification (#1006) to every claim emitted during the review cycle
- ⊗ Claim "all Greptile findings addressed" without verifying that the staged fix actually closes every P0/P1 currently surfaced in the review body -- a fix that addresses 3 out of 4 P1 findings and reports completion is the exact failure mode #1006 forbids
- ⊗ Claim "task check passes" when any test was skipped, xfailed, or run with errors suppressed -- report the full collection counts instead (#1006)
- ? Pre-existing failure carve-out: If
task check fails due to a pre-existing issue unrelated to the PR's changes, a partial test suite run is acceptable ONLY if BOTH conditions are met: (a) the task check failure is pre-existing with an open GitHub issue number tracking it, AND (b) the PR description explicitly notes the failure and includes the issue reference (e.g. "task check: test_foo fails due to #NNN (pre-existing)"). Without both conditions, the full task check pass remains mandatory.
- ~ Commit message:
fix: address Greptile review findings (batch)
⊗ Push individual fix commits per finding — always batch.
Step 3b: Proactive test coverage scan
! After committing the fix batch but before pushing, scan the changed lines for untested code paths:
- ! Run
git --no-pager diff HEAD~1 HEAD --name-only to identify files touched in the fix batch
- ! For each changed file that has a corresponding test file, review whether the fix introduced or modified logic that lacks test coverage
- ! If untested code paths are found, write tests and amend them into the fix batch commit (or add as a second commit in the same push)
- ! Run
task check again after adding tests to verify they pass
~ This eliminates one CI round-trip per fix cycle — catching coverage gaps before CI does.
⊗ Push fix commits without scanning for untested code paths in changed files.
Step 4: Push and wait
! Push the batch commit, then wait for the bot to review the latest commit.
! After pushing, the agent MUST autonomously poll for review updates and continue the review cycle without stopping to ask the user. Do not pause for confirmation, do not ask "should I continue?", do not wait for user input between push and review completion. The review/fix loop is designed to run to the exit condition without human intervention.
⊗ Push any additional commits — including unrelated fixes, doc updates, or lessons — while waiting for the bot to finish reviewing the current head. Every push re-triggers Greptile and resets the review clock. If you discover additional work while waiting, stage it locally but do NOT push until the current review completes.
Stall Detection Rubric (#564)
! Track per poll: startedAt (timestamp of the first observation of the IN_PROGRESS check run for the current commit) and commit.oid (head SHA being reviewed). Both fields MUST be re-recorded every time the head SHA changes -- the rubric measures elapsed time on a single commit, not across the whole review cycle.
! Expected duration baseline -- Greptile reviews typically complete in 2-5 minutes, with 7 minutes as the upper bound of normal. The escalation threshold is 3x expected = ~10 minutes of continuous IN_PROGRESS on the same commit.oid. The 21-minute stall observed during the rc4 swarm cascade on PR #561 is the recurrence record; see ../../meta/lessons.md ## Greptile Review Stall Detection (2026-04).
! When elapsed time on the current commit.oid exceeds 10 minutes (3x expected) without the IN_PROGRESS check transitioning to a terminal state, the agent MUST escalate to the user. The escalation message MUST include: (1) the PR number; (2) the head SHA being reviewed; (3) the elapsed time since startedAt; (4) the four canonical user-decision options.
! User-decision options at escalation -- render as a deterministic numbered menu per ../../contracts/deterministic-questions.md (final two options Discuss + Back):
- Wait another N minutes (user picks N).
- Manually re-trigger Greptile by commenting
@greptileai on the PR (logs the override in a PR comment for auditability per the next rule).
- Skip the bot review for this cycle and exit the loop with a documented reason.
- Cancel the review cycle entirely.
- Discuss.
- Back.
! Auto-restart detection -- when the polling loop observes a NEW startedAt (Greptile dropped its prior check run and started a fresh one without any push from the agent, e.g. service-side restart), the agent MUST reset its elapsed-time clock to the new startedAt AND notify the user that an auto-restart was detected. Resetting the clock without notifying is forbidden -- the user needs to know the cycle effectively re-started.
⊗ Auto-retrigger Greptile (empty commits, force-pushes, agent-posted @greptileai comments, status-check rebuilds) without explicit user approval. The escalation menu's option 2 is the ONLY supported re-trigger path, and even that requires the user to pick it.
! Document any user-approved override in a brief PR comment for auditability -- e.g. Note: review-cycle stall detected at <SHA> after <N> min; user approved manual re-trigger via @greptileai per skills/deft-directive-review-cycle Stall Detection Rubric (#564). This makes the override visible to humans reviewing the PR history and to future agents that resume the cycle.
⊗ Treat a stall as silent -- if the elapsed clock crosses the 10-minute threshold the agent MUST surface the menu, even if the agent is mid-poll. Continuing to poll past the threshold without user input is forbidden.
Review Monitoring
! Select the monitoring approach based on runtime capability detection (the matrix in skills/deft-directive-swarm/SKILL.md Phase 3 Step 1, extended per #1342 slices 1-2 for spawn_subagent / "grok-build" as a first-class tier). Probe the environment (tool set + env vars) to obtain the stable platform descriptor (grok-build, warp-orchestrated, warp-interactive, etc.) from the launch adapter / get_platform_capabilities and map the descriptor to the appropriate tier + dispatch primitive (start_agent or spawn_subagent). The descriptor (not hard-coded tool presence) is the single source of truth for both launch and review monitoring.
- Tier 1 (orchestrated sub-agent) → Approach 1 (spawn review-monitor sub-agent via the primitive matching the descriptor:
start_agent or spawn_subagent)
- Tier 2 (no sub-agent primitive, but scheduler/timer/auto-reinvocation) → Approach 2 (yield-between-polls)
- Tier 3 (interactive session, nothing else) → Approach 3 (blocking sleep loop as last resort)
! Detection: use the full runtime capability matrix (swarm Phase 3 + launch adapter from #1342 slice 2). The old single-probe for start_agent is superseded; the returned platform descriptor determines both the orchestration path and the MCP surface (see MCP probe below). If the descriptor is grok-build (spawn_subagent present, start_agent + WARP_* absent), treat as Tier 1 with the spawn_subagent poller path.
! Swarm agents (whether launched via start_agent or spawn_subagent per the platform descriptor) SHOULD prefer Approach 1 for their own review-monitor sub-agent. Approach 2's yield-between-polls is not self-sustaining for swarm agents (see warning below). Always include the canonical templates/agent-prompt-preamble.md (AGENTS.md read mandate, #810 vBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates) when spawning a poller sub-agent.
Approach 1 (preferred -- sub-agent orchestration available per platform descriptor):
! When the platform descriptor indicates Tier 1 (sub-agent support), spawn a review-monitor sub-agent using the primitive matching the descriptor:
- ! Launch via the matching primitive:
start_agent (Warp) or spawn_subagent (grok-build / TUI / non-Warp) with a prompt that instructs it to poll for Greptile completion. For spawn_subagent the prompt MUST reference the canonical poller template templates/swarm-greptile-poller-prompt.md (with placeholders filled) plus the agent preamble; the working directory / context must be the PR branch (worktree or equivalent for hybrid).
- ! The sub-agent polls using the mechanism for its primitive: for
spawn_subagent use get_command_or_subagent_output (adaptive cadence: ~20-30s first check after push, ~60s second, ~90s thereafter; Greptile typically lands in 3-7 min); for start_agent the native messaging path. Front-load the first check to catch fast reviews.
- ! When the exit condition is met (Greptile review current on the HEAD commit SHA, confidence > 3, no P0/P1 remaining), the sub-agent reports completion back to the parent (via
send_message_to_agent or the spawn_subagent result channel).
- ! The main conversation pane stays fully interactive during monitoring -- the user (or parent monitor) can continue other work.
- ! On receiving the completion message / result, the parent re-fetches findings (both gh pr view --comments and the secondary source) and proceeds to Step 5.
Approach 2 (fallback -- no sub-agent primitive for the descriptor):
! When the platform descriptor indicates no sub-agent orchestration (or the primitive is unavailable), use discrete tool calls with a yield between checks. For grok-build / spawn_subagent descriptor this path is normally avoided in favor of Approach 1; it exists for pure interactive or limited runtimes.
- ! Use the current shell execution tool (
run_terminal_command or equivalent in the runtime) in wait mode to run gh pr view <number> --comments and gh pr checks <number>.
- ! After each check, yield control (end all tool calls) -- the agent runtime will re-invoke after its interval or on next interaction.
- ! Target adaptive cadence (20-30s / 60s / 90s) where the runtime permits. The full cadence is easiest in Approach 1 (sub-agent) or 3 (blocking); pure yield is runtime-controlled.
- ! No blocking shell pane lock -- the conversation remains interactive between checks.
- ~ Approach 2 requires a periodic re-invocation trigger (timer, scheduler, user nudge, or external orchestrator for hybrid/worktree cases). Without it the poller stops after the first yield.
- ! When the exit condition is met, proceed to Step 5.
⚠️ Swarm / hybrid limitation: Approach 2 is NOT autonomous for swarm agents or manual worktree setups. Yielding ends the turn with no self-wake; the parent monitor (or external scheduler) must detect idle and re-trigger or send a message. For true grok-build / spawn_subagent hybrids, prefer Approach 1 (spawn_subagent + get_command_or_subagent_output poller) exactly as the swarm launch adapter does.
⊗ Use blocking Start-Sleep shell loops or time.sleep() loops EXCEPT as Approach 3 (see below) -- these lock the conversation and prevent user interaction.
⊗ Poll more frequently than every 20 seconds -- use a real delay between checks, not back-to-back calls. Adaptive cadence (20-30s / 60s / 90s) replaces the fixed 60s minimum.
Approach 3 (last resort -- interactive session, no start_agent, no timer/scheduler):
! Approach 3 is a blocking sleep-poll loop used ONLY when both Approach 1 and Approach 2 are unavailable (interactive session with no start_agent and no auto-reinvocation mechanism). Uses PowerShell sleep / Unix sleep commands between polls.
! User warning gate: Before activating Approach 3, the agent MUST warn the user that the conversation pane will be locked during polling and ask for explicit confirmation. Example: "No sub-agent or auto-reinvocation available. I will poll in a blocking loop (~20-30s / 60s / 90s cadence). The conversation will be locked during polling. Proceed? (yes/no)"
⊗ Activate Approach 3 without first warning the user that it will lock the conversation pane.
- ! After receiving user confirmation, use a blocking shell loop with adaptive cadence:
- First check: wait ~25 seconds (e.g.
sleep 25), then poll
- Second check: wait ~60 seconds, then poll
- Subsequent checks: wait ~90 seconds, then poll
- ! Poll using
gh pr view <number> --comments and gh pr checks <number> in the same shell session
- ! When the exit condition is met (Greptile review current, confidence > 3, no P0/P1), exit the loop and proceed to Step 5
- ! If the user interrupts (Ctrl+C or equivalent), exit gracefully and report current review status
! Greptile may advance its review by editing an existing PR issue comment rather than creating a new PR review object. Do NOT rely solely on pulls/{number}/reviews — that endpoint may remain stale at an older commit SHA even after Greptile has reviewed the latest commit.
! To confirm the review is current, check both surfaces:
- PR issue comments (primary signal) — Greptile edits its existing summary comment in place:
gh pr view <number> --comments (with do_not_summarize_output: true)
- Or
gh api repos/<owner>/<repo>/issues/<number>/comments
- Parse the comment body for
Last reviewed commit and compare to the pushed commit SHA
- Check the comment's
updated_at timestamp to confirm it was refreshed after your push
- PR review objects (secondary signal) — may or may not be updated:
gh api repos/<owner>/<repo>/pulls/<number>/reviews
- Check
commit_id on the latest review object
! Treat an edited Greptile issue comment as a valid new review pass even if no new PR review object was created.
! Fetch the full untruncated comment body or use MCP get_comments to get the actual commit URL containing the full SHA — do NOT rely on grepping truncated link text.
⊗ Re-fetch or re-trigger while the bot's last review still targets an older commit on both surfaces.
Step 5: Re-fetch and analyze
! Fetch the new review using both methods from Step 1.
! Analyze all new findings before planning any changes.
Step 6: Exit condition check
! Exit the loop and report to the user when ALL of these are true:
- No P0 or P1 issues remain (P2 issues are non-blocking style suggestions and do not gate the loop)
- Greptile confidence score is greater than 3
? If the bot says "all prior issues resolved" but lists new issues, treat it as one final batch — not the start of another loop. Go back to Step 2 one more time, then stop.
If the exit condition is not met, go back to Step 2.
Submitting GitHub Reviews
! When submitting PR reviews via the GitHub MCP tool, always use pull_request_review_write with method create and the appropriate event:
APPROVE — formally approve the PR (shows green "Approved" status)
REQUEST_CHANGES — block the PR with requested changes
COMMENT — review feedback without approving or blocking
⊗ Use add_issue_comment for review notes — that creates a regular comment, not a formal review. Review notes must always go in the review body via pull_request_review_write.
GitHub Interface Selection
~ Use the most efficient interface for the task:
- MCP GitHub tool — structured/programmatic operations (querying issues, creating PRs, bulk operations, filtering data)
- GitHub CLI (
gh) — quick ad-hoc commands and direct shell integration
Choose whichever minimizes steps and maximizes clarity for the given task.
~ When MCP is unavailable (agents without MCP tools in their dispatch environment, including start_agent / spawn_subagent ("grok-build") cases, cloud agents, oz agent run), gh CLI is sufficient as the sole interface. The dual-source requirement (MCP + gh) in Step 1 applies only when both are available -- agents without MCP access should use gh pr view --comments and gh api as their primary and only review detection surface. Runtime capability detection (swarm Phase 3 matrix) informs both orchestration tier and MCP surface choice.
Framework Events Emitted Here
! When the user replies yes / confirmed / approve on a ready-to-merge PR thread (Phase 5 -> 6 gate per the canonical #642 workflow comment), emit a plan:approved framework event via scripts/_events.py so the approval is captured as a structural artifact rather than prose-only:
python -m scripts._events emit plan:approved \
--plan-ref https://github.com/<owner>/<repo>/pull/<N> \
--approver <github-login> \
--approval-phrase <yes|confirmed|approve> \
--pr-number <N>
? Downstream consumers of plan:approved (auto-merge bots, status updates, audit reporting) are explicitly deferred to follow-up work; this event currently emits a record only (#635 events behavioral wiring).
Post-Merge Verification
! After a PR is squash-merged, verify that all referenced issues were actually closed. Squash merges can silently fail to process closing keywords (Closes #N, Fixes #N) from the PR body (#167).
- ! For each issue referenced with a closing keyword in the PR body, run:
gh issue view <N> --json state --jq .state
- ! If the issue state is not
CLOSED, close it manually with a comment referencing the merged PR:
gh issue close <N> --comment "Closed by #<PR> (squash merge — auto-close did not trigger)"
- ~ This step mirrors
skills/deft-directive-swarm/SKILL.md Phase 6 Step 2 and applies to ALL PR merges, not just swarm runs.
- ! For PRs that referenced any umbrella / staying-OPEN issue (
Refs #N), the INVERSE check applies: any protected issue that auto-closed MUST be reopened with a comment citing #701 and the merged PR. See skills/deft-directive-swarm/SKILL.md Phase 6 Step 1 protected-issue reopen sweep and meta/lessons.md ## GitHub Closing-Keyword False-Positive Layer 3 for the persistent closingIssuesReferences link case (Layer 3, #701).
Anti-Patterns
- ⊗ Push individual fix commits per finding
- ⊗ Start fixing before analyzing ALL findings
- ⊗ Rely on the bot to catch syntax errors in structured data files
- ⊗ Re-trigger a bot review before the previous one has updated
- ⊗ Report "all comments resolved" without checking both
gh pr view --comments and a second source (get_review_comments via MCP, or gh api fallback when MCP is unavailable)
- ⊗ Use
add_issue_comment for formal review submission
- ⊗ Commit or push Phase 1 audit fixes independently — always batch with Phase 2 fixes
- ⊗ Proceed to Phase 2 while any Phase 1 prerequisite is unmet
- ⊗ Rely solely on
pulls/{number}/reviews to detect whether Greptile has reviewed the latest commit — Greptile may update via an edited issue comment instead of a new review object
- ⊗ Push additional commits while Greptile is reviewing the current head — each push re-triggers Greptile and resets the review clock
- ⊗ Use blocking
Start-Sleep shell loops or time.sleep() loops to poll for review updates when Approach 1 or 2 is available -- Approach 3 (blocking loop) is permitted only as a last resort with user warning
- ⊗ Poll more frequently than every 20 seconds -- use a real delay between checks, not back-to-back calls; adaptive cadence (20-30s / 60s / 90s) replaces the fixed 60s minimum
- ⊗ Stop and ask the user whether to continue after pushing -- the review/fix loop MUST run autonomously to the exit condition
- ⊗ Push fix commits without scanning changed lines for untested code paths — always check test coverage before pushing
- ⊗ Push a fix commit that addresses fewer findings than the current Greptile review surfaces — if Greptile flags 3 issues, all 3 must be fixed in one commit before pushing
- ⊗ Push after fixing a P1 without first checking whether the same Greptile review contains additional P0 or P1 findings
- ⊗ Assume squash merge auto-closed referenced issues — always verify with
gh issue view after merge (#167)
- ⊗ Assume Approach 2 (yield-between-polls) produces a self-sustaining polling loop -- yielding ends the agent's turn with no self-wake; swarm agents will silently stop polling
- ⊗ Skip the second review source (MCP or
gh api fallback) without probing for MCP capability and documenting the fallback used
- ⊗ Run a partial test suite instead of
task check without documenting the pre-existing failure reason and open issue number in the PR body
- ⊗ Create a PR without running
skills/deft-directive-pre-pr/SKILL.md first -- the pre-PR quality loop catches issues before they reach the reviewer
- ⊗ Activate Approach 3 (blocking
Start-Sleep loop) without first warning the user that it will lock the conversation pane and receiving confirmation