Help us shape the future of Go! Take the 2026 Go Developer Survey

maintain

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package maintain inspects the installed pins and maintains the proposal-linked ones for the console and the CLI. A retarget changes the regions of a pin to the scope that today's evidence computes. A prune removes a pin and marks its proposal superseded. The CLI commits right after it plans, and it keeps no Recovery, because it has no session.

Two stores hold the state, and no transaction spans both. The pin file .seamark/lessons.yaml is the authority for the installed guidance. The proposal ledger in the index database is the authority for the recorded decisions. This package relates the two and never repairs one from an assumption about the other.

Inspect reads both and computes the readings once per snapshot. It writes nothing, takes no lock, and needs no store: without a ledger the pins stay listed and every relationship reads as unknown.

NewPlan computes the complete candidate file, the ledger changes, and the reason for every entry that cannot change. It writes nothing. Commit plans again from the current file, rows, write gate, and evidence, and refuses with ErrStale unless the result is identical. It then replaces the file through the guarded atomic write of the setup engine, and updates the ledger in one short guarded transaction.

A failure between the two writes is reported, not hidden. Commit puts the old file back only while the file still holds the bytes that it wrote and every ledger row still holds its planned values. Otherwise it leaves the file as it is and reports what it observed. It offers a Recovery only when it saw its own write land. A recovery completes the ledger update only while a fresh observation still proves the reviewed result. The proof lives in memory: after a restart, a bare absence of a pin never supersedes a proposal.

No journal records a partial operation, and no general undo exists. So a quit or a restart loses the Recovery. A later session sees only the mismatch, through the link rules of pinfile.Classify. After a retarget, the new entry links no applied proposal, and the applied proposal reads as not present. After a prune, the applied proposal reads as not present. Nothing repairs the mismatch automatically, because the mismatch alone does not prove which writer made it. A repeat of the operation finds no linked pin, and NewPlan blocks it. So a hand edit reconciles the two stores.

PlanAuthor and CommitAuthor serve the pins that a person writes in the console. The operations are a new pin, an edit or a removal of an unlinked pin, and a note edit of a linked pin. They write the pin file only. They never write the ledger and never build a Recovery, so a failure has only the three outcomes of one file write. The plan also reads the ledger, because the relationship decides which fields can change.

Many display fields hold text from the pin file, the ledger, a model, or the person. Such text can contain terminal control bytes, so a caller sanitizes it before display. These fields are PlanItem.Reason, From, To, Facts, Kept, and Rows; Plan.Blocked and FileBlock; the Reason of every reading; the error fields of Result; and Recovery.Before and After. For authoring, they are AuthorPlan.Before, After, Diff, Old, New, the owners, History, and Missing; AuthorBlocker.Text and Route; FieldIssue.Text; StaleError.Differences; and AuthorResult.Err. Only the texts in the const blocks of this package are fixed.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNothingSelected reports a request without an entry.
	ErrNothingSelected = errors.New("no pin selected")
	// ErrNoLedger reports a proposal ledger that cannot be read. Pins then
	// stay listed, but no link to a proposal is known.
	ErrNoLedger = errors.New("unknown: the proposal ledger could not be read")
	// ErrStale reports that the pin file, the ledger rows, the write gate,
	// or the evidence changed since the preview.
	ErrStale = errors.New("the pin file, the ledger, the write gate, or the evidence changed since the preview")
	// ErrWriteDisabled reports a plan that was made while distill.write
	// was off. Such a plan never authorizes a write.
	ErrWriteDisabled = errors.New("distill.write is off")
	// ErrNotConfirmable reports a plan with a blocked or no-op entry, a
	// gate that cannot be read, or a file that cannot be replaced.
	ErrNotConfirmable = errors.New("the preview cannot be confirmed; revise the selection")
)

The errors of the plan and commit boundary. A commit that returns one of them wrote nothing.

Functions

func Blocking

