1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Ownership marker recognition shared by stamping and verification.
/// The substring shared by every marker spelling alef emits or must recognize on read-back,
/// matched case-insensitively (see [`line_has_marker`]). A single substring subsumes every
/// capitalization variant produced across backends -- `"auto-generated by alef"`, `"Auto-generated
/// by alef"`, `"Generated by alef"`, `"generated by alef"` -- and also Go's own `"Code generated
/// ... by alef"` convention, which alef should honour rather than fight. Previously this was two
/// case-sensitive literals (`"auto-generated by alef"` / `"Generated by alef"`); that check missed
/// every other capitalization a backend or a hand-adopted file might use, silently refusing to ever
/// stamp or verify the file again. ~keep
const MARKER_SUBSTRING: &str = "generated by alef";
/// The alternate marker used by generated package metadata. ~keep
const MANAGED_MARKER_SUBSTRING: &str = "managed by alef";
/// The alternate marker used by generated R entrypoints. It is only an ownership marker when it
/// appears in a comment header that also says "do not edit". ~keep
const REGENERATION_MARKER_SUBSTRING: &str = "regenerate with `alef";
/// Comment prefixes accepted for regeneration ownership headers. ~keep
const COMMENT_OPENERS: & = &;
/// Case-insensitive ASCII substring search for `needle` within `haystack`.
///
/// Used instead of `haystack.to_lowercase().contains(needle)` to avoid allocating a lowercased
/// copy of every scanned line: this only ever runs against the first [`super::MARKER_SCAN_LINES`] lines
/// of a file, so the cost is already bounded, but a byte-window scan with
/// [`u8::eq_ignore_ascii_case`] gets the same correctness for free. Marker text is always plain
/// ASCII, so ASCII-only case-folding is sufficient here. ~keep
pub
/// Negation cues that, found as the single word immediately before a matched marker substring,
/// mean the phrase is being denied rather than claimed as an ownership marker (`"This file is
/// NOT generated by alef"`). Deliberately narrow -- see the module doc on
/// [`immediately_preceded_by_negation`] and `tests::marker_negation` for exactly which negated
/// forms this catches and which it does not. Over-widening this list risks the opposite,
/// strictly worse failure: a false NEGATIVE that makes alef refuse to ever manage a file it
/// genuinely authored, versus this false POSITIVE's cost of one avoidable write refusal a human
/// reviews. ~keep
const NEGATION_CUES: & = &;
/// Whether the single word immediately before byte offset `match_start` in `line` is one of
/// [`NEGATION_CUES`], case-insensitively.
///
/// Deliberately scoped to exactly one adjacent word, with no tolerance for intervening
/// punctuation or words -- `"is not generated by alef"` is caught, `"was not, in any real
/// sense, generated by alef"` is not (documented gap; see `tests::marker_negation`). A wider
/// window (scanning the whole line for a negation word anywhere) would defeat alef's own
/// standard header, which pairs the marker with "DO NOT EDIT" on the same line. ~keep
/// Case-insensitive ASCII substring search for `needle` within `haystack`, true only when at
/// least one match is not [`immediately_preceded_by_negation`].
///
/// [`contains_ignore_ascii_case`]'s marker-detection call sites route through this instead: a
/// bare substring match accepted `"This file is NOT generated by alef"` as an ownership claim,
/// which is a data-loss path -- that claim decides whether alef's write guard is willing to
/// overwrite the file (`write_files_report`, `crate::cli::pipeline::generate::write`). ~keep
/// Whether a single line carries [`MARKER_SUBSTRING`], case-insensitively, and not merely as a
/// negated denial (see [`contains_unnegated_ignore_ascii_case`]).
///
/// The one predicate every marker-scanning function in the parent module shares --
/// [`super::content_has_alef_marker`], [`super::inject_hash_line`], [`super::inject_stamp_line`], and
/// [`super::generated_hash_line`] (which backs [`super::extract_hash`]/[`super::strip_hash_line`]) -- so a line that one
/// of them treats as a marker is treated as one by all of them. They must agree: a marker
/// `content_has_alef_marker` accepts but `inject_hash_line` cannot find is a file claimed by `alef
/// verify` and never stamped, permanently stale. ~keep
pub
/// Regeneration advice is an ownership marker only in a comment header that explicitly says not
/// to edit the generated output. Handwritten prose may otherwise discuss the command freely.