Documentation
¶
Overview ¶
Package upgrade rewrites legacy on-disk CANARY token shapes into the current parseable form: markdown `# CANARY:` headings into HTML comments, unicode hyphens inside IDs into ASCII hyphens, unpadded flatfile IDs into zero-padded IDs, bare legacy ID segments into keyed REQ= tokens, bug tokens missing FEATURE= into scan-parseable single lines, STATUS=FIXED into STATUS=REMOVED, missing UPDATED= into stamped tokens, the old multi-line bug-create continuation shape into one line, and (when an ID map is supplied) old requirement IDs into new ones across both CANARY tokens and GAP_ANALYSIS.md "✅ <ID>" claim lines.
Every rule is independently selectable (Options.Rules) and independently safe: rules never touch CANARY:MIGRATE / CANARY:START / CANARY:END lines, and — including the md-heading rule — never touch lines inside fenced code blocks in markdown files: a fenced `# CANARY:` heading is a documentation example, not a live token, so it is left alone like every other rule's fenced content. CANARY: REQ=CP-275; FEATURE="TokenUpgrade"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_CBIN_302_AtomicWrite,TestCANARY_CBIN_302_CRLF,TestCANARY_CBIN_302_Combined,TestCANARY_CBIN_302_FenceProtection,TestCANARY_CBIN_302_Idempotent,TestCANARY_CBIN_302_MDHeadingFenceProtection,TestCANARY_CBIN_302_MigrateGuard,TestCANARY_CBIN_302_PlaceholderGuard,TestCANARY_CBIN_302_Remap,TestCANARY_CBIN_302_RemapCollision,TestCANARY_CBIN_302_Rules,TestCANARY_CBIN_302_RuleFiltering,TestCANARY_CBIN_302_UnicodeHyphenProse,TestCANARY_CBIN_302_ValidRule,TestGuardFailureSkipsFileAndContinues; UPDATED=2026-08-30
Index ¶
Constants ¶
This section is empty.
Variables ¶
var AllRules = []string{
"join-multiline",
"md-heading",
"unicode-hyphen",
"bare-id",
"bug-alias",
"status-fixed",
"pad-flatfile",
"add-updated",
"remap",
}
AllRules lists every named rule in canonical execution order.
Functions ¶
func TokenLineFields ¶ added in v0.3.3
TokenLineFields exposes the per-line token identity the upgrade preservation guard derives -- tokenShapeOf with no rule touched, so every declared field is kept. It lets the F-14 cross-parser parity test prove `canary upgrade` reads tokens through the same canaryscan parser as scan, index, and next. Fields come back keyed by upper-cased name with canonicalized values (BUG is left un-aliased, exactly as the scanner first sees it); ok is false for a line that carries no token. It is a thin, side-effect-free reflection of the real guard path -- not a general parsing API.
Types ¶
type Change ¶
type Change struct {
File string // root-relative, forward-slashed
Line int // 1-based, in the file state at the moment this rule ran
Old string
New string
Rule string
}
Change is one proposed (or, when Options.Write is true, applied) edit produced by a single named rule.
func Run ¶
Run walks Options.Root, applies the enabled rules to every non-skipped file, and returns every Change found (in file, then rule-application, order). When Options.Write is true, modified files are rewritten in place (permissions preserved); otherwise Run never touches disk.
A file that fails the token-preservation guard, or whose write fails, is skipped and left byte-identical; the walk continues and the returned error joins every such failure, naming each file. The changes found are returned either way, so a partial write reports both what it did and what it refused.
type Options ¶
type Options struct {
Root string
Skip *regexp.Regexp
Ignore *ignore.GitIgnore
Registry *sources.Registry
Map map[string]string // old REQ/BUG id -> new id
Write bool // false = dry run
Today string // YYYY-MM-DD for added UPDATED=; empty -> CANARY_TEST_TIMESTAMP then time.Now().UTC()
Rules []string // empty = all rules, see AllRules
}
Options configures Run.