mirror

package
v0.0.437 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package mirror is the push-fed read-only state for satelle serve (epic:serve-split / sty_dbdadfa0). Partitioned by repo_key — never a flat multi-repo bag (decision-local-db-placement). Serve renders only from this store; it never opens ~/.satelle/<repo-key>/satelle.db.

Index

Constants

View Source
const (
	// DefaultReconcileInterval is how often the serving tier re-requests a full
	// snapshot for each partition it renders. The push path is the fast path;
	// this only bounds how long a DROPPED push can survive, so it is measured in
	// minutes rather than seconds — one re-seed costs a CLI process and a full
	// snapshot per partition.
	DefaultReconcileInterval = 5 * time.Minute
	// StaleAfter is how long a partition may go without a confirmed ingest
	// before a view must say so rather than presenting its frame as current.
	// 3× the interval so one slow or briefly-failed pass never flaps the badge.
	StaleAfter = 3 * DefaultReconcileInterval
)

Reconciliation timings live HERE, in the one package serve, web and the CLI diagnostics all import (serve → web → mirror; web can never import serve), so the loop that re-asks and the badge that reports a mirror it could not repair read the same numbers (sty_e6e467fe).

View Source
const DefaultDBName = "mirror.db"

DefaultDBName is the mirror SQLite file name.

View Source
const DefaultDirName = "serve"

DefaultDirName is the subdirectory under GlobalDir() for the serve mirror.

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath(globalDir string) string

DefaultPath returns ~/.satelle/serve/mirror.db (or SATELLE_HOME).

Types

type ChangeEvent

type ChangeEvent struct {
	RepoKey string `json:"repo_key"`
	Topic   string `json:"topic"`
	Entity  string `json:"entity"`
	At      string `json:"at"`
}

ChangeEvent is the body POSTed by the CLI push publisher (sty_126228b2).

type IdentityMeta added in v0.0.281

type IdentityMeta struct {
	ProjectName string `json:"project_name"`
	RepoRoot    string `json:"repo_root"`
	FooterEmail string `json:"footer_email"`
}

IdentityMeta is the JSON shape of Snapshot.Identity — what the mirror footer and account strip render without opening a repo DB or calling git.

type IngestHandler

type IngestHandler struct {
	Store    *Store
	OnChange func(topic string)
}

IngestHandler serves POST /ingest/change and POST /ingest/snapshot. onChange is optional (SSE doorbell).

func (*IngestHandler) Mount

func (h *IngestHandler) Mount(mux *http.ServeMux)

Mount registers ingest routes on mux.

type ItemRow

type ItemRow struct {
	ID      string
	Payload string
}

ItemRow is a raw stored item.

type KindRows added in v0.0.426

type KindRows struct {
	Kind  string
	Items []ItemRow
}

KindRows is one kind's row set for ApplySnapshot (replace or merge).

type Partition

type Partition struct {
	RepoKey   string
	Slug      string
	Seq       int64
	UpdatedAt string
}

Partition is one repo's mirror slice metadata.

func (Partition) LastIngest added in v0.0.368

func (p Partition) LastIngest() (time.Time, bool)

LastIngest parses the partition's last confirmed ingest time. ok is false when the stored value is absent or unparseable — callers then have no basis to claim freshness.

func (Partition) Stale added in v0.0.368

func (p Partition) Stale(now time.Time) bool

Stale reports whether this partition has gone longer than StaleAfter without a confirmed ingest. An unparseable/absent timestamp counts as stale: an unknown last-ingest time is exactly the case the operator must not read as current.

type PartitionDetail added in v0.0.292

type PartitionDetail struct {
	Partition
	Stories int
	Tasks   int
	Docs    int
	Path    string
}

PartitionDetail is a partition plus kind counts and best-effort repo path (from identity meta) for CLI list/prune (sty_eb61be02 / epic:mirror-hygiene).

type RemoveEvent added in v0.0.292

type RemoveEvent struct {
	RepoKey string `json:"repo_key"`
}

RemoveEvent is POSTed to /ingest/remove to purge a partition (sty_eb61be02). Same trust model as snapshot ingest (localhost push-fed; CLI sole writer).

type Snapshot

type Snapshot struct {
	RepoKey      string            `json:"repo_key"`
	Slug         string            `json:"slug,omitempty"`
	Stories      []json.RawMessage `json:"stories,omitempty"`
	Tasks        []json.RawMessage `json:"tasks,omitempty"`
	Executions   []json.RawMessage `json:"executions,omitempty"`
	Docs         []json.RawMessage `json:"docs,omitempty"`
	LedgerEvents []json.RawMessage `json:"ledger_events,omitempty"`
	StoryDocs    []json.RawMessage `json:"story_docs,omitempty"` // id = story_id/name
	Seats        []json.RawMessage `json:"seats,omitempty"`
	Settings     json.RawMessage   `json:"settings,omitempty"` // single settings blob
	// Identity is the per-partition meta blob (project name, repo path, footer email).
	// Ingested as kind "identity" id "meta" (sty_400c022b / epic:mirror-ui-parity).
	Identity json.RawMessage `json:"identity,omitempty"`
	// Kinds is the explicit set of partitions this body authoritatively replaces
	// (delete+insert). Empty means full snapshot: all standard kinds.
	Kinds []string `json:"kinds,omitempty"`
	// MergeKinds are applied as upsert-without-delete (ledger is append-only).
	MergeKinds []string `json:"merge_kinds,omitempty"`
}

