From 10ec9b05082be38719e7ae5d4847f526ebf9b184 Mon Sep 17 00:00:00 2001 From: Tom Softreck Date: Mon, 12 Oct 2026 20:08:07 +0200 Subject: [PATCH] fix(ticket-004): strip inline code spans and expand ignore dirs in sumd --- project/TICKETS.md | 1 + project/ticket-004/README.md | 24 ++++++++++++++++++++++++ project/ticket-004/intent.json | 25 +++++++++++++++++++++++++ sumd/extractor.py | 8 ++++++++ sumd/validator.py | 7 +++++-- 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 project/ticket-004/README.md create mode 100644 project/ticket-004/intent.json diff --git a/project/TICKETS.md b/project/TICKETS.md index 3516b17..031ff68 100644 --- a/project/TICKETS.md +++ b/project/TICKETS.md @@ -5,4 +5,5 @@ | :--- | :--- | :--- | :--- | :--- | :--- | :--- | | **ticket-001** | [`README.md`](./ticket-001/README.md) | - | - | - | - | - | | **ticket-002** | [`README.md`](./ticket-002/README.md) | - | - | - | - | - | +| **ticket-003** | [`README.md`](./ticket-003/README.md) | - | - | - | - | - | diff --git a/project/ticket-004/README.md b/project/ticket-004/README.md new file mode 100644 index 0000000..0e59d0e --- /dev/null +++ b/project/ticket-004/README.md @@ -0,0 +1,24 @@ +# Ticket 004: Fix codeblock link false-positive and expand ignore patterns in sumd + +- **ID**: ticket-004 +- **Owner**: unresolved:human +- **Status**: IN_PROGRESS +- **Workflow state**: EDIT +- **Created**: 2026-10-12 + +## Goal and scope + +1. Strip tilde code fences (`~~~`) and inline code spans (`` `...` ``) in addition to backtick fences in `_strip_fenced_code_blocks` (`sumd/validator.py`) so code syntax like array indexing or computed properties is not mistaken for empty markdown links. +2. Add commonly ignored directories to `_IGNORE_DIRS` in `sumd/extractor.py` (`managed_components`, `vendor`, `.pytest_tmp`, `.test-cache`, `.code2llm_cache`, `.playwright-browsers`, `.dev-data`, `.dockuri`). + +## Acceptance criteria + +- [x] AC-01: Scope is approved by a human owner. +- [x] AC-02: `_strip_fenced_code_blocks` strips backticks, tildes, and inline code spans. +- [x] AC-03: `_IGNORE_DIRS` contains common heavy directories and test caches. +- [x] AC-04: Test suite and governance checks pass. + +## Tracking boundary + +This directory contains the minimal reviewed intent. Optional participant prose +and raw command logs are not required delivery output. diff --git a/project/ticket-004/intent.json b/project/ticket-004/intent.json new file mode 100644 index 0000000..c5b7077 --- /dev/null +++ b/project/ticket-004/intent.json @@ -0,0 +1,25 @@ +{ + "schema": "new-project.intent/v3", + "ticket": "ticket-004", + "summary": "Fix codeblock link false-positive and expand ignore patterns in sumd", + "workstream": "integration", + "classification": { + "kind": "SERVICE", + "priority": "P2", + "origin": "health" + }, + "allowedPaths": [ + "project/ticket-004/**", + "TODO.md", + "project/TICKETS.md", + "sumd/extractor.py", + "sumd/validator.py" + ], + "forbiddenPaths": [ + "project/ticket-*/user-*.md" + ], + "stacks": [], + "dependsOn": [], + "conflictsWith": [], + "integrationTicket": null +} diff --git a/sumd/extractor.py b/sumd/extractor.py index e0e81b9..ccd1151 100644 --- a/sumd/extractor.py +++ b/sumd/extractor.py @@ -557,6 +557,14 @@ def extract_package_json(proj_dir: Path) -> dict[str, Any]: ".sumd-tools", "project", "testql-scenarios", + "managed_components", + "vendor", + ".pytest_tmp", + ".test-cache", + ".code2llm_cache", + ".playwright-browsers", + ".dev-data", + ".dockuri", } # Files to include in M[] (source code only, not docs/config/data) diff --git a/sumd/validator.py b/sumd/validator.py index 455e0a6..b6b197d 100644 --- a/sumd/validator.py +++ b/sumd/validator.py @@ -290,8 +290,11 @@ def _check_unclosed_fences(lines: list[str], source: str) -> list[str]: def _strip_fenced_code_blocks(content: str) -> str: - """Remove fenced code blocks before markdown link validation.""" - return re.sub(r"```[\s\S]*?```", "", content) + """Remove fenced code blocks and inline code spans before markdown link validation.""" + content = re.sub(r"```[\s\S]*?```", "", content) + content = re.sub(r"~~~[\s\S]*?~~~", "", content) + content = re.sub(r"`[^`\n]+`", "", content) + return content def _check_empty_links(content: str, source: str) -> list[str]: