manager

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package manager provides the trusted home control plane.

Index

Constants

View Source
const DefaultMaintenanceInterval = 600 * time.Second

Variables

View Source
var (
	ErrConfiguration = errors.New("manager: invalid configuration")
	ErrUnknownDevice = errors.New("manager: unknown device")
)
View Source
var (
	ErrConflict = errors.New("manager: idempotency conflict")
	ErrNoUpdate = errors.New("manager: no pending update")
)
View Source
var ErrPartialUnavailable = errors.New("manager: partial refresh unavailable")

ErrPartialUnavailable rejects one scene's requested refresh mode before I/O. It is not a renderer failure, device failure or permission to silently send full.

View Source
var ErrSuperseded = errors.New("manager: render superseded by newer scene")

Functions

func TokenDigest

func TokenDigest(token []byte) [sha256.Size]byte

Types

type Clock

type Clock func() time.Time

type DeviceRecord

type DeviceRecord struct {
	ID       securetransport.DeviceID
	Key      securetransport.Key
	Timezone string
}

func LoadEnrollment

func LoadEnrollment(path string) (DeviceRecord, error)

type DeviceStatus

type DeviceStatus struct {
	Pending    bool
	Connected  bool
	LastSeen   time.Time
	LastResult update.Result
	Generation uint64
}

type Pending

type Pending struct {
	Request   update.Request
	ExpiresAt time.Time
	Accepted  bool
}

type RefreshRejectionReason

type RefreshRejectionReason string
const (
	RefreshRequiresFull RefreshRejectionReason = "full-refresh-required"
	RefreshRegionLimit  RefreshRejectionReason = "region-budget"
)

type Registry

type Registry interface {
	Lookup(securetransport.DeviceID) (DeviceRecord, bool)
}

type Screen

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

Screen coordinates complete scenes, including atomic by-ID authoring edits. The caller authenticates submissions and maps their base revision to HTTP If-Match: https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match This server-only coordinator does not change the legacy manager HTTP API.

func NewScreen

func NewScreen(renderer ScreenRenderer, size display.Size, policy renderbatch.Policy) (*Screen, error)

func NewScreenWithOptions

func NewScreenWithOptions(renderer ScreenRenderer, size display.Size, policy renderbatch.Policy, options ScreenOptions) (*Screen, error)

NewScreenWithOptions requires a renderer that explicitly reserves the corner before quantization. Legacy NewScreen remains unstamped for existing callers.

func (*Screen) InvalidatePixels

func (s *Screen) InvalidatePixels() error

InvalidatePixels fences retained evidence after device reboot, session change or explicit full resynchronization. During a leased render/delivery the owner must finish through Resolve(false), not invalidate underneath another writer. Delivered remains historical; Confirmed is the newest pixel-equivalent scene, not a claim that a new protocol ACK was received for a suppressed update.

func (*Screen) RenderNext

func (s *Screen) RenderNext(ctx context.Context, now time.Duration, available bool) (ScreenDelivery, error)

RenderNext leases one ready target, then renders without blocking new edits. A result superseded during rendering is discarded before transport. Zero revision means not ready/available. Borrow the returned frame read-only until Resolve; no second consumer or premature success may resolve this lease.

func (*Screen) Resolve

func (s *Screen) Resolve(rev renderbatch.Revision, confirmed bool) error

Resolve records protocol completion, not visible acceptance. Unknown/failure invalidates the confirmed baseline. No implicit retry; the caller must submit a complete current scene again after resynchronizing transport. Renderer errors similarly preserve current scene but require an explicit new submit.

func (*Screen) ResolveCycle

func (s *Screen) ResolveCycle(id refreshstamp.CycleID, confirmed bool) error

ResolveCycle accepts only this physical lease, even when maintenance repeats the same HTML revision. A true result must be a matching terminal protocol ACK. A clock error after true means the physical cycle DID receive success, but its timestamp proof is unusable; no historical confirmation is advanced.

func (*Screen) Status

func (s *Screen) Status() ScreenStatus

func (*Screen) Submit

func (s *Screen) Submit(base renderbatch.Revision, markup []byte, now time.Duration) (renderbatch.Revision, error)

Submit copies bounded UTF-8 input. An old base never overwrites a newer scene.

type ScreenAPI

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

ScreenAPI serves one explicitly bound screen. It never constructs devices from request paths. Mount only behind HTTPS and for trusted content authors until the renderer capability/resource-isolation gates pass.

func NewScreenAPI

func NewScreenAPI(screen *Screen, token []byte, epoch [16]byte, now Clock) (*ScreenAPI, error)

NewScreenAPI requires a fresh cryptographically random epoch per process. It prevents stale If-Match values from becoming valid after a restart.

func (*ScreenAPI) ServeHTTP

func (a *ScreenAPI) ServeHTTP(w http.ResponseWriter, r *http.Request)

type ScreenDelivery

type ScreenDelivery struct {
	Region   *screendelivery.RegionPlan
	Options  refreshpolicy.Options
	Revision renderbatch.Revision
	Cycle    refreshstamp.CycleID
	Frame    display.Frame
}

type ScreenFailure

type ScreenFailure struct {
	Revision   renderbatch.Revision `json:"revision"`
	Diagnostic renderdiag.Error     `json:"diagnostic"`
}

type ScreenOptions

