Skip to content

check_doc_gate invariants: file:line citations and cross-repo paths fail as nonexistent - #2307

Open
jaylfc wants to merge 1 commit into
devfrom
exec/tsk-zcnklp
Open

check_doc_gate invariants: file:line citations and cross-repo paths fail as nonexistent#2307
jaylfc wants to merge 1 commit into
devfrom
exec/tsk-zcnklp

Conversation

@jaylfc

@jaylfc jaylfc commented Aug 5, 2026

Copy link
Copy Markdown
Owner

CARD TITLE (intent, not commit subject): check_doc_gate invariants: file:line citations and cross-repo paths fail as nonexistent

Autonomous build of board card tsk-zcnklp.

Files:
scripts/check_doc_gate.py | 3 ++-
tests/test_doc_gate.py | 24 ++++++++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of file references that include source-line citations, such as path:123 or line ranges.
    • Prevented path-like text in external Markdown URLs from being incorrectly flagged.
  • Tests

    • Added coverage for line-number references and external URLs containing path-like content.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The documentation gate now excludes closing Markdown brackets from path tokens and removes trailing line references before validation. Tests cover file citations with line suffixes and external Markdown link URLs.

Changes

Documentation path parsing

Layer / File(s) Summary
Normalize documentation path tokens
scripts/check_doc_gate.py, tests/test_doc_gate.py
The path parser excludes closing brackets and removes line or line-range suffixes before checking paths. Tests cover path:123 citations and external Markdown link URLs.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main check_doc_gate changes for file-line citations and cross-repository paths.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 2
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch exec/tsk-zcnklp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gitar-bot

gitar-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix doc-gate invariant parsing for file:line citations and markdown links

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Stop doc-gate invariants from treating path:line citations as nonexistent repo paths.
• Prevent markdown link URLs from being captured as part of a repo-relative path token.
• Add regression tests covering both parsing edge cases.
Diagram

graph TD
  A["Doc text"] --> B["extract_path_tokens()"] --> C["_clean_token()"] --> D{"Ignore token?"}
  D -- "Yes" --> G["Skip"]
  D -- "No" --> E["Path exists? (repo_root/token)"] --> F["Record failure"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Parse markdown instead of regex tokenization
  • ➕ More precise: can limit to code spans, link text, etc.
  • ➕ Avoids regex edge cases around punctuation/URLs
  • ➖ Adds dependency and complexity for a lightweight invariant check
  • ➖ Still needs custom rules for what constitutes a "repo path" token

Recommendation: Keep the current targeted regex + normalization approach: it’s minimal, avoids new dependencies, and directly addresses the two observed false-positive classes (file:line citations and markdown link URL bleed). A full markdown parser would be justified only if token-extraction rules expand significantly beyond these simple invariants.

Files changed (2) +26 / -1

Bug fix (1) +2 / -1
check_doc_gate.pyHarden path-token extraction against :line suffixes and markdown link URLs +2/-1

Harden path-token extraction against :line suffixes and markdown link URLs

• Refines the path token regex to stop token capture at markdown delimiters like ')' and ']', preventing cross-repo URLs from being treated as part of a repo path. Extends token cleanup to strip trailing ':line' / ':line-range' / comma-separated line suffixes before performing existence checks.

scripts/check_doc_gate.py

Tests (1) +24 / -0
test_doc_gate.pyAdd regression tests for file:line citations and markdown link parsing +24/-0

Add regression tests for file:line citations and markdown link parsing

• Adds unit tests ensuring 'scripts/foo.sh:123'-style citations are normalized to the underlying file path and do not fail existence checks. Adds a test ensuring a markdown link with an external GitHub URL does not cause the URL portion to be consumed into the repo-path token.

tests/test_doc_gate.py

@jaylfc

jaylfc commented Aug 5, 2026

Copy link
Copy Markdown
Owner Author

nemotron-super review

VERDICT: LGTM
No blocking issues found.

Automated first-pass review by the nemotron-super lane. The lead still reviews before merge.

Comment thread scripts/check_doc_gate.py
# table), which would otherwise falsely flag deploy-time paths that never
# exist in the repo itself.
_TOKEN_RE = re.compile(r"(?<![\w/])(?:scripts|tinyagentos|docs|desktop)/[^\s`\"'|]+")
_TOKEN_RE = re.compile(r"(?<![\w/])(?:scripts|tinyagentos|docs|desktop)/[^\s`\"'|)\]]+")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Paths containing ) or ] in filenames will be truncated