func Blocking(issues []FieldIssue) bool

Blocking reports whether an issue blocks the draft: an issue blocks unless it is Info. The form and the planner share this rule.

func RowsHoldPlanned

func RowsHoldPlanned(p *Plan, observed []model.Proposal) (planned, target bool)

RowsHoldPlanned compares the planned ledger rows of p, as read again, with their planned and their target values. planned is true when each planned row still holds the values that the plan read. target is true when each planned row holds the values that the commit writes. A row that observed lacks holds neither. The check uses the store guard comparison, so a caller that describes the rows agrees with the guarded transaction. A plan without a ledger change gives true for both, as every check over no rows does; a ready item always carries a ledger change.

Types

type Action

type Action int

Action is a maintenance operation. The zero value is not an action, so an unset request never changes a pin.

const (
	// ActionRetarget changes the regions of linked pins to the computed
	// scope and updates the region fields of their proposals. The
	// proposals stay applied, and their recorded notes stay, because the
	// guidance stays installed. The pin identity holds the regions. So
	// the delivery history in the firing log restarts under the new
	// identity, and a plan note says so.
	ActionRetarget Action = iota + 1
	// ActionPrune removes linked pins and moves their proposals from
	// applied to superseded. A prune is a deliberate retirement of
	// installed guidance. It differs from a dismissal, which decides a
	// pending proposal. It also differs from the removal of stale pending
	// proposals in a distillation run, which never touches a pin.
	ActionPrune
)

The operations.

func (Action) String

func (a Action) String() string

String returns the lower-case name of the action.

type AuthorBlocker

type AuthorBlocker struct {
	Kind  BlockKind
	Text  string
	Route string
}

AuthorBlocker is one reason that a plan cannot be confirmed. Route names the way forward, or is empty when Text names it already. The text can quote file, ledger, or path data, so a caller sanitizes it.

func (AuthorBlocker) String

func (b AuthorBlocker) String() string

String returns the reason with its route, as one line.

type AuthorField

type AuthorField int

AuthorField names a field of the authoring form.

const (
	FieldRule AuthorField = iota + 1
	FieldNote
	FieldScope
	FieldRegions
)

The form fields.

func (AuthorField) String

func (f AuthorField) String() string

String returns the lower-case name of the field.

type AuthorOp

type AuthorOp int

AuthorOp is an authoring operation. The zero value is not an operation, so an unset request never changes a pin.

const (
	// AuthorCreate adds a new pin after the last entry of the list, so
	// the earlier pins keep their priority.
	AuthorCreate AuthorOp = iota + 1
	// AuthorEdit changes the fields of one entry in place.
	AuthorEdit
	// AuthorRemove deletes one unlinked entry and its provenance run.
	AuthorRemove
)

The authoring operations.

func (AuthorOp) String

func (o AuthorOp) String() string

String returns the lower-case name of the operation.

type AuthorPlan

