Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,9 @@ release_baseline.yaml 的 audited_sha
Direct 根据 PR 描述返回至多 3 个精确知识路由和审查门禁;Strict 返回
`run_id`。`repo_path` 可临时指定 Strict 使用的本地 checkout。
- `validate_direct_review(subtraction_signal, subtraction?,
minimality_proof?, final_comment_count=1)`:Direct 最终输出前的完成检查。
minimality_proof?, final_comment_count=1, evidence_head_sha)`:Direct 最终
输出前的完成检查。`evidence_head_sha` 必须是本次审查固定的 head 提交,
证明引用的源码和验证结果都读取自该版本而非本地工作区的其他分支。
普通小修改传 `subtraction_signal="none"`;存在新增或扩张结构时传
`"triggered"`,并提供减法项或最小性证明。
- `get_review_status(run_id)`:查看 Strict 后台任务的步骤和进度。
Expand Down
5 changes: 4 additions & 1 deletion docs/codex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,10 @@ Restart Codex after installation. Use `/mcp` or `codex mcp list` to confirm that
Strict starts the packaged workflow and accepts `review_depth` plus an
optional local checkout override through `repo_path`.
- `validate_direct_review(subtraction_signal, subtraction?, minimality_proof?,
final_comment_count=1)`: `none` completes an ordinary small fix without a
final_comment_count=1, evidence_head_sha)`: `evidence_head_sha` must be the
frozen head commit every cited source file and validation result was read
at; evidence read from another local revision does not complete the review.
`none` completes an ordinary small fix without a
minimality proof. `triggered` requires anchored subtraction actions or
concrete evidence that the inspected scope is already minimal.
- `update_knowledge(repo?)`: keeps `repo` only for call compatibility and
Expand Down
10 changes: 7 additions & 3 deletions integrations/cursor/imreview.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ call `review` once with
`quick_map` in each returned `knowledge_routes` item. Do not open the full route
file unless a concrete ambiguity blocks source review, and do not walk
`AGENTS.md`, `CLAUDE.md`, repository indexes, or model catalogs. Inspect the
live target and return only evidence-backed findings with file and line
references.
target at the pinned head SHA and return only evidence-backed findings with
file and line references. Read every file cited as evidence at that commit;
when the local checkout does not contain it, fetch the PR head ref or read
files by ref, and never cite the working tree as evidence for a different
revision.
Follow the returned `execution_budget`. Extend it once only when a concrete
unresolved P1/high-risk contract remains, and state that question before
extending.
Expand All @@ -35,7 +38,8 @@ Do not wait for CI completion or resolved mergeability before the progress
update. Mark early findings as preliminary and continue the review. This update
is not a GitHub comment; do not post an interim review.