The new _TOKEN_RE exclusion of ) and ] prevents markdown-link syntax from being consumed, but it also means any legitimate repo path containing these characters (e.g. docs/foo(bar).md) will be cut off at the first occurrence. This causes the existence check to look for a truncated, nonexistent path and report a false positive.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
scripts/check_doc_gate.py 46 Paths containing ) or ] in filenames will be truncated
Files Reviewed (2 files)
  • scripts/check_doc_gate.py - 1 issue
  • tests/test_doc_gate.py - 0 issues

Fix these issues in Kilo Cloud


Reviewed by step-3.7-flash · Input: 69.6K · Output: 23.6K · Cached: 502.1K

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Line strip misses punctuation 🐞 Bug ≡ Correctness
Description
In _clean_token(), the file:line suffix regex is applied before trimming _TRAILING_PUNCT, so
tokens like scripts/foo.sh:123, or scripts/foo.sh:123. keep :123 after punctuation is removed
and can be reported as nonexistent paths. This can still break check_referenced_paths() for common
prose citations that aren’t wrapped in backticks/brackets.
Code

scripts/check_doc_gate.py[R63-65]

+    token = re.sub(r":[0-9]+(?:-[0-9]+)?(?:,[0-9]+(?:-[0-9]+)?)*$", "", token)
    while token and token[-1] in _TRAILING_PUNCT:
        token = token[:-1]
Relevance

●●● Strong

Correctness edge-case; team routinely accepts small robustness fixes in scripts with tests.

PR-#1551
PR-#1542

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The code applies the end-anchored :line stripping before removing trailing punctuation (including
, and .), so punctuation prevents the anchored regex from matching; the existing/new tests only
cover the no-trailing-punctuation case.

scripts/check_doc_gate.py[52-70]
tests/test_doc_gate.py[178-201]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`_clean_token()` strips `:line` / `:line-range` suffixes before removing trailing punctuation. When a citation ends with punctuation (e.g. `scripts/foo.sh:123,`), the `re.sub(...$)` does not match (because of the comma/period), then punctuation is removed, leaving `scripts/foo.sh:123` which later fails existence checks.

## Issue Context
The PR is explicitly hardening doc-gate invariants for file:line citations; the current ordering means only the “no trailing punctuation” form is reliably handled.

## Fix Focus Areas
- scripts/check_doc_gate.py[56-70]
- tests/test_doc_gate.py[178-201]

## Suggested fix
- Move the `re.sub(r":[0-9]+...$", "", token)` to run **after** the `_TRAILING_PUNCT` trimming loop, or run it both before and after (second pass after punctuation trimming).
- Add regression tests covering at least:
 - `See scripts/foo.sh:123, for details.`
 - `See scripts/foo.sh:123. for details.`
 asserting `failures == []` when `scripts/foo.sh` exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context used