type AuthorPlan struct {
	Request AuthorRequest
	// Root is the root of the pin file. Guard is the observation of the
	// file that the plan read.
	Root  string
	Guard integration.FileGuard
	// Before is the file content; After is the verified candidate, or
	// nil when no candidate exists.
	Before, After []byte
	// Diff is the redacted display diff; Added and Removed count lines.
	Diff           string
	Added, Removed int
	// Old is the entry as the plan read it. New is the entry that After
	// holds, or the requested pin when no candidate exists. Old is zero
	// for a create, and New is zero for a removal.
	Old, New reviews.PinRule
	// Link is the relationship of the entry. It is meaningful only when
	// LinksKnown is true, and it is zero for a create.
	Link       pinfile.Link
	LinksKnown bool
	// EntryApplied and EntryPending are the IDs of the rows that match
	// the entry, in ascending order.
	EntryApplied, EntryPending []int64
	// Proposal and ProposalGuard are the linked row of a linked entry.
	Proposal      *model.Proposal
	ProposalGuard *store.RowGuard
	// OldOwners hold the key of the entry; NewOwners hold the new key.
	// The edited entry is never its own owner.
	OldOwners, NewOwners pinfile.Owners
	// KeyChanged and IdentityChanged compare the old and the new pin of
	// an edit: the link key, and the firing identity of the deliveries.
	KeyChanged, IdentityChanged bool
	// Write is distill.write at plan time; GateErr is its read failure.
	Write   bool
	GateErr error
	// NoOp is true for an edit whose fields all decode to the values of
	// the entry. Such a draft offers no write.
	NoOp bool
	// Issues are the verdicts of CheckDraft.
	Issues []FieldIssue
	// Blockers list every reason that the plan cannot be confirmed.
	Blockers []AuthorBlocker
	// Notes are the plain statements of the review.
	Notes []string
	// History holds the superseded and dismissed rows of the key. They
	// are history, never the source of the pin.
	History []model.Proposal
	// Missing lists the typed regions that name no file or directory
	// under Root yet. It is information, never a blocker.
	Missing []string
	// NewRef binds the new or edited entry in After; nil otherwise.
	NewRef *pinfile.EntryRef
	// Confirmable is true when nothing blocks the write.
	Confirmable bool
}

AuthorPlan is a reviewed authoring operation. It is complete even when it cannot be confirmed, so a review can show the exact change and every blocker. Some fields hold file, ledger, or typed data: Before, After, Diff, Old, New, the owners, the rows, and Missing. A caller sanitizes them before display.

func PlanAuthor

func PlanAuthor(d Deps, req AuthorRequest) (*AuthorPlan, error)

PlanAuthor computes the authoring operation of req from the current pin file, write gate, and ledger. It writes nothing. It returns an error only for an invalid request; every blocker and every issue goes into the plan.

A missing ledger, an unreadable listing, or a foreign root gives a blocker with its route (P4-8, P4-16). The plan then still holds the candidate, the diff, and the identity. A draft with a blocking issue gets no candidate, because the issue names the fix.

type AuthorRequest

type AuthorRequest struct {
	Op AuthorOp
	// Ref binds an edit or a removal to the entry that the person saw.
	Ref pinfile.EntryRef
	// Rule and Note are the typed texts.
	Rule, Note string
	// Scope and Regions are the typed scope. Regions holds the rows as
	// the person typed them; the check normalizes them.
	Scope   ScopeChoice
	Regions []string
	// RuleSet, NoteSet, and ScopeSet mark the fields of an edit that the
	// person changed. A create ignores them.
	RuleSet, NoteSet, ScopeSet bool
}

AuthorRequest is one authoring draft. A create uses every field. An edit sets only the fields that the person changed, and the planner compares each set value with the entry byte for byte. A removal uses only Ref.

type AuthorResult

type AuthorResult struct {
	Outcome WriteOutcome
	// Err is the refusal or the write failure. It can hold file paths,
	// so a caller sanitizes it before display.
	Err error
	// NewRef binds the new or edited entry when the outcome is Written.
	NewRef *pinfile.EntryRef
}

AuthorResult is the outcome of an authoring commit.

func CommitAuthor

func CommitAuthor(d Deps, p *AuthorPlan) (AuthorResult, error)

CommitAuthor writes a confirmed authoring plan. It plans again from the current file, gate, and ledger. It refuses with a StaleError unless the new plan is identical in every observation that the person reviewed. It then writes the one file through Deps.Author. It never writes the ledger and never builds a Recovery.

A non-nil error means that CommitAuthor wrote nothing: the outcome is then NotWritten, and CommitAuthor does not read the file back (P4-18). After the write starts, the error is nil and the result holds the outcome. After a failed write, CommitAuthor reads the file again and does not assume the outcome. integration.Landed decides between Written, NotWritten, and Unknown. CommitAuthor never retries a write.