Before finalizing, classify `subtraction_signal`. Use `none` without a
Before finalizing, call `validate_direct_review` with the pinned head SHA as
`evidence_head_sha` and classify `subtraction_signal`. Use `none` without a
minimality proof when the diff does not add or expand a helper, class, fallback,
compatibility branch, or public behavior. Use `triggered` for those changes and
only then provide subtraction evidence.
Expand Down
10 changes: 7 additions & 3 deletions plugins/infermatrix-copilot/skills/imreview/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ with `mode="direct"` plus the
collected `title`, `body`, and `changed_files`. Use the embedded `quick_map` in
each returned `knowledge_routes` item. Do not open the full route file unless a
concrete ambiguity blocks source review, and do not reopen `AGENTS.md`,
`CLAUDE.md`, repo indexes, or model catalogs. Inspect the live code and return
only evidence-backed findings with file/line references.
`CLAUDE.md`, repo indexes, or model catalogs. Inspect the code at the pinned
head SHA and return only evidence-backed findings with file/line references.
Read every file cited as evidence at that commit; when the local checkout does
not contain it, fetch the PR head ref or read files by ref, and never cite the
working tree as evidence for a different revision.
Treat the returned `execution_budget` as a hard ceiling. At the limit, return
the supported verdict plus any remaining validation gap. Extend it once by the
returned allowance only when a concrete unresolved P1/high-risk contract
Expand All @@ -36,7 +39,8 @@ no-issue conclusion; do not add searches only for confidence.
Do not wait for CI completion or resolved mergeability before the progress
update. Mark early findings as preliminary and continue the review. This update
is not a GitHub comment; do not post an interim review.
Before finalizing, classify `subtraction_signal`. Use `none` without a
Before finalizing, call `validate_direct_review` with the pinned head SHA as
`evidence_head_sha` and classify `subtraction_signal`. Use `none` without a
minimality proof when the diff does not add or expand a helper, class, fallback,
compatibility branch, or public behavior. Use `triggered` for those changes and
only then provide subtraction evidence.
Expand Down
33 changes: 28 additions & 5 deletions src/infermatrix_copilot/thin_mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def _knowledge_root() -> Path:
)
_DIRECT_REVIEW_CHECKLIST = [
"Freeze one base/head snapshot and collect PR intent, diff, mergeability, and CI once.",
"Read every source file cited as evidence at the frozen head SHA; when the local checkout does not contain that commit, fetch the PR head ref or read files by ref instead of trusting the working tree.",
"Immediately after snapshot metadata returns, report head SHA, CI, mergeability, and preliminary findings in the host conversation; do this before reading knowledge, searching source, or running tests.",
"Call Direct once with the collected title, body, and changed_files; read only the returned knowledge_routes and stop knowledge navigation.",
"After the progress update, run independent knowledge/source and validation tracks concurrently.",
Expand Down Expand Up @@ -208,6 +209,7 @@ def _knowledge_root() -> Path:
}
_SUBTRACTION_ACTIONS = {"DELETE", "DEFER", "INLINE", "MERGE", "MOVE"}
_SUBTRACTION_SIGNALS = {"none", "triggered"}
_EVIDENCE_HEAD_SHA = re.compile(r"[0-9a-f]{7,40}")


def _normalize_repo(repo: str) -> str:
Expand Down Expand Up @@ -559,17 +561,22 @@ def _direct_completion_result(
subtraction: list[dict[str, str]] | None = None,
minimality_proof: dict[str, str] | None = None,
final_comment_count: int = 1,
evidence_head_sha: str = "",
) -> dict:
"""Mechanically gate Direct completion on subtraction classification.

This deliberately checks structure, not whether the review evidence is
true. A diff without a subtraction trigger can finish after explicitly
declaring ``none``. Triggered diffs still need actionable subtraction or
concrete evidence that the inspected scope is already minimal.
``evidence_head_sha`` forces an explicit declaration that every cited
source file and validation result was read at the frozen head commit,
not at whatever revision the local working tree happened to hold.
"""
subtraction_signal = str(subtraction_signal).strip().casefold()
subtraction = subtraction or []
minimality_proof = minimality_proof or {}
evidence_head_sha = str(evidence_head_sha).strip().casefold()
missing: list[str] = []