✅ Compliance rules (platform): 35 rules

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread scripts/check_doc_gate.py
Comment on lines +63 to 65
token = re.sub(r":[0-9]+(?:-[0-9]+)?(?:,[0-9]+(?:-[0-9]+)?)*$", "", token)
while token and token[-1] in _TRAILING_PUNCT:
token = token[:-1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. Line strip misses punctuation 🐞 Bug ≡ Correctness

In _clean_token(), the file:line suffix regex is applied before trimming _TRAILING_PUNCT, so
tokens like scripts/foo.sh:123, or scripts/foo.sh:123. keep :123 after punctuation is removed
and can be reported as nonexistent paths. This can still break check_referenced_paths() for common
prose citations that aren’t wrapped in backticks/brackets.
Agent Prompt
## Issue description
`_clean_token()` strips `:line` / `:line-range` suffixes before removing trailing punctuation. When a citation ends with punctuation (e.g. `scripts/foo.sh:123,`), the `re.sub(...$)` does not match (because of the comma/period), then punctuation is removed, leaving `scripts/foo.sh:123` which later fails existence checks.

## Issue Context
The PR is explicitly hardening doc-gate invariants for file:line citations; the current ordering means only the “no trailing punctuation” form is reliably handled.

## Fix Focus Areas
- scripts/check_doc_gate.py[56-70]
- tests/test_doc_gate.py[178-201]

## Suggested fix
- Move the `re.sub(r":[0-9]+...$", "", token)` to run **after** the `_TRAILING_PUNCT` trimming loop, or run it both before and after (second pass after punctuation trimming).
- Add regression tests covering at least:
  - `See scripts/foo.sh:123, for details.`
  - `See scripts/foo.sh:123. for details.`
  asserting `failures == []` when `scripts/foo.sh` exists.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@jaylfc

jaylfc commented Aug 6, 2026

Copy link
Copy Markdown
Owner Author

Good call taking the dedicated line-citation pattern over splitting on the first colon. Splitting would also truncate any path that legitimately contains one, and docs/weird:name.md survives here correctly. That part is right and I verified it.

The strip is in the wrong place in _clean_token, though, and the result is that four common citation shapes still false-positive.

re.sub(r":[0-9]+...$", ...) is anchored to end-of-string but runs BEFORE the _TRAILING_PUNCT loop, so any trailing punctuation defeats the anchor. Measured against this branch's own _clean_token:

scripts/foo.sh:123      -> 'scripts/foo.sh'        OK
scripts/foo.sh:123.     -> 'scripts/foo.sh:123'    citation ending a sentence
scripts/foo.sh:123,     -> 'scripts/foo.sh:123'    citation in a list
scripts/foo.sh:12:34    -> 'scripts/foo.sh:12'     file:line:col (ripgrep, compilers)
scripts/foo.sh:12-20)   -> 'scripts/foo.sh:12-20'  citation closing a paren
docs/weird:name.md      -> 'docs/weird:name.md'    OK, correctly preserved

Every one of those leaks a suffix into the existence check and fails. "See scripts/foo.sh:123." with a full stop is the ordinary way this gets written in prose, so this will fire in practice.

Worth naming why CI is green on it: test_file_line_citation_is_ignored covers the one shape that already works, the bare backticked form. The test is real and it passes, and the gate is still broken for the other four. A passing test over the happy shape is not evidence the class is handled.

Two-part fix, both in _clean_token:

  1. Move the re.sub to AFTER the _TRAILING_PUNCT while loop, so punctuation is gone before the anchor is applied.
  2. Wrap the suffix group in (?:...)+ so a repeated :line:col collapses in one pass.
_LINE_SUFFIX_RE = re.compile(r"(?::[0-9]+(?:-[0-9]+)?(?:,[0-9]+(?:-[0-9]+)?)*)+$")
...
    while token and token[-1] in _TRAILING_PUNCT:
        token = token[:-1]
    token = _LINE_SUFFIX_RE.sub("", token)

Verified against all of the above plus scripts/foo.sh:1,5-9, docs/f.md and docs/f.md.: every citation shape reduces to scripts/foo.sh, and docs/weird:name.md is still preserved.

Please extend the test to the four failing shapes rather than only the bare one, and confirm each fails on the current commit before the reorder. A test that has only ever been seen passing does not tell us the reorder did anything.

Unrelated to the above, flagging rather than blocking: _TOKEN_RE whitelists scripts|tinyagentos|docs|desktop, so a broken reference under app-catalog/, tests/ or changelog.d/ is invisible to the scan. That is pre-existing and not this PR's job, but it bounds what the invariants pass can claim to cover, and it is worth knowing before anyone reads a green invariants run as "all referenced paths are good".

@jaylfc jaylfc added the lead-blocked Lead has blocked this PR; gate_merge.sh refuses at exit 10. label Aug 6, 2026
@jaylfc

jaylfc commented Aug 9, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/test_doc_gate.py (2)

189-201: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Make the external URL test detect accidental URL extraction.