type AuthorWriter

type AuthorWriter interface {
	// Write writes after over the file that expect observed. create
	// allows an absent file. An error that wraps ErrStale,
	// pinfile.ErrStale, or pinfile.ErrNotWritable means that nothing was
	// written. Every other error is an error of the write step.
	Write(reg *integration.Registry, root string, expect integration.FileGuard, after []byte, create bool) error
}

AuthorWriter is the pin file boundary of an authoring commit. The default writes through pinfile.PrepareAppend for a create, else pinfile.Prepare, and then Apply. Tests replace it to inject a failure.

type BlockKind

type BlockKind int

BlockKind is the cause of an authoring blocker. A screen chooses its route key by the kind.

const (
	// BlockFile means that the pin file cannot be planned or replaced.
	// Causes are its structure, CRLF line breaks, a link, its mode, a
	// hard link, and a refusal of the planner.
	BlockFile BlockKind = iota + 1
	// BlockEntry means that the reviewed entry changed or is gone.
	BlockEntry
	// BlockRelation means that the link to the ledger forbids the
	// request: a linked pin, a pending match, or an ambiguous link.
	BlockRelation
	// BlockOwner means that another pin or proposal already holds the
	// new key.
	BlockOwner
	// BlockLedger means that no readable ledger gives the relationship.
	BlockLedger
	// BlockForeignRoot means that the index records another root.
	BlockForeignRoot
	// BlockGate means that distill.write is off or cannot be read.
	BlockGate
)

The blocker kinds, in the order of a plan.

type ConfidenceReading

type ConfidenceReading struct {
	Known  bool
	Reason string
	Tier   confidence.Tier
	Facts  confidence.Facts
	// Living holds the cited findings that are still in the index. They
	// are metadata: the finding bodies are not read.
	//
	// A cited finding leaves the index when it ages out of the mining
	// window, when a later commit reverts its fix, or when a re-mine no
	// longer finds it. The proposal still cites it, but it is not living.
	// The members of the proposal keep its ID, so a caller can name each
	// cited finding that Living does not hold.
	Living []model.Finding
}

ConfidenceReading is the evidence tier of the linked proposal, as the proposal health computes it.

type Deps

type Deps struct {
	// Root is the effective repository root: the root that the index
	// records, else the workspace root.
	Root string
	// Reg is the client registry of the setup engine.
	Reg *integration.Registry
	// Reader reads the ledger and the evidence. NewPlan accepts a
	// read-only store. Commit plans again through it.
	Reader *store.Store
	// Ledger writes the ledger. Nil uses Reader, which must then be
	// writable.
	Ledger LedgerWriter
	// Files writes the pin file. Nil uses the guarded pinfile write.
	Files FileWriter
	// Author writes the pin file of an authoring commit. Nil uses the
	// guarded pinfile write. It is separate from Files, because an
	// authoring commit can create the file and restores nothing.
	Author AuthorWriter
	// ForeignRoot is set by the caller when Root is not the root of this
	// workspace (P4-16). The caller owns the root rule. An authoring plan
	// then carries a blocker with its text, and CommitAuthor refuses
	// with it. The maintenance planner ignores it.
	ForeignRoot error
	// Probe is a fresh observation of the index. A retarget needs a
	// ready index, because the scope advice reads its history.
	Probe workspace.IndexProbe
	// Now reads the clock. Nil reads the system clock.
	Now func() time.Time
}

Deps are the inputs and the boundaries of NewPlan and Commit.

type ExposureReading

type ExposureReading struct {
	Known    bool
	Reason   string
	Exposure reviews.Exposure
	// Fired is true when the firing log holds a delivery of the identity.
	Fired bool
}

ExposureReading is the delivery history of the live pin identity. It exists for every pin, linked or not, because the firing log keys on the pin text.

