Skip to content

Okf conformance#37

Merged
arthware-dev merged 22 commits into
mainfrom
okf-conformance
Jun 20, 2026
Merged

Okf conformance#37
arthware-dev merged 22 commits into
mainfrom
okf-conformance

Conversation

@arthware-dev

Copy link
Copy Markdown
Contributor

Closes #35.

Makes the family vault OKF-conformant at rest and switches entity links to
one syntax that works in Obsidian, GitHub/Forgejo, and OKF tools - no export
step. We were already ~90% OKF-shaped, so this is mostly naming.

Required type on every concept (document/note/bookmark/person/topic/
correspondent). Renames: added -> timestamp, capture source_uri ->
resource, capture kind folded into type; documents gain a per-doc
resource URL.
Relative markdown links replace Obsidian [[wikilinks]] in
document/capture headers - dual-format at rest.
Correspondents are now real entities: a generated leaf page
correspondents/.md with a backlink list, so From: links resolve.
Structure: consolidated the duplicated frontmatter/render logic
(mirror_format -> vault_entry) and moved shared vault-layout
conventions into a new stack.vault framework module.

New design/brain/open-knowledge-format.md: how the famstack vault maps
to Google's OKF spec, the cheap beta-window renames to become conformant,
and the higher-leverage borrows from the reference repo (eval harness,
two-pass enrichment, augmentation-strict regeneration).

knowledge-architecture.md: record the "second brain night shift" article
as a research source, with the briefing-as-product takeaway and the
contradiction-queue divergence decision.
git_mirror duplicated all of mirror_format's path/frontmatter/render
logic and the two copies had drifted (capture_id existed in one only).
Make git_mirror delegate to mirror_format and fold capture_id back in,
so OKF field changes are a single-site edit.
OKF requires a non-empty `type` field naming the concept kind. Add
`type: document` to document mirrors and `type: <note|bookmark>` to
captures, as the first frontmatter key per OKF convention. `type` is a
separate axis from the Paperless `document_type` subtype; both coexist.
Capture `kind` is kept for now and mirrors `type` until its readers
move over.
Member about.md pages omitted the OKF-required `type` field while topic
pages already wrote `type: topic`. Add `type: person` to member
preambles so every generated entity page is self-describing and
OKF-valid standalone.
"mirror_format" was vague about what it produces. The module builds a
vault entry — one markdown file mirroring a Paperless document or capture
(an OKF "document") — across three pure steps: path, frontmatter, body.
Rename the module and its test to say so.
OKF's recommended chronology field is `timestamp` (ISO 8601 datetime of
last meaningful change) -- the field OKF index/search/viewers sort by. We
write it on every publish and reprocess, so it is exactly last-write time.
Rename `added` -> `timestamp` so OKF consumers pick up the recency
signal instead of ignoring a custom key. (Paperless's own API `added`
field, read in reprocess, is unrelated and untouched.)
OKF's `resource` field is "a URI that uniquely identifies the underlying
asset the concept describes" -- an exact match for a bookmark's source
URL. Rename the capture frontmatter key `source_uri` -> `resource` and
update the reprocess reader. The publish/extractor argument stays
`source_uri` (it is the input); only the OKF-facing key changes. The
event-envelope `source_uri` is a separate contract and is untouched.
The note/bookmark distinction is the OKF concept kind, which `type`
already carries. Drop the redundant `kind` frontmatter key (added
alongside `type` in the prior commit) so captures have a single,
OKF-native home for it, and move the reprocess reader to `type`. The
`kind` function arguments stay -- only the frontmatter key is removed.
OKF's `resource` is the URI of the asset a concept describes. Documents
carried only `paperless_url` (the instance base); the per-document
details URL existed only for the briefing link. Add `resource` = the
document's Paperless details page so OKF consumers link to the original.
A shared `document_resource_url` helper now backs both the frontmatter
field and the "Show Document" briefing link (was duplicated inline).
Update family-memory.md's example frontmatter to the shipped shape
(type, timestamp, resource; kind promoted into type) and mark the OKF
gap-analysis items landed. Fix the stale mirror_format.py references
(module is now vault_entry.py).
The slug rules and entity-path conventions were split across stacklets
(slug in docs/vault_entry, slugify_person in memory/wiki,
correspondents_dir in memory/lib), and resolving an entity link needed
docs to reach into memory's internals. Introduce stack.vault as the
framework home for vault layout: slug, slugify_person, correspondents_dir,
entity_page_path, and entity_relpath. Both stacklets import down into the
framework instead of across into each other. Pure relocation plus the new
(unused) entity_relpath/entity_page_path helpers.
The document/capture From/About headers emitted Obsidian wikilinks
([[ADAC]], [[Homer]]) that only Obsidian understands. Render them as
relative markdown links via stack.vault.entity_relpath instead -- they
resolve in Obsidian, render and click on GitHub/Forgejo, and form OKF
graph edges. The vault is now natively dual-format with no export step.
Renderers take the entry's own path to compute the relative climb;
correspondent links target the leaf page correspondents/<slug>.md (which
the correspondent-entity pass will populate).
The wikilink-decision section recommended translate-on-export (option 1);
we shipped native relative markdown links (option 2). Rewrite it to match
what landed and why, and update the rendered examples in family-memory.md
from [[wikilinks]] to relative links.
Correspondents were referenced by documents and read by the CLI, but no
generator wrote their pages -- the From: links dead-ended. Add a
correspondent pass to the wiki command: discover correspondents from the
classifier's correspondent: frontmatter, and write a leaf page
<bucket>/correspondents/<slug>.md (type: correspondent) whose body is a
deterministic backlink list of the documents referencing it. Rebuilt each
run, so it auto-extends with no queue. Adds --correspondent <name> and
covers them in the default loop.
Design docs mirrored a real location. Swap it for a fabricated one so no
real personal data lives in the repo.
Production code, docstrings, the classifier prompt examples, and the
shipped correspondent/seed READMEs contained real personal data — real
insurers (ADAC, AOK, Allianz), a real local chapter (Ortsverband Manzell)
and adac.de, real names. The seed files ship to every user, so this was a
privacy leak, not just test hygiene. Replace with Simpsons-universe
fictional entities (Duff Insurance, Springfield Mutual, Globex, Homer).
Replace real insurers/names (ADAC, AOK, Arthur, etc.) with fabricated
Simpsons-universe data across all test fixtures and assertions. Never use
real data in tests.
Same scrub for the design docs, which mirrored the real household setup.
# Conflicts:
#	stacklets/memory/bot/cli/wiki.py
A branch can be older than it looks - main advances and a local main can
be stale. Fetch and compare against origin/main before substantial work,
so the branch doesn't silently diverge into PR conflicts.
@arthware-dev arthware-dev merged commit 08301b2 into main Jun 20, 2026
2 checks passed
@arthware-dev arthware-dev deleted the okf-conformance branch June 20, 2026 08:21
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.

feat: support the Open Knowledge Format (OKF)

1 participant