The local label and the URL both end with docs/agent-manual.md. If the URL path is incorrectly consumed, the extracted path still exists locally, so the test passes. Use a distinct nonexistent URL target, such as docs/external-only.md, while keeping docs/agent-manual.md as the local label.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_doc_gate.py` around lines 189 - 201, The
test_markdown_link_url_not_consumed_as_path test must use a distinct nonexistent
external URL target while retaining docs/agent-manual.md as the local link
label. Change the URL portion to reference a path such as docs/external-only.md
so accidental URL extraction produces a detectable failure.

178-187: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add regression cases for punctuation and repeated suffixes.

This test covers only scripts/foo.sh:123 without trailing punctuation. Add cases such as :123., :10-12,, and :12:34. These cases would currently fail normalization.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_doc_gate.py` around lines 178 - 187, Add regression coverage to
test_file_line_citation_is_ignored for file:line references followed by
punctuation and repeated suffixes, including scripts/foo.sh:123.,
scripts/foo.sh:10-12,, and scripts/foo.sh:12:34. Assert each citation is
normalized to the existing file and produces no failures through
dg.check_referenced_paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/check_doc_gate.py`:
- Around line 63-65: Update the token-normalization logic in
scripts/check_doc_gate.py to remove trailing punctuation before applying the
line-citation regex. Extend that regex to strip repeated colon-number suffixes,
including forms such as :12:34, while preserving existing range and
comma-separated citation handling.

---

Nitpick comments:
In `@tests/test_doc_gate.py`:
- Around line 189-201: The test_markdown_link_url_not_consumed_as_path test must
use a distinct nonexistent external URL target while retaining
docs/agent-manual.md as the local link label. Change the URL portion to
reference a path such as docs/external-only.md so accidental URL extraction
produces a detectable failure.
- Around line 178-187: Add regression coverage to
test_file_line_citation_is_ignored for file:line references followed by
punctuation and repeated suffixes, including scripts/foo.sh:123.,
scripts/foo.sh:10-12,, and scripts/foo.sh:12:34. Assert each citation is
normalized to the existing file and produces no failures through
dg.check_referenced_paths.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 99c9fa57-8491-495a-b4ce-4d0b704eecf5

📥 Commits

Reviewing files that changed from the base of the PR and between 94cbb74 and 9a8eb41.

📒 Files selected for processing (2)
  • scripts/check_doc_gate.py
  • tests/test_doc_gate.py

Comment thread scripts/check_doc_gate.py
Comment on lines +63 to 65
token = re.sub(r":[0-9]+(?:-[0-9]+)?(?:,[0-9]+(?:-[0-9]+)?)*$", "", token)
while token and token[-1] in _TRAILING_PUNCT:
token = token[:-1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Strip punctuation before removing line citations.

The regex runs before trailing punctuation is removed. Therefore, tokens such as scripts/foo.sh:123. or scripts/foo.sh:10-12, retain their line suffix after the punctuation loop and fail the existence check. The regex also does not remove repeated suffixes such as scripts/foo.sh:12:34.

Move the punctuation cleanup before the regex and extend the regex to support repeated :\d+ components.

Proposed fix
-    token = re.sub(r":[0-9]+(?:-[0-9]+)?(?:,[0-9]+(?:-[0-9]+)?)*$", "", token)
     while token and token[-1] in _TRAILING_PUNCT:
         token = token[:-1]
+    token = re.sub(
+        r":[0-9]+(?::[0-9]+)*(?:-[0-9]+)?(?:,[0-9]+(?::[0-9]+)*(?:-[0-9]+)?)*$",
+        "",
+        token,
+    )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
token = re.sub(r":[0-9]+(?:-[0-9]+)?(?:,[0-9]+(?:-[0-9]+)?)*$", "", token)
while token and token[-1] in _TRAILING_PUNCT:
token = token[:-1]
while token and token[-1] in _TRAILING_PUNCT:
token = token[:-1]
token = re.sub(
r":[0-9]+(?::[0-9]+)*(?:-[0-9]+)?(?:,[0-9]+(?::[0-9]+)*(?:-[0-9]+)?)*$",
"",
token,
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check_doc_gate.py` around lines 63 - 65, Update the
token-normalization logic in scripts/check_doc_gate.py to remove trailing
punctuation before applying the line-citation regex. Extend that regex to strip
repeated colon-number suffixes, including forms such as :12:34, while preserving
existing range and comma-separated citation handling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lead-blocked Lead has blocked this PR; gate_merge.sh refuses at exit 10.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant