vault

package
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2026 License: AGPL-3.0 Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultScope = "dev"

DefaultScope is the scope an unlabeled note belongs to. Unlabeled = dev-only, so a note that predates scoping (or forgets the field) is never leaked to a non-dev scope.

Variables

View Source
var Now = func() time.Time { return time.Now() }

Now returns the current time and is overridable in tests.

Functions

func DirForType

func DirForType(t NoteType) string

DirForType maps a note type to its vault subdirectory.

func Dirs

func Dirs(root string) ([]string, error)

Dirs returns every directory under root that Walk traverses (root included, skipped/hidden dirs pruned). The fsnotify watcher needs these because kqueue and inotify watch a single directory at a time, not a tree, so it adds one watch per indexed directory and skips the same noise Walk does.

func IsConflictSibling

func IsConflictSibling(name string) bool

IsConflictSibling reports whether a filename is a sync-conflict artifact (e.g. note.sync-conflict-20260616-bob-1a2b3c4d.md). These are a copy of a note the team-sync hub parked for a human to resolve; they duplicate the original's frontmatter id, so the indexer, watcher, and linter must skip them rather than trip on a duplicate id or surface a half-merged version in retrieval.

func ScopeAllows added in v0.1.1

func ScopeAllows(noteScopes []string, allowed map[string]bool) bool

ScopeAllows reports whether a note carrying noteScopes is readable given the caller's allowed-read set. nil allowed = unrestricted (no scoping configured). Absent/empty noteScopes falls back to DefaultScope, the fail-safe every read check must honor.

This is the ONE scope-intersect predicate. It used to be hand-copied in the MCP, retrieve, and web layers (with subtly different shapes), which is exactly how the changed_since / health / code_* leaks happened: a surface reimplemented the check and got it wrong. All read surfaces now call this (or ScopeAllowsCSV) so the logic cannot drift per surface.

func ScopeAllowsCSV added in v0.1.1

func ScopeAllowsCSV(csv string, allowed map[string]bool) bool

ScopeAllowsCSV is ScopeAllows for a comma-joined scope string, the shape the index stores (notes.scope, graph node Attrs["scope"]).

func Slugify

func Slugify(s string) string

Slugify turns arbitrary text into a kebab-case slug. Used for ids, filenames, and heading anchors.

func SplitFrontmatter

func SplitFrontmatter(content string) (fm string, body string, had bool)

SplitFrontmatter separates a leading YAML frontmatter block from the body. It returns the inner YAML (no --- markers), the body after the closing marker, and whether a block was present.

func Walk

func Walk(root string) ([]string, error)

Walk returns every markdown file under root, skipping noise and hidden dirs. This is the M0 walker; .meshignore support lands with the index step.

func WalkConflictSiblings

func WalkConflictSiblings(root string) ([]string, error)

