sentinel

package
v0.0.0-...-2769864 Latest Latest
Warning

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

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

Documentation

Overview

Package sentinel is the single source of truth for how a memory sentinel error crosses the HTTP wire, in both directions: httpsrv reads Table to pick the response status and stamp Header; httpclient reads it to rebuild the sentinel from Header. Neither holds a switch of its own to fall out of date.

Both halves are load-bearing. The status decides retry behaviour — httpclient retries 5xx eight times over a ~17s backoff budget and treats 4xx as permanent. The reconstruction decides whether errors.Is still matches once a call crosses a process boundary: the runner's memory IS an httpclient, so a sentinel with no row arrives as an opaque status error and every errors.Is test against it on the live path silently answers false.

Adding a sentinel

Add a row here. The drift test (sentinel_test.go) fails if a memory sentinel exists with no row and no explicit "not on the wire" entry, so the decision cannot be made by omission.

Index

Constants

View Source
const Header = "X-Memory-Sentinel"

Header carries the machine-readable discriminator naming which sentinel a response represents.

The status alone cannot identify one: 403 is answered by TWO sentinels (ErrMissingApproval, ErrKGScopeMismatch) and also by refusals that are no sentinel at all — handleKG's approval door, the read-only-token gate, a cross-session token, any intermediary proxy. Inferring a sentinel from "403" would hand the caller a forged authorization verdict; 400 and 404 are ambiguous the same way (a body-decode failure, an unroutable path).

A header rather than a JSON error envelope keeps the plain-text bodies httpsrv writes (http.Error) intact for the callers and operators that read them as text. A server too old to send the header simply produces no reconstruction — the fail-toward-unknown direction a mixed-version cluster needs.

Variables

View Source
var Table = []Mapping{
	{

		Err:    memory.ErrInvalidQuery,
		Status: http.StatusBadRequest,
		Code:   "invalid_query",
	},
	{

		Err:    memory.ErrMissingApproval,
		Status: http.StatusForbidden,
		Code:   "missing_approval",
	},
	{

		Err:    memory.ErrKGScopeMismatch,
		Status: http.StatusForbidden,
		Code:   "kg_scope_mismatch",
	},
	{

		Err:    memory.ErrNoSearchProviders,
		Status: http.StatusNotFound,
		Code:   "no_search_providers",
	},
	{

		Err:    memory.ErrKGUnsupported,
		Status: http.StatusNotFound,
		Code:   "kg_unsupported",
	},
	{

		Err:    memory.ErrKindNotSessionWritable,
		Status: http.StatusForbidden,
		Code:   "kind_not_session_writable",
	},
	{

		Err:    memory.ErrKindNotSessionReadable,
		Status: http.StatusForbidden,
		Code:   "kind_not_session_readable",
	},
}

Table is the mapping, in match order. Order is only consulted for an error that wraps two sentinels, which no construction in this repo produces.

Functions

func ForCode

func ForCode(code string) (error, bool)

ForCode returns the sentinel a wire code names — the CLIENT direction.

Lookup is by code alone, never by status, and an unknown or empty code yields ok=false. Only httpsrv sets Header, so a 403 from an intermediary or from one of the server's non-sentinel refusals stays out of the sentinel space.

func StatusAndCode

func StatusAndCode(err error) (status int, code string, ok bool)

StatusAndCode reports the wire status and discriminator for err — the SERVER direction. ok is false for anything that is not a sentinel, which the caller must treat as a fault (5xx) so the client's backoff can ride it out.

Types

type Mapping

type Mapping struct {
	// Err is the sentinel itself. Both directions test with errors.Is, so a
	// wrapped sentinel matches and keeps its wrapper's message.
	Err error
	// Status is the HTTP status httpsrv answers Err with. Every one is 4xx:
	// these are permanent verdicts (a caller bug, a policy refusal, a
	// deployment fact), and no retry can produce a better answer. That is the
	// same property that makes their text worth guaranteeing delivery of.
	Status int
	// Code is Header's value — a stable, machine-readable name. It is wire
	// format: never rename one, only add.
	Code string
}

Mapping is one sentinel's complete wire contract.

Jump to

Keyboard shortcuts

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