Skip to content

Add skill and Cursor engine for local adversarial review - #2255

Merged
d-morrison merged 71 commits into
mainfrom
implement_adversarial_review_skill
Aug 26, 2026
Merged

Add skill and Cursor engine for local adversarial review#2255
d-morrison merged 71 commits into
mainfrom
implement_adversarial_review_skill

Conversation

@d-morrison

Copy link
Copy Markdown
Collaborator

Implements the adv adversarial code review skill and extends scripts/pre-push-review.py with Cursor CLI support and automatic fallback logic. Also addresses multiple critical findings from self-review, including robust head SHA tracking, safe GitHub PR commenting, strict section matching, and invoking agent filtering for true model independence.

…on, engine fallback, test suite, and strict merge policy
@github-actions

This comment has been minimized.

- Expand contradictory blocker regex to correctly fail when report mentions 'must be fixed' but claims clean verdict, while safely ignoring 'no blocking issues'.
- Ensure alternate engine routing correctly identifies Codex and OpenCode invokers and actively fails when no actual alternate engine is available rather than silently reusing the same model.
- Sync automatic routing contract ('cursor' added) with SKILL and spec documentation.
- Add test coverage for single-engine alternate fallback, cursor CLI contract, and contradiction parsing.
@cursor

cursor Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Independent adversarial review of HEAD 62c9fda08c21b34d75fd5e194ef363e0ea0eb121. First review of this PR.

Parser probes were executed in memory against this blob. Claude skip notices on sibling PRs are not reviews of this HEAD.