The identity covers the rule, the note, and the regions (reviews.PinIdentity). A retarget changes the regions, so it starts a new history. The firings of the old regions stay with the old identity. Exposure holds the delivery count and the first delivery. A known reading with Fired false is a fact, not an unknown: the log was read and holds no delivery of this identity.

type FieldIssue

type FieldIssue struct {
	Field AuthorField
	// Index is the 0-based row of a region issue. It is -1 for an issue
	// of a whole field.
	Index int
	Text  string
	// Info marks a line that explains a normalization of a region, such
	// as a removed trailing "/". It never blocks the draft.
	Info bool
}

FieldIssue is one verdict of CheckDraft about one field. The text can quote typed text, so a caller sanitizes it before display.

func CheckDraft

func CheckDraft(req AuthorRequest, base *reviews.PinRule) []FieldIssue

CheckDraft checks the typed fields of an authoring draft. The form shows the verdicts live, and PlanAuthor fills AuthorPlan.Issues with the same verdicts. base is the decoded entry of an edit, or nil.

A create needs a rule, a nonblank note, and a scope choice. An edit checks a rule or a note only when it sets it and the value differs from base. So a legacy rule or note that the person did not edit never blocks the draft. An edit can clear the note while the rule stays nonblank. A removal has no field to check.

A set scope replaces the whole region list, so the check covers every region row. A scope equal to base is checked too. The entry stores its scope in two keys, region and regions, so a typed list has no one stored text to compare with. A legacy region that CheckPinRegion refuses thus blocks every scope edit of its entry.

type FileWriter

type FileWriter interface {
	// Replace writes after over the file that expect observed. An error
	// that wraps pinfile.ErrStale means that the file changed first.
	Replace(reg *integration.Registry, root string, expect integration.FileGuard, after []byte) error
	// Restore writes original back, but only while the file holds the
	// bytes with the SHA-256 written.
	Restore(reg *integration.Registry, root string, written [32]byte, original []byte) error
}

FileWriter is the pin file boundary of a commit. The default writes through pinfile.Prepare, Apply, and Restore. Tests replace it to inject a failure or another writer.

type Inspection

type Inspection struct {
	// Doc is the read of the pin file; nil when DocErr is set.
	Doc *pinfile.Document
	// DocErr is a read failure of the file itself: a path that is not a
	// regular file, or an I/O error. The listing is then empty.
	DocErr error
	// Links is the classification of the entries against the ledger. It
	// is nil when the ledger cannot be read.
	Links *pinfile.Links
	// LinkErr says why no link is known: pinfile.ErrUnreadable for a pin
	// file that cannot be read, or an error that wraps ErrNoLedger. It is
	// nil when every link is known.
	LinkErr error
	// Pins holds one item per Doc.Entries item, in file order.
	Pins []Pin
	// Superseded is the read-only history of pruned proposals, in
	// ascending ID order.
	Superseded []model.Proposal
	// Clusters groups the pins whose wording restates each other, by
	// index in Pins. Only present, linked pins take part.
	Clusters [][]int
	// LedgerErr is the read failure of the ledger; ReadingsErr joins the
	// read failures of the readings.
	LedgerErr, ReadingsErr error
	// Index is the index probe that the readings used.
	Index workspace.IndexProbe
	// At is the time that the readings used.
	At time.Time
}

Inspection is one snapshot of the installed pins and their relation to the ledger. Every field is a read; nothing in it selects an action.

func Inspect

func Inspect(root string, st *store.Store, probe workspace.IndexProbe, now time.Time) *Inspection

Inspect reads the pin file under root and relates it to the ledger in st. It computes the readings once, with the clock value now. st can be nil, and a ledger that cannot be read leaves the pins listed with unknown links. Inspect writes nothing: no file, no ledger row, and no firing record.

type ItemStatus

type ItemStatus int

ItemStatus is the state of one selected entry in a plan. The zero value is ItemBlocked, so an unset item never reads as ready.