Snapshot is a full-state push for one partition (order:4 reconcile). Every kind the UI reads must arrive here so serve never opens a repo DB.

Partial drains (sty_3562c820) set Kinds / MergeKinds so only those partitions are written; kinds named in neither are left untouched. Absent both fields, behaviour is today's full replace of every kind (workspace add + reconcile).

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is the push-fed multi-repo mirror. All rows carry repo_key.

func Open

func Open(path string) (*Store, error)

Open opens (or creates) the mirror database at path.

func (*Store) ApplyChange

func (s *Store) ApplyChange(ctx context.Context, repoKey, topic string, now time.Time) (seq int64, err error)

ApplyChange records a coarse change event (order:2 publisher). Bumps seq and leaves item bodies unchanged — full bodies arrive via snapshot (order:4).

func (*Store) ApplySnapshot added in v0.0.426

func (s *Store) ApplySnapshot(ctx context.Context, repoKey string, replace, merge []KindRows, now time.Time) error

ApplySnapshot applies every replace (delete+insert) and merge (upsert) kind inside one transaction so a mid-apply failure leaves the partition unchanged (sty_3562c820 AC2). Callers pass only the kinds they authorise.

func (*Store) Close

func (s *Store) Close() error

Close closes the database.

func (*Store) CountItems added in v0.0.292

func (s *Store) CountItems(ctx context.Context, repoKey, kind string) (int, error)

CountItems returns how many rows of kind exist for repoKey.

func (*Store) DeletePartition added in v0.0.292

func (s *Store) DeletePartition(ctx context.Context, repoKey string) error

DeletePartition removes a partition and all of its items/docs. No-op success when repo_key is unknown (idempotent prune). CLI remains the sole writer via POST /ingest/remove (sty_eb61be02).

func (*Store) FindBySlug added in v0.0.289

func (s *Store) FindBySlug(ctx context.Context, slug string) (p Partition, ok bool, err error)

FindBySlug returns the first partition whose landing slug equals slug. ok is false when slug is empty or no row matches. Mechanism only — callers decide collision policy (sty_57d5ce25).

func (*Store) GetItem

func (s *Store) GetItem(ctx context.Context, repoKey, kind, id string) (string, error)

GetItem returns one item payload or sql.ErrNoRows.

func (*Store) GetPartition added in v0.0.368

func (s *Store) GetPartition(ctx context.Context, repoKey string) (p Partition, ok bool, err error)

GetPartition returns one partition's metadata. ok is false when repoKey is unknown.

func (*Store) ListItems

func (s *Store) ListItems(ctx context.Context, repoKey, kind string) ([]ItemRow, error)

ListItems returns all items of kind for a partition.

func (*Store) ListPartitionDetails added in v0.0.292

func (s *Store) ListPartitionDetails(ctx context.Context) ([]PartitionDetail, error)

ListPartitionDetails returns every partition with story/task/doc counts and path from identity meta when present.

func (*Store) ListPartitions

func (s *Store) ListPartitions(ctx context.Context) ([]Partition, error)

ListPartitions returns known repo keys.

func (*Store) MarkFresh added in v0.0.368

func (s *Store) MarkFresh(ctx context.Context, repoKey string, now time.Time) error

MarkFresh records that the partition was confirmed current at now WITHOUT claiming anything changed: updated_at moves so the staleness badge clears, seq does not, so no viewer is told to re-render (sty_e6e467fe). Used by the reconcile path when the re-requested snapshot is byte-identical to the one already stored. No-op success for an unknown repo_key.

func (*Store) ReplaceKind

func (s *Store) ReplaceKind(ctx context.Context, repoKey, kind string, items []ItemRow, now time.Time) error

ReplaceKind deletes all items of kind for repoKey then inserts the given set. Thin wrapper over ApplySnapshot so the DELETE+INSERT SQL lives once.

func (*Store) SetSnapshotHash added in v0.0.368

func (s *Store) SetSnapshotHash(ctx context.Context, repoKey, hash string) error

SetSnapshotHash records the digest of the snapshot body just applied.

func (*Store) SnapshotHash added in v0.0.368

func (s *Store) SnapshotHash(ctx context.Context, repoKey string) (string, error)

SnapshotHash returns the digest of the last snapshot applied to repoKey, or "" when the partition is unknown or predates hashing.

func (*Store) TouchPartition

func (s *Store) TouchPartition(ctx context.Context, repoKey, slug string, now time.Time) (seq int64, err error)

TouchPartition ensures a partition row exists and bumps seq.

func (*Store) UpsertItem

func (s *Store) UpsertItem(ctx context.Context, repoKey, kind, id string, payload any, now time.Time) error

UpsertItem stores one work item JSON payload under (repo_key, kind, id).

func (*Store) UpsertItems added in v0.0.426

func (s *Store) UpsertItems(ctx context.Context, repoKey, kind string, items []ItemRow, now time.Time) error

UpsertItems insert-or-updates rows of one kind without deleting siblings (ledger merge path for light drains — sty_3562c820).

Jump to

Keyboard shortcuts

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