Findings

  1. [Defect] scripts/pre-push-review.py — HTML comments are never stripped; section presence is a substring test. A report whose entire clean skeleton lives inside <!-- ... --> is admitted. Probe: HTML-comment-only structure → valid=True clean=True. Sibling #2251 already strips comments and anchors headings.

  2. [Defect] Qualifier after [-:—(] is discarded. Probe: Ready for merge — except the tests fail and do not merge and Ready for merge (do not merge) both return CLEAN. The unit test encodes the hole: a rationale after an em-dash is asserted clean.

  3. [Defect] The prompt example Verdict: Ready for merge (or Verdict: Needs work with concise reason) splits on ( to ready for merge. A model that echoes the instruction line is graded CLEAN and stops the fallback chain.

  4. [Defect] Cursor engine: official --print has write/shell tools; --trust skips the workspace prompt. The skill says the auto chain runs in plan/read-only mode. --model is appended after the positional prompt, so it is swallowed as prompt text. detect_available_engines inserts cursor ahead of codex. Tests never invoke run_cursor_review.

  5. [Factual Error] Skill and Conductor spec describe auto priority claude -> codex -> opencode -> agy. Implementation and argparse help are claude -> cursor -> codex -> opencode -> agy.

  6. [Factual Error] OpenCode pipes a tempfile on stdin with no positional message. This repo's measured opencode run contract (2026-08-19) takes the message as positional arguments. Default --engine opencode-zen is zen/free, which is not a measured provider/model id.

  7. [Defect] Merge order vs still-open #2251: overlap is 18 paths, including all of conductor/ and scripts/pre-push-review.py. Neither head is an ancestor of the other. Merging either first conflicts on the shared files.

  8. [Convention] Literal U+2014 in scripts/pre-push-review.py and three test fixtures. shared/coding/ascii-punctuation-in-source.md requires \u2014.

  9. [Edge Case] --post is not gated on is_clean/is_valid. It is gated on headRefOid == local HEAD, so the advertised pre-push path (unpushed commits) cannot post. Empty diff exits 0 (vacuous CLEAN). HEAD~1 fallback reviews only the last commit of an N-commit branch.

Verdict: Needs more work

Reviewed-Commit: 62c9fda

Posted by Cursor Grok 4.6 (AI agent) --- not written by a human.

@d-morrison

Copy link
Copy Markdown
Collaborator Author

@claude review

@github-actions

Copy link
Copy Markdown
Contributor

👀 Picked up by workflow run #32946854685. Setup runs first; Claude itself responds after that.

@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Warning

No review ran --- this PR edits .github/workflows/validate.yml.
claude-code-action requires workflow files to match the default branch on dispatched runs, so its token exchange fails until this change merges.
The review is skipped by design, and re-running or re-dispatching will not change that: the skip lifts only if the PR stops editing that file.

require-review reports a gray skipped rather than green.
A green there attests that a reviewer ran, never that one approved; here none ran at all.
Merge on a self-review or a human review instead.

View run

@d-morrison

Copy link
Copy Markdown
Collaborator Author

Local Adversarial AI Review (Cursor Agent)

Reviewed Commit: 7dd5f9759c6b8c79beb687dea0000ddea2bba7ec

Summary Verdict

Verdict: Needs work with two contract-level regressions: the new skills are not registered on the Antigravity/Gemini workspace-discovery surface, and pre-push-review.py can silently review the wrong diff when the PR base branch is not present locally.

Critical Findings

  1. The new adv / pre-push-review skills are not wired into the workspace manifest that Antigravity/Gemini uses to discover repo-local skills, so one advertised harness never sees the feature at all.

    The repo explicitly documents .agents/skills.json as the workspace-plugin discovery point:

- **Global Plugin**: `bootstrap.sh` symlinks `plugins/ai-config` to `~/.gemini/config/plugins/ai-config` and registers `~/.gemini/config/plugins.json` and `skills.json`.
- **Workspace Plugin**: Opening this repository directly in Antigravity automatically discovers `.agents/skills.json` and `.agents/plugins.json` to load all skills, rules (`AGENTS.md`), and plugin features.

But this diff only adds skills/adv/SKILL.md, skills/pre-push-review/SKILL.md, and the generated Codex wrappers; it does not update .agents/skills.json. That means the feature is missing on the exact discovery path the repo claims for Antigravity/Gemini workspaces. The conductor spec even says this registration should happen, so this is not just documentation drift.

  1. resolve_diff() does not fetch or require the PR's actual base ref; if that branch is not already present locally, it silently falls back to origin/main / main and reviews a different diff than the PR is based on.
def resolve_diff(head_sha: str, pr_number: Optional[int] = None, explicit_base: str = "") -> Tuple[str, str, str, str]:
    """Compute local git diff against the PR base branch or default main.

    Always diffs the provided head_sha to include unpushed commits.
    """
    base_ref = explicit_base
    if not base_ref and pr_number:
        pr_base = get_pr_base_branch(pr_number)
        if pr_base:
            for cand in [f"origin/{pr_base}", pr_base]:
                r = subprocess.run(["git", "rev-parse", "--verify", cand], capture_output=True, text=True)
                if r.returncode == 0:
                    base_ref = cand
                    break

    if not base_ref:
        for cand in ["origin/main", "origin/master", "main", "master"]:
            r = subprocess.run(["git", "rev-parse", "--verify", cand], capture_output=True, text=True)
            if r.returncode == 0:
                base_ref = cand
                break

That violates the skill's own contract to review against "the detected PR base / explicit base branch":

## How it works

1. Computes the local outgoing diff against `origin/main` (or the detected PR base / explicit base branch).
2. Injects universal repository standards (`AGENTS.md`).
3. Dispatches to the selected engine or auto-fallback chain in plan/read-only mode (`claude` -> `cursor` -> `codex` -> `opencode` -> `agy`), or alternates round-robin across available models.
4. Strictly parses and validates structured findings (Summary Verdict, Critical Findings, Observations, Verification Steps, and Reviewed-Commit SHA).
5. Exits nonzero on blocking `Needs work` findings (unless `--allow-findings` is specified) and optionally posts verified review notes directly to the GitHub PR.

On a PR retargeted to a release branch, or on any checkout that has not fetched the base branch yet, the tool will produce and optionally post a verdict for the wrong change set.

Observations & Non-Blocking Suggestions

[MINOR] The new conductor/ docs introduce workflow rules like "plan.md is the source of truth" and mandatory per-task commits/git-notes that are not referenced anywhere else in the repo and conflict with the existing universal workflow in AGENTS.md. If they are meant to be advisory notes, link them from an owning doc; if they are meant to be active policy, they need a clearly defined loading/activation path.

[MINOR] skills/pre-push-review/SKILL.md and its frontmatter describe the supported engines inconsistently: the implementation supports cursor, but the frontmatter description and the "Explicitly choose AI engine" text omit it. That will mislead users even if the code path works.

[INFO] The added CI coverage is useful, but it only exercises mocked subprocess boundaries. The two regressions above both live in integration seams the unit tests currently do not pin: manifest registration for workspace discovery, and PR-base resolution when the remote base ref is absent locally.

Verification Steps

  1. Compared the new skill/docs claims against the repo's existing installation and discovery documentation in README.md.
  2. Inspected scripts/pre-push-review.py for diff-base resolution, engine selection, report validation, and PR-posting behavior.
  3. Cross-checked the new skill files against the implementation contract they advertise.
  4. Looked for surrounding validator/generator coverage to see whether these failure modes would be caught automatically.

Reviewed-Commit: 7dd5f97


Posted by Cursor Agent (AI agent) --- not written by a human.

…base, and docs)

- Register adv and pre-push-review in .agents/skills.json
- Fetch remote PR base before checking local existence in resolve_diff
- Add AGENTS.md disclaimer to conductor/workflow.md
- Document cursor support in skill manifests
@github-actions

Copy link
Copy Markdown
Contributor

Warning

Claude review skipped — API credential or quota unavailable. No CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret is configured, or account API quota is exhausted. Re-trigger the review by pushing a new commit or re-running the workflow once configured/reset. View run

@github-actions

Copy link
Copy Markdown
Contributor

Warning

Claude review skipped — API credential or quota unavailable. No CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret is configured, or account API quota is exhausted. Re-trigger the review by pushing a new commit or re-running the workflow once configured/reset. View run

@github-actions

Copy link
Copy Markdown
Contributor

Warning

Claude review skipped — API credential or quota unavailable. No CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret is configured, or account API quota is exhausted. Re-trigger the review by pushing a new commit or re-running the workflow once configured/reset. View run

@github-actions

Copy link
Copy Markdown
Contributor

Warning

Claude review skipped — API credential or quota unavailable. No CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret is configured, or account API quota is exhausted. Re-trigger the review by pushing a new commit or re-running the workflow once configured/reset. View run

@d-morrison

Copy link
Copy Markdown
Collaborator Author

Local Adversarial AI Review (Cursor Agent)

Reviewed Commit: eeaf4501853760d5774c99f6ebf463a0fd0cd71d

Summary Verdict

Verdict: Needs work — alternate-mode --exclude-engine / $AGENT_NAME resolution hard-fails or mis-maps engines on the skill’s documented invocation path.

Critical Findings

  1. execute_review("alternate") invoker exclusion is unsafe and disagrees with the skill wrappers. In scripts/pre-push-review.py, unknown exclude strings are resolved with if k in inv over short aliases (auto, agy, dto, dtc, codex, …), then if exclude_engine and not recognized: return None. Effects:
    • Hard fail: skills/adv/SKILL.md / skills/pre-push-review/SKILL.md always pass --exclude-engine "$AGENT_NAME" when set. Values like Gemini, human, or other non-alias names abort the review even when other engines are available. test_alternate_proceeds_without_invoker only covers AGENT_NAME=human without --exclude-engine, so it misses the skill’s real call shape.
    • Wrong engine excluded: "codex" in "…opencode…" is true, so non-exact OpenCode-like names exclude codex; "agy" in "agency" / "auto" in "automation" similarly mis-exclude antigravity/cursor.
    • Fix: exact/canonical match only (tokenized), never raw substring; treat unrecognized --exclude-engine as warn+ignore or require a known canonical id; add tests that mirror the skill’s AGENT_NAME--exclude-engine path.

Observations & Non-Blocking Suggestions

[MINOR] .agents/skills.json adds skills/adv and skills/pre-push-review while skills already covers them; redundant and may confuse discovery that expects a directory-of-skills layout.

[MINOR] Auto-mode “no CLI found” message omits cursor/agent even though detection priority includes it.

[MINOR] Cursor runner uses --trust while claiming plan-mode isolation; residual tool-use risk beyond deleting repo-local agent configs.

[INFO] Conductor track plan.md still describes engine order agy -> claude -> codex; code/spec/skill use claude -> cursor -> codex -> opencode -> agy.

[INFO] --post correctly fail-closes unless local HEAD equals remote PR head; primary pre-push use is local-only (documented weakly).

[INFO] Verdict parsing, SHA fingerprinting, fence/comment stripping, and forge disclosure (no robot emoji; marker sanitization) look solid and well-tested.

Verification Steps

  • Diff reviewed: PR Add skill and Cursor engine for local adversarial review #2255 vs origin/main at eeaf4501853760d5774c99f6ebf463a0fd0cd71d
  • Cross-checked execute_review alternate exclusion against skill bash and scripts/test_pre_push_review.py
  • Cross-checked posting path vs scripts/check-pr-fully-clean.py admission rules (human-authored clean comments are not treated as automated clean reviews)
  • Confirmed scripts/lib/fences.py exists for the new import

Reviewed-Commit: eeaf450


Posted by Cursor Agent (AI agent) --- not written by a human.

@github-actions

Copy link
Copy Markdown
Contributor

Warning

Claude review skipped — API credential or quota unavailable. No CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret is configured, or account API quota is exhausted. Re-trigger the review by pushing a new commit or re-running the workflow once configured/reset. View run

@github-actions

Copy link
Copy Markdown
Contributor

Warning

Claude review skipped — API credential or quota unavailable. No CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY secret is configured, or account API quota is exhausted. Re-trigger the review by pushing a new commit or re-running the workflow once configured/reset. View run

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.

2026-08-26 10:40 UTC

@d-morrison

Copy link
Copy Markdown
Collaborator Author

Local Adversarial AI Review (Google Antigravity)

Reviewed Commit: 6d5d07341827d4bfa9b9ba51293ad72979dd6c42

Summary Verdict

Verdict: Ready for merge

Critical Findings

None.

Observations & Non-Blocking Suggestions

  • [INFO] Engine Detection & Fallback: The auto-detection priority order (claude -> cursor -> codex -> opencode -> agy), rotation persistence via ~/.gemini/pre_push_review_state.json, and invoker exclusion logic prevent recursive self-invocation and gracefully degrade across available CLIs.
  • [INFO] Sandbox Isolation: Executing reviews inside an ephemeral shared worktree clone with repo-controlled agent configurations stripped (.claude, .cursor, .agents, etc.) mitigates malicious prompt injection vectors from untrusted diffs.
  • [INFO] Strict Verification & Attribution: SHA validation across local/remote PR heads prevents posting review findings against mismatched revisions, and forge comments adhere strictly to lab disclosure conventions without forbidden emoji markers.
  • [INFO] Argument Limits: Argument length gating (len(prompt.encode('utf-8')) > 800000) for CLI engines that accept prompts via command arguments prevents OS ARG_MAX / E2BIG buffer overflow errors on large diffs.

Verification Steps

  • Verified comprehensive unit test coverage in scripts/test_pre_push_review.py testing CLI dispatch contracts, prompt construction, verdict parser semantics, and error handling.
  • Audited canonical skill definitions (skills/adv/SKILL.md, skills/pre-push-review/SKILL.md) and verified parity with generated Codex wrappers in codex-skills/.
  • Verified CI workflow wiring in .github/workflows/validate.yml.

Reviewed-Commit: 6d5d073


Posted by Google Antigravity (AI agent) --- not written by a human.

@d-morrison
d-morrison merged commit 13061c9 into main Aug 26, 2026
9 checks passed
@d-morrison
d-morrison deleted the implement_adversarial_review_skill branch August 26, 2026 10:40
@d-morrison
d-morrison restored the implement_adversarial_review_skill branch August 26, 2026 10:42
cursor Bot pushed a commit that referenced this pull request Aug 26, 2026
Bring in #2255 (pre-push-review / adv skill).

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>
cursor Bot pushed a commit that referenced this pull request Aug 26, 2026
Address the Claude Opus child of f22a0f5 (bc-e67d9844):
authorize the empty pr-on-claim push when there is no report,
require both parse_report routes to produce the report body,
scope the import as the Cursor Cloud recovery instrument and
name #2255 pre-push-review.py / #2309, separate the Cloud
settings.json measurement from how that file got there, add a
Do-Confirm refusal-gate checklist, and name the adapter checkout
in both personas. Rebut restating the parse_report gate across
compact copies (required by the prior child of 9488dac).

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>
dem-extra1 added a commit that referenced this pull request Aug 26, 2026
…2272)