const (
	// ItemBlocked means that the entry cannot change; Reason says why.
	ItemBlocked ItemStatus = iota
	// ItemNoOp means that the change would leave the entry as it is.
	ItemNoOp
	// ItemReady means that the candidate file holds the change.
	ItemReady
)

The item states.

func (ItemStatus) String

func (s ItemStatus) String() string

String returns the lower-case name of the state.

type LedgerWriter

type LedgerWriter interface {
	ProposalsWithIDs(ids []int64) ([]model.Proposal, error)
	RetargetApplied(changes []store.RegionChange) error
	SupersedeExact(guards []store.RowGuard) error
}

LedgerWriter is the ledger boundary of a commit. *store.Store implements it. Tests replace it to inject a failure after the file write.

type OutcomeReading

type OutcomeReading struct {
	Known   bool
	Reason  string
	Reading outcome.Reading
}

OutcomeReading is the passive outcome reading of the linked proposal. It is a derived recurrence check. It counts the mistake events before and after the first delivery, so it shows a correlation and never proves a cause. No plan reads it, so no verdict selects a prune: a working verdict validates the pin (outcome.VerdictWorking).

type Pin

type Pin struct {
	Entry    pinfile.Entry
	Link     pinfile.EntryLink
	Readings Readings
}

Pin is one live entry with its link and readings.

type Plan

type Plan struct {
	Action  Action
	Request Request
	Items   []PlanItem
	// Change is the verified candidate file of the ready items; nil when
	// no item is ready.
	Change *pinfile.Change
	// Retarget and Supersede are the guarded ledger changes of the ready
	// items, in item order.
	Retarget  []store.RegionChange
	Supersede []store.RowGuard
	// Write is distill.write at plan time; GateErr is its read failure.
	Write   bool
	GateErr error
	// FileBlock is the reason the pin file cannot be edited or replaced.
	// It can name a path, so a caller sanitizes it before display.
	FileBlock string
	// Confirmable is true when every item is ready, the gate is on, and
	// the file can be replaced. Only such a plan can be committed.
	Confirmable bool
	// Blocked lists the reasons that the plan cannot be confirmed. One
	// reason can quote FileBlock, so a caller sanitizes them.
	Blocked []string
	// Evidence binds a retarget to its inputs: the living findings, the
	// trigger fields, the computed regions, and the index run.
	Evidence [32]byte
	// File is the observation of the pin file that the plan read.
	File integration.FileGuard
	// Notes are plain statements for the preview.
	Notes     []string
	PlannedAt time.Time
	// Recovery is set on a plan from PlanRecovery. Such a plan completes
	// the ledger only and commits through CommitRecovery.
	Recovery *Recovery
}

Plan is a reviewed maintenance operation. It is complete even when it cannot be confirmed, so a preview can show the exact change.

func NewPlan

func NewPlan(deps Deps, req Request) (*Plan, error)

NewPlan computes the operation of req from the current pin file, ledger, write gate, and evidence. It writes nothing. Every selected entry gets an item: ready, no-op, or blocked with a reason. A plan is confirmable only when every item is ready, so it never acts on a different subset.

func PlanRecovery

func PlanRecovery(deps Deps, r *Recovery) (*Plan, error)

PlanRecovery plans the ledger-only completion of a partial operation. It is confirmable only while a fresh observation proves the reviewed result: the pin file reads without error; for a retarget, every target entry is present with exactly the reviewed content, every earlier key is absent, and no other applied row records a target key; for a prune, no pruned key is present; every ledger row still holds its planned values; and the write gate is on, because a completion writes the ledger. It writes nothing.

type PlanItem

