GoogleCloudPlatform / GoogleCloudPlatform/knowledge-catalog
Consumer report: supersession is a retrieval problem — what a bundle serves when `status: deprecated` has no counterpart
- Dominant language
- TypeScript
- Stars
- 9.2k
- Forks
- 782
- Avg merge
- 6h 36m
- Merged PRs (30d)
- 85
Description
Reading #158, #148, #182 and #207 changed what this issue is. We set out to propose `superseded_by`, found that #158 had already named the gap exactly ("the spec's quiet on conflicting content — no `contradicts`/`supersedes`") and that #148 and #182 are carrying the vocabulary further than we would. So this is a consumer report instead, on the one part those threads don't cover: what happens on the **read** path when supersession is absent.
For context, we build Hands, a multi-agent CRM assistant. Each workspace keeps an OKF bundle as its long-term memory: agents write concepts with `remember`, a scheduled synthesis pass consolidates them into canonical topics, and a `recall` tool searches the bundle to ground future turns. Producer and consumer are the same system, which is what surfaced this.
## The finding: supersession is a retrieval problem before it is a vocabulary problem
Our synthesis pass has always resolved contradictions in favour of recent information — it merges overlapping concepts and prefers the newer fact. That logic was correct and it was **invisible**, because the only thing it wrote was the winner.
So the corpus contained, simultaneously:
- `memory/sruly-owns-android.md` — `status` absent, therefore `stable` per §5.4
- `memory/android-ownership.md` — the newer, correct concept
and `recall` returned both. Ranked by text relevance, the stale one often ranked higher, because it was written when the topic was the whole subject of a conversation rather than one line in a consolidated note.
The system had already decided the first concept was false. It had nowhere to put that decision, so it kept serving it. That is worse than not having the fact at all: a wrong answer with a bundle path attached reads as sourced.
The two existing mechanisms don't close this:
- **`status: deprecated`** (§5.4) is the right marker and we now use it, but on its own it only says *not current*. It doesn't say what to read instead, so a consumer can suppress the bad answer but not repair it.
- **`log.md`** (§9) is where a `**Deprecation**` would conventionally go, but §9 makes both the file and the convention optional, and the entry is prose. Our retrieval path cannot depend on it. #207 makes the same observation about deletion from the other direction.
## What we shipped
Two extension keys under the §4.1 allowance, in production this week with test coverage:
| Key | Written when | Consumer behaviour |
|---|---|---|
| `superseded_by` | synthesis produces a concept that contradicts an existing one | the replacement's bundle-relative path; retrieval can follow it |
| `deprecated_at` | same moment | ISO 8601; distinguishes "deprecated in March" from "deprecated yesterday" |
Both ride alongside `status: deprecated` rather than replacing it.
The consumer half is where the value landed. Our `recall` now reads §5.2 and §5.4 at query time and:
- **drops** `status: deprecated` outright
- **sinks** concepts past their `stale_after` (§5.5)
- **floats** `human-reviewed` above `machine-confirmed` above `unverified` (§5.2 tiers)
It over-fetches before filtering, so suppressing a superseded hit doesn't silently return fewer results than asked for.
Two constraints that mattered more than we expected:
**Supersession must be narrower than "was consolidated into".** Our first cut deprecated every source a topic absorbed. That was wrong: a summary of a March conversation remains a true record of that conversation even after its claims are superseded. Only a concept whose *assertions* are now false is marked. The distinction is between an episode and a claim, and OKF's document model doesn't currently force producers to notice it.
**`verified` needs a machine writer to be worth anything.** We had `markConceptVerified` for a year with exactly one caller — a human "mark reviewed" button. Every concept sat at `unverified`, so the §5.2 tiers were dead weight in our consumer. The synthesis pass now promotes a topic to machine-confirmed when a re-derivation still agrees with its sources, and the tiers became a usable ranking signal the same day. If other producers are seeing flat trust distributions, this may be why.
## Where we think it belongs
Not as a new thread — we'd rather defer:
- **`superseded_by` as a typed relationship** → #148. A supersession is a typed edge; if that proposal lands, this is one of its types and needs no separate key.
- **The contradiction signal generally** → #158, which named it first.
- **As a lifecycle key with a home** → #182's table is the right shape; ours would be two more rows.
- **Distinct from deletion** → #207. A deleted concept and a superseded one differ: the superseded one should stay readable and keep resolving links, which is exactly what §5.4 already promises ("kept for links and history").
## One thing we deliberately did not build
Time-range validity (`valid_from` / `valid_to`) — "true from March to June". We wanted it, and stopped: it's bitemporal modelling, it's a larger change than the format needs, and git history answers the audit question ("what did we believe in April") for anything short of a compliance requirement. Recording it here only as a considered-and-rejected data point, not a request.
Happy to share the bundle, the tests, or the retrieval ranking code if any of it is useful to the threads above.
Contributor guide
Research direction
No repository file, test, or entry point is identified; begin with #158, #148, #182, and #207 and compare their proposed homes for supersession and lifecycle metadata. The payload describes shipped producer and recall behavior rather than a requested repository change, so done is not defined until maintainers turn the report into an actionable spec or implementation issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend-api-design, search
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100