lifecycle

package
v0.4.9 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package lifecycle carries a memory's bi-temporal lifecycle: supersession (one memory replacing another) and provenance. A superseded memory is not deleted; it is stamped invalid_at + superseded_by and keeps a tombstone line in its file body, so the on-disk source of truth stays honest while the memory leaves every active index (briefing, prompt corpus, recall).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrAlreadyInvalid is returned when superseding or archiving a memory whose
	// invalid_at is already set; re-stamping would rewrite supersession history.
	ErrAlreadyInvalid = errors.New("memory is already superseded or archived")
	// ErrSelfSupersede is returned when a memory would supersede itself, which
	// would create a superseded_by self-cycle.
	ErrSelfSupersede = errors.New("memory cannot supersede itself")
	// ErrInvalidReplacement is returned when the replacement is missing an id or
	// is itself invalid; pointing superseded_by at an inactive memory could form
	// a cycle or a dangling chain.
	ErrInvalidReplacement = errors.New("replacement memory is not active")
	// ErrNotArchived is returned when unarchiving a memory that is not archived
	// -- either still active or superseded (whose undo is Unsupersede).
	ErrNotArchived = errors.New("memory is not archived")
	// ErrNotSuperseded is returned when unsuperseding a memory that carries no
	// superseded_by edge -- either still active or plainly archived.
	ErrNotSuperseded = errors.New("memory is not superseded")
)

Domain errors guarding the supersession invariants: invalid_at is stamped exactly once, and superseded_by edges always point from a newly invalidated memory to an active one, so cycles cannot form.

Functions

func Archive

func Archive(ctx context.Context, w MemoryWriter, old core.Memory, reason string, now time.Time) (core.Memory, error)

Archive marks a memory inactive without a replacement: it sets invalid_at = now (leaving superseded_by empty), appends an archive tombstone to the body, and rewrites the file (which re-indexes it out of the active set). Unlike Supersede there is no successor to point at -- the memory is simply retired. old must carry its full Body (read the file first; index rows have no body). It returns the updated memory.

func MemoryRef

func MemoryRef(project, name string) string

MemoryRef renders a project-qualified memory reference (project/name), or just name for a global memory. Used in tombstones and read warnings.

func Supersede

func Supersede(ctx context.Context, w MemoryWriter, old, replacement core.Memory, now time.Time) (core.Memory, error)

Supersede marks old as replaced by replacement: it sets old.InvalidAt = now and old.SupersededBy = replacement.ID, appends a tombstone line to old's body, and rewrites old's file (which re-indexes it out of the active set). old must carry its full Body (read the file first, since index rows have no body). It returns the updated old memory.

old and replacement must be distinct memories with distinct file paths; same-name replacement is handled as an in-place update by memory_write and must not reach here (guarded by the caller).

func Unarchive added in v0.4.6

func Unarchive(ctx context.Context, w MemoryWriter, old core.Memory, now time.Time) (core.Memory, error)

Unarchive is the inverse of Archive: it clears invalid_at, strips the archive tombstone the archive appended, and rewrites the file (which re-indexes the memory back into the active set). old must carry its full Body.

It refuses a memory that is not archived. A superseded memory in particular is not "archived with a note attached": undoing that is Unsupersede's job, and silently accepting it here would drop the superseded_by edge on the floor.

func Unsupersede added in v0.4.6

func Unsupersede(ctx context.Context, w MemoryWriter, old core.Memory, now time.Time) (core.Memory, error)

Unsupersede is the inverse of Supersede: it clears invalid_at and superseded_by, strips the supersession tombstone, and rewrites the file. old must carry its full Body. The replacement memory is untouched -- supersession only ever marked the old one.

It refuses a memory that is not superseded (an active or plainly archived one).

Types

type MemoryWriter

type MemoryWriter interface {
	WriteMemory(ctx context.Context, mem core.Memory) (core.Memory, error)
}

MemoryWriter is the subset of files.Manager that Supersede needs, so the flow is testable against a real files.Manager without importing the whole world.

Jump to

Keyboard shortcuts

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