okf

package module
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 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.5.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/verify the machine stamp: source digests, commit and path checks, the writer
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.5.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 whose at will not parse, or is 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
SourceHasAResource a sources entry with no resource:, §5.1's one required key
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 everything but LogVerbs, 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.

The four spec rules arrived in v0.4.0 firing on 172, 31, 27 and 3 fleet concepts, waited one tag in Strict() while that was converted, and are Standard() from v0.4.1 with all ten bundles measuring zero. That is the promotion condition, and it is the same one NoIntraBundleWikilinks met.

Strict() adds LogVerbs alone, 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.

Machine verification

okf verify knowledge                       # report only; writes nothing
okf verify -stamp -run-verifiers knowledge

§5.3 derives three trust tiers from the stamp's actor: no verified key is unverified, a non-human: actor is machine-confirmed, and a human: one is human-reviewed. verify writes the middle tier — process:okf-verify by default — and it writes it only on evidence it just checked:

Gate What it settles
the bundle check the document raises no error under the caller's rules
sources[].resource a commit <sha> is in this history, a path exists, a URL still hashes to its recorded digest:
verifier.command the repo's own test for the claim exits 0, and only under -run-verifiers

A concept with nothing outward to check is not stampable and stays unverified: 33 of 295 fleet concepts earn a stamp, and rubber-stamping the other 262 would cost the key its meaning. A resource that is a scope descriptor (§5.1 allows one a consumer cannot follow) earns no credit and is not a failure.

digest: is a producer-defined key under §4.1. The first run records it, later runs compare, and a mismatch blocks the stamp and names both digests — which is the drift a stale_after date cannot see, since it fires on the calendar and not on the upstream page. GitHub blob URLs are hashed through raw.githubusercontent.com, and an extensionless docs path is tried as .md first: the HTML those hosts serve is an app shell whose hash moves on every site deploy.

Stamp refuses -by human:* when CLAUDECODE is set. A human sign-off is the one tier no run can earn, so it is the one an agent must not write, and that is a fact about who is running that no document rule can see.

The write is a line insert at the canonical position, never a YAML round-trip: every byte outside the inserted block is unchanged, an existing human: event is carried through verbatim, and re-running updates the process event in place rather than appending a second one.

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.
Package verify re-confirms what a concept points outward at, and records the result as §5.3's machine-confirmed tier.
Package verify re-confirms what a concept points outward at, and records the result as §5.3's machine-confirmed tier.

Jump to

Keyboard shortcuts

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