Documentation
¶
Overview ¶
Package rollup turns episodic events into proposed vault notes.
The contract of the two-tier design lives here: raw events go in, notes the user has approved come out, and nothing is written to markdown that cannot be traced back to specific observed rows.
Index ¶
- Constants
- func Apply(db *sql.DB, vaultDir string, p Proposal) error
- func Enqueue(db *sql.DB, p *Proposal) error
- func InitQueue(db *sql.DB) error
- func NearMiss(db *sql.DB, name, kind string) []string
- func PendingCount(db *sql.DB) (int, error)
- func ProposeRoutines(db *sql.DB, rt *router.Router, periodics []routine.Periodic, ...) (int, error)
- func SetStatus(db *sql.DB, id int64, s Status) error
- type Category
- type Classification
- type Entity
- type Extractor
- type Kind
- type Match
- type Payload
- type Proposal
- type Result
- type Session
- type Status
Constants ¶
const IdleGapS int64 = 15 * 60
IdleGapS is how long a silence has to run before the next activity counts as a new session rather than a continuation. Fifteen minutes is long enough to survive a coffee break and short enough to separate genuinely different stretches of work.
const ObservationsHeading = "## Observations"
ObservationsHeading is the only part of a note this system may append to.
const QueueSchema = `` /* 396-byte string literal not displayed */
Variables ¶
This section is empty.
Functions ¶
func NearMiss ¶
NearMiss finds existing notes of the same kind with a similar name, for proposing a merge rather than creating a near-duplicate.
func ProposeRoutines ¶
func ProposeRoutines(db *sql.DB, rt *router.Router, periodics []routine.Periodic, sequences []routine.Sequence) (int, error)
Propose turns mined patterns into queue entries.
Routines go through the same review queue as everything else — there is no privileged write path. A discovered pattern is still an inference about the user, and inferences get approved.
Types ¶
type Classification ¶
type Extractor ¶
type Extractor struct {
// contains filtered or unexported fields
}
func NewExtractor ¶
func (*Extractor) ClassifySession ¶
func (x *Extractor) ClassifySession(s Session) (Classification, string, error)
func (*Extractor) ExtractEntities ¶
func (*Extractor) WriteDaily ¶
func (x *Extractor) WriteDaily(date string, sessions []Session, classes []Classification) (string, string, error)
WriteDaily produces the day's prose from the session table.
Built from session digests, never from previously written summaries. Weekly notes built from daily notes drift into mush within a month, so every rollup re-derives from the episodic source.
type Match ¶
type Match struct {
Slug string
// Certain is true for an exact slug or alias hit. Uncertain matches become
// merge proposals for the user to settle rather than silent decisions.
Certain bool
}
func Resolve ¶
Resolve finds the existing note an entity refers to, if any.
Deliberately only does the two cheap, safe steps: exact slug and declared alias. Embedding-similarity matching is available but is routed through a merge proposal instead of applied here — a wrong automatic merge silently destroys information, while a wrong proposal costs one keystroke.
type Payload ¶
type Payload struct {
Title string `json:"title,omitempty"`
Type string `json:"type,omitempty"`
Body string `json:"body,omitempty"`
// Edge fields.
Pred string `json:"pred,omitempty"`
Obj string `json:"obj,omitempty"`
// Merge field: the slug to fold Target into.
Into string `json:"into,omitempty"`
}
Payload carries the kind-specific detail. One struct rather than four keeps the queue table and the review UI simple; unused fields stay empty.
type Proposal ¶
type Proposal struct {
ID int64
Kind Kind
Target string // note slug
Payload Payload
Conf float64
Evidence []int64 // event ids
Model string
Created int64
Status Status
}
Proposal is a change the system would like to make, and never makes on its own until the user raises the auto-accept threshold.
Evidence is mandatory and enforced at write time. A proposal that cannot be traced back to observed events is a hallucination with good manners, and it must be impossible to accept one.
func Braindump ¶
Braindump classifies raw text and queues a proposal for it. Returns the proposal so the caller can report what it decided.
Tasks are handled by the caller (they become open loops, not notes); this returns the classification for everything, and a note proposal for the rest.
func (*Proposal) Validate ¶
Validate enforces the invariants that make the queue trustworthy. Called on every insert rather than trusted from the model.
Every field here is model output, written by a small local model reading captured text — web pages, other people's messages, whatever was on the clipboard. So the target is checked for staying inside the vault (joining it on unchecked made accepting a proposal a way to write a file anywhere the user can write) and the one-line fields are checked for the newlines that would let a note's frontmatter be forged from its own title.
type Result ¶
Run rolls a single day up into a daily note and a set of proposals.
The order matters: entities are resolved against the existing vault *before* any note is proposed, so a near-duplicate becomes a merge proposal rather than a second note.
type Session ¶
type Session struct {
Start, End int64
Events []event.Event
// EventIDs is the evidence set. Every proposal derived from this session
// cites these.
EventIDs []int64
}
Session is a contiguous stretch of activity. This is the unit the model reasons about — never individual events, which carry no context, and never a whole day, which exceeds what a small local model handles well.
func Sessionise ¶
Sessionise groups events into sessions separated by idle gaps.
Incidental focus flickers are dropped here rather than downstream: they add noise to the model's context without adding information, and a small model spends its limited attention on whatever it is shown.
func (Session) Digest ¶
Digest renders a session for a model: compact, deduplicated, and capped.
Feeding 400 near-identical rows to an 8B model wastes context and degrades the output. What matters is which apps, which pages, which commits — not the exact ordering of every tab switch.
func (Session) DigestForEntities ¶
DigestForEntities is Digest minus the host list.
Showing a small model a list of visited domains reliably produces a list of domains back, regardless of how the prompt is worded. The entities actually worth a note come from window titles and commit subjects — text the user or their collaborators wrote — so that is all this carries.