Skip to content

fix(repo): follow-ups to #116: refusal block, fenced bodies, Copilot tool cwd - #322

Open
xaleryb wants to merge 4 commits into
intel:mainfrom
xaleryb:fix/116-review-followups
Open

xaleryb wants to merge 4 commits into
intel:mainfrom
xaleryb:fix/116-review-followups

Conversation

@xaleryb

@xaleryb xaleryb commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Follows up #116 with fixes for the three automated review findings left on its last head.

  • A refusal read as a clean review. convert_answer("codex-review", "Unable to review because the repository is unavailable.") -> [] appended -> expected: no block, i.e. a missing review (contract §6: no block means no review, not a clean one). Fix: an empty block is appended only after a clean-verdict sentence (No issues found., I did not find any issues in this change., Looks good to me.); otherwise the answer is returned unchanged.
  • A code fence in a finding body broke the block. A finding whose body holds a fenced sample -> findings_of() returns None -> expected: the finding. Fix: the block's JSON escapes each fence as \u0060\u0060\u0060, as the review oracles already do.
  • Copilot tool paths ignored the run's cwd. view of AGENTS.md with cwd sub -> AGENTS.md -> expected: sub/AGENTS.md. Fix: relative view, edit and apply_patch paths are joined to cwd, as shell reads already were.

Each fix comes with a test that fails without it.

…no block

An empty block says the review found nothing, so a refusal such as
"Unable to review." read as a clean review and passed a clean-diff control.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
A finding body with a fenced sample put a literal fence in the JSON, which
last_json() read as the block's end: the review graded as unparseable.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
…s cwd

A relative tool path was taken from the workspace root, so a reach scenario
started in sub/ recorded AGENTS.md for sub/AGENTS.md; shell reads already used cwd.

Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
@xaleryb
xaleryb requested a review from a team as a code owner October 31, 2026 05:36
@exai-bot

exai-bot commented Oct 31, 2026 •

Copy link
Copy Markdown

✅ OpenCodeReview: Review complete: 0 finding(s) across 6 selected item(s).

Review details
  • Commit reviewed: fc6c5b2 against merge base 1f95568
  • Coverage: 6 files in 1 groups
  • Engine: OpenCodeReview v1.13.3, us.openai.gpt-6.1-sol
  • Usage: 67k tokens (37k from cache), 12s
  • Tool calls: 8 (7 file_read, 1 code_search)
  • Repository CLI evaluation answers, traces, and contract updates: 6 files

Comment thread dokimi/dokimi/repos/cli_traces.py Resolved
@codecov-commenter

codecov-commenter commented Oct 31, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.04%. Comparing base (1f95568) to head (fc6c5b2).
⚠️ Report is 8 commits behind head on main.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #322      +/-   ##
==========================================
+ Coverage   94.00%   94.04%   +0.03%     
==========================================
  Files         292      297       +5     
  Lines       37823    38027     +204     
  Branches     6399     6425      +26     
==========================================
+ Hits        35557    35763     +206     
+ Misses       1458     1454       -4     
- Partials      808      810       +2     
Files with missing lines Coverage Δ
dokimi/dokimi/repos/answers.py 100.00% <100.00%> (ø)
dokimi/dokimi/repos/cli_traces.py 94.95% <100.00%> (+0.05%) ⬆️

... and 29 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

… path

Address review: posixpath kept ..\AGENTS.md as one name, so repo reach
missed the guidance read.

Thread: PRRT_kwDOVBg7g86yOVMM
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
@napetrov

Copy link
Copy Markdown
Contributor

pr-review, re-review at fc6c5b2 (new since 74ab336: one commit, _from_cwd now turns backslashes into separators before joining the cwd).

What the PR is for: follow-ups to #116. A refusal sentence no longer reads as a clean review, a code fence in a finding body no longer drops the block, and Copilot view/edit/apply_patch paths start in the run's cwd. This push fixes a gap in the last one: a Windows CLI's relative path ..\AGENTS.md was kept as one POSIX name, so repo reach missed the guidance read.

