installruntime

package
v1.48.0 Latest Latest
Warning

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

Go to latest
Published: Oct 6, 2026 License: GPL-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package installruntime owns the shared installation transaction primitives. Lock order is component, then config paths in canonical sorted order. Config-only migration must never acquire the component lock.

Index

Constants

View Source
const CoordinatorLockName = ".setup-coordinator.lock"

CoordinatorLockName is the single ControlRoot process lock that serializes setup coordinators. The kernel lock inode is separate; death releases this lease, but a persisted reservation remains.

View Source
const LocalPolicyWriterFloor = 3

LocalPolicyWriterFloor protects binding-scoped native/manual consent. It is independent of the reservation protocol; older unrelated installs stay at 2.

View Source
const LocalWriterProtocolMarker = "agent-notifications-managed-writer-protocol-v3"
View Source
const OpenCodeStoreLimit = 1 << 20
View Source
const OpenCodeStoreLock = ".opencode-admission.lock"
View Source
const OpenCodeWriterFloor = 4

OpenCode private Init/Purge recovery must be refused by the published Local3 kernel before it reads blobs or publishes generic files. Ledger/journal schema4 is retained.

View Source
const OpenCodeWriterProtocolMarker = "agent-notifications-managed-writer-protocol-v4"
View Source
const ReservationWriterFloor = 2

ReservationWriterFloor is published with guarded start/change/cleanup of a PendingMutation. Ordinary installs keep WriterFloor. The floor never decreases.

View Source
const SupportedWriterFloor = OpenCodeWriterFloor

SupportedWriterFloor is the kernel/reader ceiling, not a replacement for the historical v1 marker or reservation-v2 declaration.

View Source
const WriterFloor = 1
View Source
const WriterProtocolMarker = "agent-notifications-managed-writer-protocol-v1"

WriterProtocolMarker is an offline compatibility declaration in the trusted package bytes, not publisher authentication. No historical writer is run to discover its capabilities. Increment the floor for destructive protocol changes.

Variables

View Source
var ErrPolicyConflict = errors.New("managed policy observation changed or invalid")

ErrPolicyConflict refuses a stale ExpectedPolicy or invalid raw-policy observation under the commit locks, before any journal or product mutation.

View Source
var ErrPolicyRecovery = errors.New("pending installation transaction requires installer recovery")

ErrPolicyRecovery leaves pending installer work untouched for its owner.

View Source
var ErrReservationConflict = errors.New("pending mutation reservation blocks this operation")

ErrReservationConflict is a pending mutation blocking an unmatched writer.

Functions

func AcquireCoordinatorLease

func AcquireCoordinatorLease(ctx context.Context, root string) (func(), error)

AcquireCoordinatorLease serializes confirmed cross-system mutation/resume. Read-only operations must not take it. The OS releases the lease on process death; file age is not ownership.

func CanonicalPath

func CanonicalPath(path string) (string, error)

CanonicalPath resolves directory roots, including a not-yet-created suffix. File CAS leaves must not use it: a final symlink is itself the owned identity.

func CheckPrivateControlRoot

func CheckPrivateControlRoot(root string) error

CheckPrivateControlRoot is read-only and shared by installed-state consumers. Missing roots are errors; it never creates or migrates state.

func ControlRoot

func ControlRoot() (string, error)

ControlRoot is independent of any client's installation or cache directory.

func DiscardNative

func DiscardNative(ctx context.Context, control string, change *NativeChange) error

DiscardNative removes only this invocation's unused, unchanged candidate. The component lock and recovery references prevent deleting either an interrupted transaction's input or the previous callback retained by a swap. This is best-effort staging cleanup, never the transaction's rollback path.

func IdentityMode

func IdentityMode(mode uint32) uint32

IdentityMode returns the permission bits retained by the host fingerprint. Windows has no Unix execute bit and normalizes its file modes accordingly.

func Lock

func Lock(ctx context.Context, path string) (func(), error)

