okf

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

okf

A checker for OKF v0.2 bundles — directories of markdown with YAML frontmatter.

go install github.com/fairyhunter13/okf/cmd/okf@v0.4.0
okf check knowledge          # conformance errors exit 1
okf check -Werror knowledge  # warnings exit 1 too

Pin the tag, don't take @latest: this binary decides whether a consumer's CI is green, and @latest lets that verdict change with no commit in the repo it gates.

Only §11's three rules are errors: a concept needs a non-empty type, index.md carries no frontmatter (bar okf_version at the root), and log.md headings are YYYY-MM-DD. Dangling links, stale stale_after and orphans are warnings — §11 forbids rejecting a bundle over them, and TestSeverityNeverEscalates keeps it that way.

Conformance is pinned to Google's four reference bundles in testdata/google/ rather than to a reading of the spec: whatever the checker rejects there is a bug in the checker.

Packages

Package Holds
okf the engine: §11 conformance, Parse, CheckBundle, Rule/BundleRule
okf/rules the fleet's own invariants, which §11 forbids the engine to enforce
okf/sweep the fleet report, which imports both

rules is a package and not part of okf so that importing the engine gets a conformant checker and nothing this fleet decided. It was module github.com/fairyhunter13/okfrules until v0.3.0; that split bought the same separation at the price of two pins and a sweep that could not reach the rules, because they imported it. Pins at okfrules@v0.2.1 and earlier keep resolving through the module proxy.

Repo-local rules

An invariant the spec cannot express goes in as a Rule instead of upstream:

findings, err := okf.CheckBundle("knowledge", time.Now().UTC(), myRule)

Rules run on concepts only, never on index.md or log.md. To ship them in the CLI, call okf.Main(os.Args[1:], os.Stderr, myRule) from a local main.

An invariant over the reserved files, the link graph, or any two concepts at once needs the whole bundle, which is what BundleRule is for:

okf.MainWith(os.Args[1:], os.Stderr, okf.Rules{
	Doc:    []okf.Rule{myRule},
	Bundle: []okf.BundleRule{myBundleRule},
})

Bundle findings are appended after the per-concept ones and sorted among themselves, so adding one never moves a line the stock check already prints — TestStockCheckOutputIsByteIdentical holds that.

The fleet rules

go install github.com/fairyhunter13/okf/cmd/okfrules@v0.4.0
okfrules check -Werror knowledge
okfrules -strict check -Werror knowledge
Rule Refuses
ResourceResolves a resource: naming a path that is gone
TypeVocabulary a type outside the skills' table
VerifiedWellFormed a verified: stamp not naming a human:, or older than generated.at
StaleAfterHasAReason a stale_after with no sources: naming what expires
IndexHeadingsAreSingularTypes ## Decisions where the table says Decision
LogFrontmatter a log.md missing type: Log or its title
NoIntraBundleWikilinks [[name]] inside a bundle — link with markdown, or name the home
PreferRelativeLinks a link written /from-the-bundle-root — a warning, and the one here that is
ActorConvention a by: outside §7's <producer>/<version>, human:, process:, team:
StatusVocabulary a status outside §5.4's draft | stable | deprecated
FootnoteLabelsJoinSources a [^1] footnote where §5.1 requires a sources[].id
AttestedComputationHasContract an Attested Computation with no runtime, or with no readable computation
LogVerbs a log entry led by something outside the five verbs

Standard() is the first eight, and all but PreferRelativeLinks are errors rather than the spec's advisory half: each says a concept describes something that is not there, or is filed where nothing will find it. PreferRelativeLinks was an engine warning until v0.4.0; §6.1 only recommends a shape, so the engine had no business holding the opinion, and moving it is why the four reference bundles now exit 0 under -Werror.

Strict() adds the five a bundle has to be converted into first. LogVerbs is opt-in on a measurement — 2026-08-21, 84 offending entries across the three bundles that fired, 57 ordinary drift since renamed, and 26 left in two bundles: 13 sentences and 13 labels the five verbs have no word for (Refused, Refutation, Not changed). Rewriting dated history to fit a closed vocabulary falsifies it. The four spec rules added in v0.4.0 are here for the same reason and not as staging: at the tag they fired on 146, 32, 27 and 4 fleet concepts, and they move to Standard() once the fleet measures clean.

Fleet sweep

okf sweep --roots ~/git/github.com/fairyhunter13,~/go/src/github.com/fairyhunter13
okf sweep --roots ~/git/github.com/fairyhunter13 --memory ~/.claude/memory --json

Every directory under a root holding both .git and a knowledge/ sibling is a repo, so an eleventh is picked up the day it gets a bundle and there is no registry to drift. The verdict is okf plus rules.Standard() — until v0.3.0 it was §11 alone, because the rules were a module importing this one. A repo's strict or local rules still run only in its own gate, which is why every line names the checker that repo invokes. Per repo it reports the check verdict, field coverage, expired stale_after, unresolved [[memory:…]] references, and the gates: a hook that runs okf (directly, through a symlinked script, or through make), a workflow step, and every version literal found. A hook present but not executable is reported as such rather than as a gate — git skips it silently. More than one pin is printed as drift.