Findings (this round)

  • dokimi/dokimi/repos/cli_traces.py:757 (_from_cwd), question: a drive-less rooted Windows path \AGENTS.md with cwd sub now returns /AGENTS.md (absolute, outside the workspace); at 74ab336 it returned sub/\AGENTS.md. Both are wrong. Fix: decide what \x means and pin it with a test case.
  • dokimi/dokimi/repos/cli_traces.py:758 (_from_cwd), question: a POSIX file name with a literal backslash, cwd set, now splits into directories (a\b.txt → sub/a/b.txt; Copilot also runs on Linux). Fix: convert only for Windows runs or drive-qualified paths, or accept and say so in the docstring.
  • dokimi/tests/test_repo_cli_traces.py:370, nit: the new case only covers ..\AGENTS.md. Add dir\f.py (expect sub/dir/f.py) so the separator conversion itself is pinned.

No blocking findings. Probes: the new test fails on the 74ab336 source and passes on fc6c5b2 (tests/test_repo_cli_traces.py: 256 passed); ruff check clean on both files; _from_cwd and copilot_json probed on both trees (outputs in the review log).

Coverage: read the one-commit delta and its callers, ran the cli_traces tests and ruff, probed edge paths on head and the parent. Not checked: the rest of the PR (reviewed at 74ab336), the full test suite.

@vlad-perevezentsev vlad-perevezentsev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at fc6c5b2. The fence escape and the Copilot cwd join are right. The "no finding and no clean verdict gets no block" rule needs two changes before it goes in: the wider verdict regex now also takes back earlier findings, and an earlier clean verdict before a "Review finished." no longer counts. Details are in the line comments.

Agreed with @napetrov: a drive-less rooted \AGENTS.md with cwd sub gives /AGENTS.md (I see the same for \ws\a.py); a POSIX name with a literal backslash is split into directories (a\b.txt gives sub/a/b.txt); the test should pin dir\f.py.

What I ran, at fc6c5b2:

  • make ci-local --offline: 0 failed, 19 passed, 13 skipped (network-only steps); the test suite 11,642 passed, 58 skipped.
  • convert_answer on the same message lists at the base (1f95568) and at this head: a P1 followed by "Overall: looks good." or "Tests pass. No regressions." keeps the P1 on the base and gives [] here; ["No issues found.", "Review finished."] gives [] on the base and no block here; a refusal gives [] on the base and no block here, as intended.
  • _from_cwd on ~/…, C:foo, \ws\a.py, a\b.txt, dir\f.py with cwd sub.

Checked, no issues

  • Fenced bodies: the escaped block round-trips through findings_of, and ``` decodes back to the original backtick in the message.
  • Copilot cwd: view, edit and apply_patch all go through _from_cwd; absolute POSIX and drive paths are left alone, and .. is normalized before relative_path.
  • Docs and changelog: the contract and the (still unreleased) #116 fragment describe the new no-block case.

Comment on lines +48 to +50
+ r"|(?:i )?(?:did not|didn't|could not|couldn't) (?:find|identify|spot) any " + _NOUN + _WHERE
+ r"|(?:the )?(?:patch|change|commit|diff) (?:is|looks) (?:correct|good)|lgtm|looks good(?: to me)?)"
r"[ \t]*(?:[.!\n]|$)", re.I)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: The wider clean-verdict regex also widens the take-back at line 127, so a final "looks good" or "No regressions" now drops the findings of earlier messages.

messages=["- [P1] Leak — /w/a.py:3\n body", "Overall: looks good."] and [..., "Tests pass. No regressions."] now end in an empty ```json [] block, so a review that reported a P1 is graded as clean. On the base (1f95568) both keep the P1 finding: looks good and regressions did not match before.

Suggestion: keep the narrow regex for the take-back (a final message that says the earlier findings are gone) and use the wider one only to tell a clean review from a missing one at line 147. A test with a P1 message followed by "Overall: looks good." would catch it.