Lock holds a permanent inode. Closing releases the kernel lock; the path is never unlinked, including after crashes. Callers must supply a deadline.

func LockExisting

func LockExisting(ctx context.Context, path string) (func(), error)

LockExisting acquires the permanent inode without creating any filesystem state.

func MatchPersistedDirectory added in v1.47.0

func MatchPersistedDirectory(stored, current, parentDev string) bool

MatchPersistedDirectory compares a durable identity with a freshly observed physical directory. Callers must reject symlinks/non-directories first and supply the device of its held or no-follow observed parent. Only Darwin may renumber devices, and only away from a current volume boundary.

func OwnedNotificationCommand

func OwnedNotificationCommand(l Ledger, root string) (string, error)

OwnedNotificationCommand selects the installed entry, including native Windows architecture names. Never infer an executable from an unowned filesystem file.

func PhysicalPath

func PhysicalPath(path string) (string, error)

PhysicalPath rewrites only Darwin root-owned /var, /tmp, and /etc aliases. Arbitrary user-directory symlinks are not canonicalized.

func ReconcileNativeRegistration added in v1.47.0

func ReconcileNativeRegistration(ctx context.Context, control string) error

ReconcileNativeRegistration is a post-success adapter, never transaction redo. It leaves bundle bytes and published callback identities intact. Callers must report failure as a warning: the committed installation remains successful.

func WindowsLauncherScript

func WindowsLauncherScript(launcher, entry string) []byte

WindowsLauncherScript is the transaction-owned BAT wrapper. The shell installer must emit the same bytes and must not rewrite a committed launcher.

func WithInstalledLease

func WithInstalledLease(ctx context.Context, root string, expected InstalledSnapshot, handoff func(InstalledSnapshot) error) error

WithInstalledLease fences generation, owner, fingerprints and recovery until the bounded handoff returns. It never changes policy. Missing state is rejected without creating a control directory or lock.

func WriterCompatible

func WriterCompatible(data []byte) bool

WriterCompatible is available to package adapters before any candidate exec. Source authentication remains the adapter's prerequisite.

func WriterCompatibleAtFloor added in v1.47.1

func WriterCompatibleAtFloor(data []byte, floor int) bool

Candidate bytes are inspected before exec; no environment or installed marker is changed by this compatibility wrapper. Floors 1/2 keep their old meaning.

Types

type Consumer

type Consumer struct {
	RuntimeRoot  string
	Registration string
	Commands     []string
	OpenCode     *OpenCodeRegistration `json:",omitempty"`
}

type File

type File struct {
	// WindowsReplacementID binds the evacuated preimage used by Windows redo.
	WindowsReplacementID string
	Parents              []PathAnchor
	BeforeData           []byte
	Link                 string
	Path                 string
	Before               Identity
	Data                 []byte
	Mode                 uint32
	Remove               bool
	DataSHA256           string `json:",omitempty"`
	BeforeDataSHA256     string `json:",omitempty"`
}

func NativeAlias

func NativeAlias(change *NativeChange, bin string) ([]File, error)

NativeAlias publishes a required product-owned discovery alias while retaining pre-existing concrete conventional bundles and every queued callback inode.

func StageFiles

func StageFiles(source, destination string, allow func(string) bool) ([]File, error)

StageFiles snapshots bytes and target identities before taking the component lock. The caller supplies its existing runtime allowlist. Callback bundles require the separate native promotion path and are never flattened here.

type Identity

type Identity struct {
	Link   string
	Exists bool
	SHA256 string
	Mode   uint32
}

Identity includes existence: an empty file is not an absent file.

func Fingerprint

func Fingerprint(path string) (Identity, error)

func OwnedFile

func OwnedFile(l Ledger, path string) (Identity, bool)

OwnedFile looks up a ledger identity by the published path or its canonical form.

func PredictPolicyIdentity added in v1.48.0

func PredictPolicyIdentity(root string, expected Identity, changes map[string]json.RawMessage) (Identity, error)