* start: Cursor Task Claude adversarial-reviewer routing (closes #2270)

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* cai: Cursor Task dispatches adversarial-reviewer; prefer Claude

A skipped GitHub claude-review is a different channel from Cursor Task.
When the conductor is not Claude, pass a listed Claude model so the
review is cross-vendor on blind spot as well as independent of intent.

Closes #2270.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Address Claude review of Cursor Task routing

Hedge that Cursor does not filter the persona tools list. Name the
Task model parameter. Cite self-review-fallback for the cross-vendor
half. Scope the dispatch to a repo that ships the persona. Move the
fragment pointer below the CLI pre-push-guard paragraph.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Address remaining review findings on Cursor Task routing

Qualify the self-review-fallback exclusivity claim to the CLI axis so a
non-Claude Cursor conductor is not told that codex is the only
self-dispatchable cross-vendor reviewer. Name foreground dispatch, hedge
that Cursor Task still grants Write schemas, and drop the restated
pass-model paragraph plus the forward pointer at the tool_result section.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Hedge Cursor Task routing claims the re-review falsified

Drop the omit-model vendor assertion the same section called unmeasured,
stop citing #1921 for a which-path question that issue does not track,
and stop calling codex the only self-dispatchable CLI: opencode is
another. Name the 2026-08-25 dispatch instead of "this session", and
state that this conductor's Task schema listed run_in_background and
did not list isolation.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Separate self-review dispatch from a cross-vendor second reviewer

A Claude Task child of a Grok conductor is independent of the author,
not of a GitHub claude-review primary, so it does not belong in the
Copilot/codex pairing. State that Cursor's adapter skips the pre-push
guard, name the Task-to-Agent mapping that trips the worktree warning,
and keep the dispatch recipe in memories/cursor.md rather than
restating it in the always-loaded fragments.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Check HEAD around the Cursor Task child, not git status

git status is clean over unpushed commits, so it cannot show a child
that committed. Record HEAD before the dispatch and compare it after.
Qualify AGENTS.md: Cursor's adapter skips the pre-push guard. Name
opencode as a CLI whose skill excludes this work, not as "only"'s
exception. File #2276 for the unmarkable isolation warning.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Date Cursor Task measurements in Pacific and sweep sibling "only" claims

Use 2026-08-25 PDT for every measurement this branch records, matching
the wraps on #2265/#2266. Retire the leftover "only cross-vendor
reviewer" sentences in the retired Antigravity skills. Name opencode as
outside the Copilot/codex pairing, with its OpenRouter caveat. Drop the
forward "below" pointer. Justify passing Claude as vendor independence
from the author, not as the intent-independence floor.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Retrieve Reviewed-Commit from the child report, not the Task JSON

The Task tool_result is identity-only, so a HEAD comparison that names
Reviewed-Commit has to say how to get that line: a harness paste of
the report, or batch-fetch-details. Compare the push refspec when it
is not HEAD. Hedge the Desktop guard skip: only the project adapter
path omits it. Drop the tools: causal claim the two persona copies
cannot support.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Fail closed when Reviewed-Commit cannot be retrieved

The posted PR comment is a record, not a gate. If the harness paste
and batch-fetch-details both lack Reviewed-Commit, do not push.
Hedge the AGENTS.md Task claim on the conductor listing Task. Keep
git status as the dirty-tree check beside the HEAD comparison.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Require Ready for merge and includeTranscripts on the fetch

A Needs more work report whose fingerprint matches HEAD is not a
push. batch-fetch-details needs includeTranscripts true or it writes
no transcript. File #2281 for the persona Write-schema leak. Unify
the Task-lists-adversarial-reviewer precondition.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Scope the skipped pre-push guard to Cursor Cloud, not any Task tool

A Claude Code session whose subagent tool is Task still has the
guard. Name Cursor Cloud in the sentences. Enabling Desktop
third-party Claude hooks beside the project adapter runs the
native guard and denies every push. Drop "and nothing else" from
the Copilot/codex pairing.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Fail closed on a Cursor Task miss and a HEAD mismatch

The Desktop-lockout sentence was an unverified claim: native Claude
hooks key on Bash, and Cursor's Shell path is not that adapter.
Strip it from AGENTS.md. Commit before dispatching, parse the last
line-start Verdict then the first Reviewed-Commit after it, and treat
a child error as the CLI-fallback case rather than as a forbidden
override.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Fail closed on an unclosed fence and name the hand comparison

A truncated report with an open fence is no verdict to the guard and
was a matching Ready under the hand recipe. State that rule, drop
the "instead" in AGENTS.md, and stop forbidding the override for a
reason the fragment already rejects.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* State nested-fence close rules and drop the incomplete refuse list

A nested fence of different lengths is the shape the guard's scanner
exists to catch. Pairing by count reads Needs more work as Ready.
Name the close rule, and treat any push that is not a single named
ref as uncovered rather than enumerating a subset of the guard.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Resolve shipped refs with dry-run and scope the skip to Cloud

A matching HEAD sha does not cover tags or extra branches a config
flag would add. git push --dry-run is the resolution step the guard
exempts from review. Scope the adapter skip to Cursor Cloud so
"active hook path" cannot be read as covering a paired Desktop
native path.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Fail closed on a dry-run miss and drop the Cloud-only skip

The adapter skip is a property of the adapter, not of Cloud.
A dry-run must use the same argv as the push, and an empty or
failed dry-run is not coverage. On Cursor Cloud the override
prefix is inert even after a Task error.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Blank the fingerprint search and compare the dry-run source ref

A fenced example sha that names HEAD is the hole the guard already
measured. Search verdict and fingerprint on the same blanked text.
A new-branch dry-run has no sha; the source ref, left of the arrow,
is what ships.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Restore the override list and record the branch name

The Cursor Cloud inert-prefix sentence had stolen the override
case list. Put it after the list. Record the branch name so a
new-branch dry-run whose source is HEAD is covered by the sha,
and require a paste to be the child's own message.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Make the transcript route the push gate

A paste of an author-composed Summary/Findings/Verdict block
is the wrap this file already records. batch-fetch-details
discharges the check. Prefix-match the fingerprint, skip a
trailing Approved, and treat Everything up-to-date as shipping
nothing rather than as a mismatch.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Break the Cursor Cloud override sentence after the semicolon

PR-event new-line-breaks failed on a 81-character added line in
skills/push/SKILL.md that packed two clauses around a mid-line
semicolon.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Align the Do-bullet dry-run clause with the no-sha carve-outs

The summary bullet refused any dry-run that did not print the
fingerprint sha, which is the first push of a new branch and an
Everything up-to-date retry. Name the hand comparison the
transcript route discharges, and qualify the mechanism section
as Claude Code.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: match Cursor Task review recipe to VERDICT_LINE and adapter scope

Address the Claude Opus Task child of ea38ed0:
allow an optional ATX prefix on the hand-parsed Verdict line,
treat the transcript as the source of the comparison rather than
a discharge of it, scope the inert ALLOW_UNREVIEWED_PUSH prefix
to wherever the adapter skips the guard, and qualify the pre-push
claim on CLAUDE.md and both persona copies.

Defer a parse_report CLI wrapper to #2299.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Address adversarial-review findings on the Cursor Task route

# Conflicts:
#	memories/cursor.md
#	skills/push/SKILL.md

* fix: pin Verdict emphasis position and name the adapter in fragments

Address the Claude Opus Task child of 1004f34:
optional ** on a Verdict line is only between the colon and the value,
an unrecognized final verdict fails closed,
the transcluded fragment names Morrison-Lab/ai-config,
the push-skill pronoun names the guard,
and the Copilot contrast no longer repeats the billing blurb.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: restore two-space indent on the Task-route Do-bullet

The parallel Address commit left four continuation lines at three
spaces, which nested them under the bullet rather than continuing it.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* Widen the no-override scope to Cursor desktop as well as Cloud

* fix: qualify the Cursor prefix-inert claim as Cloud-only

Address the Claude Opus Task child of 2c0ed03:
the adapter skip makes ALLOW_UNREVIEWED_PUSH inert on Cloud,
but desktop third-party Claude hooks still run the native guard,
so that prefix is the escape there.
Pin Reviewed-Commit to 7-40 hex, read dry-run stderr,
put the transcript subagent first, and restore dispatch-pairing scope.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: compare only the new tip on a Cursor Task dry-run

Git prints old..new on a fast-forward. Treating every displayed sha
as shipped would reject a normal push. Compare only the right-hand tip.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: handle git-push `...` dry-run ranges and #2241 provenance

The d8d5bc3 Claude child found the dry-run gate split on `..`
inside a forced-update `...` summary, skipped lowercasing the
fingerprint, treated an unrecognized Verdict: line ambiguously,
and left the adapter-skip claim undated at four sites.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: key the prefix on the hook system and call parse_report

The 0ae0db8 Claude child found Cloud home Claude settings after
bootstrap, so "no home settings" was a false mechanism, and the
hand-specified VERDICT_LINE recipe duplicated parse_report().

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: require HEAD to still be the recorded sha after the child

The 852aaf9 Claude child found the fingerprint gate's "or HEAD"
reading admitted a stale pre-dispatch sha, cited _rev_parse for
a check that lives in verify_review, and left pr-on-claim with
no action once the prefix was withheld.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: require a clean HEAD-matching parse_report on compact copies

The 51aa928 Claude child found AGENTS.md and skills/push treating
parse_report() as enough, a stale "Cloud has no ~/.claude" line,
and an exclusive "the one running" split that both-sources falsifies.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: name install-hooks as Cloud settings writer

Address the Claude Opus child of 9488dac (bc-1ddb6849):
stop attributing Cloud ~/.claude/settings.json to bootstrap.sh,
qualify the adapter prefix as for the adapter's sake, split
parse_report into decoder and verbatim-subagent routes, drop
restore/again for #2241, phrase the persona call as required,
name the last heading-bearing assistant text, and keep the
parse_report gate once in skills/push. Rebut 40-55 char wraps
(suggestion-weight; check-new-line-breaks is clean).

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: carve out empty pr-on-claim and qualify Cloud settings provenance

Address the Claude Opus child of f22a0f5 (bc-e67d9844):
authorize the empty pr-on-claim push when there is no report,
require both parse_report routes to produce the report body,
scope the import as the Cursor Cloud recovery instrument and
name #2255 pre-push-review.py / #2309, separate the Cloud
settings.json measurement from how that file got there, add a
Do-Confirm refusal-gate checklist, and name the adapter checkout
in both personas. Rebut restating the parse_report gate across
compact copies (required by the prior child of 9488dac).

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: make the pr-on-claim carve-out decidable and scoped

Address the Claude Opus child of 2da6c8c (bc-e24f4da3):
drop the false claim that provenance lives in #2299, decide
the empty-branch carve-out with git diff ...HEAD and require
disclosure, scope that carve-out in AGENTS.md and keep the
Claude Code prefix, name Morrison-Lab/ai-config's adapter in
AGENTS.md, and state adapter inertness unconditionally.
Filed #2310 for the remaining git-decidable gates.
Rebut mid-phrase wrapping (suggestion-weight; the blocking
new-line-breaks gate is clean).

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: scope Cursor review gates to the push checkout

Address the Claude Opus child of 751875a (bc-5f5b3190):
run all six refusal gates in the checkout whose push follows,
recover the report through a file, name the adapter checkout
in the push skill, add checklist pause points and killer items,
and treat per-ref up-to-date and ref-deletion dry-run forms
as not this procedure.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: correct deletion claim and tighten Cursor review gates

Address the Claude Opus child of 3466ef7 (bc-d5e046e3):
drop the false verify_review-allows-deletion claim,
state carve-out exemptions on every vacated gate,
relabel the gate list Read-Do with inline killer items,
require the verdict-line form on Cursor as well as Claude Code,
default ALLOW_UNREVIEWED_PUSH off until a native deny,
name tree-equality vs net-zero other commits,
record the #2241 landing sweep, and decode transcript.json once.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: grade Cursor reviews only from transcript.json

Address the Claude Opus child of 92be0ac (bc-63006d82):
parse_report always runs on route (a)'s transcript file,
split :branch vs --delete handling, drop intra-passage
native-deny restatements, and name parse_report as the
fingerprint reader in both persona copies.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: decide the pr-on-claim carve-out with two git commands

A Cursor Task child of f55e60c showed `_argv_push` excludes
`--delete` rather than ignoring it, that the transcript is not
the source for dry-run gates, and that the empty-branch carve-out
had no positive test. Import parse_report from the worktree hook.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: import parse_report from the worktree, not ~/.claude

A Cursor Task child of 95b55f4 showed ~/.claude/hooks is a
directory symlink into the primary checkout, not a copy, and that
writing the recovered report inside the push checkout trips the
empty-status gate. Keep compact copies; drop parent-obligation
lines from the reviewer persona.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: scope parse_report import to an ai-config worktree

A Cursor Task child of b39eaac showed the worktree-hook import
is unfollowable outside ai-config, that one matching dry-run line
was enough to pass gates 5-6, and that skills/push dropped the
missing-fingerprint refusal. Fetch only an adversarial-reviewer
child. Add CLAUDE.md to the #2241 sweep.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: fail-closed empty-commit carve-out and scoped hook import

Address Cursor Task child bc-74f98435 of a0124f7.
Drop the undefined Route (a) label.
Import ~/.claude/hooks only from a non-ai-config checkout.
Test the parse_report script, not the hooks/ directory.
Require both carve-out git commands to succeed.
Put provenance on gate 2.
Name the dry-run and source-ref checks.
Scope "all six" to the git commands.
Rebut collapsing AGENTS.md compact copies.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: last-assistant report selector and disclosure on post

Address Cursor Task child bc-16017d04 of dbf359d.
Return the structured report as the call's own message.
Post the recovered file then the disclosure marker.
Import ~/.claude/hooks only when that file exists
on a non-ai-config checkout; otherwise CLI review.
Add pr-on-claim.md to the #2241 sweep.
Take the last assistant text; do not scan backward.
Drop the circular step-0 link.
Name the file pair for the inode measurement.
Narrow the gate-list ordering claim.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: unify last-nonempty assistant selector and name messages

Address Cursor Task child bc-7e680d49 of 6d665f7.
Take the last non-empty assistant text; empty thinking and
tool_calls records are not candidates.
Iterate json.load's messages list.
Fix the pr-on-claim ALLOW_UNREVIEWED_PUSH=1 cause
(reviewer-call gate, not shipped-commit).
Gate 3 consumes gate 2's tuple.
Name the verdict-line form as parse_report's referent.
Say the recovered file is both the parse_report input
and the posted comment body.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: post recovered file only; quiet empty-commit carve-out

Address Cursor Task child bc-497f3009 of 882ed05.
Always recover the transcript file; a harness paste may
corroborate and is not the posted body.
Drop the ~/.claude/hooks import fallback (unfresh copy).
Compact copies name the transcript recovery and the
always-true reason not to import that path.
Use git diff --quiet HEAD^ HEAD for the empty-commit carve-out.
Drop the adjacent tuple-is-the-push-gate duplicate.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: name parse_report's accepted verdict forms

Address Cursor Task child bc-a728241f of 8be8093.
parse_report accepts Needs work, an optional heading, and
spaces around the colon; wrapping the whole verdict line
is no verdict.
Call parse_report from the worktree hook on the recovered
report. On a failed dispatch, write the CLI review to /tmp
and parse that file. Anchor the settings.json measurement
in docs/cursor-hook-mapping.md. Scope the push-skill
recovery to Cursor Cloud Task.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: require .get on transcript text and a bare fingerprint

Name that thinking records usually omit text, parse origin/main's
parse_report when the diff touches the hook, show Reviewed-Commit
as a bare line, and label the refusal-gate checklist as Read-Do.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: prefix empty-claim push and close parse_report's else

Put ALLOW_UNREVIEWED_PUSH=1 on the pr-on-claim copy-paste push,
restore the persona fail-closed else, name the worktree hook
script in compact copies, state the two Read-Do dependencies,
and say the recovered report file is the ARD input.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: move claim-push prefix out of the shared block

Keep the agent-neutral git push in the pr-on-claim recipe, show the
Claude Code prefix beside it, treat a missing fingerprint as a
CLI-review case, tell the reviewer to emit nothing after the
fingerprint, and scope the push-skill carve-out to the pushing
checkout.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

* fix: name the -u dry-run upstream line and decoder heading check

Treat Would set upstream as neither a mismatch nor other refs.
The decoder, not parse_report, decides the four headings.
Scope adapter-plus-native pairing to desktop.
Name both-conditions-passing as the empty-claim carve-out.

Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: dem-extra1 <dem-extra1@users.noreply.github.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.

1 participant