if final_comment_count != 1:
Expand All @@ -578,6 +585,13 @@ def _direct_completion_result(
if subtraction_signal not in _SUBTRACTION_SIGNALS:
missing.append("subtraction_signal must be 'none' or 'triggered'")

if not _EVIDENCE_HEAD_SHA.fullmatch(evidence_head_sha):
missing.append(
"evidence_head_sha must be the frozen head commit SHA "
"(7-40 hex characters) that every cited source file and "
"validation result was read at"
)

malformed_subtractions: list[int] = []
for index, item in enumerate(subtraction):
if not isinstance(item, dict):
Expand Down Expand Up @@ -633,6 +647,7 @@ def _direct_completion_result(
"status": "complete" if complete else "partial_review",
"publish_ready": complete,
"final_comment_count": final_comment_count,
"evidence_head_sha": evidence_head_sha,
"subtraction_signal": subtraction_signal,
"subtraction_required": subtraction_signal == "triggered",
"subtraction_items": len(subtraction),
Expand Down Expand Up @@ -712,9 +727,12 @@ def build_mcp(
"verdict at the limit. Extend it once by the returned allowance "
"only for a stated unresolved P1/high-risk contract. Continue "
"reviewing without "
"posting an early GitHub comment. Before treating a Direct review as "
"complete or posting its only final comment, call "
"validate_direct_review. Mark subtraction_signal=none when the diff "
"posting an early GitHub comment. Read every source file cited as "
"evidence at the frozen head SHA; fetch the PR head ref when the "
"local checkout holds another revision. Before treating a Direct "
"review as complete or posting its only final comment, call "
"validate_direct_review with that evidence_head_sha. Mark "
"subtraction_signal=none when the diff "
"does not add or expand a helper, class, fallback, compatibility "
"branch, or public behavior. Only subtraction_signal=triggered "
"requires subtraction evidence. "
Expand Down Expand Up @@ -799,6 +817,7 @@ def run() -> dict:
},
"completion_gate": {
"tool": "validate_direct_review",
"evidence_head_sha": "Required: the frozen head commit SHA every cited source file and validation result was read at; fetch the PR head ref when the local checkout holds another revision.",
"subtraction_signal": {
"none": "No helper/class/fallback/compatibility/public-behavior expansion; no subtraction evidence required.",
"triggered": "Require subtraction items or minimality_proof.",
Expand Down Expand Up @@ -856,21 +875,25 @@ def validate_direct_review(
subtraction: list[dict[str, str]] | None = None,
minimality_proof: dict[str, str] | None = None,
final_comment_count: int = 1,
evidence_head_sha: str = "",
) -> dict:
"""Validate the Direct completion gate before the only final comment.

Use ``subtraction_signal='none'`` when the diff does not add or expand a
helper, class, fallback, compatibility branch, or public behavior. Use
``'triggered'`` for those diffs, then supply actionable subtraction
items or concrete minimality evidence. A ``partial_review`` result is
not a completed Direct review.
items or concrete minimality evidence. Pass ``evidence_head_sha`` as
the frozen head commit every cited source file and validation result
was read at; a review whose evidence came from another revision is not
complete. A ``partial_review`` result is not a completed Direct review.
"""
started = time.perf_counter()
result = _direct_completion_result(
subtraction_signal=subtraction_signal,
subtraction=subtraction,
minimality_proof=minimality_proof,
final_comment_count=final_comment_count,
evidence_head_sha=evidence_head_sha,
)
result.setdefault("diagnostics", {})["timing_ms"] = {
"validate_direct_review": int(
Expand Down
4 changes: 4 additions & 0 deletions test/test_imreview_output_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ def test_imreview_returns_github_style_findings(prompt_path: Path) -> None:
assert "bounded `rg` searches" in prompt
assert "import/version compatibility preflight" in prompt
assert "head SHA and an environment fingerprint" in prompt
assert "at the pinned head SHA" in prompt
assert "fetch the PR head ref" in prompt
assert "never cite the working tree as evidence" in prompt
assert "`evidence_head_sha`" in prompt
49 changes: 46 additions & 3 deletions test/test_thin_mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ def test_direct_entrypoints_do_not_resolve_repo(monkeypatch):
and "environment fingerprint" in item
for item in review["first_review_checklist"]
)
assert any(
"at the frozen head SHA" in item
and "fetch the PR head ref" in item
for item in review["first_review_checklist"]
)
assert review["progress_update"] == {
"deadline_seconds": 60,
"channel": "host_conversation",
Expand All @@ -151,6 +156,7 @@ def test_direct_entrypoints_do_not_resolve_repo(monkeypatch):
}
assert review["completion_gate"] == {
"tool": "validate_direct_review",
"evidence_head_sha": "Required: the frozen head commit SHA every cited source file and validation result was read at; fetch the PR head ref when the local checkout holds another revision.",
"subtraction_signal": {
"none": "No helper/class/fallback/compatibility/public-behavior expansion; no subtraction evidence required.",
"triggered": "Require subtraction items or minimality_proof.",
Expand Down Expand Up @@ -294,8 +300,11 @@ def test_direct_routes_model_rules_without_index_navigation():
assert all(route["quick_map"] for route in routing["routes"])


_HEAD_SHA = "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b"


def test_direct_completion_requires_subtraction_signal_classification():
result = _direct_completion_result()
result = _direct_completion_result(evidence_head_sha=_HEAD_SHA)

assert result["status"] == "partial_review"
assert result["publish_ready"] is False
Expand All @@ -304,17 +313,46 @@ def test_direct_completion_requires_subtraction_signal_classification():
]


def test_small_fix_accepts_no_subtraction_signal_without_full_proof():
def test_direct_completion_requires_evidence_head_sha():
result = _direct_completion_result(subtraction_signal="none")

assert result["status"] == "partial_review"
assert result["publish_ready"] is False
assert result["missing"] == [
"evidence_head_sha must be the frozen head commit SHA "
"(7-40 hex characters) that every cited source file and "
"validation result was read at"
]


def test_direct_completion_rejects_non_commit_evidence_reference():
result = _direct_completion_result(
subtraction_signal="none",
evidence_head_sha="main",
)

assert result["status"] == "partial_review"
assert result["publish_ready"] is False


def test_small_fix_accepts_no_subtraction_signal_without_full_proof():
result = _direct_completion_result(
subtraction_signal="none",
evidence_head_sha=_HEAD_SHA,
)

assert result["status"] == "complete"
assert result["publish_ready"] is True
assert result["subtraction_required"] is False
assert result["subtraction_items"] == 0
assert result["evidence_head_sha"] == _HEAD_SHA


def test_triggered_subtraction_requires_evidence():
result = _direct_completion_result(subtraction_signal="triggered")
result = _direct_completion_result(
subtraction_signal="triggered",
evidence_head_sha=_HEAD_SHA,
)

assert result["status"] == "partial_review"
assert result["publish_ready"] is False
Expand All @@ -329,6 +367,7 @@ def test_triggered_subtraction_requires_evidence():
def test_issue_5559_trigger_accepts_single_comment_with_subtractions():
result = _direct_completion_result(
subtraction_signal="triggered",
evidence_head_sha=_HEAD_SHA,
subtraction=[
{
"anchor": "examples/offline_inference/text_to_image/text_to_image.py:358",
Expand All @@ -353,6 +392,7 @@ def test_issue_5559_trigger_accepts_single_comment_with_subtractions():
def test_direct_completion_accepts_concrete_minimality_proof():
result = _direct_completion_result(
subtraction_signal="triggered",
evidence_head_sha=_HEAD_SHA,
minimality_proof={
"scope_ledger": "Every changed production file maps to the requested API fix.",
"abstraction_census": "No new helper, class, projection, fallback, or compatibility branch.",
Expand All @@ -368,6 +408,7 @@ def test_direct_completion_accepts_concrete_minimality_proof():
def test_direct_completion_rejects_malformed_subtraction_and_two_comments():
result = _direct_completion_result(
subtraction_signal="triggered",
evidence_head_sha=_HEAD_SHA,
subtraction=[{
"anchor": "examples/task.py:120",
"action": "",
Expand All @@ -384,6 +425,7 @@ def test_direct_completion_rejects_malformed_subtraction_and_two_comments():
def test_direct_completion_does_not_count_bug_fixes_as_subtraction():
result = _direct_completion_result(
subtraction_signal="triggered",
evidence_head_sha=_HEAD_SHA,
subtraction=[{
"anchor": "src/adapter.py:42",
"action": "FIX the incorrect default value",
Expand All @@ -398,6 +440,7 @@ def test_direct_completion_does_not_count_bug_fixes_as_subtraction():
def test_no_signal_rejects_contradictory_subtraction_evidence():
result = _direct_completion_result(
subtraction_signal="none",
evidence_head_sha=_HEAD_SHA,
subtraction=[{
"anchor": "src/adapter.py:42",
"action": "DELETE unused compatibility branch",
Expand Down