Skip to content

feat(dialect): add okf target (Open Knowledge Format bundles) - #11

Open
andrebaaij wants to merge 4 commits into
mainfrom
feature/GCP-KP
Open

feat(dialect): add okf target (Open Knowledge Format bundles)#11
andrebaaij wants to merge 4 commits into
mainfrom
feature/GCP-KP

Conversation

@andrebaaij

@andrebaaij andrebaaij commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

What and why

Adds okf as an emit-only target: Google Cloud's Open Knowledge Format, a vendor-neutral bundle of markdown concepts with YAML frontmatter. It gives semglot an output aimed at agents that read curated context as files rather than as a semantic-layer config.

The bundle is one type: Table concept per model under tables/, one type: Metric concept per metric under metrics/, notes.md for passthrough notes, and the reserved index.md in every directory. Relationships become markdown links between concepts, so the joins are part of the knowledge graph rather than prose only.

Emit-only by design. The spec prescribes no type taxonomy and carries meaning in free prose, so reading a bundle back into the IR would be a heuristic markdown scraper, not a parser. A test pins that okf does not register as a source.

The spec and the reference implementation disagree

SPEC.md requires exactly one frontmatter field, type. The reference implementation's OKFDocument.validate() requires type, title, description and timestamp to all be non-empty:

# okf/src/reference_agent/bundle/document.py
REQUIRED_FRONTMATTER_KEYS = ("type", "title", "description", "timestamp")

The reference implementation is what actually reads bundles, so this PR satisfies the stricter of the two. The first draft omitted timestamp on spec grounds, and all 13 concepts failed validation. What changed:

  • timestamp is stamped, but never from a clock. It comes from a new profile timestamp field, falling back to the source's last commit date. The same checkout still produces a byte-identical bundle, so the goldens hold.
  • Descriptions are synthesized when the IR has none. A metric falls back to its rendered definition, a table to "The <name> table."
  • index.md is byte-identical to regenerate_indexes output, so their tooling is a no-op on our bundles instead of rewriting them.
  • Links are directory-relative and body headings are #, matching the published ga4 bundle. The spec recommends absolute links for stability, but stability is moot for a generated bundle and relative is what the reference viewer resolves.

How this is tested against upstream

Three layers, since goldens happily pin a malformed bundle:

  1. test/okf_conformance_test.go re-implements the reference rules in Go: frontmatter parses, required keys non-empty, every link resolves. Runs in CI with no extra toolchain. Mutation-checked, it fails when the timestamp is dropped.
  2. test/okf_contract_test.py runs the real OKFDocument.validate() and regenerate_indexes() over the golden bundle. Not in CI (needs Python 3.11+ and a clone of upstream); setup is in the docstring.
  3. reference_agent visualize renders the bundle as the reference viewer draws it.

All three pass against knowledge-catalog @ main as of 2026-07-20:

OK: test/models/ecommerce/dbt/okf validates against the OKF reference implementation
Wrote 13 concept(s), 24 edge(s), 23865 bytes → viz.html

The 24 edges are our generated links resolving in their viewer, for example metrics/aov -> tables/fct_orders.

Measures and data types are emitted as well. Without a # Measures section the bundle never names the aggregatable columns (order_net_booked, quantity); a reader would have had to reverse them out of a metric's definition SQL.

No IR changes were needed: ir.Model already carries everything OKF can express. dialect.Options gained a Timestamp field.

Checklist

  • This PR is based on main (not stacked on another unmerged branch)
  • If it changes emitted output, I regenerated goldens (UPDATE_GOLDEN=1 go test ./...) and reviewed the diff (don't bless output you haven't read)
  • Docs updated if behavior or a dialect mapping changed (README.md, dialect/README.md)

🤖 Generated with Claude Code

andrebaaij and others added 4 commits July 20, 2026 08:48
Adds `okf` as an emit-only target: Google Cloud's Open Knowledge Format,
a bundle of markdown concepts with YAML frontmatter
(GoogleCloudPlatform/knowledge-catalog, okf/SPEC.md).