PredictPolicyIdentity computes only the existing field writer's output from an exact observed preimage. It grants no authority: Commit must still enforce the original generation and policy CAS. Neither disk nor changes are mutated.

type InstalledSnapshot

type InstalledSnapshot struct {
	Ledger   Ledger
	Recovery bool
	Enabled  bool
}

InstalledSnapshot is a read-only observation, not an admission lease. Missing, corrupt or interrupted state never creates files or performs recovery. Delivery must revalidate with WithInstalledLease immediately before handoff, without holding a journal lock. The callback must be bounded by ctx.

func AcquireInstalledLease

func AcquireInstalledLease(ctx context.Context, root string, expected InstalledSnapshot) (InstalledSnapshot, func(), error)

AcquireInstalledLease revalidates the snapshot under the existing component lock. The caller must release it after bounded handoff (or readiness probing), and must not hold a journal lock. Errors release the lease automatically. Missing state never creates a directory or a replacement lock inode.

func AcquireSetupLease

func AcquireSetupLease(ctx context.Context, root string, expected InstalledSnapshot) (InstalledSnapshot, func(), error)

AcquireSetupLease pins an existing, unchanged installation for explicit setup probes. It does not authorize notification delivery or enable policy. The caller must qualify native protocol support before executing the retained helper.

func ReadInstalledSnapshot

func ReadInstalledSnapshot(root string) (InstalledSnapshot, error)

type Ledger

type Ledger struct {
	WriterFloor      int
	Enabled          bool
	Native           *NativeRecord
	Schema           int
	ID               string
	Owner            string
	RuntimeRoot      string
	Generation       uint64
	PolicyGeneration uint64
	Consumers        map[string]Consumer
	Files            map[string]Identity
	DecoderFloor     int
	PendingMutation  *PendingMutation `json:",omitempty"`
}

func Commit

func Commit(ctx context.Context, r Request) (result Ledger, resultErr error)

Commit serializes all component decisions, then config locks in canonical order. The durable redo record precedes every live mutation. Recovery checks every identity before changing anything and refuses ambiguous foreign edits.

func ReadOwnership

func ReadOwnership(root string) (Ledger, bool, error)

ReadOwnership returns the durable ledger and whether a recovery marker is present. Unlike ReadInstalledSnapshot it does not fingerprint unrelated published files, so a single-path Prepare callback can still repair a missing sibling under the component lock.

func Recover

func Recover(ctx context.Context, controlRoot string) (Ledger, error)

Recover replays a pending journal for this control root and returns. It does not refresh, install, add a consumer, or require a package.

type NativeChange

type NativeChange struct {
	Parents       []PathAnchor
	PurgeTrees    []PurgeTree
	Staged        string
	StagedID      string
	Before, After NativeRecord
	Purge         bool
	Retire        bool
}

func StageNative

func StageNative(ctx context.Context, control, source string) (*NativeChange, error)

StageNative accepts executable-code trust from the adapter's explicitly selected installation source (the same package authority as the Go sender). A self-signed manifest does not establish that authority. Shell uses its fixed upstream HTTPS release source; setup uses the user-selected plugin package. Missing manifests are legacy and never probed. Existing bin fallbacks must use StageRetainedNative instead: their presence does not authorize execution.

func StageRetainedNative

func StageRetainedNative(ctx context.Context, control, source string) (*NativeChange, error)

StageRetainedNative preserves existing unknown callbacks without probing them. Only a previously recorded exact managed fingerprint can retain a known floor.

type NativeGeneration

type NativeGeneration struct {
	DirectoryID, Path, SHA256 string
	DecoderFloor              int
	Attestation               []byte
	InstalledTreeSHA256       string
}

NativeGeneration is one published callback identity. Paths and inodes stay durable after later promotions; the ledger only selects the active artifact.

type NativeRecord