WalkConflictSiblings returns every sync-conflict sibling under root (the inverse of Walk's filter), pruning the same noise/hidden dirs. Used by `mesh conflicts` to find the parked loser copies that Walk deliberately hides.

Types

type CreateResult

type CreateResult struct {
	Path  string
	ID    string
	When  string
	TODOs []string
}

CreateResult reports what Mesh filled in and what the author still must.

func CreateNote

func CreateNote(root string, spec NewNoteSpec) (*CreateResult, error)

CreateNote writes a new note with everything derivable already filled: id from the title (collision-suffixed), when/created auto-stamped, placed in the type's subdirectory, with a type-specific body skeleton. The author only fills the judgment fields. Returns the path and any flywheel fields still to fill.

type Frontmatter

type Frontmatter struct {
	ID         string     `yaml:"id"`
	Type       NoteType   `yaml:"type"`
	Title      string     `yaml:"title"`
	When       string     `yaml:"when"`
	Created    string     `yaml:"created,omitempty"`
	Updated    string     `yaml:"updated,omitempty"`
	Related    StringList `yaml:"related,omitempty"`
	Tags       StringList `yaml:"tags,omitempty"`
	Do         string     `yaml:"do,omitempty"`
	Dont       string     `yaml:"dont,omitempty"`
	Why        string     `yaml:"why,omitempty"`
	Status     string     `yaml:"status,omitempty"`
	Supersedes StringList `yaml:"supersedes,omitempty"`
	Severity   string     `yaml:"severity,omitempty"`
	Role       string     `yaml:"role,omitempty"`
	Stack      StringList `yaml:"stack,omitempty"`
	RepoPath   string     `yaml:"repo_path,omitempty"`
	// Provenance: who/what wrote this note, where it came from, when to recheck.
	// Feeds the audit trail, the knowledge-lifecycle health checks, and the
	// contributor/ROI views. All optional.
	Author     string `yaml:"author,omitempty"`     // human who authored it
	Agent      string `yaml:"agent,omitempty"`      // tool that wrote it, e.g. "claude-code"
	Source     string `yaml:"source,omitempty"`     // manual | agent | import:<connector>
	SourceURL  string `yaml:"source_url,omitempty"` // upstream link for imported notes
	Confidence string `yaml:"confidence,omitempty"` // low | med | high
	ReviewBy   string `yaml:"review_by,omitempty"`  // YYYY-MM-DD; lifecycle re-check date
	ImportedAt string `yaml:"imported_at,omitempty"`
	// Scope is the access-control partition(s) this note belongs to (dev, sales, ...).
	// A note may carry several. ABSENCE means dev-only (the fail-safe): an unlabeled
	// note is never accidentally exposed to or writable by a non-dev scope. Read
	// EffectiveScopes() rather than this field directly so the default lives in one place.
	Scope StringList `yaml:"scope,omitempty"`
}

Frontmatter is the whitelisted view of a note's YAML header. Raw YAML is never spread into storage; only known keys are kept (the JSONB house rule).

func ParseFrontmatter

func ParseFrontmatter(b []byte) (*Frontmatter, map[string]any, error)

ParseFrontmatter decodes a YAML frontmatter block into the whitelisted struct and a raw map. Empty input yields a zero Frontmatter, not an error.

func (*Frontmatter) EffectiveScopes

func (f *Frontmatter) EffectiveScopes() []string

EffectiveScopes returns the note's access scopes, defaulting to {DefaultScope} when none are declared. This is the single source of the fail-safe default; every read and write check must go through it.

func (*Frontmatter) Validate

func (f *Frontmatter) Validate() []string

Validate returns the lint problems for this frontmatter. An empty slice means it satisfies the schema for its type.

type MigrateResult

type MigrateResult struct {
	Path    string
	Changed bool
	Actions []string // changes applied (or that would be, in dry-run)
	Issues  []string // flywheel fields still needing human authoring (never fabricated)
}

MigrateResult records what a migration pass did to one file.

func BackfillScopeFile

func BackfillScopeFile(path, scope string, dryRun bool) (*MigrateResult, error)

BackfillScopeFile stamps `scope: <scope>` onto a note that declares no scope yet, idempotently (a note that already has a scope is left untouched). Unlabeled notes already behave as dev by the EffectiveScopes fail-safe; this just makes that explicit so a note can be deliberately relabeled into another scope later.

func MigrateFile

func MigrateFile(path string, dryRun bool) (*MigrateResult, error)

MigrateFile brings one file up to the Mesh schema, idempotently:

  • synthesize a stable id from the filename when missing,
  • add type: note when absent (concept/map are valid, so they are kept),
  • map updated -> when (falling back to the file mtime),
  • lift a "## Related" section's [[links]] into a related: array.

It never fabricates do/dont/why; missing flywheel fields are reported in Issues. With dryRun it reports without writing. Re-running is a no-op.

type NewNoteSpec

type NewNoteSpec struct {
	Type     NoteType
	Title    string
	Do       string
	Dont     string
	Why      string
	Related  []string
	Tags     []string
	Status   string
	Severity string
	By       string
	// Provenance (all optional; recorded in the note's frontmatter).
	Author     string
	Agent      string
	Source     string
	SourceURL  string
	Confidence string
	ReviewBy   string
	ImportedAt string
	// Scope is the access-control partition(s) to stamp on the new note. Empty leaves
	// the note unlabeled (= dev-only by the EffectiveScopes default).
	Scope []string
}

NewNoteSpec is the irreducible, judgment-only input an author provides. Mesh derives everything else: id, timestamps, placement, filename, skeleton.

type NoteType

type NoteType string

NoteType is the kind of a note. The first five are the canonical Mesh types. concept and map are accepted so `mesh migrate` can ingest a Hive-style vault losslessly (Open Decision 4 default: extend the enum rather than remap).

const (
	TypeNote       NoteType = "note"
	TypePostMortem NoteType = "post-mortem"
	TypeDecision   NoteType = "decision"
	TypeGotcha     NoteType = "gotcha"
	TypeEntity     NoteType = "entity"
	TypeConcept    NoteType = "concept"
	TypeMap        NoteType = "map"
)

func (NoteType) RequiresFlywheel

func (t NoteType) RequiresFlywheel() bool

RequiresFlywheel reports whether do/dont/why are mandatory for this type. These are the institutional-memory types that fuel tier-0 retrieval.

func (NoteType) Valid

func (t NoteType) Valid() bool

type StringList

type StringList []string

StringList decodes either a YAML scalar or a sequence into []string, so `related: foo` and `related: [foo, bar]` both work.

func (*StringList) UnmarshalYAML

func (s *StringList) UnmarshalYAML(value *yaml.Node) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL