Documentation
¶
Overview ¶
Package ledger is f10's local record of what runs did: one append-only events table in ~/.f10/f10.db, outside every repo, so stealth is unaffected. Hooks write what they observe, `f10 state` what the model claims, and artifacts (plans, findings) what they hold.
A ledger write never fails its caller: an event that cannot reach the database goes to a spool file beside it, which the next successful open replays.
Index ¶
Constants ¶
const ( BusyAsync = 3 * time.Second BusySync = 200 * time.Millisecond )
Busy timeouts: under the 5s hook timeout for async writers, so a contended write spools instead of the hook being killed; short for a synchronous hook, so a busy ledger never delays a skill's start.
const ( Observed = "observed" Artifact = "artifact" Claimed = "claimed" )
Sources: what the hook saw, what an artifact holds, what the model said.
const ( RunStarted = "run_started" TaskCaptured = "task_captured" StepEntered = "step_entered" Committed = "committed" Pushed = "pushed" PROpened = "pr_opened" TaskFinished = "task_finished" TaskHalted = "task_halted" // drive's, not a hook's: a task it stopped SessionStopped = "session_stopped" PlanSaved = "plan_saved" PlanSuperseded = "plan_superseded" ReviewRoundOpened = "review_round_opened" FindingVerdict = "finding_verdict" JudgeVerdict = "judge_verdict" StateSet = "state_set" StateTask = "state_task" StateNote = "state_note" StateAsk = "state_ask" StateFinal = "state_final" )
Kinds, by source.
const PathEnv = "F10_LEDGER"
PathEnv overrides the database's path; the spool and machine id live beside it, so a test pointing it at a temp dir touches nothing else.
Variables ¶
This section is empty.
Functions ¶
func MachineID ¶
MachineID is this machine's id, generated once into <dir>/machine-id. Created exclusively, so two first runs read back the same id. Empty when the directory cannot be written.
func NewPayload ¶
func NewPayload(p Payload) r3.JSONColumn[Payload]
NewPayload wraps a payload for an Event.
func NormalizeRemote ¶
NormalizeRemote turns a git remote url into a project id, so one repo cloned over ssh and over https is one project: scheme, user and a trailing `.git` dropped, scp-style `host:path` read as `host/path`, the host lowercased. `git@github.com:a/b.git` and `https://github.com/a/b` are both `github.com/a/b`. A local path stays a cleaned path.
Types ¶
type Event ¶
type Event struct {
ID string `db:"id,pk" json:"id"`
Machine string `db:"machine,immutable" json:"machine"`
At time.Time `db:"at,immutable" json:"at"`
Project string `db:"project,immutable" json:"project"`
ProjectLocal bool `db:"project_local,immutable" json:"project_local"`
Checkout string `db:"checkout,immutable" json:"checkout"`
Branch string `db:"branch,immutable" json:"branch"`
Session string `db:"session,immutable" json:"session"`
Task string `db:"task,immutable" json:"task"`
Kind string `db:"kind,immutable" json:"kind"`
Source string `db:"source,immutable" json:"source"`
Payload payloadCol `db:"payload,immutable" json:"payload"`
}
Event is one row. Every column but the id is immutable, so r3 has no update path for it and an upsert of a known id does nothing: the table only grows.
type Ledger ¶
type Ledger struct {
// contains filtered or unexported fields
}
A Ledger is an open database.
func Open ¶
Open opens the database at path for writing: it creates the file and runs the migrations. With replay it also replays the spool, which a synchronous hook leaves to the next async writer: a backlog has no bound.
func OpenRead ¶
OpenRead opens an existing database read-only: no migration, no replay, so reading never writes. A missing file is fs.ErrNotExist.
func (*Ledger) Append ¶
Append writes events, ids and machine filled in where empty. An event the database refuses goes to the spool with the ones after it.
type Observer ¶
type Observer struct {
StateDir string
Busy time.Duration
// NoReplay leaves the spool to a later writer: a synchronous hook holds
// the prompt while it runs.
NoReplay bool
// TaskID is the tracker task id a created issue's url names.
TaskID func(ctx context.Context, cwd, url string) string
// contains filtered or unexported fields
}
Observer records a hook's observations. It opens the ledger on the first one, so an event that yields nothing never touches the database; Close releases it.