Documentation
¶
Overview ¶
Package knowledge defines the card model and parses the canonical file store. Files are the source of truth; everything here must parse permissively — one bad card is logged and skipped, never fatal.
Index ¶
- func Commit(kdir, message string) error
- func EstimateTokens(s string) int
- func Render(c Card) ([]byte, error)
- func ShortID(cardID string) string
- func SplitFrontmatter(raw []byte) (fm, body []byte, err error)
- func UpdateFile(knowledgeDir, relPath string, mutate func(*Card)) error
- type Card
- type ExportMeta
- type FileInfo
- type Provenance
- type Triggers
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Commit ¶
Commit records the current state of the knowledge dir as one git commit with a structured message — the governance trail: `git log` answers when a card appeared, which pipeline wrote it, and why it changed. Automated commits are authored as "culi" so they are distinguishable from the user's own edits, and they work even without a global git identity.
Best-effort by contract: callers must never fail a pipeline over history. A knowledge dir that is not a git repo returns an error the caller logs and moves on; a clean tree commits nothing and returns nil. The .import staging area is excluded — staged-but-unreviewed content is not knowledge yet (C4's review gate would be meaningless if staging were archived as if applied).
func EstimateTokens ¶
EstimateTokens approximates token count without a tokenizer dependency: chars/4 for ASCII-heavy text, runes/1.8 when >20% multibyte (Vietnamese is token-denser). ±15% accuracy is fine — this drives budgets, not billing.
func Render ¶
Render serializes a Card back to file bytes: YAML frontmatter + body. yaml.Marshal handles quoting, so summaries containing ": " or quotes can never produce an unparseable card (a hand-rolled writer once did). Round-tripping through Parse loses nothing culi reads, but drops unknown frontmatter keys — Render is for cards culi authors (import, learning), never for rewriting hand-edited files.
func ShortID ¶
ShortID returns a stable 4-hex-char pointer ID derived from the card ID. Collisions are resolved at index time (store.uniqueShortID appends a decimal suffix deterministically).
func SplitFrontmatter ¶
SplitFrontmatter separates a leading "---" YAML block from the body of any markdown file (cards, but also Claude Code agent/skill files during import). A file without frontmatter returns nil fm and the full raw as body.
func UpdateFile ¶
UpdateFile parses one card file, applies mutate, and rewrites it atomically (temp + rename). ONLY for culi-authored cards — Render drops frontmatter keys culi does not model, so a hand-edited file must never pass through here (C4). Callers gate on Provenance.Source before calling.
Types ¶
type Card ¶
type Card struct {
ID string // derived from path: "rules/go-error-wrapping"
Path string // relative to the knowledge dir
Type string // rule|skill|lesson|style|pattern|agent
Title string
Summary string
Body string
Scopes []string // global | lang:<x> | repo:<name> | branch:<repo>@<glob> | dir:<hash>
Key string // optional shadowing key: narrowest scope wins among cards sharing it
Triggers Triggers
Aliases []string // extra FTS keywords (e.g. Vietnamese terms)
Baseline bool // part of the SessionStart baseline for its scope
Status string // ""/confirmed | candidate | retired (learning lifecycle)
// Learning lifecycle (Phase 4): a mined card starts as a candidate with
// Observations 1 and confirms at 2 (re-learning reinforces instead of
// duplicating). Supersedes names the card ID this one replaces; the old
// card is retired when this one confirms.
Observations int
Supersedes string
ContentHash string // sha256 of raw file content
TokSummary int // estimated tokens, computed at parse time
TokBody int
// Export links a card back to a generated ~/.claude artifact; nil for
// cards that are knowledge-only. Provenance records where imported or
// learned content came from. Neither is stored in the SQLite index —
// files are truth, and only `culi import`/`culi export` read them.
Export *ExportMeta
Provenance *Provenance
}
Card is one atomic unit of knowledge (a rule, lesson, style note, pattern, skill, or agent definition) with three granularities: HookLine (~15 tok), Summary (~60 tok), Body (full markdown).
func Parse ¶
Parse builds a Card from raw file bytes. relPath is the path relative to the knowledge dir (it derives the default ID and type). Errors are returned for the caller to log-and-skip — a bad card must never fail an index run.
type ExportMeta ¶
type ExportMeta struct {
Kind string `yaml:"kind"` // agent | skill
Name string `yaml:"name"` // basename in ~/.claude/agents or ~/.claude/skills
Frontmatter string `yaml:"frontmatter,omitempty"`
Attachments []string `yaml:"attachments,omitempty"` // skill sibling files, dir-relative
}
ExportMeta describes how `culi export` regenerates a Claude Code agent or skill file from this card. Frontmatter is the verbatim YAML block of the original artifact (without --- delimiters) so exports round-trip exactly.
type FileInfo ¶
FileInfo describes one card file on disk, cheap enough to stat the whole store per index run (100s–1000s of files).
type Provenance ¶
type Provenance struct {
Source string `yaml:"source,omitempty"` // import | learn | mcp | gen | manual
MergedFrom []string `yaml:"merged_from,omitempty"` // contributing repo names
Model string `yaml:"model,omitempty"` // LLM used, if any
// SourceHash fingerprints the deterministic input a generated card
// derives from (gitfacts hash) — unchanged input ⇒ regen skips the card.
SourceHash string `yaml:"source_hash,omitempty"`
}
Provenance records the origin of imported or learned content.