type ScreenOptions struct {
	Partial             *ScreenPartialOptions // Nil preserves full-only behavior; copied at construction.
	Zone                *time.Location
	MaintenanceInterval time.Duration // Zero selects 600 seconds; negative rejects.
	Now                 Clock         // Nil selects time.Now; the caller establishes clock trust.
}

ScreenOptions enables full-cycle stamps and maintenance. Now supplies trusted wall time only; scheduling uses elapsed monotonic time, never calendar time.

type ScreenPartialOptions

type ScreenPartialOptions struct {
	Rules          screendelivery.RegionRules
	MaxConsecutive uint16
}

ScreenPartialOptions is local adapter/operator policy, never document input. Physical support must be negotiated by the RegionSender before transmission.

type ScreenPump

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

ScreenPump is the sole live renderer/delivery owner for a Screen. It does not poll, spawn a worker per request, or interpret errors as permission to retry.

func NewScreenPump

func NewScreenPump(screen *Screen, sender ScreenSender, interval time.Duration) (*ScreenPump, error)

func NewScreenPumpWithPolicy

func NewScreenPumpWithPolicy(screen *Screen, sender ScreenSender, policy refreshpolicy.Policy) (*ScreenPump, error)

NewScreenPumpWithPolicy opts into the negotiated EPS2 extension. The legacy constructor preserves Pico's fixed cadence and rejects urgent HTTP requests.

func (*ScreenPump) ConfigurePartial

func (p *ScreenPump) ConfigurePartial(policy refreshpolicy.Policy) error

ConfigurePartial opts into mode-aware scheduling before Run. The caller must serialize configuration with startup. Geometry/count limits belong to Screen; the transport negotiates support and enforces the same cadence on the wire.

func (*ScreenPump) Run

func (p *ScreenPump) Run(ctx context.Context) (runErr error)

Run starts with a conservative cooldown because the last physical refresh is unknown after process restart. No partial lane bypasses that guard. Restart only after explicit transport resynchronization; this is not a retry loop.

type ScreenRefresh

type ScreenRefresh struct {
	Cycle     refreshstamp.CycleID `json:"cycle"`
	Started   time.Time            `json:"started"`
	Completed time.Time            `json:"completed"`
}

ScreenRefresh is historical matching-terminal-ACK evidence, not optical proof. RefreshTrusted becomes false after ambiguity, reset, or unusable completion time.

type ScreenRefreshFailure

type ScreenRefreshFailure struct {
	Revision renderbatch.Revision   `json:"revision"`
	Reason   RefreshRejectionReason `json:"reason"`
}

ScreenRefreshFailure contains only bounded metadata, never document contents.

type ScreenRenderer

type ScreenRenderer interface {
	Render(context.Context, display.Size, []byte) (display.Frame, error)
}

ScreenRenderer must return canonical packed 1bpp with independently owned storage, never modifying it after return. engine.Renderer satisfies this.

type ScreenSender

type ScreenSender = screendelivery.Sender

ScreenSender must return nil only for a matching terminal protocol success. Any other result is ambiguous: it must stop using the borrowed frame before returning. Implementations bound I/O and respect cancellation. No auto-retry.

type ScreenStatus

type ScreenStatus struct {
	Current        renderbatch.Revision  `json:"current"`
	InFlight       renderbatch.Revision  `json:"in_flight"`
	Confirmed      renderbatch.Revision  `json:"confirmed"`
	Delivered      renderbatch.Revision  `json:"delivered"`
	Failure        *ScreenFailure        `json:"failure,omitempty"`
	RefreshFailure *ScreenRefreshFailure `json:"refresh_failure,omitempty"`
	Warnings       []renderdiag.Warning  `json:"warnings,omitempty"`
	InFlightCycle  refreshstamp.CycleID  `json:"in_flight_cycle,omitempty"`
	FullRefresh    *ScreenRefresh        `json:"full_refresh,omitempty"`
	RefreshTrusted bool                  `json:"refresh_trusted"`
}

type Server

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

func NewServer

func NewServer(store *Store, registry Registry, token []byte, now Clock, ttl time.Duration) (*Server, error)

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(writer http.ResponseWriter, request *http.Request)

type StaticRegistry

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

func NewStaticRegistry

func NewStaticRegistry(records []DeviceRecord) (*StaticRegistry, error)

func (*StaticRegistry) Lookup

type Store

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

func NewPersistentStore

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

func NewStore

func NewStore() *Store

func (*Store) Complete

func (s *Store) Complete(id securetransport.DeviceID, generation uint64, result update.Result,
	now time.Time,
) error

func (*Store) Disconnect

func (s *Store) Disconnect(id securetransport.DeviceID, now time.Time)

func (*Store) Lease

func (s *Store) Lease(id securetransport.DeviceID, now time.Time) (Pending, uint64, error)

func (*Store) ReopenAccepted

func (s *Store) ReopenAccepted(id securetransport.DeviceID, now time.Time) error

ReopenAccepted makes an acknowledged update deliverable after a device reconnects without reporting any retained runtime state. That indicates a reboot before the physical refresh completed.

func (*Store) Status

func (s *Store) Status(id securetransport.DeviceID, now time.Time) DeviceStatus

func (*Store) Submit

func (s *Store) Submit(id securetransport.DeviceID, request update.Request, now time.Time,
	ttl time.Duration,
) (uint64, bool, error)

Jump to

Keyboard shortcuts

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