type PlanItem struct {
	// Ref is the reviewed binding of the entry.
	Ref pinfile.EntryRef
	// Pin is the entry as the plan read it, with its link. A plan fills
	// only the scope and trigger readings; the other readings stay
	// unknown. Pin is zero when the entry changed since the review.
	Pin    Pin
	Status ItemStatus
	// Reason explains a blocked or no-op item. For a ready prune it says
	// whether a retained alternative is established. It can quote a
	// pinfile error with a rule or a path from the file, so a caller
	// sanitizes it before display.
	Reason string
	// From is the live region set; To is the computed set of a retarget.
	// Nil is repository-wide. To is meaningful only for a ready or a
	// no-op retarget. Both hold paths from the file or the model, so a
	// caller sanitizes them before display.
	From, To []string
	// Broader and RepoWide label a retarget that widens the scope.
	Broader, RepoWide bool
	// Facts explain what supports the computed scope. They hold file and
	// model data, so a caller sanitizes them before display.
	Facts []string
	// Kept lists the similar pins that stay in the file and stay linked
	// after a prune. Similar wording does not prove the same coverage.
	// Their entries hold file text, so a caller sanitizes it.
	Kept []Pin
	// Rows are the applied proposals linked to the entry. Their rule and
	// note come from the ledger, so a caller sanitizes them.
	Rows []model.Proposal
}

PlanItem is the plan of one selected entry.

type Readings

type Readings struct {
	Confidence ConfidenceReading
	Scope      ScopeReading
	Trigger    TriggerReading
	Outcome    OutcomeReading
	Exposure   ExposureReading
	// Similar holds the indexes in Inspection.Pins of the other pins of
	// the same redundancy cluster. Similar wording does not prove the
	// same coverage, so a similar pin is no reason to prune. A prune
	// plan decides its items first and then only lists the similar pins
	// that stay (PlanItem.Kept).
	Similar []int
}

Readings are the derived readings of one pin. Each one says whether it is known, and an unknown one carries the reason. Missing input is not a negative result. A reading is advice: it never selects or runs an action. A reason can quote a store error, so a caller sanitizes it before display. Confidence, Scope, Trigger and Outcome read the linked proposal, so a pin without exactly one linked proposal has only the Exposure reading.

type Recovery

type Recovery struct {
	Action  Action
	Request Request
	// Items are the reviewed items, in the order of the edits and the
	// ledger changes.
	Items []PlanItem
	// Written is the SHA-256 of the bytes that the session wrote.
	Written [32]byte
	// Before and After are the reviewed file contents. They hold file
	// data, so a caller sanitizes them before display.
	Before, After []byte
	// Edits and NewKeys are the reviewed file edits and their target keys.
	Edits   []pinfile.Edit
	NewKeys []reviews.PinKey
	// Retarget and Supersede are the ledger changes that did not complete.
	Retarget  []store.RegionChange
	Supersede []store.RowGuard
}

Recovery is the in-memory proof that this session wrote the pin file of an operation whose ledger update did not complete. The session saw the written bytes in the file. It does not survive a restart: a later session sees only the mismatch.

type Request

type Request struct {
	Action Action
	// Refs are the reviewed entries, in selection order.
	Refs []pinfile.EntryRef
	// Cursor is true when no entry was marked and the request names the
	// cursor row. The preview then says so.
	Cursor bool
}

Request names the entries that the user selected. A plan binds to each entry as the Pins view read it, never to a list position alone.

type Result

type Result struct {
	Action Action
	// FileWritten is true when the pin file holds the new bytes, or when
	// a failed write could not be checked. It never claims an untouched
	// file that was not observed.
	FileWritten bool
	FileErr     error
	// LedgerDone is true when every planned row holds its target values.
	LedgerDone bool
	LedgerErr  error
	// Restored is true only when the restore write succeeded.
	Restored   bool
	RestoreErr error
	// RestoreRefused says why no restore ran over the file of another
	// writer.
	RestoreRefused string
	// Observed holds the planned rows as read again after a failure;
	// ObservedErr is the failure of that read.
	Observed    []model.Proposal
	ObservedErr error
	// Moved lists the proposals that this commit changed, ascending.
	Moved []int64
	// Recovery is the session proof of a partial operation. It is set
	// when the commit neither restored the file nor completed the ledger,
	// and the session saw its own write land. A write that could not be
	// checked offers no recovery, because a prune recovery then rests on
	// a bare absence (D-13).
	Recovery *Recovery
	// Note is one plain sentence about the outcome. It names the step
	// that failed: the file write or the ledger update.
	Note string
}

