Vyasa Context Syntax — engine handoff
4-min readUpdated Jun 18, 2026
This describes a new vyasa KG model where a graph is split into one append-only identity pool and many
standalone context files. A context is a self-contained snapshot of the graph (a day, a what-if, a
perspective). The renderer shows one context at a time and never reasons about time. The birdhouse pack
at tmp/birdhouse/birdhouse.kg is the reference implementation.
File model URL copied
kg.schema root. identity pool + base attrs + palette + context discovery + status defaults + views
kg.nodes identity pool: "id: label" (+ optional inline immutable summary)
kg.attrs base attributes, inverted index: kind, owner, dept (things that never change)
kg.palette colors (JSON payload)
*.context standalone snapshots, auto-discovered
A graph has exactly one pool (kg.nodes + kg.attrs) and any number of .context files in the same
folder.
kg.schema URL copied
@graph id=birdhouse title=Backyard Birdhouse
pool=kg.nodes
attrs=kg.attrs
palette=kg.palette
contexts=*.context # glob; auto-discovered; ordered by @context seq
default_context=latest # which context to show on open (latest = highest seq)
hover_attrs=summary,owner,dept,status
@status_defaults # status used when a context does not assign one, keyed by kind
entity=active
decision=active
constraint=active
question=open
action=open
deliverable=done
@relations # closed verb vocabulary (unchanged from current vyasa)
about
constrains
addresses
produces
reinforces
supersedes
answers
@views # lenses applied to whichever context is loaded; no source pinned
state:
group_by,color_by=status
caption="Where everything stands"
plate:
group_by,color_by=owner
caption="Each owner's work"
mia_todo:
filter=owner:Mia
group_by,color_by=status
caption="One owner's work only"
Differences from the current schema:
pool=/attrs=replace the@sources nodes=/attrs=lines; there is no per-sourceedges=and nobase:/snap:source blocks. Edges now live in context files.contexts=declares a glob for auto-discovery instead of enumerating sources.@status_defaultsis new.- Views no longer take
source=. They are lenses over the active context.filter=key:valueis a new per-view filter (used for per-owner todo views).
kg.nodes — identity pool URL copied
a1: Mia gathers the wood
bh: Backyard Birdhouse
summary=Three friends build a birdhouse over one week.
Append-only. id: label, optional indented immutable attrs (e.g. summary). Ids never change. Labels
are the current best name; a context may override a label through its @attrs.
kg.attrs — base attributes URL copied
Standard vyasa inverted index, but only immutable attributes belong here (kind, owner, dept). Anything that changes between contexts (status) does not go here.
@node_attrs
kind:
action: a1 a2 a3
owner:
Mia: a1
.context — a standalone snapshot URL copied
@context id=day3 seq=3 label="Wednesday — A change of mind"
caption=|
One line describing what this snapshot is.
@attrs # inverted index, same format as kg.attrs. Inherits kg.attrs as base.
status: # list only values that differ from @status_defaults.
done: a1 a2 a3
resolved: q2
@edges # the edges true in this snapshot. Defines which nodes are present.
a1 -> bh addresses
a3 -> d_panels produces
@contextheader:id,seq(orders contexts; not derived from filename),label.caption: one-line summary; used as the row label in changelog navigation.@attrs: optional. Overrides or adds attributes for this context. A context with everything at its defaults has no@attrsblock (seeday1.context).@edges: the edge set for this snapshot. There is no node list; presence is derived from edges.- A context may optionally carry its own
palette=line to override colors.
Resolution semantics (the engine contract) URL copied
- Discover. Glob
contexts=. Parse each@contextheader. Order byseq. Do not sort by filename (day10must not sort beforeday2). - Lazy-load. Load
default_contexton open. Load others on demand. Evict contexts not in use to bound browser memory. Each context is independent, so eviction is safe. - Presence. A node appears in a context if and only if an
@edgesline in that context references it as a source or target. Nodes wired by no edge are absent (this is how pruning works — a superseded node is simply not wired in later contexts).- Discard-on-death-day (tombstone). A node is not dropped silently. On the one context where it
is discarded, keep it wired by a
supersedesedge from the node that replaces it, and mark itsupersededin@attrs. The reader sees what is leaving and why. From the next context on, omit both the node and the edge.
- Discard-on-death-day (tombstone). A node is not dropped silently. On the one context where it
is discarded, keep it wired by a
- Attribute resolution. For each present node, start from
kg.attrs(base), then merge the context's@attrsover it; the context wins on any key it sets. Forstatusspecifically, if the merged result assigns no status to a node, fall back to@status_defaults[kind]. - Render. Draw the present nodes and the context's edges. Apply the active view's
group_by/color_by/filter. Nothing else; a context is a plain graph. - Diff. "What changed between A and B" is computed by the engine as the set difference of nodes, edges, and resolved attributes between two loaded contexts. This is the navigation primitive, not a property stored in any context.
Navigation (for thousands of contexts) URL copied
Do not present a dropdown or a name search. Navigate by structure and significance:
- Changelog spine: list contexts by
seq, each row showing itscaption. This is the primary navigator. - Significance scoring: score each context by the size of its diff against its predecessor (nodes added, superseded, resolved, done). Surface high-score contexts as milestones; collapse runs of low-score contexts into an expandable group.
- Pinning:
latestis always pinned. Allow user-pinned landmarks. - Content search: search node/edge content across contexts and jump to the context where a concept first appears or changes state.
- Compare: select two contexts and show the diff.
- Branches: contexts whose
seqforks (what-ifs) render as a tree off the main spine.
Deferred / not built URL copied
same_asmerge resolution (collapsing two ids found to be one concept at read time).- Branch/what-if context semantics beyond the file format (the engine currently assumes a linear
seq). - Storage-layer deduplication of near-identical contexts (acceptable to skip; contexts are small).
Reference implementation URL copied
tmp/birdhouse/birdhouse.kg: kg.nodes, kg.attrs, kg.schema, kg.palette, and day1..day5.context.
The five contexts exercise: status changes (open→done, open→resolved), pruning by absence
(forsparrows gone from day3, intree gone from day4), and a context with no @attrs (day1).