From b5f3128f9f06ccf45e384c9f45ef1f2fbf1fdaf4 Mon Sep 17 00:00:00 2001 From: manumishra12 Date: Sat, 11 Jul 2026 14:44:35 -0700 Subject: [PATCH] okf: don't end a section at a fenced '#' comment line (bundle_tools) _section_content_lines treated any line starting with '# ' as a heading, including '#' comment lines inside fenced code blocks. A code fence in a '# Schema' or '# Citations' section therefore ended the section early, so _schema_field_names and _citation_entry_count under-read it and the web-pass augmentation guard in write_concept_doc could compare truncated field or citation sets. Track fenced code blocks (backtick and tilde fences) and only treat '# ' lines outside a fence as headings. Adds regression tests. --- okf/src/reference_agent/tools/bundle_tools.py | 12 +++++- okf/tests/test_bundle_tools.py | 38 ++++++++++++++++++- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/okf/src/reference_agent/tools/bundle_tools.py b/okf/src/reference_agent/tools/bundle_tools.py index 18d42cc5..2d898f73 100644 --- a/okf/src/reference_agent/tools/bundle_tools.py +++ b/okf/src/reference_agent/tools/bundle_tools.py @@ -18,12 +18,20 @@ def _section_content_lines(body: str, heading: str) -> list[str]: - """Return non-blank lines under a top-level `# heading` section.""" + """Return non-blank lines under a top-level `# heading` section. + + Fenced code blocks are treated as content: a `#`-prefixed line inside a + fence is not mistaken for a heading, so it does not prematurely end the + section. + """ in_section = False + in_fence = False out: list[str] = [] for line in body.splitlines(): stripped = line.strip() - if stripped.startswith("# "): + if stripped.startswith("```") or stripped.startswith("~~~"): + in_fence = not in_fence + elif not in_fence and stripped.startswith("# "): in_section = stripped == heading continue if in_section and stripped: diff --git a/okf/tests/test_bundle_tools.py b/okf/tests/test_bundle_tools.py index bf60f262..95f82639 100644 --- a/okf/tests/test_bundle_tools.py +++ b/okf/tests/test_bundle_tools.py @@ -5,7 +5,11 @@ import pytest -from reference_agent.tools.bundle_tools import write_concept_doc +from reference_agent.tools.bundle_tools import ( + _schema_field_names, + _section_content_lines, + write_concept_doc, +) from reference_agent.tools.context import ( clear_web_state, set_context, @@ -148,3 +152,35 @@ def test_web_pass_skips_guard_for_non_bigquery_table_types(tmp_path): "# Citations\n[1] [Src](https://src)\n", ) assert "error" not in result + + +def test_section_survives_fenced_hash_comment(): + body = ( + "# Schema\n" + "- `id` STRING\n" + "```\n" + "# looks like a heading but is code\n" + "```\n" + "- `name` STRING\n" + "# Other\n" + "- ignored\n" + ) + text = "\n".join(_section_content_lines(body, "# Schema")) + assert "`id`" in text + assert "`name`" in text + assert "ignored" not in text + + +def test_schema_fields_survive_fenced_hash_comment(): + body = ( + "# Schema\n" + "- `id` STRING\n" + "```sql\n" + "# partition by ingestion day\n" + "SELECT 1\n" + "```\n" + "- `name` STRING\n" + "# Citations\n" + "[1] [BQ](https://bq)\n" + ) + assert _schema_field_names(body) == {"id", "name"}