Result is the outcome of a commit. The file and the ledger have separate outcomes, because no transaction spans both. The error fields hold file paths and store text, so a caller sanitizes them before display.

func Commit

func Commit(deps Deps, p *Plan) (Result, error)

Commit applies a confirmed plan. It plans again from the current observations and refuses with ErrStale, before any write, unless the new plan is identical. It then replaces the pin file and updates the ledger in one guarded transaction. A non-nil error means that no write started. After the file write starts, every outcome is in the Result and the error is nil. Nothing is retried.

func CommitRecovery

func CommitRecovery(deps Deps, p *Plan) (Result, error)

CommitRecovery completes the ledger update of a recovery plan. It plans the recovery again and refuses with ErrStale unless the proof still holds and the observations are identical. It never writes the pin file. A failed ledger write keeps the recovery available.

func (Result) Partial

func (r Result) Partial() bool

Partial reports a commit that changed the file or could not check it, did not complete the ledger, and did not restore the file.

type ScopeChoice

type ScopeChoice int

ScopeChoice is the scope that a person chose for a pin. The zero value is no choice, because a blank form must never read as repository-wide.

const (
	// ScopeUnset means that the form holds no choice yet.
	ScopeUnset ScopeChoice = iota
	// ScopeRepoWide delivers the pin for every file.
	ScopeRepoWide
	// ScopeRegions delivers the pin for the regions of the request.
	ScopeRegions
)

The scope choices.

type ScopeReading

type ScopeReading struct {
	Known  bool
	Reason string
	Advice distill.ScopeAdvice
}

ScopeReading is the scope that today's evidence computes for the linked proposal (distill.RecommendScope). It needs an indexed database, because the shared region engine reads the history. Without a living cited finding the advice is distill.ScopeNoEvidence, because missing evidence must never widen a pin.

type StaleError

type StaleError struct {
	Differences []string
}

StaleError is the ErrStale of an authoring commit. It names each observation that changed since the review, in plain words, so the review can show them before the person reviews again. A difference can quote a blocker with file, ledger, or path text, so a caller sanitizes it before display.

func (*StaleError) Error

func (e *StaleError) Error() string

Error returns ErrStale with the differences.

func (*StaleError) Unwrap

func (e *StaleError) Unwrap() error

Unwrap returns ErrStale, so errors.Is matches it.

type TriggerReading

type TriggerReading struct {
	Known  bool
	Reason string
	// Open is true when an extraction can ask the question.
	Open  bool
	State distill.TriggerReason
	// Blocked holds the confirmed triggers that the region set does not
	// deliver. They come from the scope reading, so they are empty while
	// that reading is unknown.
	Blocked []distill.TriggerFact
}

TriggerReading is the trigger question state of the linked proposal. The stored trigger paths passed the path checks of the extraction before the store saved them, so the reading shows them as facts.

type WriteOutcome

type WriteOutcome int

WriteOutcome says what the pin file holds after an authoring commit (P4-18). The zero value is NotWritten, so a refused commit reads as "nothing written".

const (
	// NotWritten means that the file does not hold the planned bytes.
	NotWritten WriteOutcome = iota
	// Written means that the file holds the planned bytes.
	Written
	// Unknown means that the write failed and the file cannot be read
	// again. The caller must not report "written" or "not written".
	Unknown
)

The commit outcomes.

func (WriteOutcome) String

func (o WriteOutcome) String() string

String returns the name of the outcome.

Jump to

Keyboard shortcuts

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