okf 1.13.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +195 -0
  3. data/README.md +25 -6
  4. data/lib/okf/bundle/folder.rb +27 -1
  5. data/lib/okf/bundle/graph.rb +12 -3
  6. data/lib/okf/bundle/linter.rb +470 -47
  7. data/lib/okf/bundle/reader.rb +10 -4
  8. data/lib/okf/bundle/references.rb +111 -0
  9. data/lib/okf/bundle/row_filter.rb +53 -0
  10. data/lib/okf/bundle/search.rb +20 -2
  11. data/lib/okf/bundle/validator/result.rb +6 -3
  12. data/lib/okf/bundle/validator.rb +267 -26
  13. data/lib/okf/bundle/writer.rb +1 -1
  14. data/lib/okf/bundle.rb +105 -4
  15. data/lib/okf/cli/catalog.rb +1 -1
  16. data/lib/okf/cli/command.rb +27 -8
  17. data/lib/okf/cli/files.rb +1 -1
  18. data/lib/okf/cli/index.rb +1 -1
  19. data/lib/okf/cli/lint.rb +70 -12
  20. data/lib/okf/cli/references.rb +97 -0
  21. data/lib/okf/cli/search.rb +2 -1
  22. data/lib/okf/cli/stats.rb +3 -39
  23. data/lib/okf/cli/tags.rb +6 -43
  24. data/lib/okf/cli/types.rb +1 -1
  25. data/lib/okf/cli/validate.rb +3 -3
  26. data/lib/okf/cli.rb +4 -1
  27. data/lib/okf/concept.rb +362 -10
  28. data/lib/okf/markdown/citations.rb +41 -4
  29. data/lib/okf/markdown/frontmatter.rb +1 -1
  30. data/lib/okf/markdown/links.rb +67 -7
  31. data/lib/okf/render/graph/template.html.erb +173 -41
  32. data/lib/okf/render/graph.rb +11 -3
  33. data/lib/okf/server/app.rb +47 -15
  34. data/lib/okf/server/hub.rb +1 -1
  35. data/lib/okf/skill/SKILL.md +14 -12
  36. data/lib/okf/skill/playbooks/curate.md +8 -3
  37. data/lib/okf/skill/playbooks/doctor.md +3 -1
  38. data/lib/okf/skill/playbooks/maintain.md +7 -6
  39. data/lib/okf/skill/playbooks/menu.md +5 -4
  40. data/lib/okf/skill/playbooks/migrate.md +31 -8
  41. data/lib/okf/skill/playbooks/produce.md +16 -9
  42. data/lib/okf/skill/playbooks/search.md +2 -2
  43. data/lib/okf/skill/reference/SPEC.md +739 -187
  44. data/lib/okf/skill/reference/authoring.md +154 -35
  45. data/lib/okf/skill/reference/cli.md +155 -42
  46. data/lib/okf/skill/templates/attested-computation.md +41 -0
  47. data/lib/okf/skill/templates/concept.md +13 -6
  48. data/lib/okf/skill/templates/root-index.md +1 -1
  49. data/lib/okf/version.rb +1 -1
  50. data/lib/okf.rb +22 -2
  51. metadata +5 -1
@@ -1,7 +1,7 @@
1
1
  <!--
2
2
  Vendored from the Open Knowledge Format reference repository.
3
3
  Source: https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md
4
- Commit: ee67a5ca27044ebe7c38385f5b6cffc2305a9c1a
4
+ Commit: 3fcbb9f828c2f23d109c855ee403c3a4c81f3a96
5
5
  License: Apache-2.0 (c) Google LLC — included verbatim under its terms.
6
6
  Full license text: ./APACHE-2.0.txt
7
7
  This is the canonical normative reference loaded by the okf skill.
@@ -9,10 +9,10 @@
9
9
 
10
10
  # Open Knowledge Format (OKF)
11
11
 
12
- **Version 0.1 — Draft**
12
+ **Version 0.2**
13
13
 
14
14
  OKF is an open, human- and agent-friendly format for representing
15
- *knowledge* the metadata, context, and curated insight that surrounds
15
+ *knowledge*: the metadata, context, and curated insight that surrounds
16
16
  data and systems. It is designed to be authored by people, generated by
17
17
  agents, exchanged across organizations, and consumed by both.
18
18
 
@@ -21,6 +21,10 @@ YAML frontmatter. There is no schema registry, no central authority, and
21
21
  no required tooling. If you can `cat` a file, you can read OKF; if you
22
22
  can `git clone` a repo, you can ship it.
23
23
 
24
+ This document is self-contained: it specifies everything needed to
25
+ produce and consume OKF v0.2. A summary of what changed from v0.1 is in
26
+ §13.
27
+
24
28
  ---
25
29
 
26
30
  ## 1. Motivation
@@ -35,69 +39,104 @@ formats that are:
35
39
  - **Diffable** in version control.
36
40
  - **Portable** across tools, organizations, and time.
37
41
 
38
- The format is minimally opinionated. It standardizes only the small set
39
- of structural conventions needed to make a knowledge corpus
40
- *self-describing* anything beyond that is left to the producer.
42
+ Increasingly, a knowledge corpus is not authored once and then read: it
43
+ is **continuously written and maintained by agents**. When most concepts
44
+ are machine-generated, a consumer needs answers that a plain
45
+ markdown-plus-frontmatter convention does not make first-class:
46
+
47
+ 1. What was this created from, and how was it verified? (**provenance**)
48
+ 2. How much should I trust it? (**trust**)
49
+ 3. Is it still true? (**freshness**)
50
+ 4. Is it the current version? (**lifecycle**)
51
+ 5. Was this number produced the way we said it must be? (**attestation**)
52
+
53
+ OKF v0.2 makes provenance, trust, lifecycle, and attestation first-class
54
+ while keeping the format minimally opinionated. The format is minimally
55
+ opinionated. It standardizes only the small set of structural conventions
56
+ needed to make a knowledge corpus self-describing — anything beyond that
57
+ is left to the producer.
41
58
 
42
59
  ### Goals
43
60
 
44
- 1. Define a universal format that **enrichment agents** can write into.
45
- 2. Inform how **consumption agents** should read and traverse it.
61
+ 1. Define a universal format that **producers** (people, agents, export
62
+ pipelines) can write into.
63
+ 2. Inform how **consumers** (agents, UIs, search indexes, deterministic
64
+ code) should read and traverse it.
46
65
  3. Facilitate **exchange** of knowledge across systems and organizations.
47
- 4. Standardize the small number of **required** fields that must be
48
- present for content to be meaningfully consumed.
66
+ 4. Standardize the small set of frontmatter fields that make an
67
+ agent-maintained corpus **trustable**, without prescribing any runtime.
49
68
 
50
69
  ### Non-goals
51
70
 
52
71
  - Defining a fixed taxonomy of concept types.
53
72
  - Prescribing storage, serving, or query infrastructure.
54
- - Replacing domain-specific schemas (Avro, Protobuf, OpenAPI, etc.) —
73
+ - Replacing domain-specific schemas (Avro, Protobuf, OpenAPI, and so on).
55
74
  OKF *references* them; it does not subsume them.