Layout is one `type: Table` concept per model under `tables/`, one
`type: Metric` concept per metric under `metrics/`, the reserved
`index.md` listing both, and `notes.md` for passthrough notes.
Relationships become bundle-absolute markdown links between concepts, so
the joins are part of the knowledge graph rather than prose only.

Emit-only by design: the spec prescribes no type taxonomy and carries
meaning in free prose, so reading a bundle back into the IR would be a
heuristic markdown scraper, not a parser.

Two format choices worth recording:

- No `timestamp`. The spec only recommends it, and writing a clock into
  every concept would make two builds of the same input differ
  byte-for-byte, which the goldens rely on.
- `resource` reuses the profile's database/schema as
  `table://DATABASE/SCHEMA/TABLE`, and is dropped entirely rather than
  emitted half-qualified when no database is configured.

Measures and data types are emitted too. Without a Measures section the
bundle never names the aggregatable columns; a reader would have to
reverse them out of a metric's definition SQL.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Validating the emitted bundle with the OKF reference implementation
(knowledge-catalog @ main) found three divergences. All 13 concepts in
the golden bundle failed OKFDocument.validate().

The spec and the reference implementation disagree. SPEC.md requires
only a non-empty `type`; document.py's REQUIRED_FRONTMATTER_KEYS also
requires title, description and timestamp. The reference implementation
is what actually reads bundles, so satisfy the stricter of the two:

- Stamp a `timestamp`, sourced from the new profile `timestamp` field or
  the source's last commit date. Never a clock, so the same checkout
  still produces a byte-identical bundle and the goldens hold.
- Synthesize a description when the IR has none: a metric falls back to
  its rendered definition, a table to "The <name> table."
- Write the reserved index.md into every directory, byte-identical to
  what bundle/index.regenerate_indexes produces, so their tooling is a
  no-op on our bundles rather than rewriting them.

Also switch concept links from bundle-absolute to directory-relative and
body headings from `##` to `#`, matching the published ga4 bundle. The
spec recommends absolute links for stability, but stability is moot for
a generated bundle and relative is what the reference viewer resolves.

Testing, three layers:

- test/okf_conformance_test.go re-implements the reference rules in Go
  (frontmatter parses, required keys non-empty, every link resolves), so
  CI has a check with no extra toolchain. Mutation-checked: it fails
  when the timestamp is dropped.
- test/okf_contract_test.py runs the real OKFDocument.validate() and
  regenerate_indexes() over the golden bundle. Not in CI; it needs a
  Python 3.11+ venv and a clone of upstream.
- `reference_agent visualize` renders the bundle. 13 concepts, 24 edges,
  confirming the viewer resolves our links.

All three pass against knowledge-catalog @ main as of 2026-07-20.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two workflows, deliberately split, because they answer different
questions.

okf-contract.yml runs the contract test on PRs touching okf, against the
commit pinned in test/OKF_UPSTREAM_REF. Pinning is what makes it safe to
block a merge on: it cannot break because upstream moved. It validates
the committed golden rather than re-emitting, since ci.yml already fails
on a stale golden, so it needs no Go toolchain.

okf-upstream.yml runs weekly against upstream main. It never blocks: a
Google engineer's commit must not turn an unrelated semglot PR red. When
our bundles stop validating it opens an issue labelled okf-drift listing
the commits that touched okf/SPEC.md or bundle/, and comments on the
existing issue rather than filing duplicates. Acting on it means
reconciling dialect/okf.go, bumping the pin, and regenerating the golden
in one reviewed PR.

Rehearsed locally: the pin extraction, the clone-at-SHA, the install, and
the validation all run clean, and the drift log command surfaces real
format commits when pointed at an older ref.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CI caught this: git renders %cI in the LOCAL timezone, so the same
commit reads as "2026-07-20T00:00:00+00:00" on my machine and
"2026-07-20T00:00:00Z" on the UTC runner. Both are valid RFC 3339 for
the same instant, but they are different bytes, so two developers in
different timezones would emit different bundles from the same checkout.
That defeats the point of deriving the timestamp from git at all.

Parse and reformat in UTC. The test now reads the same commit under
three timezones and asserts identical output, rather than asserting the
string git happened to produce on the machine that wrote the test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant