drift-check
Detect drift between the project's public API surface and its
knowledge base (a docs/knowledge/ directory that names every public
type and function).
When to use
- Before committing a change that adds, renames, or removes a public symbol.
- As a CI step that runs after every push.
- After a
git pullif the upstream changed the public API.
Do not use this skill to scan private internals, generated code, or third-party dependencies. Its job is to keep the human-readable knowledge base honest about the public surface.
Inputs
| Name | Required | Default | Description |
|---|---|---|---|
source_glob |
yes | none | Glob for the source files to scan, e.g. Sources/CaffCore/*.swift or src/**/*.py. |
knowledge_base |
yes | none | Path to a Markdown directory, usually docs/knowledge/. The skill extracts identifier tokens from every file under it. |
baseline |
no | none | Optional file with one identifier per line, listing symbols intentionally left undocumented. Add an entry here only after a human has confirmed it is genuinely not worth a knowledge-base entry. |
scope |
no | all |
all scans every file matching source_glob. changed scans only files in git diff (staged + unstaged + untracked-but-staged). |
Output
| Channel | Content |
|---|---|
| stdout | One line per undocumented symbol in the form <relative_path>:<Symbol>. |
| exit code | 0 = every public symbol in scope is either in the knowledge base or in the baseline. 1 = at least one symbol is missing. 2 = the input was malformed (e.g. the knowledge base path does not exist). |
| stderr | Summary line, then a hint pointing at where to fix the drift. |
What counts as a public symbol
The skill uses a coarse regex; the precise rules are language-specific:
| Language | Public surface is |
|---|---|
| Swift | public struct, public class, public enum, public protocol, public func, public static func, public init |
| Python | def and class not prefixed with _ at module top level; __all__ if present |
| Go | identifiers in package ... that start with an uppercase letter |
| Rust | pub struct, pub fn, pub enum, pub trait, pub use re-exports |
| TypeScript | export function, export class, export interface, export type |
The skill is deliberately not a full parser. It trades false positives
for a small, predictable rule set. If the regex does not match a
deliberate public symbol, add it to baseline rather than fight the
regex.
Algorithm (in three steps)
- Extract public symbol names from the source tree using the language-specific regex.
- Tokenise every file under
knowledge_baseinto identifier-like tokens (alphanumerics and underscores). - Diff the symbol set against
(knowledge base tokens ∪ baseline). Any symbol not present is drift.
Worked example (Swift)
Suppose Sources/CaffCore/SafetyPolicy.swift adds:
public struct SafetyPolicy {
public func someNewMethod() { ... }
}
docs/knowledge/L1_modules.md does not mention someNewMethod.
Running drift-check with source_glob=Sources/CaffCore/*.swift and
knowledge_base=docs/knowledge/ produces:
scanned 24 public symbol(s) across 9 file(s)
drift: 1 public symbol(s) not in L1_modules.md or baseline:
- Sources/CaffCore/SafetyPolicy.swift:someNewMethod
The fix is to add someNewMethod to the L1 modules document. If it is
genuinely not worth a knowledge-base entry, add someNewMethod to the
baseline file.
Anti-patterns
- Running the skill on generated code. Generated code can change
with every build, and its public surface is the generator's contract,
not the project's. Exclude it from
source_glob. - Adding every internal helper to the baseline. The baseline is for symbols intentionally left out of the knowledge base, not for skipping the work. Use the knowledge base.
- Treating drift warnings as a code review substitute. The skill tells you the knowledge base is stale. It does not tell you whether the new symbol is well-designed.
Cross-references
- failure-classify — the next step in the loop. drift-check runs before the test, failure-classify runs after.
- init-loop — installs the script that this skill describes into a fresh project.
- drill — verifies that this skill actually reacts to a deliberately drifted commit.