Header detection over-matched on line-comment file types: lineCommentRegion
tolerated truly-blank lines between comment lines, so a layout of
"license header / blank line / unrelated file doc comment" collapsed into a
single detected span. render.replaceSpan then deleted that doc comment on
relicense or year-refresh. This is safety-critical -- a false positive in
detection means apply removes real source content.
Two fixes:
1. lineCommentRegion now stops at the first non-comment line, and a
truly-blank line ends the contiguous run. Our own rendered headers never
contain a truly-blank internal line: the renderer emits separator lines as
a bare comment prefix (e.g. "#" or "//"), which is still a comment line and
stays in-region. Confining the region to contiguous comment lines is
therefore byte-idempotent for headers we write, while refusing to absorb a
foreign comment that a blank line has separated from the header.
2. spdxIdentifierTag now requires the SPDX-License-Identifier tag to begin a
comment line (leading whitespace allowed) rather than matching anywhere via
strings.Index. A comment that merely mentions the tag mid-prose is
documentation, not a managed header, and must not qualify a foreign comment
for replacement.
When in doubt the detector now under-detects (leaves a foreign comment alone)
rather than over-detecting. Block-comment multi-block de-stacking (issue #30
LOW) is deferred: spanning only the first block is the safe, under-detecting
choice.
Idempotency and round-trip are preserved and verified by the existing
TestSpliceIdempotent / TestApplyFile* suites plus a new end-to-end applier
test that relicenses a line-comment file and asserts a doc comment below the
header's blank separator survives. The enshrining region test was updated to
require the corrected contiguous behavior with the safety rationale inline.