type NativeRecord struct {
	DirectoryID, PreviousDirectoryID string
	// Attestation stores the external post-signing package evidence durably,
	// outside the signed bundle. InstalledTreeSHA256 binds it to bundle bytes.
	Attestation                                []byte
	InstalledTreeSHA256                        string
	Path, SHA256, PreviousPath, PreviousSHA256 string
	DecoderFloor                               int
	Published                                  []NativeGeneration
}

NativeRecord is separate from ordinary runtime files: final consumer removal retains the callback reader and its previously published artifacts by default.

type OpenCodeRegistration added in v1.48.0

type OpenCodeRegistration struct {
	Origin, Salt, Namespace, BundleSHA256 string
	OriginBound                           bool
}

OpenCodeRegistration is private persisted protocol, never public diagnostics.

func (OpenCodeRegistration) Valid added in v1.48.0

func (r OpenCodeRegistration) Valid() bool

type OpenCodeStore added in v1.48.0

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

OpenCodeStore is the permanent private lock below the component/policy fence. Event callers use existing-only acquisition. Close before provider IO.

func AcquireOpenCodeStore added in v1.48.0

func AcquireOpenCodeStore(ctx context.Context, root string, r OpenCodeRegistration) (*OpenCodeStore, error)

func (*OpenCodeStore) Close added in v1.48.0

func (s *OpenCodeStore) Close()

func (*OpenCodeStore) Read added in v1.48.0

func (s *OpenCodeStore) Read() ([]byte, error)

func (*OpenCodeStore) Write added in v1.48.0

func (s *OpenCodeStore) Write(payload []byte) error

type PathAnchor

type PathAnchor struct{ Path, Identity string }

PathAnchor binds a staged destination's existing parents to their opened filesystem identities. Recovery must not reinterpret a substituted directory.

type PendingMutation

type PendingMutation struct {
	ID        string
	Owner     string
	IntentRef string
}

PendingMutation is the kernel-owned reservation. The intent payload lives in a host-owned file; this package does not parse it.

type PolicySnapshot

type PolicySnapshot struct {
	// Preimage identifies exactly the bytes parsed into Fields, not a later
	// fingerprint. Setup may pass it unchanged as Request.ExpectedPolicy.
	Preimage     Identity
	Installation InstalledSnapshot
	Policy       UserPolicy
	Fields       map[string]json.RawMessage
}

PolicySnapshot belongs to one request, never to a service lifetime. Fields contains the authoritative policy (including adapter-owned route settings), without a second on-disk configuration. Callers must treat it as immutable. Pass Installation unchanged to AcquireInstalledLease for readiness/handoff.

func AcquirePolicyLease added in v1.46.0

func AcquirePolicyLease(ctx context.Context, root string, expected PolicySnapshot) (PolicySnapshot, func(), error)

AcquirePolicyLease pins the exact observed policy and installation through a consumer's bounded handoff. Unlike AcquireInstalledLease, portable enablement is not an admission condition: the consumer must check its own registration and consent against the returned snapshot before using the retained native bundle. Both existing locks are retained until release.

func ReadPolicySnapshot

func ReadPolicySnapshot(ctx context.Context, root string) (PolicySnapshot, error)

ReadPolicySnapshot reads policy and installation generation under component, then policy config locking. It never creates state or recovers transactions. Call once per request without a journal lock; release precedes journal work. Managed mutations use the same lock order. Manual edits have snapshot semantics.

type PurgeEntry

type PurgeEntry struct {
	ObjectID  string
	Directory string
	File      Identity
}

PurgeEntry persists individual ownership before the first deletion. Directory identities survive renames and reject replacement even by an identical tree.

type PurgeTree

type PurgeTree struct {
	Path    string
	Entries map[string]PurgeEntry
}

type Request

