[RFC] Upgrade L0/L1 Semantic Sidecars to OKF Markdown #4073
Closed
MaojiaSheng
started this conversation in
RFC
Replies: 2 comments 1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment


Uh oh!
There was an error while loading. Please reload this page.
RFC: Upgrade L0/L1 Semantic Sidecars to OKF Markdown
Status: Draft
Summary
OpenViking today stores built-in context-layer summaries as directory-level Markdown sidecars:
.abstract.mdfor L0.overview.mdfor L1This RFC proposes keeping those filenames and the visible Markdown body, while upgrading their internal document format to minimal OKF-style Markdown: YAML frontmatter metadata followed by the summary body.
The change makes L0/L1 sidecars more self-describing without changing the public context-layer model described in
docs/zh/concepts/03-context-layers.md.Background
OpenViking uses a three-layer context model:
.abstract.md.overview.mdThe current implementation treats
.abstract.mdand.overview.mdas generated hidden sidecars.SemanticProcessor/SemanticDagExecutorgenerate them bottom-up, and the vector pipeline maps those two filenames toContextLevel.ABSTRACTandContextLevel.OVERVIEW.Goals
find,ls, tree, and agent previews should show only the visible summary body unless explicitly reading the file.read/getaccess to the sidecar files.write.Non-Goals
Proposed Format
L0 and L1 remain UTF-8 Markdown files with
.mdsuffixes. Each generated file starts with YAML frontmatter:L0 Example Across Surfaces
Use one directory as the running example:
Raw Storage
The stored
.abstract.mdkeeps metadata and body together:Preview Reads
abstract(),ls output=agent, tree agent output, andfindpreviews use the body only:Normal
lsstill hides.abstract.mdunless hidden files are explicitly requested.Full Reads
read()/get()of the sidecar file return the raw stored document, including frontmatter and body. This is the path for callers that intentionally need metadata.Embedding Text
Embedding uses the body plus whitelisted metadata. The initial whitelist contains
directory, so the text sent to the embedder is equivalent to:source,generated_by, andfreshnessare intentionally absent from this embedding text.Regeneration Input
When a parent summary is regenerated from this L0, the semantic pipeline uses the body only:
Metadata is not prompt input for re-summarization.
freshnessmay still be updated out of band to indicate that the stored body is stale relative to child changes.L1 uses the same storage and access rules. Its body is longer and navigation-oriented, but metadata handling is identical.
The metadata block is intentionally narrower than general OKF wiki pages. L0/L1 are generated context abstractions, so metadata should only carry machine-facing fields that are not already available from file attributes such as
stat, and not repeat the visible summary itself.The initial metadata should stay small and deterministic. Timestamps are intentionally omitted at first to avoid rewriting sidecars when semantic content has not changed.
Existing L0/L1 content length limits apply to the Markdown body only. Metadata is outside those limits and should not be truncated by summary-size enforcement.
Metadata Fields
The initial metadata set should stay small:
directorysourcegenerated_byfreshnessfreshnesscounts direct child entries, not the total recursive subtree size. Files and child directories share the same counters because both contribute one direct input to the parent summary. For large directories, it should distinguish total input size from the subset actually read for summary generation. A directory with many entries may recordtotal_entries: 161,sampled_entries: 32, andunsampled_entries: 129.freshness.pending_child_changes > 0means the body is still readable, but known to lag behind lower-level changes.Sampling should be deterministic for a stable tree so repeated refreshes do not rewrite sidecars unnecessarily. The first policy can be simple: summarize all direct children up to a threshold, and for larger directories use a bounded sample that preserves useful ordering and diversity. Freshness metadata should make that choice visible without forcing the body to enumerate unsampled files.
Metadata should not duplicate information already available through
stat, such as file name, file size, mode, modified time, or lock state.Embedding Behavior
The embedding input for generated L0/L1 sidecars should be the visible Markdown body plus explicitly whitelisted metadata fields.
The initial whitelist includes
directory, because the directory URI helps retrieval connect a summary to its location in the context tree. Operational and provenance fields remain excluded by default, includingsource,generated_by, andfreshness.Conceptually:
This keeps the semantic vector space focused on user-facing summaries and stable location context, while avoiding accidental ranking changes from source URLs, generator details, or freshness counters.
Read and Preview Semantics
Direct file reads of sidecar files remain raw: callers receive frontmatter plus body.
Semantic accessors return body-only content. Preview surfaces also use body-only content:
findresult summariesls output=agentNormal
lsbehavior remains unchanged: hidden sidecars are not listed unless the caller explicitly asks for hidden entries.Compatibility
Existing sidecars without frontmatter remain valid. Readers should treat them as legacy Markdown and return the full content as body.
Writers should emit OKF-formatted sidecars after the feature lands. There is no need for an eager migration job. Existing directories migrate naturally when semantic refresh rewrites their L0/L1 files.
The current L0 extraction rule should continue to operate on the L1 body, not the raw OKF document. This preserves the current convention that L0 is derived from the brief paragraph before the first
##section in L1.Implementation Sketch
Introduce a small semantic-sidecar document helper near the existing sidecar write/read code:
render_semantic_sidecar(level, dir_uri, body, metadata) -> strparse_semantic_sidecar(raw) -> {metadata, body}body_for_preview(raw) -> strbody_for_embedding(raw, whitelist=()) -> strUse it in these paths:
.abstract.md/.overview.mdabstract()/overview().overview.mdbody before extracting file summariesThe parser should be tolerant: valid YAML object frontmatter is metadata; missing frontmatter means legacy body; malformed frontmatter should not silently enter embeddings. For generated sidecars, malformed frontmatter should be treated as a processing error.
Size-limit enforcement should parse the sidecar and apply existing L0/L1 limits only to the body before rendering metadata back around it. Metadata size should remain bounded by field policy rather than by the summary body limit.
Test Plan
Format and compatibility:
Read and preview behavior:
abstract()andoverview()return body-only content.read_file()returns raw frontmatter plus body.ls output=agent, tree agent output, andfindpreviews do not include metadata fields.lsstill hides.abstract.md/.overview.mdunless hidden files are requested.Metadata generation:
sourcemetadata is preserved on the generated import root and not repeated in nested directories unless a nested source boundary exists.generated_byrecords the component and trigger for generated sidecars.Freshness and sampling:
pending_child_changeswithout changing the visible summary body.pending_child_changesand updates freshness coverage.Semantic reuse and embedding:
.overview.md..abstract.mdand.overview.mdincludes whitelisteddirectorymetadata.source,generated_by, andfreshness.Decisions
read_metadata()API in the first version. Directread()/get()of the sidecar file is enough for callers that intentionally need metadata.directoryis included initially;source,generated_by, andfreshnessare excluded.All reactions