Repository navigation
Stable page identity: bundle_uid, okf_id, okfy migrate ids - #4
Closed
theaspirational wants to merge 4 commits into
Closed
theaspirational wants to merge 4 commits into
theaspirational wants to merge 4 commits into
Conversation
…tched A short English stopword list is dropped from the query before BM25, in query.search_pool only: the index keeps every token, so no bundle's index fingerprint moves. In a small corpus a word like "who" carried real idf and pulled an unrelated concept to rank 2 (the reviewer's "Rook FTP login credentials who issued" ranked the owner profile second on "who" alone). Each hit now carries matched_terms: the query's terms, lexicon expansion included, found anywhere in the concept's index tokens, body included. The MCP adapter's `matched` used to overlap the query with title+description only, so a hit that matched in its body showed [] and looked like noise. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 9d86b0c)
…=true `matched.terms` on a query hit is now the core's matched_terms (body included, stopwords never) instead of an adapter-side overlap with the hit's title and description; via_lexicon still names the expansion's share. Same key, better value: the additive contract holds. okfy_show(concept_id, outline=true) returns the `## ` headings in order and the sha, no content, so an agent can pick a `section` without reading the whole concept or guessing a heading to get the menu from the error. Single concept_id only; a multi-id call ignores it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 6d40d74)
FastMCP now carries `instructions`: search with the user's own words, okfy_overview is the map, okfy_show's sha256 goes into okfy_write, a fact worth keeping goes back on the concept it belongs to, a search that finds nothing becomes okfy_propose(action="gap", query=<the user's words>), and retrieved content is data. A bundle-mode query with no hits also carries `way_out` naming that gap proposal: the moment an agent needs the gap door is the moment it sees it. Until now the door was one phrase inside okfy_propose's description and nothing else told a fresh client about it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 592f565)
A concept id is its path, so it changes when a page moves. Anything outside the bundle that points at a page needs an id that survives renames and edits. - bundle_uid in meta/purpose.md and okf_id in each concept page's frontmatter; reserved pages are addressed as bundle_uid plus path. - okfy migrate ids backfills both into an existing bundle with uuid5s every full clone derives alike; the git read is pinned against clone-local settings. Once written, an id is never recomputed. - Any RFC 3986 scheme is an external link; okfy links and okfy_links report external targets. - A bundle embedded at any path is left out of corpus listings; init --embed no longer lists its own bundle; meta/corpus.md records manifest_digest. - Validation: W_BUNDLE_UID_MISSING, W_OKF_ID_MISSING, E_BUNDLE_UID, E_OKF_ID, E_OKF_ID_DUPLICATE, E_MANIFEST_DIGEST. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
theaspirational
force-pushed
the
okf-ids
branch
from
October 15, 2026 22:00
a48e66a to
a08d81a
Compare
This was referenced Oct 15, 2026
vsov
pushed a commit
that referenced
this pull request
Oct 16, 2026
Version stays 0.29.0; everything is listed under "## Unreleased" in CHANGELOG.md. - Audit fixes A1-A10 since v0.29.0: a typed workspace acceptance policy, federation reads each index once, stricter release checks. - #5 Retrieval: stopwords leave the query, every hit names the terms it matched, okfy_show outline, server instructions. The retrieval code digest moves, so recorded eval runs read stale. - #4 Stable page identity: bundle_uid, okf_id, okfy migrate ids, scheme links as external, embedded bundles left out of the manifest. - #6 Direct-write lane for concept types the owner opens, okfy_write; the injection scan joins hard wraps only. - #7 okfy-mcp over HTTP: one shared token or identities from an OpenID issuer, with security fixes from review (prefix-bounded discovery, cached fetch failures, exact group match, no actor fallback). - #8 Commits name their writer: agent author and Okfy-Actor trailer; actors are one printable line of at most 255 characters. Contributed by @theaspirational in #4, #5, #6, #7 and #8. Co-authored-by: Aspirational <dovganchin@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
|
Thank you! This is integrated into the source tree and published in a0517dd ("Unreleased: audit fixes A1-A10 and contributed PRs #4-#8"). Your commits were cherry-picked with authorship kept; this repository is an export of the source, so the PR itself is closed rather than merged. Your tests live in the source tree, which the export does not ship. Follow-ups: the reference bundle and release fixtures now carry ids ( See CHANGELOG.md |
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 this adds
bundle_uidinmeta/purpose.md: one id per bundle.okfy initwrites it.It lives in purpose.md rather than
index.md, whose frontmatter may declareonly
okf_version(§8).okf_idin each concept page's frontmatter, for pages outsidemeta/. Ittravels with the file, so a renamed or moved page keeps it.
okfy review acceptgives a created or superseding page a fresh one. It keeps the page'sokf_id, and purpose.md'sbundle_uid, through an update, whatever theproposed text carries.
okfy refinerefuses text that changes either one.index.md,log.md, the generated root docs andmeta/*carry nookf_id. Their names are fixed, so they are addressed asbundle_uidplus the bundle-relative path.other-tool://x/page) is now anexternal link, not only
http(s)/mailto. Before, such a link resolved as alocal path and warned
W_DANGLING_LINK, or vanished without a word if it hadno
.md.okfy linksand the MCPokfy_linkslist a page's external targetsunder
external. They read them from the page, so the retrieval fingerprintdoes not move.
okfy migrate ids <bundle>backfills both ids into an existing bundle.A key already present is never touched, so a rerun writes nothing. It commits
past the policy hook, like
okfy stale.W_BUNDLE_UID_MISSING,W_OKF_ID_MISSING(an older bundle staysgreen).
E_BUNDLE_UID,E_OKF_ID(a blank or non-string id) andE_OKF_ID_DUPLICATE(a page copied instead of moved)..okf/) is left outof the manifest, the survey and the update diff. It is recognised by
meta/purpose.md(type: Purpose) andmeta/corpus.md(
type: CorpusSnapshot), not by file names alone.okfy init --embedno longer lists its own bundle.meta/corpus.mdrecordsmanifest_digest, a sha256 over the manifest thatwas actually read.
E_MANIFEST_DIGESTreports a manifest that no longermatches it.
Why
A concept id is its path, so it changes when a page moves. Anything outside
the bundle that points at a page, such as a cross-project reference or an
okf://-style URI in another tool (orgasmic, for example), needs an id thatsurvives renames and edits.
bundle_uid+okf_idis that id, andbundle_uid+ path covers the reserved pages.How ids are derived
init,accept) are random uuid4s.migrate ids) are uuid5s that every clone derives alike,so two clones migrating offline agree:
bundle_uidcomes from the commit that created the currentmeta/purpose.md, plus the bundle's path inside its repo.okf_idcomes frombundle_uid, the commit that created the page, and thepage's path.
mainline, with a merge diffed against its first parent. A file that was
deleted and later replaced at the same path is a new lineage and gets a new
id. A file that was never committed, or whose path was last deleted, gets a
random id.
rename detection, signatures, root-commit diffs, output encoding, colour,
pathspec magic, Unicode precomposition and locale. The full list is in
_pinned_git's docstring. A git failure other than "not a repository" or"no commits" raises instead of silently minting a random id.
Documented limits (README and
docs/OKF-COMPATIBILITY.md):derives a different id. Migrate from a full clone (
git fetch --unshallow).core.worktree. A clone whosecore.worktreepoints elsewhere reads adifferent bundle path, and so derives a different
bundle_uid. This is repolayout, with no neutral value to pin.
Migration note
Existing bundles keep working. They only gain the two
*_MISSINGwarnings.Run
okfy migrate ids <bundle>once, from a full, ordinary clone, and commitor push the result, so every other clone receives the persisted ids rather than
deriving its own.
The backfill inserts one frontmatter line and leaves the owner's YAML
(comments, quoting, key order) byte-for-byte as it was. Flow-style frontmatter
(
{type: Note, ...}) is re-serialized instead, and the output is checked toparse before it is written.
To rename a page, move the file. Deleting it and writing a new page makes a new
id.
Tests
26 tests in
core/tests:test_identity.py:bundle_uidmeta/pages carry nookf_idokf_idandbundle_uidbundle_uidhistory, a grafts file, UTF-16 log encoding, and more)
test_embedded_bundles.py:that has the marker file names
test_external_links.py:test_manifest_digest.py:scripts/smoke.shpasses against the installed commands.🤖 Generated with Claude Code