type Request struct {
	// RevokeOpenCode permits only the exact desktop/webhook false policy patch
	// when delivery assets are damaged. It still requires a registered consumer,
	// generation and policy CAS; no asset, native or other policy mutation is allowed.
	RevokeOpenCode bool
	// RevokeGemini permits only Gemini's exact desktop/webhook false patch.
	// Damaged assets do not prevent revocation; ownership and CAS still apply.
	RevokeGemini bool
	// RevokeCopilotVSCode is the exact false-only portable Local specialization.
	// It skips delivery readiness, never written-file anchors, ownership or CAS.
	RevokeCopilotVSCode bool
	// RevokeCursor permits only the exact recorded portable Cursor false pair.
	RevokeCursor bool
	// PolicyOnly requires an already-managed runtime and existing kernel locks.
	// It refuses recovery and asset/consumer mutations; setup cannot accidentally
	// promote native or rewrite hooks from an unrelated pending transaction.
	PolicyOnly bool
	// PolicyDocument is an exact raw config edit for the existing OpenCode
	// policy. Nil preserves it. Prepare must only fence the observed full ledger
	// and return no files; the kernel alone derives the publication path.
	PolicyDocument []byte
	// PolicyEnabled changes explicit intent; nil preserves it. Mutations require
	// an expected generation and share component/config locking and recovery.
	PolicyEnabled *bool
	// PolicyFields merges installer-owned route/rates and setupState ownership
	// members into the same
	// policy CAS transaction. Nil preserves all existing fields.
	PolicyFields map[string]json.RawMessage
	// ExpectedPolicy optionally fences the exact setup policy preimage, including
	// manual config edits that do not increment the installation generation.
	ExpectedPolicy *Identity
	// RefreshOnly updates an already registered runtime without adding a consumer.
	RefreshOnly bool
	// RelocateVersionedCache explicitly moves only the existing Claude hooks
	// consumer between sibling, versioned Claude plugin cache directories.
	// Other consumers and their runtime roots are never moved implicitly.
	RelocateVersionedCache bool
	// RollbackPending explicitly reverses a pending transaction using per-file CAS.
	RollbackPending bool
	Native          *NativeChange
	PurgeNative     bool
	// RetireNative removes only the drained predecessor, retaining the stable reader.
	// Requires ExpectedGeneration; may not be combined with native promotion/removal.
	RetireNative                                bool
	ControlRoot, Owner, RuntimeRoot, ConsumerID string
	Consumer                                    Consumer
	RemoveConsumer                              bool
	ExpectedGeneration                          *uint64
	Files                                       []File
	ConfigPaths                                 []string
	Prepare                                     func() ([]File, error)
	// RecoverOnly replays a pending journal and returns without refresh, install,
	// or consumer registration. It does not require owner/runtime/package.
	RecoverOnly bool
	// Reservation publishes or continues a kernel-owned pending mutation.
	Reservation *PendingMutation
	// ClearReservation removes a matching pending mutation. Floor/schema stay.
	ClearReservation bool
	// Fault is a test seam; returning an error intentionally leaves recovery data.
	Fault func(string) error
}

Request stages ordinary file bytes before Commit. Prepare runs under the component and config locks, and may only compute adapter-owned JSON changes.

type RevocationSnapshot added in v1.46.0

type RevocationSnapshot struct {
	Generation uint64
	Preimage   Identity
}

RevocationSnapshot is only a CAS preimage for turning a consumer's channels off. It deliberately does not assert that native or owned assets are usable.

func ReadRevocationSnapshot added in v1.46.0

func ReadRevocationSnapshot(ctx context.Context, root string) (RevocationSnapshot, error)

ReadRevocationSnapshot keeps the same component/config lock order as policy reads while allowing a damaged delivery asset to be revoked. Commit performs the final generation, ownership and exact policy preimage checks again.

type UserPolicy

type UserPolicy struct {
	SchemaVersion int  `json:"schemaVersion"`
	Enabled       bool `json:"enabled"`
}

UserPolicy is durable user intent. Runtime eligibility and its generation fence remain in the ledger; routes belong only in this authoritative file.

func ReadUserPolicy

func ReadUserPolicy(root string) (UserPolicy, error)

ReadUserPolicy never creates or migrates configuration. Missing means disabled. Unknown fields are retained by managed enable/disable for future route adapters.

Jump to

Keyboard shortcuts

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