Documentation
¶
Overview ¶
Package drift decides, per requirement, whether the tree in front of it still matches the index baseline `canary index` recorded. The verdict is one of three states — CURRENT, DRIFTED, UNKNOWN — and it is decided by evidence, never by a token's self-reported UPDATED= date:
- the content hash of every file a requirement's tokens live in is compared against the hash stored at index time (a mismatch is DRIFTED, which is why a same-day edit that never touches a date is still caught);
- a file whose hash matches is only CURRENT when git can also confirm its history — when git is unavailable, not a repository, or the file is untracked, the verdict is UNKNOWN, never CURRENT.
Staleness and documentation rollup remain available as clearly separate advisory output (see Advisories); they are deliberately not folded into the drift State, because neither is evidence that the indexed code changed. CANARY: REQ=CP-278; FEATURE="DriftDetect"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_CP_278_Check_CleanRepoCurrent,TestCANARY_CP_278_Check_ChangedFileDrifted,TestCANARY_CP_278_Check_GitFailureUnknown,TestCANARY_CP_278_Check_MissingBaselineUnknown,TestCANARY_CP_278_Check_UnreadableFileUnknown,TestCANARY_CP_278_Check_Precedence,TestCANARY_CP_278_Check_NoIndex,TestCANARY_CP_278_Advisories_Stale,TestCANARY_CP_278_Advisories_DocDrift,TestAuditF20; UPDATED=2026-08-31
Index ¶
Constants ¶
const ( KindStale = "stale" KindDocDrift = "doc-drift" )
Kind values for Finding.Kind. These are advisory signals, deliberately kept out of the drift State: neither is evidence that indexed code changed.
Variables ¶
var ErrNoIndex = errors.New("no index; run 'canary index'")
ErrNoIndex is returned by Check when the database carries no index metadata, i.e. `canary index` has never populated it. Reporting UNKNOWN for every requirement would be technically true and practically useless; naming the one fix is better.
Functions ¶
This section is empty.
Types ¶
type FileState ¶ added in v0.3.3
type FileState struct {
Path string `json:"path"`
State State `json:"state"`
Detail string `json:"detail"`
}
FileState is the drift verdict for one file a requirement's tokens live in.
type Finding ¶
type Finding struct {
ReqID string `json:"req_id"`
File string `json:"file"`
Kind string `json:"kind"` // stale | doc-drift
Detail string `json:"detail"`
}
Finding is one advisory signal for a requirement (staleness or a doc rollup). It is not a drift verdict; see ReqState for that.
func Advisories ¶ added in v0.3.3
func Advisories(root string, rep canaryscan.Report, staleDays int, refTime time.Time) ([]Finding, error)
Advisories returns the non-drift signals worth surfacing alongside the drift verdict but never mixed into it: TESTED/BENCHED tokens past the staleness window, and — when root/.canary/canary.db exists — tokens whose tracked documentation is DOC_STALE or DOC_MISSING. If refTime is zero, time.Now().UTC() is used.
type ReqState ¶ added in v0.3.3
type ReqState struct {
RequirementID string `json:"requirement_id"`
State State `json:"state"`
Files []FileState `json:"files"`
}
ReqState is the drift verdict for one requirement, rolled up from its files.
func Check ¶ added in v0.3.3
Check returns a drift verdict for every requirement in the index at db, comparing the tree rooted at root against the baseline `canary index` recorded. projectID scopes the check to one project's tokens; "" checks every project's tokens.
For each file a requirement's tokens live in, Check compares the file's current SHA-256 against the content_hash stored at index time. A mismatch is DRIFTED. A matching hash is CURRENT only when git can also confirm the file's history; when git cannot (no repository, git absent, file untracked) the file is UNKNOWN. A missing baseline hash or an unreadable file is also UNKNOWN. The requirement's state is the worst of its files: any DRIFTED makes it DRIFTED, else any UNKNOWN makes it UNKNOWN, else CURRENT.
Check is read-only. It never re-scans the tree, never writes the database, and never fabricates a verdict from a token's UPDATED= date.
type State ¶ added in v0.3.3
type State string
State is the drift verdict for a file or a requirement.
const ( // StateCurrent means every file's content hash matches the index baseline // and git could confirm each file's history. StateCurrent State = "CURRENT" // StateDrifted means at least one file's content hash differs from the // index baseline: the code moved on since it was indexed. StateDrifted State = "DRIFTED" // StateUnknown means the verdict could not be decided — a missing // baseline, an unreadable file, or git being unable to answer for a file // whose hash otherwise matches. A git failure is UNKNOWN, never CURRENT. StateUnknown State = "UNKNOWN" )