len(findings) + unparsed, len(findings))
return answer
if not findings and not answer.strip(): # an empty final answer is a missing review, as with one message
if not findings and not _CLEAN_VERDICT.search(texts[-1]): # an empty block is a claim the review made

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the final message has neither a finding nor a verdict, every message is read, but the clean-verdict check still looks only at texts[-1], which is known to hold none.

messages=["No issues found.", "Review finished."] now gets no block, so a clean review is graded as missing; on the base it got []. The docstring says such a final message "only points back at the review, so the block is built from every message".

Suggestion: if not findings and not any(_CLEAN_VERDICT.search(t) for t in texts): and a case for it in test_convert_answer_a_clean_verdict_gets_an_empty_block.

Comment on lines +147 to 148
if not findings and not _CLEAN_VERDICT.search(texts[-1]): # an empty block is a claim the review made
return answer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A clean answer that the verdict phrase list does not know now silently reads as a missing review.

These all get no block (checked): "I did not find any discrete, actionable bugs in this commit.", "No issues found in the changes.", "No major issues found.", "The changes look correct.". On the base each got []. Missing is the safe side, but nothing in the log says why the arm has no review, unlike the unparsed-marker case above.

Suggestion: log.warning("%s: no finding and no clean verdict in the answer; no findings block", fmt) before this return, so phrase-list gaps show up in a run.


def _from_cwd(path: str, cwd: str) -> str:
"""A tool's relative ``path`` joined to ``cwd``, the workspace-relative directory the CLI started in."""
if not cwd or path.startswith("/") or PureWindowsPath(path).is_absolute():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_from_cwd joins a home-relative path to the cwd.

A Copilot view of ~/.copilot/config.json with cwd sub is recorded as a read of sub/~/.copilot/config.json, a workspace path that does not exist; without a cwd it stays ~/.copilot/config.json.

Suggestion: also return path unchanged when it starts with ~.

@antonwolfy antonwolfy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at fc6c5b2. The fence escape and the Copilot cwd join hold up, and the refusal case now gets no block. The merge waits on points that @vlad-perevezentsev raised and that still hold at this head, and on questions to the author.

Points still open that I confirm:

I agree with @vlad-perevezentsev's four points, which still hold at this head:

  • The widened clean-verdict regex also widens the take-back: a P1 followed by "Overall: looks good." or "Tests pass. No regressions." ends in an empty block.
  • Only texts[-1] is checked, so ["No issues found.", "Review finished."] gets no block.
  • Clean answers outside the phrase list read as a missing review. New evidence: "**No issues found.**", "No actionable issues found." and "Nothing to report." each get no block.
  • A home-relative path is joined to the cwd: _from_cwd("~/x", "sub") returns sub/~/x.

@napetrov's questions on \AGENTS.md (a rooted drive-less path gives /AGENTS.md) and on a POSIX name with a literal backslash (a\b.txt gives sub/a/b.txt) wait for the author, as does the request to pin dir\f.py in the test. New evidence: _from_cwd("C:foo", "sub") returns sub/C:foo, so a drive-relative path needs the same decision.

What I ran, on a Linux review host at fc6c5b2:

  • make ci-local: 11,641 tests passed, 59 skipped; changed-line coverage 100% (13 lines).
  • Reproductions of convert_answer and _from_cwd for the points above, with the LLM transport mocked.
  • A mutation run on the new code: the no-verdict check, the fence escape, the Windows conversion and the apply_patch/view use are all caught. Dropping the is_absolute check or the startswith("/") check in _from_cwd passes the new test, because no case combines a Windows absolute path with a cwd.

Checked, no issues

  • Fenced bodies: a finding with a fenced sample round-trips through findings_of; at the base it returns None.
  • Refusal: "Unable to review..." gets no block here and [] at the base.
  • Commits: all four carry Signed-off-by.
  • Docs: the contract and the changelog fragment describe the no-block case.

This branch has not been deployed

No deployments
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.

6 participants