--memory is where [[memory:…]] resolves; unset, every such reference reports unresolved rather than being skipped, because the four profile homes differ and a verdict depending on which one ran would be no verdict.

Sweep exits 0 on findings. It is a report, not a gate: a red not attached to a change is the accumulating advisory the severity split exists to avoid. Exit 1 means the sweep itself did not run.

Why this repo has no knowledge/

Swept and refused, not overlooked. Every non-obvious decision here is already a load-bearing comment at the site it constrains — the severity split, the §11 refusals, the parse rules — and a bundle would give each of them two edit sites, one of which would go stale first. okf-bootstrap's own test is whether the reasons are recoverable from the code; in ~400 lines describing a spec, they are.

Documentation

Overview

Package okf checks OKF v0.2 bundles.

The spec is deliberately permissive: only three rules are conformance failures. That split is why findings carry a severity — everything beyond §11 is advice and must never fail a build. A repo whose graph carries an invariant the spec cannot express passes it to CheckBundle as a Rule.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Main

func Main(args []string, w io.Writer, rules ...Rule) int

Main runs the `okf check` CLI and returns the process exit code. A repo with its own rules wires them in here rather than forking the command. `sweep` is dispatched by cmd/okf instead: it runs the fleet rules, which import this package, so the engine cannot reach them.

func MainWith added in v0.2.0

func MainWith(args []string, w io.Writer, rules Rules) int

MainWith is Main with bundle-wide rules as well.

func Parse

func Parse(text string) (map[string]any, string, error)

Parse splits an OKF document into its YAML frontmatter and body. A document with no frontmatter block yields a nil map and no error; whether that is a violation depends on the filename, which Parse does not know.

func Reserved added in v0.3.0

func Reserved(rel string) bool

Reserved reports whether a bundle-relative path is one of OKF's two reserved names. A Rule never sees these; a BundleRule does, and has to say so.

Types

type Bundle added in v0.2.0

type Bundle struct {
	Root string
	Docs []Doc // walk order, which is lexical by path
}

Bundle is every parsed document in one root, index.md and log.md included.

func (Bundle) Concepts added in v0.2.0

func (b Bundle) Concepts() []Doc

Concepts returns the documents that are not index.md or log.md.

func (Bundle) Find added in v0.2.0

func (b Bundle) Find(rel string) (Doc, bool)

Find returns the document at this bundle-relative path, or false.

type BundleRule added in v0.2.0

type BundleRule func(Bundle) []Finding

BundleRule is a caller-supplied check over a whole bundle. A Rule runs per concept and so cannot see the reserved files, the link graph, or any pair of concepts at once.

type Doc

type Doc struct {
	Root string         // bundle root, as given to CheckBundle
	Rel  string         // bundle-relative path, slash-separated
	FM   map[string]any // frontmatter
	Body string
}

Doc is one parsed concept, handed to a Rule.

type Finding

type Finding struct {
	Path string
	Sev  Severity
	Msg  string
}

func CheckBundle

func CheckBundle(root string, today time.Time, rules ...Rule) ([]Finding, error)

CheckBundle walks a bundle root and reports conformance errors (§11) and advisory warnings, plus whatever the caller's rules report.

func CheckBundleWith added in v0.2.0

func CheckBundleWith(root string, today time.Time, rules Rules) ([]Finding, error)

CheckBundleWith is CheckBundle with bundle-wide rules as well. Their findings are appended after the per-concept ones and sorted among themselves, so adding one cannot move a line the stock check already prints.

func (Finding) String

func (f Finding) String() string

type Rule

type Rule func(Doc) []Finding

Rule is a caller-supplied check over one concept. It runs on concepts only, never on the reserved index.md and log.md. A Finding with an empty Path is stamped with the concept's.

type Rules added in v0.2.0

type Rules struct {
	Doc    []Rule
	Bundle []BundleRule
}

Rules is what a caller passes to CheckBundleWith and MainWith.

type Severity

type Severity int
const (
	Warning Severity = iota
	Error
)

func (Severity) String

func (s Severity) String() string

Directories

Path Synopsis
cmd
okf command
Command okf checks OKF bundles.
Command okf checks OKF bundles.
okfrules command
Command okfrules is okf's check with this fleet's shared rules wired in, for the repos that are not Go and cannot build one of their own.
Command okfrules is okf's check with this fleet's shared rules wired in, for the repos that are not Go and cannot build one of their own.
Package rules holds the invariants every bundle in this fleet keeps but the OKF spec deliberately does not: §11 forbids rejecting a bundle over an unknown type, a missing key or a broken link, so a local vocabulary is only a rule while something asserts it.
Package rules holds the invariants every bundle in this fleet keeps but the OKF spec deliberately does not: §11 forbids rejecting a bundle over an unknown type, a missing key or a broken link, so a local vocabulary is only a rule while something asserts it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL