flags

package
v1.801.79 Latest Latest
Warning

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

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

Documentation

Overview

Package flags is cloud's NATIVE feature-flag engine: definitions live in per-(org, project) SQLite (cloud.OrgDB — {DataDir}/orgs/{org}/projects/{project}/ flags.db, encrypted at rest via cek) and evaluation runs in-process through the embedded hanzo-flags Rust evaluator (native/flags, FFI) with PostHog-compatible semantics: rollout hash, full property-operator set, variants, payloads. Stateless and scalable by construction — no KV, no network hop, every pod evaluates from its own hot in-memory copy of the definitions.

TWO surfaces, ONE engine:

  • /v1/flags — the product API (org-scoped via the gateway principal): evaluate flags for a distinct_id + properties, manage definitions, read the activity log. PostHog-shaped responses so existing SDK consumers port 1:1.

  • the PLATFORM switches — the launch/ops knobs the SuperAdmin flips from admin.hanzo.ai (registry below). They evaluate from the reserved platform/platform store through the same engine. A switch with no stored definition falls back env -> literal default — exactly the pre-engine behavior, zero regression; the first cockpit write creates the definition and takes effect within one cache TTL (default 15s), no redeploy.

FAIL-SAFE. When the native engine is absent (!cgo) or a store read fails, evaluation degrades to env fallback -> literal default and the HTTP surface says so honestly — never fail-wrong.

── THE POLICY PRIMITIVE ─────────────────────────────────────────────────────────

This engine IS Hanzo's runtime decision primitive: (Principal, context) -> verdict, evaluated in-process, stateless, hot. It knows ONLY flags — definitions, evaluation, and the platform-switch registry. It has ZERO knowledge of any specific policy that rides on it: no host→service map, no waitlist, no service registry. Those COMPOSE this engine from the OUTSIDE, one-way (they import flags; flags imports none of them):

  • the launch waitlist gate (clients/admission) — a service's mode IS the switch waitlist.<svc>; admission owns the host→service registry + Enforce and reads the mode through flags.Bool. It USED to live in this package; extracting it is the PROOF the engine composes its tenants rather than absorbing them.
  • authz (access policy) — (Principal, resource+action) -> allow/deny
  • entitlements (product-access policy) — (Principal, feature/plan) -> granted/denied

Every one is (Principal, context) -> verdict. Folding them onto this evaluator makes Policy ONE composable primitive with one audit log and one hot-apply path. authz and entitlements are NOT built on it yet — this note only names the target so the seam stays visible; the launch waitlist (now external) is the first, proven composition.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Bool

func Bool(key string) bool

Bool returns the live boolean value of a registered switch (flags -> env -> default).

func Int

func Int(key string) int

Int returns the live integer value of a registered switch.

func Mount

func Mount(app *zip.App, deps cloud.Deps) error

Mount opens the per-org definition stores, installs the process-wide evaluation seam, and registers the /v1/flags surface. The native engine being absent (!cgo) degrades every switch to env/default and the HTTP surface reports it — never an error at boot.

func Register

func Register(d Def)

Register adds a switch to the platform-flag registry. Any subsystem may call it (in its init) to surface its own flag in the cockpit — the registry is open, not hardcoded. A duplicate key REPLACES the prior def (last registration wins).

func SetPlatformSwitch

func SetPlatformSwitch(key string, definition json.RawMessage, actor string) error

SetPlatformSwitch stores/overwrites a platform switch's definition (the admin cockpit's ONE write path) and applies it immediately in this pod.

func Shutdown

func Shutdown(_ context.Context) error

Shutdown closes every open per-org definitions store.

func String

func String(key string) string

String returns the live string value of a registered switch.

Types

type ActivityRow

type ActivityRow struct {
	ID     int64  `json:"id"`
	Key    string `json:"key"`
	Action string `json:"action"`
	Actor  string `json:"actor"`
	At     string `json:"at"`
	Detail string `json:"detail,omitempty"`
}

type BoardView

type BoardView struct {
	Engine     string       `json:"engine"`
	Configured bool         `json:"configured"`
	ManageURL  string       `json:"manageUrl"`
	AuditURL   string       `json:"auditUrl"`
	Switches   []SwitchView `json:"switches"`
}

BoardView is the full control-plane read board: the engine status plus every switch's live value. Definitions are edited in place over /v1/flags (the cockpit writes through SetPlatformSwitch); the activity log is the native change audit.

func Board

func Board() BoardView

Board evaluates every registered switch live and returns the cockpit read board.

type Client

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

Client is the in-process evaluation seam: per-(org, project) SQLite definition stores + the embedded native evaluator, with the platform project's evaluation cached for one TTL (the hot-apply bound).

type Def

type Def struct {
	Key      string // the flag key (snake_case)
	Category string // Launch | Signup | Subsystems | Gateway | Network
	Label    string
	Desc     string
	Type     Type
	Env      string // env var supplying the fallback default (may be "")
	Default  string // literal fallback when neither the store nor env has a value
	ReadOnly bool   // surfaced read-only (boot-time activation, network ids)
}

Def is ONE platform switch: a flag key qualified by the metadata the cockpit shows and the env var that provides the fallback default. This table is the ONE place the platform switches are named; the embedded engine evaluates them.

func Defs

func Defs() []Def

Defs returns a snapshot of the registered switches in registration order.

type DefRow

type DefRow struct {
	Key        string          `json:"key"`
	Definition json.RawMessage `json:"definition"`
	Version    int             `json:"version"`
	UpdatedAt  string          `json:"updated_at"`
	UpdatedBy  string          `json:"updated_by"`
}

type Store

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

func (*Store) Activity

func (s *Store) Activity(limit int) ([]ActivityRow, error)

func (*Store) Close

func (s *Store) Close() error

func (*Store) DefsJSON

func (s *Store) DefsJSON() ([]byte, int, error)

DefsJSON assembles every definition into the JSON array the evaluator takes. The stored definition's "key" wins; a row whose JSON is corrupt is skipped rather than poisoning the whole project.

func (*Store) Delete

func (s *Store) Delete(key, actor string) (bool, error)

func (*Store) Get

func (s *Store) Get(key string) (DefRow, bool, error)

func (*Store) List

func (s *Store) List() ([]DefRow, error)

func (*Store) Upsert

func (s *Store) Upsert(key string, definition json.RawMessage, actor string) error

Upsert stores a definition under key (the definition's own "key" field is forced to match) and logs the change.

type SwitchView

type SwitchView struct {
	Key         string `json:"key"`
	Category    string `json:"category"`
	Label       string `json:"label"`
	Description string `json:"description"`
	Type        string `json:"type"`
	Value       string `json:"value"`
	Source      string `json:"source"`
	Env         string `json:"env,omitempty"`
	ReadOnly    bool   `json:"readOnly"`
}

SwitchView is one platform switch as the admin cockpit renders it: the live value + where it came from (flags | env | default).

type Type

type Type string

Type is the switch kind the cockpit renders (and how the value is decoded).

const (
	TypeBool   Type = "bool"
	TypeInt    Type = "int"
	TypeString Type = "string"
)

Jump to

Keyboard shortcuts

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