GoogleCloudPlatform / GoogleCloudPlatform/open-knowledge-format

Proposal: typed, directed, trust-bearing `relationships` — today they are prose

Open
#16 6 comments 1 reaction 0 assignees View on GitHub
Dominant language
HTML
Stars
467
Forks
35
Avg merge
9m
Merged PRs (30d)
1

Description

Second observation from implementing OKF in [Roteiro](https://github.com/OffeneDatenmodellierung/Roteiro) (see also #15, on imported concepts). This one is about the links *between* concepts rather than the concepts themselves.

Please correct me if v0.2 has a mechanism here I have missed — I could not find one, but this is the kind of thing a spec can express in a place I did not look.

## Problem

**A relationship in OKF is an untyped, undirected, untrusted markdown link.** Everything a producer knows *about* the relationship has to be flattened into prose.

Roteiro's graph edges each carry four attributes — `kind`, `provenance`, `confidence`, and the import layer they came from. Rendering to OKF, we currently emit:

```markdown
## Relationships

### calls

* → [checkout](../functions/checkout.md)
* ← [handler](../functions/handler.md) (confidence 0.85)
```

The relationship *type* is a markdown heading. The *direction* is a glyph. Everything else is parenthetical prose. All of it is machine-readable only by a consumer that reverse-engineers our layout conventions — which is precisely the coupling OKF exists to remove, and it is the one part of our bundle that a different producer would encode differently.

Scale, from this repository's own graph: **19,349 relationships across 9 types** — `calls` 10,222, `defines` 4,652, `contains` 3,214, `imports` 967, `references` 294, and a long tail. An agent asking "what calls this?" has to distinguish a `calls` edge from a `contains` edge, and today the only signal is a heading it must parse.

## The sharper half: trust stops at the concept boundary

§5.3's tiers describe how much to believe a **concept**. There is no equivalent for a **relationship** — so these two render identically:

- a link a human wrote in an architecture decision record, and
- a link an embedding-similarity pass guessed at.

In our graph they are different provenance classes (546 authored edges versus 18,803 derived, in this repository). In the bundle they are both a bullet under a heading. A consumer that correctly refuses to trust an unverified *concept* has no way to apply the same judgement to an unverified *relationship* — and relationships are what turn a pile of documents into a graph, so they are arguably where a wrong claim propagates furthest.

## Proposal

Express relationships in frontmatter, reusing the trust vocabulary the spec already has rather than inventing a parallel one:

```yaml
relationships:
- to: ../functions/checkout.md # REQUIRED. a concept in this bundle
type: calls # REQUIRED. producer-defined, like `type` on a concept
direction: outbound # OPTIONAL. outbound (default) | inbound
verified: # OPTIONAL. §5.3 shape, applied to the relationship
- { by: roteiro/5.0.0, at: 2026-09-01T12:00:00Z }
generated: # OPTIONAL. §5.3 shape
by: roteiro/5.0.0
at: 2026-09-01T12:00:00Z
```

The tier rules of §5.3 then apply unchanged, one level down: a relationship with no `verified` is unverified, one confirmed by a non-human actor is machine-confirmed, one confirmed by `human:` is human-reviewed. Nothing new to learn.

`type` is deliberately producer-defined and unconstrained, exactly as concept `type` is — the spec's only hard requirement there is that it be non-empty, and the same reasoning applies. Standardising a vocabulary of relationship types across domains would be a much larger undertaking and is not what this asks for.

**Not asking for a confidence field.** The spec's reasoning against scores — subjective, unportable, goes stale — applies here too, and I agree with it. I mention our `(confidence 0.85)` only to be transparent that it currently leaks into the body, where it is neither queryable nor governed by anything. Under this proposal we would drop it rather than lobby for it.

## Backwards compatibility

- Optional. A bundle without `relationships` behaves exactly as today, and body links keep working.
- Additive to §5.3 rather than a change: the same `verified`/`generated` shapes, the same actors (§7), the same tier derivation.
- Body links are **not** deprecated. A producer may write both, and a consumer that ignores `relationships` sees the bundle it sees today. Whether the spec should say anything about keeping the two consistent is worth deciding — my instinct is to say the frontmatter is authoritative where both exist, and say nothing stronger.
- Composes with #15 (an imported relationship reports the upstream's tier without inheriting it) and with #13 (`refuted` applies to a relationship by the same rule).

## Background

We chose OKF because the trust mapping was, in our ADR's words, "a rename rather than an invention" — our authored/derived/inferred provenance already meant what §5.3's tiers mean. That is a strong endorsement of the concept model, and it is why the relationship gap stands out: the graph we can describe in our own store is strictly richer than the graph we can describe in the bundle, and the part that does not survive is the part that makes it a graph.

Happy to prototype against a draft and report what a real round-trip needs.

Contributor guide

Open the contributing guide

Research direction

Start by reading §5.3 and §7, then compare the proposed relationships frontmatter with the existing concept trust and actor rules. Check how §5.3, §7, #13, and #15 interact with typed, directed relationships; done means the specification resolves the schema, tier derivation, compatibility, and consistency questions raised here.

Written by the indexing model from the issue text.

Assessment

Tech stack
markdown, yaml
Domain
documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.