OKF Bundle Examples
Eight production-ready bundles you can steal, adapt, and ship today. Each one passes the three conformance rules, has working cross-links, and uses a folder structure you’d actually deploy.
Hot take: A good bundle passes the “new hire” test. Someone opens
index.mdand understands the domain in 30 seconds. If they need a guide to navigate it, the structure failed.
1. SaaS Application
A SaaS team documenting revenue metrics, subscriptions, and operational playbooks. The scenario: your finance team wants to know how MRR is calculated and your agents need to answer “why did revenue drop?”
Folder tree
saas-app/
├── index.md
├── log.md
├── metrics/
│ ├── index.md
│ ├── monthly-recurring-revenue.md
│ └── churn-rate.md
├── tables/
│ ├── index.md
│ └── subscriptions.md
└── playbooks/
├── index.md
└── revenue-review.mdmetrics/monthly-recurring-revenue.md
---
type: Metric
title: Monthly Recurring Revenue
description: Recurring subscription revenue normalized to a monthly period.
resource: dashboard://revenue/mrr
tags: [revenue, saas, finance]
timestamp: 2026-06-21T00:00:00Z
---
# Definition
MRR is the predictable recurring revenue generated by active subscriptions
in the [subscriptions table](/tables/subscriptions.md). It normalizes annual,
quarterly, and monthly plans to a single monthly figure.
Include active subscriptions with recurring billing. Exclude one-time setup
fees, refunds, and usage-only charges unless normalized into a recurring plan.
# Formula
MRR = Σ(active_subscription_monthly_value) ARR = MRR × 12
# Examples
```sql
SELECT SUM(monthly_amount_usd) AS mrr
FROM analytics.subscriptions
WHERE status = 'active'
AND billing_type = 'recurring';Related
- Churn Rate uses MRR as denominator for revenue churn
- Subscriptions is the source table
Citations
The SQL is the source of truth. No ambiguity about "what counts as recurring" — the query answers it. Notice how `churn-rate.md` links back here too — the bundle is a graph, not just a folder tree.
---
## 2. Data Warehouse
A data team documenting BigQuery tables, datasets, and metrics. The scenario: a new analyst joins and needs to understand the schema, joins, and where revenue numbers come from without pinging Slack.
### Folder tree
data-warehouse/ ├── index.md ├── log.md ├── datasets/ │ ├── index.md │ └── sales.md ├── tables/ │ ├── index.md │ ├── orders.md │ └── customers.md └── metrics/ ├── index.md └── gross-revenue.md
### `tables/orders.md`
```markdown
---
type: BigQuery Table
title: Orders
description: One row per completed customer order across all channels.
resource: https://console.cloud.google.com/bigquery?p=acme&d=sales&t=orders
tags: [sales, orders, revenue]
timestamp: 2026-06-21T00:00:00Z
---
# Schema
| Column | Type | Description |
|--------|------|-------------|
| `order_id` | STRING | Globally unique order identifier |
| `customer_id` | STRING | FK to [customers](/tables/customers.md) |
| `total_usd` | NUMERIC | Order total in US dollars |
| `placed_at` | TIMESTAMP | When the customer submitted the order |
| `channel` | STRING | `web`, `mobile`, `pos` |
# Joins
Joined with [customers](/tables/customers.md) on `customer_id`.
# Examples
```sql
SELECT customer_id, SUM(total_usd) AS lifetime_value
FROM sales.orders
GROUP BY customer_id
ORDER BY lifetime_value DESC
LIMIT 100;Related
- Part of the sales dataset
- Used by Gross Revenue metric
Citations
[1] BigQuery table
Schema tables are doing the heavy lifting. An agent reads the column descriptions, understands the FKs, and can write correct joins without guessing.
---
## 3. Laravel Application
A dev team documenting their Laravel app's models, routes, policies, and background jobs. The scenario: a new developer (or a coding agent) needs to understand what the User model does, which routes expose it, and what happens when you update a profile.
### Folder tree
laravel-app/ ├── index.md ├── log.md ├── models/ │ ├── index.md │ └── user.md ├── routes/ │ ├── index.md │ └── api-users.md ├── policies/ │ ├── index.md │ └── user-policy.md └── jobs/ ├── index.md └── sync-stripe-customer.md
### `models/user.md`
```markdown
---
type: Laravel Model
title: User
description: Authenticated account model for customers and internal operators.
resource: repo://app/Models/User.php
tags: [laravel, model, authentication]
timestamp: 2026-06-21T00:00:00Z
---
# Responsibilities
The User model represents an authenticated account. It owns customer-facing
resources (orders, subscriptions, API keys) and handles authentication
via Laravel Sanctum.
# Schema
| Column | Type | Description |
|--------|------|-------------|
| `id` | BIGINT | Primary key |
| `name` | VARCHAR | Display name |
| `email` | VARCHAR | Unique login email |
| `role` | ENUM | `customer`, `operator`, `admin` |
| `stripe_id` | VARCHAR | Stripe customer ID (nullable) |
| `created_at` | TIMESTAMP | Account creation |
# Relationships
- `hasMany` Orders
- `hasOne` Subscription
- `belongsToMany` Teams
# Related
- Protected by the [user policy](/policies/user-policy.md)
- Exposed via the [API users route](/routes/api-users.md)
- Synced to Stripe by [sync job](/jobs/sync-stripe-customer.md)
# Citations
[1] [Source file](repo://app/Models/User.php)Notice resource: repo:// — it points to a file in the codebase, not an external URL. Any agent can resolve that to open the actual source. And the “Related” section weaves the graph: model → policy → route → job. One concept, four connections.
4. WordPress Site
A WordPress shop documenting custom post types, taxonomies, ACF field groups, and template files. The scenario: a freelancer inherits the project or an agent needs to understand the content architecture before making changes.
Folder tree
wordpress-site/
├── index.md
├── log.md
├── post-types/
│ ├── index.md
│ └── product.md
├── taxonomies/
│ ├── index.md
│ └── product-category.md
├── acf/
│ ├── index.md
│ └── product-fields.md
└── templates/
├── index.md
└── single-product.mdpost-types/product.md
---
type: WordPress Post Type
title: Product
description: Custom post type used to manage product landing pages and catalog content.
resource: wp-admin/edit.php?post_type=product
tags: [wordpress, post-type, content, ecommerce]
timestamp: 2026-06-21T00:00:00Z
---
# Registration
Registered in `functions.php` via `register_post_type('product', ...)`.
Supports title, editor, thumbnail, excerpt, and custom fields.
# Features
- Publicly queryable with archive at `/products/`
- Has single template: [single-product](/templates/single-product.md)
- Categorized by [Product Category](/taxonomies/product-category.md) taxonomy
- Enriched with [Product Fields](/acf/product-fields.md) ACF group
# Schema
| Field | Source | Description |
|-------|--------|-------------|
| `post_title` | Core | Product name |
| `post_content` | Core | Long description |
| `post_excerpt` | Core | Short description for cards |
| `featured_image` | Core | Hero image |
| `price` | ACF | Display price |
| `sku` | ACF | Stock keeping unit |
# Related
- Template: [single-product](/templates/single-product.md)
- Taxonomy: [Product Category](/taxonomies/product-category.md)
- Fields: [Product Fields](/acf/product-fields.md)
# Citations
[1] [WP Admin](wp-admin/edit.php?post_type=product)WordPress’s content model is infamously scattered across CPTs, taxonomies, ACF groups, and template files. A single OKF bundle connects all four. An agent reading this knows exactly what a “Product” is without grepping through functions.php.
5. API Documentation
A bundle for documenting a REST API with contextual knowledge. Not a replacement for OpenAPI — this answers “what happens when you use it wrong” and “why does this endpoint exist.”
Folder tree
api-docs/
├── index.md
├── log.md
├── endpoints/
│ ├── index.md
│ ├── create-customer.md
│ └── list-customers.md
├── schemas/
│ ├── index.md
│ └── customer.md
└── errors/
├── index.md
└── rate-limit.mdendpoints/create-customer.md
---
type: API Endpoint
title: Create Customer
description: Creates a new customer record and returns the created object.
resource: https://api.example.com/v1/customers
tags: [api, customers, write]
timestamp: 2026-06-21T00:00:00Z
---
# Request
```http
POST /v1/customers
Content-Type: application/json
Authorization: Bearer {token}Accepts a payload conforming to the Customer schema.
{
"name": "Jane Doe",
"email": "jane@example.com",
"segment": "enterprise"
}Response
Returns 201 Created with the full customer object including generated id and created_at.
Errors
| Status | Description |
|---|---|
| 400 | Validation error — missing required fields |
| 409 | Email already exists |
| 429 | Rate limit exceeded |
Related
- Schema: Customer
- Error: Rate Limit
Citations
[1] API reference
The error table is the highest-value section. "What goes wrong and how to fix it" is exactly what an agent (or a frustrated developer at 2am) needs.
---
## 6. Company Knowledge
An ops team documenting teams, policies, systems, and escalation playbooks. The scenario: an AI support agent needs to know the refund policy, who owns billing, and when to escalate — from one canonical source.
### Folder tree
company-knowledge/ ├── index.md ├── log.md ├── teams/ │ ├── index.md │ └── support.md ├── policies/ │ ├── index.md │ └── refunds.md ├── systems/ │ ├── index.md │ └── billing.md └── playbooks/ ├── index.md └── incident-response.md
### `policies/refunds.md`
```markdown
---
type: Policy
title: Refund Policy
description: Rules support and billing teams use when evaluating customer refund requests.
resource: docs://policies/refunds
tags: [support, billing, policy]
timestamp: 2026-06-21T00:00:00Z
---
# Purpose
Defines when support can approve a refund autonomously, when billing review
is required, and which cases must be escalated to management.
# Decision Matrix
| Condition | Action | Approver |
|-----------|--------|----------|
| Within 14 days, no usage | Auto-approve | Support agent |
| Within 14 days, with usage | Pro-rate and refund | Support lead |
| 15-30 days | Partial refund (50%) | Billing team |
| Over 30 days | Deny unless extenuating | VP Support |
| Chargeback/dispute | Escalate immediately | [Incident Response](/playbooks/incident-response.md) |
# Process
1. Verify active subscription in [billing system](/systems/billing.md).
2. Check usage metrics in analytics dashboard.
3. Apply decision matrix above.
4. Process refund via Stripe (partial or full).
5. Log outcome in ticket for audit trail.
# Related
- Executed by: [Support team](/teams/support.md)
- Uses: [Billing System](/systems/billing.md)
- Escalates to: [Incident Response](/playbooks/incident-response.md)
# Citations
[1] [Refund policy source](docs://policies/refunds)This is the kind of doc that makes an AI support agent actually useful. The decision matrix is unambiguous — the agent reads it, applies the rules, and either handles the refund or escalates.
7. AI Agent Context
A bundle that defines what an AI agent can and cannot do. Systems it has access to, tools it may call, procedures it should follow, and hard boundaries it must never cross. This is the OKF bundle an agent reads about itself.
Folder tree
ai-agent-context/
├── index.md
├── log.md
├── systems/
│ ├── index.md
│ └── billing.md
├── tools/
│ ├── index.md
│ └── stripe.md
├── playbooks/
│ ├── index.md
│ └── support-triage.md
└── constraints/
├── index.md
└── agent-safety-rules.mdconstraints/agent-safety-rules.md
---
type: Constraint
title: Agent Safety Rules
description: Operating boundaries the AI agent must follow before using tools or changing customer-facing systems.
resource: docs://agent-context/safety-rules
tags: [agent, safety, constraint, guardrails]
timestamp: 2026-06-21T00:00:00Z
---
# Core Rules
1. **Read before acting.** Always read relevant system, tool, and playbook
concepts before taking any action.
2. **No destructive actions without approval.** Do not change billing data,
process refunds, send external messages, or modify production settings
unless a human explicitly approves the specific action.
3. **No data exfiltration.** Never share customer PII, payment details, or
internal system information with external parties or in logs.
4. **Scope awareness.** Only use tools listed in this bundle. Do not attempt
to access systems not documented here.
5. **Fail safe.** If uncertain about an action's impact, escalate to a human
rather than proceeding.
# Prohibited Actions
- Processing refunds or credits
- Modifying subscription plans
- Sending emails to customers on behalf of the company
- Accessing production databases directly
- Sharing API keys, tokens, or credentials
# Escalation Triggers
Escalate to human immediately when:
- Customer expresses intent to harm themselves or others
- Legal threats or regulatory inquiries
- Account compromise suspected
- Action would affect more than one customer
# Related
- Applies to: [Stripe tool](/tools/stripe.md), [Billing System](/systems/billing.md)
- Context for: [Support Triage](/playbooks/support-triage.md)
# Citations
[1] [Safety rules source](docs://agent-context/safety-rules)This is the meta-example — an OKF bundle describing the agent’s own operating boundaries. The agent reads this bundle, discovers what tools exist, what it’s allowed to do, and what requires escalation. No system prompt gymnastics. Just files it can cat.
8. Astro Site
A development team documenting their Astro site’s pages, components, content collections, and integrations. The scenario: a developer or coding agent needs to understand the routing, data flow, and how content reaches the rendered page.
Folder tree
astro-site/
├── index.md
├── log.md
├── pages/
│ ├── index.md
│ ├── docs-slug.md
│ └── blog-index.md
├── components/
│ ├── index.md
│ └── header.md
├── collections/
│ ├── index.md
│ ├── docs.md
│ └── blog.md
└── integrations/
├── index.md
├── starlight.md
└── sitemap.mdpages/docs-slug.md
---
type: Astro Page
title: Docs Slug
description: Dynamic route that renders documentation pages from the docs content collection.
resource: repo://src/pages/docs/[...slug].astro
tags: [astro, page, routing, docs]
timestamp: 2026-06-21T00:00:00Z
---
# Routing
File-based dynamic route at `src/pages/docs/[...slug].astro`. Uses
`getStaticPaths()` to generate one page per entry in the
[docs collection](/collections/docs.md).
# Data Flow
1. `getStaticPaths()` calls `getCollection('docs')` to get all entries.
2. Each entry's `slug` becomes the URL path (`/docs/{slug}`).
3. The page renders the entry's compiled markdown via `entry.render()`.
# Examples
```astro
---
import { getCollection } from 'astro:content';
import DocsLayout from '../../layouts/DocsLayout.astro';
export async function getStaticPaths() {
const docs = await getCollection('docs');
return docs.map(entry => ({
params: { slug: entry.slug },
props: { entry },
}));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<DocsLayout title={entry.data.title}>
<Content />
</DocsLayout>Related
Citations
### `collections/docs.md`
```markdown
---
type: Content Collection
title: Docs
description: Type-safe documentation collection with Zod schema validation for frontmatter.
resource: repo://src/content/docs/
tags: [astro, collection, content, docs]
timestamp: 2026-06-21T00:00:00Z
---
# Schema
Defined in `src/content.config.ts` using Astro's `defineCollection` + Zod:
```typescript
import { defineCollection, z } from 'astro:content';
const docs = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string().optional(),
order: z.number().default(999),
draft: z.boolean().default(false),
}),
});
export const collections = { docs };Frontmatter Fields
| Field | Type | Required | Description |
|---|---|---|---|
title | string | yes | Page title |
description | string | no | Meta description for SEO |
order | number | no | Sort order in sidebar (default: 999) |
draft | boolean | no | Excluded from production builds if true |
Directory
Files live in src/content/docs/. Subdirectories create nested slugs (e.g., guides/getting-started.md → /docs/guides/getting-started).
Related
- Rendered by: Docs Slug page
Citations
Astro's abstractions — pages, components, collections, integrations — map perfectly to OKF concepts. The data flow from collection → page → component is explicit in the cross-links. An agent reading this bundle understands the architecture without opening a single `.astro` file.
---
## Patterns across all eight bundles
1. **`type` is domain-specific.** There's no fixed list. Use `Metric`, `BigQuery Table`, `Laravel Model`, `WordPress Post Type`, `Astro Page`, `Constraint` — whatever your team actually calls these things.
2. **Cross-links are generous.** If one concept references another, link it. Every bundle above is a graph, not just a folder. The Laravel bundle has 4 concepts with 8+ cross-links between them.
3. **`index.md` is a map, not a junk drawer.** One line per item. Direct link + description. Zero preamble.
4. **Extra frontmatter fields are free.** The spec allows any additional key. `method`, `severity`, `queue` — add whatever the consumer needs to filter.
5. **`# Citations` at the end.** External links that validate content. Agents use these to verify. Humans use them to dig deeper.
6. **Body is structured.** Headings, tables, code blocks. More structure = better retrieval by agents. Prose paragraphs are noise.
7. **One concept per file.** Never mix concerns. The refund policy is not inside the support team doc — it has its own file with its own cross-links.
8. **The `resource` field anchors to reality.** It points to the actual thing — a BigQuery table, a GitHub file, a Stripe dashboard, an admin URL. The concept describes it; the resource IS it.