75
+ - Specifying a packaging or invocation standard for the code an executor
76
+ or attester points at. OKF fixes the interface, not the packaging.
56
77
 
57
78
  ---
58
79
 
59
80
  ## 2. Terminology
60
81
 
61
- - **Knowledge Bundle** A self-contained, hierarchical collection of
62
- knowledge documents. The unit of distribution.
63
- - **Concept** A single unit of knowledge within a bundle. Represented
64
- as one markdown document. May describe a tangible asset (a table, an
82
+ - **Knowledge Bundle** (or **bundle**): A self-contained, hierarchical
83
+ collection of knowledge documents. The unit of distribution.
84
+ - **Concept**: A single unit of knowledge within a bundle, represented as
85
+ one markdown document. It may describe a tangible asset (a table, an
65
86
  API), an abstract idea (a metric, a business process), or anything in
66
87
  between.
67
- - **Concept ID** The path of the concept's file within the bundle,
68
- with the `.md` suffix removed. For example, `tables/users.md` has
69
- concept ID `tables/users`.
70
- - **Frontmatter** — YAML metadata block delimited by `---` at the top of
88
+ - **Concept ID**: The path of the concept's file within the bundle, with
89
+ the `.md` suffix removed.
90
+ - **Frontmatter**: A YAML metadata block delimited by `---` at the top of
71
91
  a markdown file.
72
- - **Body** Everything in the file after the frontmatter.
73
- - **Link** A standard markdown link from one concept to another, used
74
- to express relationships beyond the implicit parent/child hierarchy.
75
- - **Citation** A link from a concept to an external source that
76
- supports a claim in the body.
92
+ - **Body**: Everything in the file after the frontmatter.
93
+ - **Link**: A standard markdown link from one concept to another, used to
94
+ express relationships beyond the implicit parent/child hierarchy.
95
+ - **Source**: A material a concept derives from, external or internal to
96
+ the bundle, recorded in the `sources` frontmatter field.
97
+ - **Provenance**: The set of sources a concept derives from.
98
+ - **Credibility signal**: An objective, per-source fact (`author`,
99
+ `usage_count`, `last_modified`) used to infer trust; OKF records the
100
+ signals, not a verdict (see §5.1).
101
+ - **Actor**: A string identifying who or what performed an action, using
102
+ the convention `<producer>/<version>` for agents, `human:<id>` for
103
+ people, and `process:<id>` for automated processes (see §7).
104
+ - **Trust tier**: A level derived from a concept's `verified` field:
105
+ unverified, machine-confirmed, or human-reviewed (see §5.3).
106
+ - **Attested Computation**: A concept (`type: Attested Computation`)
107
+ carrying a sanctioned way to compute a value, so a consumer can confirm
108
+ the value was produced by running it (see §10).
109
+ - **Executor**: Run instructions or code that executes a computation and
110
+ returns a receipt (see §10.2).
111
+ - **Receipt**: The evidence a run returns, shaped by `executor.receipt`; a
112
+ runtime artifact, not stored in the bundle (see §10).
113
+ - **Attester**: Deterministic (no-LLM) code that inspects a receipt and
114
+ returns a verdict (see §10.2).
77
115
 
78
116
  ---
79
117
 
80
- ## 3. Bundle Structure
118
+ ## 3. Bundle structure
81
119
 
82
120
  A bundle is a directory tree of markdown files. The directory structure
83
- is independent of the domain producers organize concepts however makes
121
+ is independent of the domain: producers organize concepts however makes
84
122
  sense for the knowledge being captured.
85
123
 
86
124
  ```
87
125
  path/to/bundle/
88
- ├── index.md # Optional. Directory listing for progressive disclosure.
89
- ├── log.md # Optional. Chronological history of updates.
90
- ├── <concept>.md # A concept at the bundle root.
91
- └── <subdirectory>/ # Subdirectories organize concepts into groups.
92
- ├── index.md
93
- ├── <concept>.md
94
- └── <subdirectory>/
95
- └── …
126
+ index.md # Optional. Directory listing for progressive disclosure.
127
+ log.md # Optional. Chronological history of updates.
128
+ <concept>.md # A concept at the bundle root.
129
+ <subdirectory>/ # Subdirectories organize concepts into groups.
130
+ index.md
131
+ <concept>.md
132
+ <subdirectory>/
133
+ ...
96
134
  ```
97
135
 
98
136
  A bundle MAY be distributed as:
99
137
 
100
- - A git repository (recommended provides history, attribution, diffs).
138
+ - A git repository (recommended, since it provides history, attribution,
139
+ and diffs).
101
140
  - A tarball or zip archive of the directory.
102
141
  - A subdirectory within a larger repository.
103
142
 
@@ -106,26 +145,26 @@ A bundle MAY be distributed as:
106
145
  The following filenames have defined meaning at any level of the
107
146
  hierarchy and MUST NOT be used for concept documents:
108
147
 
109
- | Filename | Purpose |
110
- |--------------|--------------------------------------------------------|
111
- | `index.md` | Directory listing. See §6. |
112
- | `log.md` | Update history. See §7. |
148
+ | Filename | Purpose |
149
+ |------------|----------------------------------|
150
+ | `index.md` | Directory listing. See §8. |
151
+ | `log.md` | Update history. See §9. |
113
152
 
114
153
  All other `.md` files are concept documents.
115
154
 
116
- Tags themselves remain a first-class concept see the `tags`
117
- frontmatter field in §4.1. OKF does not specify a separate file format
118
- for aggregating documents by tag; producers that want a tag-browsing
119
- view can synthesize one at consumption time by scanning frontmatter.
155
+ Tags remain a first-class concept through the `tags` frontmatter field
156
+ (§4.1). OKF does not specify a separate file format for aggregating
157
+ documents by tag; a consumer that wants a tag-browsing view can
158
+ synthesize one at consumption time by scanning frontmatter.
120
159
 
121
160
  ---
122
161
 
123
- ## 4. Concept Documents
162
+ ## 4. Concept documents
124
163
 
125
- Every concept is a UTF-8 markdown file. It has two parts:
164
+ Every concept is a UTF-8 markdown file with two parts:
126
165
 
127
- 1. A **YAML frontmatter block**, delimited by `---` on its own line at
128
- the start of the file and a closing `---` on its own line.
166
+ 1. A **YAML frontmatter block**, delimited by `---` on its own line at the
167
+ start of the file and a closing `---` on its own line.
129
168
  2. A **markdown body**, containing free-form content.
130
169
 
131
170
  ### 4.1 Frontmatter
@@ -136,54 +175,63 @@ type: <Type name> # REQUIRED
136
175
  title: <Optional display name>
137
176
  description: <Optional one-line summary>
138
177
  resource: <Optional canonical URI for the underlying asset>
139
- tags: [<tag>, <tag>, ] # Optional
140
- timestamp: <ISO 8601 datetime> # Optional last-modified time
141
- # other producer-defined key/value pairs
178
+ tags: [<tag>, <tag>, ...] # Optional
179
+ # ... trust, lifecycle, provenance, and computation families (see §5, §10)
180
+ # ... other producer-defined key/value pairs
142
181
  ---
143
182
  ```
144
183
 
145
184
  **Required:**
146
185
 
147
- - `type` A short string identifying the kind of concept. Consumers
148
- use this for routing, filtering, and presentation. Example values:
186
+ - `type`: A short string identifying the kind of concept. Consumers use it
187
+ for routing, filtering, and presentation. Example values:
149
188
  `BigQuery Table`, `BigQuery Dataset`, `API Endpoint`, `Metric`,
150
- `Playbook`, `Reference`.
189
+ `Playbook`, `Reference`, `Attested Computation`.
151
190
 
152
191
  Type values are **not** registered centrally. Producers SHOULD pick
153
192
  values that are descriptive and self-explanatory; consumers MUST
154
- tolerate unknown types gracefully (typically by treating them as
155
- generic concepts).
193
+ tolerate unknown types gracefully, typically by treating them as generic
194
+ concepts.
195
+
196
+ `type` is the only always-required key; a concept carrying just `type` is
197
+ fully conformant (§11).
156
198
 
157
- **Recommended (in priority order):**
199
+ **Recommended:**
158
200
 
159
- - `title` Human-readable display name. If omitted, consumers MAY
160
- derive a title from the filename.
161
- - `description` A single sentence summarizing the concept. Used by
201
+ - `title`: Human-readable display name. If omitted, consumers MAY derive a
202
+ title from the filename.
203
+ - `description`: A single sentence summarizing the concept. Used by
162
204
  `index.md` generators, search snippets, and previews.
163
- - `resource` A URI that uniquely identifies the underlying asset the
205
+ - `resource`: A URI that uniquely identifies the underlying asset the
164
206
  concept describes. Absent for concepts that describe abstract ideas
165
207
  rather than physical resources.
166
- - `tags` A YAML list of short strings for cross-cutting categorization.
167
- - `timestamp` — ISO 8601 datetime of last meaningful change.
208
+ - `tags`: A YAML list of short strings for cross-cutting categorization.
209
+
210
+ The optional **provenance**, **trust**, and **lifecycle** families (§5) and
211
+ the **computation** fields for Attested Computation concepts (§10) may also
212
+ appear.
168
213
 
169
214
  **Extensions:** Producers MAY include any additional keys. Consumers
170
- SHOULD preserve unknown keys when round-tripping and SHOULD NOT reject
215
+ SHOULD preserve unknown keys when round-tripping and MUST NOT reject
171
216
  documents with unrecognized fields.
172
217
 
173
218
  ### 4.2 Body
174
219
 
175
- The body is standard markdown. Producers SHOULD favor structural
176
- markdown — headings, lists, tables, fenced code blocks over freeform
177
- prose, since structure aids both human reading and agent retrieval.
220
+ The body is standard markdown. Producers SHOULD favor structural markdown
221
+ (headings, lists, tables, fenced code blocks) over freeform prose, since
222
+ structure aids both human reading and agent retrieval.
178
223
 
179
- There are no required body sections. The following section headings have
224
+ There are no required body sections. The following headings have
180
225
  **conventional** meaning and SHOULD be used when applicable:
181
226
 
182
- | Heading | Purpose |
183
- |----------------|--------------------------------------------------------|
184
- | `# Schema` | Structured description of an asset's columns/fields. |
185
- | `# Examples` | Concrete usage examples, often as fenced code blocks. |
186
- | `# Citations` | External sources backing claims in the body. See §8. |
227
+ | Heading | Purpose |
228
+ |-----------------|--------------------------------------------------------|
229
+ | `# Schema` | Structured description of an asset's columns/fields. |
230
+ | `# Examples` | Concrete usage examples, often as fenced code blocks. |
231
+ | `# Computation` | The sanctioned computation of an Attested Computation. See §10. |
232
+
233
+ Per-claim attribution to external sources uses markdown footnotes keyed to
234
+ `sources` entries rather than a body citations list (§5.1).
187
235
 
188
236
  ### 4.3 Example: a concept bound to a resource
189
237
 
@@ -194,7 +242,7 @@ title: Customer Orders
194
242
  description: One row per completed customer order across all channels.
195
243
  resource: https://console.cloud.google.com/bigquery?p=acme&d=sales&t=orders
196
244
  tags: [sales, orders, revenue]
197
- timestamp: 2026-05-28T14:30:00Z
245
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-05-28T14:30:00Z }
198
246
  ---
