feat(dialect): add okf target (Open Knowledge Format bundles) - #11
Open
andrebaaij wants to merge 4 commits into
Open
feat(dialect): add okf target (Open Knowledge Format bundles)#11andrebaaij wants to merge 4 commits into
andrebaaij wants to merge 4 commits into
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What and why
Adds
okfas 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: Tableconcept per model undertables/, onetype: Metricconcept per metric undermetrics/,notes.mdfor passthrough notes, and the reservedindex.mdin 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
okfdoes not register as a source.The spec and the reference implementation disagree
SPEC.mdrequires exactly one frontmatter field,type. The reference implementation'sOKFDocument.validate()requires type, title, description and timestamp to all be non-empty:The reference implementation is what actually reads bundles, so this PR satisfies the stricter of the two. The first draft omitted
timestampon spec grounds, and all 13 concepts failed validation. What changed:timestampis stamped, but never from a clock. It comes from a new profiletimestampfield, falling back to the source's last commit date. The same checkout still produces a byte-identical bundle, so the goldens hold.<name>table."index.mdis byte-identical toregenerate_indexesoutput, so their tooling is a no-op on our bundles instead of rewriting them.#, 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:
test/okf_conformance_test.gore-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.test/okf_contract_test.pyruns the realOKFDocument.validate()andregenerate_indexes()over the golden bundle. Not in CI (needs Python 3.11+ and a clone of upstream); setup is in the docstring.reference_agent visualizerenders the bundle as the reference viewer draws it.All three pass against
knowledge-catalog @ mainas of 2026-07-20: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
# Measuressection 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.Modelalready carries everything OKF can express.dialect.Optionsgained aTimestampfield.Checklist
main(not stacked on another unmerged branch)UPDATE_GOLDEN=1 go test ./...) and reviewed the diff (don't bless output you haven't read)README.md,dialect/README.md)🤖 Generated with Claude Code