Immutable. This exact content is served forever at /api/v1/blob/283892e7fdd362cb.
# AGENTS.md
This repository is a monorepo shipping four Ruby gems around one format: `okf`,
the
baseline that reads, validates, lints, searches and serves Open Knowledge
Format (OKF) v0.2 bundles, and three surfaces over it — an MCP shell, a terminal UI and
an enforcement layer.
**This file is context, routing and reference.** It states what binds every
change, points at where to read, and lists the commands. It explains nothing: the
arguments live in the bundles, which are the harness a contributor works from.
Start with the row for what you are changing.
## Where to go
| working on | guide | bundle |
| --- | --- | --- |
| the baseline gem | [`gems/okf/AGENTS.md`](gems/okf/AGENTS.md) | `okf search @okf <term>` |
| the MCP shell | [`gems/okf-mcp/AGENTS.md`](gems/okf-mcp/AGENTS.md) | `okf search @okf-mcp <term>` |
| the terminal UI | [`gems/okf-tui/AGENTS.md`](gems/okf-tui/AGENTS.md) | `okf search @okf-tui <term>` |
| the enforcement layer | [`gems/okf-pro/AGENTS.md`](gems/okf-pro/AGENTS.md) | `okf search @okf-pro <term>` |
| the plugin, the skills, the resources, or anything binding all four | this file | `okf search @okf-eco <term>` |
`okf search @all <term>` reaches every bundle at once; `rake serve` opens this
repository's own as a graph.
## What binds every change
Four rules to follow unprompted. The argument for each is one link away; these
lines are the whole of what you must obey without reading it.
- **A change starts with a failing test, read failing**, then the code, then the
same test green and **unedited**. A bug report earns a red test before a patch.
- **Assertions must be able to fail for a real reason.** Run the thing, read
what it prints, assert *that* — never what you assume the code does.
- **The bundle ships in the same commit as the code it documents.** A file under
`lib/` that no concept names is a red suite, not a stale document.
- **Don't improve adjacent code**, and add no abstraction for single-use code.
Match the surrounding style (`.rubocop.yml` — spaced brackets `[ 1, 2 ]`,
double quotes); remove only orphans your own change created.
Why each, and what they are worth:
[.okf/design/how-a-change-is-proven.md](.okf/design/how-a-change-is-proven.md).
**Commits are attributed to the human maintainer only** — no AI co-author
trailers, no "generated by" lines, in commits or PRs.
If a request is ambiguous, name the interpretations rather than picking one
silently, and push back when a simpler approach exists.
## Map
```
gems/okf/ the baseline gem, registered as plain `@okf`. Floor 2.4; deps
exactly rack + webrick + minifts. Ships the skill, and its own
`.okf/` inside the gem
gems/okf-mcp/ the MCP shell: the kernel's capabilities as MCP tools + prompts.
Floor 2.7 — the `mcp` SDK's — deps exactly `mcp` + `okf`
gems/okf-tui/ the terminal UI: six views over one or many bundles, and the
registry. Floor 2.4, deps `okf` + the TTY toolkit
gems/okf-pro/ the enforcement layer: `okf pro setup` writes an agent's
knowledge repo, `okf pro hook` runs one gate against one hook
event. Floor 2.4, deps exactly `okf`. Its `hook` verb is the one
place in the repo where exit 1 is *non-blocking* and 2 refuses
plugin/ the Claude Code plugin — generated skill copy, command, curation hook
.claude-plugin/ the marketplace manifest (the repo doubles as the marketplace)
skills/ the skills a generic installer reads: a generated copy of okf's,
and okf-principles, whose canonical copy this is
.okf/ the ecosystem's map, registered as `@okf-eco` — a concept per
gem, per plugin item, per skill and per resource, plus the
format, the decisions and the design that govern them all
.okf-registry.json
every bundle in the tree, addressable as `@slug`; while you stand
under this root it *replaces* your global $OKF_HOME registry
Dockerfile builds gems/okf/ — from a root context, because the gemspec needs .git
Rakefile a delegator: `rake` runs every gem's default task
```
**A directory under `gems/` is a gem and is named for the gem it ships; anything
at the root is named for what it is.** A new root name has to be forced by an
external consumer — a marketplace path, an installer's discovery walk — or it
belongs under `resources/`.
Never edit `plugin/skills/okf` or `skills/okf`: both are generated by `rake
skill:sync` in the *gem's* Rakefile, and two guards fail the build on drift.
## Commands
Plain `rake`, no bundler — there is no root Gemfile, and `bundle exec rake` here
failing with "Could not locate Gemfile" is the intended answer.
```bash
rake # every gem's default task, then the repo-level rubocop
rake test # every gem's suite
rake okf # validate + lint all five bundles
rake serve # serve this repo's own .okf as a graph
```
Everything about one gem — its suite, its CLI from a checkout, its floor
container, its release — is in that gem's own guide. A release is cut from the
gem's directory; `rake release` here refuses.
## Reference
| question | read |
| --- | --- |
| why gems live under `gems/`, and what earns a root name | [.okf/decisions/monorepo-layout.md](.okf/decisions/monorepo-layout.md) |
| why there is no root Gemfile, and how CI is split | [.okf/decisions/the-root-is-not-a-gem.md](.okf/decisions/the-root-is-not-a-gem.md) |
| why a sibling ships no exe, and the seam's threat model | [.okf/decisions/one-door-per-sibling.md](.okf/decisions/one-door-per-sibling.md), [.okf/design/extension-points.md](.okf/design/extension-points.md) |
| which of README, AGENTS.md or a bundle a fact belongs in | [.okf/design/where-knowledge-lives.md](.okf/design/where-knowledge-lives.md) |
| what a README may and may not carry | [.okf/design/the-readmes.md](.okf/design/the-readmes.md) |
| the shape of a PR, and what a release PR adds | [.okf/design/pull-requests.md](.okf/design/pull-requests.md) |
| the tag convention across the four gems | [.okf/decisions/release-and-tags.md](.okf/decisions/release-and-tags.md) |
| which obligations nothing enforces, and why that is said out loud | [.okf/design/nothing-runs-it.md](.okf/design/nothing-runs-it.md) |
| what the plugin, the skills and the resources are | [.okf/plugin/](.okf/plugin/), [.okf/skills/](.okf/skills/), [.okf/resources/](.okf/resources/) |
Five bundles: `.okf/` for the ecosystem, one in each gem. A fact that survives
deleting a gem is the ecosystem's. A concept cannot link out of its own bundle,
so a reference across the line names the other in prose — `` `@okf
capabilities/linter` ``.