199
247
 
200
248
  # Schema
@@ -209,10 +257,6 @@ timestamp: 2026-05-28T14:30:00Z
209
257
  # Joins
210
258
 
211
259
  Joined with [customers](/tables/customers.md) on `customer_id`.
212
-
213
- # Citations
214
-
215
- [1] [BigQuery table schema](https://console.cloud.google.com/bigquery?p=acme&d=sales&t=orders)
216
260
  ```
217
261
 
218
262
  ### 4.4 Example: a concept not bound to a resource
@@ -220,72 +264,260 @@ Joined with [customers](/tables/customers.md) on `customer_id`.
220
264
  ```markdown
221
265
  ---
222
266
  type: Playbook
223
- title: Incident response data freshness alert
267
+ title: "Incident response: data freshness alert"
224
268
  description: Steps to triage a freshness alert on the orders pipeline.
225
269
  tags: [oncall, incident]
226
- timestamp: 2026-04-12T09:00:00Z
270
+ generated: { by: human:ahormati, at: 2026-04-12T09:00:00Z }
227
271
  ---
228
272
 
229
273
  # Trigger
230
274
 
231
- A freshness alert fires when `orders` lags more than 30 minutes behind
232
- its expected SLA. See the [orders table](/tables/orders.md).
275
+ A freshness alert fires when `orders` lags more than 30 minutes behind its
276
+ expected SLA. See the [orders table](/tables/orders.md).
233
277
 
234
278
  # Steps
235
279
 
236
280
  1. Check the [ingestion job dashboard](https://example.com/dash).
237
- 2.
281
+ 2. ...
238
282
  ```
239
283
 
240
284
  ---
241
285
 
242
- ## 5. Cross-linking
286
+ ## 5. Provenance, trust, and lifecycle
243
287
 
244
- Concepts MAY link to other concepts using standard markdown links. Two
245
- forms are supported:
288
+ These frontmatter families make "where did this come from," "how much
289
+ should I trust it," and "is it still current" answerable from frontmatter.
290
+ All are optional. Their absence carries meaning: an unverified concept is
291
+ distinguishable from a verified one, but is never rejected (§11).
292
+
293
+ ### 5.1 Provenance: `sources`
246
294
 
247
- ### 5.1 Absolute (bundle-relative) links
295
+ `sources` records the materials a concept derives from, external or
296
+ internal to the bundle.
248
297
 
249
- Begin with `/`, interpreted relative to the bundle root.
298
+ ```yaml
299
+ sources:
300
+ - id: ga4-schema
301
+ resource: https://developers.google.com/analytics/bigquery/export-schema
302
+ title: GA4 BigQuery Export schema
303
+ author: team:ga4-docs
304
+ usage_count: 5000
305
+ last_modified: 2026-05-30
306
+ usage_window: { from: 2026-06-01, to: 2026-06-30 }
307
+ ```
308
+
309
+ Each `sources` entry:
310
+
311
+ - `resource`: REQUIRED within an entry. Names either a concrete artifact a
312
+ consumer can follow (an absolute URL, a bundle-relative path, or a path
313
+ into a `references/` subdirectory, §6) or a population or scope descriptor
314
+ it cannot (for example `all queries in BigQuery project X`).
315
+ - `id`: Optional. A stable key used to attribute individual claims (see
316
+ below). SHOULD be present when the body cites the source.
317
+ - `title`: Optional. Human-readable label for the source.
318
+ - The optional credibility signals `author`, `usage_count`, and
319
+ `last_modified`, described next.
320
+
321
+ **Source credibility signals.** OKF records objective, per-source signals
322
+ so a consumer can judge how much to trust a concept by judging the sources
323
+ it was extracted from. It does not store a credibility score: a score is
324
+ subjective, unportable across consumers, and goes stale. Credibility is
325
+ *inferred* from the signals, the same way trust tiers are (§5.3), not
326
+ stored. Each signal is optional and lives on a `sources` entry:
327
+
328
+ - `author`: Who or what produced the source, in the actor convention (§7).
329
+ An authority signal.
330
+ - `usage_count`: How often `resource` was exercised (dashboard views, query
331
+ executions, page reads) over `usage_window`. An adoption and liveness
332
+ signal. For a single artifact it is that artifact's own exercise count;
333
+ for a scope descriptor it is the number of exercises within the scope that
334
+ touch the concept.
335
+ - `last_modified`: When the source itself last changed (`YYYY-MM-DD`). A
336
+ recency signal, distinct from `generated.at` (§5.2), which records when
337
+ the concept was written.
338
+ - `usage_window`: Written once as a sibling of `sources`, it frames every
339
+ `usage_count` with a `{ from, to }` date range. A single entry MAY carry
340
+ its own `usage_window` to override the shared one.
341
+
342
+ `usage_count` is a coarse signal. It is comparable at the
343
+ alive-versus-dead and order-of-magnitude level, and against a source's own
344
+ history over time, but not as a precise cross-kind ranking: a scheduled
345
+ query's executions and a human's deliberate dashboard views do not carry
346
+ equal weight. Consumers SHOULD read it as liveness and trend, not as a
347
+ score.
348
+
349
+ Lineage is expressed through links, not a dedicated field. When a
350
+ `resource` points at another OKF concept, the derivation edge already
351
+ exists in the bundle graph (§6), so a consumer MAY recurse into that
352
+ source's own `sources` and let credibility propagate. External leaf sources
353
+ carry only their intrinsic signals. Deeper lineage (an explicit external
354
+ `derived_from`, or data lineage) is out of scope for v0.2.
355
+
356
+ **Per-claim attribution.** To attribute a specific claim, use a markdown
357
+ footnote whose label is a `sources[].id`:
250
358
 
251
359
  ```markdown
252
- See the [customers table](/tables/customers.md) for the join key.
360
+ The `events_` table is sharded daily as `events_YYYYMMDD`.[^ga4-schema]
361
+
362
+ [^ga4-schema]: GA4 BigQuery Export schema
253
363
  ```
254
364
 
255
- This is the **recommended** form because it is stable when documents are
256
- moved within their subdirectory.
365
+ The footnote label is the join key into `sources`; consumers resolve
366
+ attribution through the matching entry, not by parsing the footnote prose.
367
+ Labels are keyed rather than positional (`sources[0]`) because agents
368
+ constantly rewrite these documents: a positional index misattributes
369
+ silently the moment the list is reordered, whereas a stable `id` survives
370
+ reordering.
257
371
 
258
- ### 5.2 Relative links
372
+ ### 5.2 Trust: `generated` and `verified`
259
373
 
260
- Standard markdown relative paths.
374
+ `generated` records how the current content was produced. `verified`
375
+ records who or what has confirmed the content against its sources or
376
+ `resource`. They are kept distinct because who *wrote* a concept need not
377
+ be who *confirmed* it.
261
378
 
262
- ```markdown
263
- See the [neighboring concept](./other.md).
379
+ ```yaml
380
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-20T22:53:05Z }
381
+ ```
382
+
383
+ - `generated.by`: REQUIRED within `generated`. An actor (§7).
384
+ - `generated.at`: An ISO 8601 datetime marking the content's last
385
+ meaningful change. Consumers use it to tell a recent edit from a stale
386
+ fact.
387
+
388
+ ```yaml
389
+ verified:
390
+ - { by: human:ahormati, at: 2026-06-25T09:00:00Z }
391
+ - { by: process:finance-nightly, at: 2026-06-26T02:00:00Z }
392
+ ```
393
+
394
+ - `verified`: A list of verification events, each with `by` (an actor) and
395
+ `at` (an ISO 8601 datetime). Multiple entries capture independent
396
+ checks, for example a human sign-off plus a nightly process. "How
397
+ recently" is the latest `at`.
398
+ - `verified` is independent of `generated.at`: content can change without
399
+ re-confirmation, and facts can be re-confirmed without regeneration.
400
+ - A single verifier MAY be written as one `{ by, at }` mapping without the
401
+ list dash. Consumers MUST treat a bare mapping as a one-element list:
402
+
403
+ ```yaml
404
+ verified: { by: human:ahormati, at: 2026-06-25T09:00:00Z }
405
+ ```
406
+
407
+ ### 5.3 Trust tiers
408
+
409
+ Consumers derive a trust tier from `verified`, lowest to highest:
410
+
411
+ - No `verified` key ⇒ **unverified**.
412
+ - `verified` by non-`human:` actors only ⇒ **machine-confirmed**.
413
+ - `verified` by a `human:<id>` actor ⇒ **human-reviewed**.
414
+
415
+ A concept with no trust frontmatter is still consumable; consumers MUST
416
+ NOT reject it (§11). Trust tiers are advisory signals, not access control.
417
+
418
+ ### 5.4 Lifecycle: `status`
419
+
420
+ ```yaml
421
+ status: stable # draft | stable | deprecated
422
+ ```
423
+
424
+ - `draft`: not yet reviewed; possibly incomplete.
425
+ - `stable`: default; ready for consumption.
426
+ - `deprecated`: kept for links and history; no longer current.
427
+
428
+ Absent `status` ⇒ `stable`.
429
+
430
+ ### 5.5 Lifecycle: `stale_after`
431
+
432
+ ```yaml
433
+ stale_after: 2026-09-23 # absolute date; content is stale on/after this day
264
434
  ```
265
435
 
266
- ### 5.3 Link semantics
436
+ Optional. An absolute date (`YYYY-MM-DD`). A concept is stale when
437
+ `today >= stale_after`. An absolute date, not a relative TTL, keeps the
438
+ staleness decision a plain date comparison with no reference to when the
439
+ concept was read.
440
+
441
+ ---
442
+
443
+ ## 6. Cross-linking and paths
444
+
445
+ ### 6.1 Links between concepts
446
+
447
+ Concepts MAY link to other concepts using standard markdown links. Two
448
+ forms are supported:
449
+
450
+ - **Absolute (bundle-relative):** begins with `/`, interpreted relative to
451
+ the bundle root. This is the **recommended** form because it is stable
452
+ when documents are moved within their subdirectory.
267
453
 
268
- A link from concept A to concept B asserts a *relationship*. The
269
- specific kind of relationship (parent/child, references, joins-with,
270
- depends-on, etc.) is conveyed by the surrounding prose, not by the link
271
- itself. Consumers that build a graph view typically treat all links as
272
- directed edges of an untyped relationship.
454
+ ```markdown
455
+ See the [customers table](/tables/customers.md) for the join key.
456
+ ```
273
457
 
274
- Consumers MUST tolerate broken links — a link whose target does not
275
- exist in the bundle is not malformed; it may simply represent
276
- not-yet-written knowledge.
458
+ - **Relative:** a standard markdown relative path.
459
+
460
+ ```markdown
461
+ See the [neighboring concept](./other.md).
462
+ ```
463
+
464
+ A link from concept A to concept B asserts a *relationship*. The specific
465
+ kind (parent/child, references, joins-with, depends-on) is conveyed by the
466
+ surrounding prose, not by the link itself. Consumers that build a graph
467
+ view typically treat all links as directed edges of an untyped
468
+ relationship.
469
+
470
+ Consumers MUST tolerate broken links: a link whose target does not exist
471
+ in the bundle is not malformed; it may simply represent not-yet-written
472
+ knowledge.
473
+
474
+ ### 6.2 Path-valued fields
475
+
476
+ Several fields name a path or URI: `resource`, `sources[].resource`,
477
+ `computation`, `executor.resource`, and `attester.resource` (§10). A
478
+ `sources[].resource` may instead be a scope descriptor (§5.1), in which
479
+ case it is not a path. Each path-valued field accepts:
480
+
481
+ - an absolute URL (for example `https://...`),
482
+ - a bundle-relative path beginning with `/`, or
483
+ - a relative path (for example `../computations/revenue.md`).
484
+
485
+ ### 6.3 The `references/` convention
486
+
487
+ A `references/` subdirectory conventionally mirrors external material, run
488
+ instructions, or code as first-class concepts within the bundle. Sources,
489
+ executors, and attesters commonly point into it (for example
490
+ `references/attesters/revenue.py`). It is a naming convention, not a
491
+ requirement.
277
492
 
278
493
  ---
279
494
 
280
- ## 6. Index Files
495
+ ## 7. Actor convention
281
496
 
282
- An `index.md` file MAY appear in any directory, including the bundle
283
- root. It enumerates the directory's contents to support **progressive
284
- disclosure** — letting a human or agent see what is available before
497
+ Fields that record an identity (`generated.by`, `verified[].by`) use a
498
+ single actor convention:
499
+
500
+ - `<producer>/<version>` for agents and tools, for example
501
+ `reference_agent/gemini-2.5-pro`.
502
+ - `human:<id>` for a person, for example `human:ahormati`.
503
+ - `process:<id>` for an automated process, for example
504
+ `process:finance-nightly`.
505
+
506
+ Consumers that classify trust (§5.3) key off the `human:` prefix, so
507
+ producers MUST use it for hand-authored or human-confirmed content.
508
+
509
+ ---
510
+
511
+ ## 8. Index files
512
+
513
+ An `index.md` file MAY appear in any directory, including the bundle root.
514
+ It enumerates the directory's contents to support **progressive
515
+ disclosure**: letting a human or agent see what is available before
285
516
  opening individual documents.
286
517
 
287
- Index files contain no frontmatter. The body uses one or more sections,
288
- each grouping concepts under a heading:
518
+ Index files contain no frontmatter, with one exception: a bundle-root
519
+ `index.md` MAY carry an `okf_version` key (§12). The body uses one or more
520
+ sections, each grouping concepts under a heading:
289
521
 
290
522
  ```markdown
291
523
  # Section / Group Heading
@@ -304,7 +536,7 @@ MAY synthesize one on the fly when none is present.
304
536
 
305
537
  ---
306
538
 
307
- ## 7. Log Files (optional)
539
+ ## 9. Log files
308
540
 
309
541
  A `log.md` file MAY appear at any level of the hierarchy to record the
310
542
  history of changes to that scope. The format is a flat list of
@@ -314,48 +546,217 @@ date-grouped entries, newest first:
314
546
  # Directory Update Log
315
547
 
316
548
  ## 2026-05-22
317
- * **Update**: Added new BigQuery table reference for [Customer Metrics](/tables/customer-metrics.md).
549
+ * **Update**: Added a BigQuery table reference for [Customer Metrics](/tables/customer-metrics.md).
318
550
  * **Creation**: Established the [Dataplex Playbook](/playbooks/dataplex.md).
319
551
 
320
552
  ## 2026-05-15
321
553
  * **Initialization**: Created foundational directory structure.
322
- * **Update**: Added progressive-disclosure guidelines to the root [index](/index.md).
323
554
  ```
324
555
 
325
- Date headings MUST use ISO 8601 `YYYY-MM-DD` form. Log entries are
326
- prose; the leading bold word (`**Update**`, `**Creation**`,
327
- `**Deprecation**`, etc.) is a convention, not a requirement.
556
+ Date headings MUST use ISO 8601 `YYYY-MM-DD` form. Log entries are prose;
557
+ the leading bold word (`**Update**`, `**Creation**`, `**Deprecation**`) is
558
+ a convention, not a requirement.
328
559
 
329
560
  ---
330
561
 
331
- ## 8. Citations
562
+ ## 10. Attested computations concept
563
+
564
+ An Attested Computation concept carries not just what a value *means* but a
565
+ sanctioned way to *compute* it, so a consumer can confirm the agent ran the
566
+ blessed computation instead of improvising its own. Provenance (§5.1)
567
+ answers "where did this claim come from"; attestation answers "was this
568
+ number produced the way we said it must be." OKF records the computation
569
+ and the means to check it; it does not execute anything itself.
570
+
571
+ ### 10.1 A computation is its own concept
572
+
573
+ A sanctioned computation is a standalone concept of
574
+ `type: Attested Computation`. A concept that needs the value (a `Metric`, a
575
+ `BigQuery Table`) links to it with a normal markdown link (§6). Three
576
+ properties motivate the standalone concept:
577
+
578
+ - **`runtime` defines what `parameters` mean.** A parameter is a SQL bind
579
+ variable, a dbt var, or a Python argument depending on the runtime.
580
+ Keeping `runtime` and `parameters` in one frontmatter makes the binding
581
+ semantics self-evident.
582
+ - **One computation, many consumers.** The same computation can back a
583
+ metric, a dashboard concept, and a report; as a concept it is referenced
584
+ once and reused.
585
+ - **Trust state is per computation.** `verified`, `stale_after`, and a
586
+ single `attester` describe one thing. Revenue, profit, and margin each
587
+ verify and attest independently, which is three concepts, not three
588
+ entries in one frontmatter.
589
+
590
+ ### 10.2 Contract fields
591
+
592
+ The contract is the concept's top-level frontmatter. In addition to the
593
+ provenance, trust, and lifecycle families (§5), an Attested Computation
594
+ concept carries:
595
+
596
+ - `runtime`: REQUIRED for this type. The single field that says how to run
597
+ the computation, and so how the executor and attester interpret it and
598
+ what `parameters` mean. Example values: `bigquery`, `postgres`, `dbt`,
599
+ `python`, `Looker`.
600
+ - `parameters`: A list of the typed, named holes the agent may fill. Each
601
+ entry: `{ name, type, required }`. Binding semantics follow `runtime`.
602
+ - `computation`: Optional. A path (§6.2) to a file holding the
603
+ computation, used instead of an inline body fence (see §10.3). Absent ⇒
604
+ the body `# Computation` fence is the computation.
605
+ - `executor`: How the computation is run. `resource` names run
606
+ instructions or code; a runner (an agent, or deterministic consumer
607
+ code) follows it. `receipt` declares the fields a run must return, the
608
+ evidence the attester inspects (for example a BigQuery `job_id` and the
609
+ SQL the job actually executed).
610
+ - `attester`: The deterministic check. `resource` names code (no LLM) that
611
+ takes a receipt and returns a verdict. It is meant to run consumer-side.
612
+
613
+ What sits behind a `resource` (a Skill, a script, a container) is a
614
+ packaging choice; OKF fixes the interface, not the packaging (§1).
332
615
 
333
- When a concept's body makes claims sourced from external material,
334
- those sources SHOULD be listed under a `# Citations` heading at the
335
- bottom of the document, numbered:
616
+ ```markdown
617
+ ---
618
+ type: Attested Computation
619
+ title: Revenue for fiscal year
620
+ description: Recognized revenue for a fiscal year, per Finance's definition.
621
+ status: stable
622
+ runtime: bigquery
623
+ parameters:
624
+ - { name: year, type: integer, required: true }
625
+ executor:
626
+ resource: references/skills/run-on-bq.md
627
+ receipt: [job_id, executed_sql, result]
628
+ attester:
629
+ resource: references/attesters/revenue.py
630
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-20T22:53:05Z }
631
+ verified: { by: human:ahormati, at: 2026-06-25T09:00:00Z }
632
+ stale_after: 2026-09-23
633
+ sources:
634
+ - id: rev-policy
635
+ resource: https://wiki.acme/finance/revenue-recognition
636
+ title: Revenue recognition policy
637
+ ---
638
+
639
+ # Computation
640
+
641
+ SELECT SUM(amount) AS revenue
642
+ FROM finance.recognized_revenue
643
+ WHERE fiscal_year = @year
644
+
645
+ The computation binds only the declared `parameters`, per the recognition
646
+ policy.[^rev-policy]
647
+
648
+ [^rev-policy]: Revenue recognition policy
649
+ ```
650
+
651
+ ### 10.3 The computation
652
+
653
+ Provide the computation in one of two ways:
654
+
655
+ - **Inline:** a single fenced code block in the body under `# Computation`.
656
+ Best for a short computation reviewed alongside the contract.
657
+ - **File:** set `computation` to a path (§6.2) and omit the body fence.
658
+ Best for a long or generated computation, or one already kept as a real
659
+ file shared with non-OKF tooling.
660
+
661
+ ```yaml
662
+ runtime: bigquery
663
+ computation: references/computations/lib/revenue.sql
664
+ parameters:
665
+ - { name: year, type: integer, required: true }
666
+ ```
667
+
668
+ The agent MAY only supply *values* for the declared `parameters`; it MUST
669
+ NOT author or edit the computation. Binding `computation` with the
670
+ parameter values into the executable artifact is the consumer's job, and
671
+ the attester independently re-derives that same binding to compare against
672
+ what actually ran. Because the comparison is on the expanded, compiled
673
+ artifact the receipt carries (`executed_sql`, `compiled_sql`), a rewritten
674
+ query, a swapped computation file, or a mutated dependency fails the check.
675
+ A typed, parameter-only surface is what makes "did the sanctioned thing
676
+ run" a mechanical comparison rather than a judgement call.
677
+
678
+ ### 10.4 Concepts that use a computation
679
+
680
+ A document is rarely a single computation. An income-statement overview
681
+ that discusses revenue, profit, and margin stays one readable concept and
682
+ links to one Attested Computation per figure:
336
683
 
337
684
  ```markdown
338
- # Citations
685
+ ---
686
+ type: Metric
687
+ title: Revenue
688
+ description: Recognized revenue for a fiscal year.
689
+ tags: [finance, revenue]
690
+ status: stable
691
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-20T22:53:05Z }
692
+ ---
339
693
 
340
- [1] [BigQuery public dataset announcement](https://cloud.google.com/blog/products/data-analytics/...)
341
- [2] [Internal data quality runbook](https://wiki.acme.internal/data/quality)
694
+ # Definition
695
+
696
+ Recognized revenue sums `amount` over rows booked to the fiscal year,
697
+ computed by [the revenue computation](../computations/revenue.md).
342
698
  ```
343
699
 
344
- Citation links MAY be absolute URLs, bundle-relative paths, or paths
345
- into a `references/` subdirectory that mirrors external material as
346
- first-class OKF concepts.
700
+ Because each computation is its own concept, revenue can be fresh while
701
+ profit is past its `stale_after`, and each attests on its own run.
702
+ Co-locating them is a directory choice (a `computations/` folder with an
703
+ `index.md`), not a frontmatter one.
704
+
705
+ ### 10.5 How a consumer uses it (informative)
706
+
707
+ This subsection is informative, not normative. The runtime artifacts below
708
+ are **not** stored in the bundle.
709
+
710
+ 1. **Discover** via `type: Attested Computation`, a frontmatter signal
711
+ liftable into `index.md`; a consumer reaches one directly or by
712
+ following a link from a concept that uses it.
713
+ 2. **Load** the contract from frontmatter and the computation from the
714
+ body (or the file named by `computation`).
715
+ 3. **Parameterize**: the agent supplies values for the declared parameters.
716
+ 4. **Execute**: the executor runs the bound computation and returns a
717
+ receipt shaped by `executor.receipt`.
718
+ 5. **Attest**: the consumer runs the attester over the receipt. It
719
+ confirms provenance (the computation that ran equals `computation` bound
720
+ with the claimed parameters, not agent-authored SQL) and fidelity (the
721
+ displayed value matches the receipt's authoritative source, re-read by
722
+ job id rather than taken from the agent's text).
723
+ 6. **Gate**: refuse to display a failing attestation; warn or refuse when
724
+ `today >= stale_after`. On success, surface the verdict (for example a
725
+ link to the job log) so trust is visible.
726
+
727
+ ### 10.6 Verification versus attestation
728
+
729
+ `verified` (§5.2) and attestation are distinct, and both exist:
730
+
731
+ - `verified` confirms the *definition* still matches policy. It is
732
+ doc-level, slow, and recorded in the bundle.
733
+ - Attestation confirms a single *run* produced the value the sanctioned
734
+ way. It is per-call, runtime, and not stored in the bundle.
735
+
736
+ A concept with a stale definition can still attest cleanly, and a
737
+ freshly-verified definition still requires attestation on each run, which
738
+ is why both are needed.
347
739
 
348
740
  ---
349
741
 
350
- ## 9. Conformance
742
+ ## 11. Conformance
351
743
 
352
- A bundle is **conformant** with OKF v0.1 if:
744
+ A bundle is **conformant** with OKF v0.2 if:
353
745
 
354
746
  1. Every non-reserved `.md` file in the tree contains a parseable YAML
355
747
  frontmatter block.
356
748
  2. Every frontmatter block contains a non-empty `type` field.
357
- 3. Every reserved filename (`index.md`, `log.md`) follows the structure
358
- described in §6 and §7 respectively when present.
749
+ 3. Every reserved filename (`index.md`, `log.md`) follows the structure in
750
+ §8 and §9 respectively when present.
751
+
752
+ When the trust, lifecycle, provenance, or computation families are
753
+ present, producers SHOULD follow §5 through §10, and consumers:
754
+
755
+ - MUST treat a bare `verified` mapping as a one-element list (§5.2).
756
+ - MUST NOT reject a concept for missing any optional family (§5.3).
757
+ - SHOULD derive trust tiers and staleness only from the fields specified
758
+ here, and SHOULD surface, not silently drop, a failing attestation
759
+ (§10.5).
359
760
 
360
761
  Consumers SHOULD treat all other constraints as soft guidance. In
361
762
  particular, consumers MUST NOT reject a bundle because of:
@@ -366,95 +767,246 @@ particular, consumers MUST NOT reject a bundle because of:
366
767
  - Broken cross-links.
367
768
  - Missing `index.md` files.
368
769
 
369
- This permissive consumption model is intentional: OKF is meant to
370
- remain useful as bundles grow, get refactored, and are partially
371
- generated by agents.
770
+ ---
771
+
772
+ ## 12. Versioning
773
+
774
+ This document specifies OKF version **0.2**. Revisions are versioned as
775
+ `<major>.<minor>`:
776
+
777
+ - A **minor** version bump introduces backward-compatible additions (new
778
+ optional fields, new conventional section headings).
779
+ - A **major** version bump may make breaking changes (renaming required
780
+ fields, changing reserved filenames).
781
+
782
+ Bundles MAY declare the version they target with `okf_version: "0.2"` in a
783
+ bundle-root `index.md` frontmatter block (the only place frontmatter is
784
+ permitted in an `index.md`). Consumers that do not understand the declared
785
+ version SHOULD attempt best-effort consumption rather than refusing the
786
+ bundle.
787
+
788
+ ### Considered and deferred
789
+
790
+ The following are intentionally left to a future revision:
791
+
792
+ - The full runtime protocol: receipt and verdict wire formats, and the
793
+ attestation lifecycle around a run.
794
+ - The attester ABI, portability, and sandboxing, likely bundled with
795
+ future work on serving and Skills.
796
+ - Attestation caching.
797
+ - Semantic-layer templates (Looker, dbt) where the attester comparison
798
+ shifts from SQL equality to model-and-binding equality.
372
799
 
373
800
  ---
374
801
 
375
- ## 10. Relationship to other formats
802
+ ## 13. Changes from v0.1
803
+
804
+ v0.2 supersedes OKF v0.1 and is a minor version bump under §12, except for
805
+ two deliberate breaking changes called out below because they rename or
806
+ retire v0.1 fields. A v0.1 bundle is consumable by a v0.2 consumer under
807
+ the fallbacks noted here.
376
808
 
377
- OKF is intentionally close to several established patterns:
809
+ ### 13.1 Breaking changes
378
810
 
379
- - **LLM "wiki" repositories** that use markdown + frontmatter as
380
- agent-readable knowledge bases.
381
- - **Personal knowledge tools** like Obsidian and Notion, which use
382
- hierarchical markdown with cross-links.
383
- - **"Metadata as code"** approaches that store catalog metadata
384
- alongside source code rather than in a separate registry.
811
+ - **`timestamp` is superseded by `generated.at`.** A concept's last
812
+ content change is now recorded as `generated: { by, at }` (§5.2).
813
+ Consumers MAY fall back to a legacy `timestamp` when `generated` is
814
+ absent.
815
+ - **The body `# Citations` list is superseded by `sources`.** Provenance
816
+ moves to frontmatter (§5.1). Consumers SHOULD read `sources` and MAY
817
+ still parse a legacy `# Citations` body list for v0.1 documents.
385
818
 
386
- OKF differs primarily in being **specified** — pinning down the small
387
- set of rules needed for interoperability without dictating tooling.
819
+ ### 13.2 Additive changes
820
+
821
+ All of the following are additive: new optional keys, one new concept
822
+ type, and one new conventional heading. Their absence yields a plain v0.1
823
+ concept.
824
+
825
+ - New frontmatter families: `sources` with its per-source credibility
826
+ signals (`author`, `usage_count`, `last_modified`) and the `usage_window`
827
+ sibling; `generated`, `verified`; `status`, `stale_after` (§5).
828
+ - New concept type `Attested Computation` and its computation keys
829
+ `runtime`, `parameters`, `computation`, `executor`, `attester` (§10).
830
+ - New conventional body heading `# Computation` (§4.2).
831
+ - The actor convention for `generated.by` and `verified[].by` (§7).
832
+
833
+ Everything else (bundle structure, reserved filenames, the required
834
+ `type`, recommended `title`/`description`/`resource`/`tags`, cross-linking,
835
+ index files, log files, permissive conformance) is carried forward
836
+ unchanged.
388
837
 
389
838
  ---
390
839
 
391
- ## 11. Versioning
840
+ ## Appendix A: Worked example, an income statement
392
841
 
393
- This document specifies OKF version **0.1**. Future revisions will be
394
- versioned in the form `<major>.<minor>`:
842
+ One bundle exercising every family, shown as a v0.1 to v0.2 migration of an
843
+ income statement with two figures, revenue and gross profit.
395
844
 
396
- - A **minor** version bump introduces backward-compatible additions
397
- (new optional fields, new conventional section headings).
398
- - A **major** version bump may make breaking changes (renaming required
399
- fields, changing reserved filenames).
845
+ ### v0.1 form
400
846
 
401
- Bundles MAY declare the OKF version they target by including
402
- `okf_version: "0.1"` in a bundle-root `index.md` frontmatter block (the
403
- only place frontmatter is permitted in an `index.md`). Consumers that
404
- do not understand the declared version SHOULD attempt best-effort
405
- consumption rather than refusing the bundle.
847
+ A single doc: both figures in one concept, the SQL in prose an agent can
848
+ read, ignore, or rewrite, citations a flat list, and the only timestamp is
849
+ `timestamp`.
406
850
 
851
+ ```markdown
407
852
  ---
853
+ type: Metric
854
+ title: Income statement (fiscal year)
855
+ description: Headline income-statement figures for a fiscal year.
856
+ tags: [finance, income-statement]
857
+ timestamp: '2026-05-28T22:53:05+00:00'
858
+ ---
859
+
860
+ # Definition
861
+ The income statement reports revenue and gross profit for a fiscal year.
862
+
863
+ # Revenue
864
+ Recognized revenue sums `amount` over rows booked to the fiscal year:
865
+
866
+ SELECT SUM(amount) AS revenue
867
+ FROM finance.recognized_revenue
868
+ WHERE fiscal_year = <year>
869
+
870
+ # Gross profit
871
+ Gross profit by segment, per the cost-allocation standard:
872
+
873
+ SELECT gross_profit FROM fct_income_statement
874
+ WHERE fiscal_year = <year> AND segment = <segment>
875
+
876
+ # Citations
877
+ - https://wiki.acme/finance/fpa-handbook
878
+ - https://wiki.acme/finance/revenue-recognition
879
+ - https://wiki.acme/finance/cost-allocation
880
+ ```
881
+
882
+ ### v0.2 form
408
883
 
409
- ## Appendix A Minimal example bundle
884
+ The two figures split into attested computations linked from a narrative
885
+ concept. Every family is populated, and the two computations sit in
886
+ deliberately different states so one consumer reaches two verdicts.
410
887
 
411
888
  ```
412
- my_bundle/
413
- ├── index.md
414
- ├── datasets/
415
- │ ├── index.md
416
- │ └── sales.md
417
- └── tables/
418
- ├── index.md
419
- ├── orders.md
420
- └── customers.md
889
+ bundles/finance/
890
+ metrics/income-statement.md type: Metric (narrates, links both)
891
+ computations/revenue.md type: Attested Computation (runtime: bigquery)
892
+ computations/profit.md type: Attested Computation (runtime: dbt)
893
+ references/skills/run-on-bq.md, run-dbt.md
894
+ references/attesters/sql-equality.py, dbt-binding.py
421
895
  ```
422
896
 
423
- `datasets/sales.md`:
897
+ `metrics/income-statement.md`, the readable doc; trust lives on what it
898
+ links, not here:
424
899
 
425
900
  ```markdown
426
901
  ---
427
- type: BigQuery Dataset
428
- title: Sales
429
- description: All sales-related tables for the retail business.
430
- resource: https://console.cloud.google.com/bigquery?p=acme&d=sales
431
- tags: [sales]
432
- timestamp: 2026-05-28T00:00:00Z
902
+ type: Metric
903
+ title: Income statement (fiscal year)
904
+ description: Headline income-statement figures for a fiscal year.
905
+ tags: [finance, income-statement]
906
+ status: stable
907
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-20T22:53:05Z }
908
+ verified: { by: human:ahormati, at: 2026-06-25T09:00:00Z }
909
+ stale_after: 2026-12-31
910
+ sources:
911
+ - id: fpa-handbook
912
+ resource: https://wiki.acme/finance/fpa-handbook
913
+ title: FP&A reporting handbook
433
914
  ---
434
915
 
435
- The sales dataset contains transactional tables, including
436
- [orders](/tables/orders.md) and [customers](/tables/customers.md).
916
+ # Definition
917
+ The income statement reports [revenue](../computations/revenue.md) and
918
+ [gross profit](../computations/profit.md) for a fiscal year, per the FP&A
919
+ reporting handbook.[^fpa-handbook] Each figure is produced by a sanctioned,
920
+ attestable computation; this concept only narrates them.
921
+
922
+ [^fpa-handbook]: FP&A reporting handbook
437
923
  ```
438
924
 
439
- `tables/orders.md`:
925
+ `computations/revenue.md`, BigQuery SQL, human-verified, fresh, and
926
+ corroborated by a live dashboard source carrying credibility signals:
440
927
 
441
928
  ```markdown
442
929
  ---
443
- type: BigQuery Table
444
- title: Orders
445
- description: One row per completed customer order.
446
- resource: https://console.cloud.google.com/bigquery?p=acme&d=sales&t=orders
447
- tags: [sales, orders]
448
- timestamp: 2026-05-28T00:00:00Z
930
+ type: Attested Computation
931
+ title: Revenue for fiscal year
932
+ description: Recognized revenue for a fiscal year, per Finance's definition.
933
+ tags: [finance, revenue]
934
+ status: stable
935
+ runtime: bigquery
936
+ parameters:
937
+ - { name: year, type: integer, required: true }
938
+ executor:
939
+ resource: references/skills/run-on-bq.md
940
+ receipt: [job_id, executed_sql, result]
941
+ attester:
942
+ resource: references/attesters/sql-equality.py
943
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-28T14:00:00Z }
944
+ verified: { by: human:ahormati, at: 2026-06-25T09:00:00Z }
945
+ stale_after: 2026-12-31
946
+ sources:
947
+ - id: rev-policy
948
+ resource: https://wiki.acme/finance/revenue-recognition
949
+ title: Revenue recognition policy
950
+ author: team:finance-fpa
951
+ last_modified: 2026-04-02
952
+ - id: exec-rev-dash
953
+ resource: dashboards/exec-revenue
954
+ title: Executive revenue dashboard
955
+ author: team:finance-fpa
956
+ usage_count: 5000
957
+ last_modified: 2026-06-18
958
+ usage_window: { from: 2026-06-01, to: 2026-06-30 }
449
959
  ---
450
960
 
451
- # Schema
961
+ # Computation
962
+
963
+ SELECT SUM(amount) AS revenue
964
+ FROM finance.recognized_revenue
965
+ WHERE fiscal_year = @year
966
+
967
+ Recognized revenue per the recognition policy,[^rev-policy] corroborated by
968
+ the executive revenue dashboard.[^exec-rev-dash]
969
+
970
+ [^rev-policy]: Revenue recognition policy
971
+ [^exec-rev-dash]: Executive revenue dashboard
972
+ ```
973
+
974
+ `computations/profit.md`, a dbt model, process-verified, and past its
975
+ `stale_after`:
976
+
977
+ ```markdown
978
+ ---
979
+ type: Attested Computation
980
+ title: Gross profit for fiscal year
981
+ description: Gross profit by segment for a fiscal year, per the cost-allocation standard.
982
+ tags: [finance, profit]
983
+ status: stable
984
+ runtime: dbt
985
+ parameters:
986
+ - { name: year, type: integer, required: true }
987
+ - { name: segment, type: string, required: true }
988
+ executor:
989
+ resource: references/skills/run-dbt.md
990
+ receipt: [run_id, compiled_sql, result]
991
+ attester:
992
+ resource: references/attesters/dbt-binding.py
993
+ generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-14T14:00:00Z }
994
+ verified: { by: process:finance-nightly, at: 2026-06-12T08:00:00Z }
995
+ stale_after: 2026-06-15
996
+ sources:
997
+ - id: cost-alloc
998
+ resource: https://wiki.acme/finance/cost-allocation
999
+ title: Cost allocation standard
1000
+ ---
1001
+
1002
+ # Computation
1003
+
1004
+ SELECT gross_profit
1005
+ FROM {{ ref('fct_income_statement') }}
1006
+ WHERE fiscal_year = {{ var('year') }}
1007
+ AND segment = {{ var('segment') }}
452
1008
 
453
- | Column | Type | Description |
454
- |---------------|-----------|------------------------------|
455
- | `order_id` | STRING | Unique order identifier. |
456
- | `customer_id` | STRING | FK to [customers](/tables/customers.md). |
457
- | `total_usd` | NUMERIC | Order total in USD. |
1009
+ Gross profit by segment per the cost-allocation standard.[^cost-alloc]
458
1010
 
459
- Part of the [sales dataset](/datasets/sales.md).
1011
+ [^cost-alloc]: Cost allocation standard
460
1012
  ```