Skip to content

fix(detector): anchor scheme define slices at the outer paren (#2933) - #2960

Merged
squid-protocol merged 2 commits into
mainfrom
fix/2933-scheme-lisp-start-line
Sep 11, 2026
Merged

fix(detector): anchor scheme define slices at the outer paren (#2933)#2960
squid-protocol merged 2 commits into
mainfrom
fix/2933-scheme-lisp-start-line

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Summary

Scheme (recursive_block_lisp) has no ScopeParsingRegistry entry and is in neither the Mode-A nor Mode-C tuple, so it falls through to Mode B (_slice_by_braces). Mode B anchored each function at match.start(), but scheme's func_start leads with ^[ \t\n]*\( under re.M — its newline-inclusive class swallows the blank/blanked-comment lines before (define. The anchor therefore landed at the top of that whitespace run: line 1 for the first form, shifted early for every later one. block hides this (it's .strip()ped), but start_line/end_line were counted from the bad anchor, which also poisoned #2908's is_documented header window.

Fix: for the lisp family only, advance start_idx to the outer ( of the form. end_idx was already correct. Same set of matches → function count is unchanged; only line numbers move — keeping scheme consistent with every other language's declaration-start anchor semantics and staying a single slicer-layer change (#2812 rule 4).

Measured before→after on a 3-define file: add 1→4, mul 6→9, square 11→12 (each now lands on its real (define line).

Tests (tests/core_engine/test_detector.py)

  • test_detector_scheme_start_line_multi_declaration_2933 — correct start_line/end_line/loc per define (verified to fail pre-fix).
  • test_detector_scheme_start_line_char_literal_balance_2933#\(/#\) char literals and a ) inside a string don't derail the anchor or the balanced end.
  • Updated test_detector_is_documented_recursive_block_lisp_scheme (Epic: risk_documentation becomes a per-unit coverage ratio (Phase 4 score contract; child of #2812) #2908): its "far comment" case had leaned on the anchor bug (start_line always 1), so the gap now sits between the comment and the define to be genuinely outside the k=5 window; docstring refreshed.

Verification

  • tests/core_engine/ + tests/extraction/: 8316 passed, 4 skipped, 9 xfailed, 3 xpassed, 0 failed.
  • tests/ruff_audit.py --ci with pinned ruff==0.16.0: no new lint findings beyond baseline; format clean.

Rebless owed (follow-ups, per #2812 rule 4)

This slicer-layer change moves recorded line numbers, so after merge:

  • Regen both golden masters (scripts/update_golden_masters.sh); scope-check with bless_scope.py — expect scheme line columns only, no count change.
  • Open the keyword-rosetta corpus re-bless PR against engine main.

Label: rosetta:rebless-owed

Closes #2933

🤖 Generated with Claude Code

Scheme (recursive_block_lisp) has no ScopeParsingRegistry entry and is in
neither the Mode-A nor Mode-C tuple, so it falls through to Mode B
(_slice_by_braces). Mode B anchored each function at match.start(), but
scheme's func_start leads with `^[ \t\n]*\(` under re.M -- its newline-
inclusive class swallows the blank/blanked-comment lines before `(define`,
so the anchor landed at the top of that whitespace run: line 1 for the
first form, shifted early for every later one. block hides this (it's
.strip()ped), but start_line/end_line were counted from the bad anchor,
which also poisoned #2908's is_documented header window.

Advance start_idx to the outer `(` for the lisp family only. Same set of
matches -> function COUNT is unchanged; only the line numbers move. This
keeps scheme consistent with every other language's declaration-start
anchor semantics and stays a single slicer-layer change (#2812 rule 4).

Tests: multi-declaration start_line/end_line/loc guard, a `#\(`/`#\)`
char-literal + string-paren balance guard, and an update to the #2908
scheme is_documented test (its "far comment" case had leaned on the anchor
bug -- start_line always 1 -- so the gap now sits between the comment and
the define to be genuinely outside the k=5 window).

Slicer layer moves recorded line numbers -> golden-master + keyword-rosetta
re-bless owed as follow-ups.

Closes #2933

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014rUcYDAzYYCgrLdHyKBT9G
@squid-protocol squid-protocol added the rosetta:rebless-owed Intentionally moves keyword-rosetta counts; audit warns, corpus re-blesses after merge label Sep 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

The #2933 slicer fix anchors scheme (recursive_block_lisp) `define` forms
at their outer paren instead of match.start(), correcting start_line/
end_line for forms preceded by blank/comment lines. Both golden masters
move on exactly 3 scheme/racket corpus files (schemify.rkt, io.ss,
thread.rkt), and ONLY on `Start Line`/`End Line`:

  - schemify.rkt::schemify-linklet   33-1067 -> 83-1117 (50-line license header)
  - io.ss::extract-permission-mask   398-411 -> 400-413
  - thread.rkt::do-make-thread       186-1318 -> 190-1322

LOC, branch/arg counts, control-flow ratio, impact, is_public/is_documented,
function names and function COUNT are all unchanged; bless_scope.py reports
0 topological re-solve and no files newly parsed/excluded on both legs.

Regenerated per-leg in isolated venvs (full-precision: all deps; zero-dep:
PyYAML only) via tests/tools/update_golden_master.py against
language-crucible @ v1.2.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014rUcYDAzYYCgrLdHyKBT9G
@squid-protocol
squid-protocol marked this pull request as ready for review September 11, 2026 14:35
@squid-protocol
squid-protocol merged commit c9dc4bb into main Sep 11, 2026
31 checks passed
@squid-protocol
squid-protocol deleted the fix/2933-scheme-lisp-start-line branch September 11, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rosetta:rebless-owed Intentionally moves keyword-rosetta counts; audit warns, corpus re-blesses after merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

scheme: recursive_block_lisp has no slicing mode of its own, falls through to Mode_B_Braces; start_line wrong beyond the first declaration

1 participant