Documentation
¶
Overview ¶
Package imzero2env centralises the IMZERO2_* environment variables consumed across the imzero2 demo carousel, tours, and embedded applications. Each spec is registered with the boxer-wide registry (ADR-0058).
Index ¶
Constants ¶
const ( RenderCadenceContinuous = "continuous" RenderCadenceReactive = "reactive" )
Render cadence values for RenderCadence.
const ( HeadlessCodecH264 = "h264" HeadlessCodecVP9 = "vp9" HeadlessCodecAV1 = "av1" HeadlessCodecAV1444 = "av1-444" // AV1 High profile, 4:4:4 chroma HeadlessCodecMesh = "mesh" // ADR-0128 draw-stream lane (no encoder; viewer paints via WebGL2) )
Startup video codec values for HeadlessCodec (ADR-0088). A cross-language contract: the Rust client's VideoCodec::parse (codeclane.rs) accepts these canonical spellings when reading IMZERO2_HEADLESS_CODEC.
Variables ¶
var ( // ScreenshotDir is the destination for per-window PNG captures // produced by the demo tour infrastructure. Empty means // "screenshot capture disabled". ScreenshotDir = env.NewPath(env.Spec{ Name: "IMZERO2_SCREENSHOT_DIR", Description: "destination directory for per-window PNG captures; empty disables capture", Category: env.CategoryDev, }) // ScreenshotDeterministic gates whether demos / tours with // non-deterministic content (time-of-day, live sysmetrics, randomised // initial state, etc.) participate in a screenshot capture run. Empty // = "include everything" (default — reviewers still see them). // Non-empty = "skip" — the widgets TestDriver omits demos tagged // with registry.DemoFlagNonDeterministic, and standalone tour // drivers (imztop, regex_explorer) return early so their PNGs aren't // produced. Used for byte-stable captures suitable for CI gating or // review diffs. ScreenshotDeterministic = env.NewString(env.Spec{ Name: "IMZERO2_SCREENSHOT_DETERMINISTIC", Description: "non-empty: skip non-deterministic demos / tours so captures are byte-stable across runs", Category: env.CategoryDev, }) // AllowNetwork gates the demo widgets that fetch external // resources (tiles, HTTP APIs). The legacy contract is "any // non-empty value other than \"1\" is treated as off". AllowNetwork = env.NewString(env.Spec{ Name: "IMZERO2_ALLOW_NETWORK", Description: "set to \"1\" to allow demo widgets to fetch external resources", Category: env.CategoryDev, }) // DebugMode selects an imzero2 launch profile: "memcheck", // "massif", "flamegraph", or "heaptrack". Empty means the default // launch path. DebugMode = env.NewString(env.Spec{ Name: "BOXER_IMZERO_DEBUG_MODE", Description: "imzero2 debug profile: memcheck|massif|flamegraph|heaptrack; empty uses the default launcher", Category: env.CategoryDev, }) // Density is the IDS density preset (tight | standard | roomy). // Case-insensitive; anything else is treated as "standard". Density = env.NewString(env.Spec{ Name: "IMZERO2_DENSITY", Description: "IDS density preset (tight|standard|roomy); empty defaults to standard", Category: env.CategoryDev, }) // ScreenshotSize is the canonical capture size override for tours. // Parsed as "WxH" (e.g. "1600x900"). When set, the widgets // TestDriver uses these dimensions as the stage rect for every // demo (overriding per-demo Demo.Stage values); standalone tours // (imztop, regex_explorer) switch from full-viewport capture to // rect-based capture at the same size. The launch wrapper // (src/rust/hmi.sh) widens the eframe viewport to fit so the // captured rect does not silently clip. ADR-0057 SD5. ScreenshotSize = env.NewString(env.Spec{ Name: "IMZERO2_SCREENSHOT_SIZE", Description: "tour capture size as WxH (e.g. 1600x900); empty uses per-demo defaults", Category: env.CategoryDev, }) // RenderCadence selects how the imzero2 frame loop schedules repaints // when the UI is idle (no input or animation): // - "continuous" (default): request a repaint every pass, so the client // paints at vsync rate. Most responsive; an occluded window is still // throttled to the compositor's frame-callback rate for free, so this // no longer floods the slow-frame log (that gate keys on real work, // not wall-clock — see metrics.shouldWarnSlowFrame). // - "reactive": after a short warmup, request only a slow idle heartbeat; // egui still repaints immediately for input and animation, so // interaction stays at vsync rate while a visible-but-idle window drops // to a few fps, saving CPU/GPU. // Read by both the Go decorator (carousel.decorateRenderer) and the Rust // client (src/imzero2/app.rs), which inherits the variable as a child // process. RenderCadence = env.NewCategorialString(env.Spec{ Name: "IMZERO2_RENDER_CADENCE", Description: "frame-loop repaint cadence when idle: continuous (vsync rate) | reactive (idle heartbeat)", Category: env.CategoryDev, Default: RenderCadenceContinuous, }, []string{RenderCadenceContinuous, RenderCadenceReactive}) // HeadlessListen is the carrier bind address (host:port); this port // and port+1 each serve the viewer page and accept the WebSocket // upgrade. Empty disables remote access. HeadlessListen = env.NewString(env.Spec{ Name: "IMZERO2_HEADLESS_LISTEN", Description: "headless carrier bind address host:port (port and port+1 both serve page + WebSocket); empty disables remote access", Category: env.CategoryDev, }) // HeadlessIgnoreClose, when truthy, makes a viewport-close request (an // app-emitted ViewportCommand::Close, e.g. a "Quit" menu item) a no-op // instead of a host shutdown — so one viewer of a served deployment cannot // terminate the shared host (ADR-0085). The genuine shutdown path (the Go // control closing the FFFI2 pipe) is unaffected. Read by the Rust client // (headless.rs); the carousel also reads HeadlessListen to drop the Quit // affordance entirely in served mode. Registered here for the env catalog. HeadlessIgnoreClose = env.NewBool(env.Spec{ Name: "IMZERO2_HEADLESS_IGNORE_CLOSE", Description: "truthy makes a UI viewport-close (e.g. a File→Quit item) a no-op instead of a host shutdown; set for a long-lived served deployment so one viewer can't take the host down for everyone", Category: env.CategoryDev, }) // HeadlessMaxConnections bounds how many viewers may be connected to the // carrier at once (ADR-0086 SD2 active/passive roster): one is active // (drives input), the rest passive (read-only), and a surplus connection // past this bound is refused. Read by the Rust client (wscarrier.rs). HeadlessMaxConnections = env.NewInt(env.Spec{ Name: "IMZERO2_HEADLESS_MAX_CONNECTIONS", Description: "max simultaneous viewers on the carrier (ADR-0086 active/passive roster): 1 active + the rest passive; a surplus connection is refused", Category: env.CategoryDev, Default: "8", }) // HeadlessFps is the headless render tick in Hz (Rust clamps to // 1–240). Paces the FFFI2 loop in place of vsync. HeadlessFps = env.NewFloat(env.Spec{ Name: "IMZERO2_HEADLESS_FPS", Description: "headless render tick in Hz, 1-240; Rust clamps to that range", Category: env.CategoryDev, Default: "60", }) // HeadlessPixelsPerPoint is the initial HiDPI scale of the offscreen // target (Rust clamps to 0.25–4.0); a connected viewer's reported // devicePixelRatio then takes over. HeadlessPixelsPerPoint = env.NewFloat(env.Spec{ Name: "IMZERO2_HEADLESS_PIXELS_PER_POINT", Description: "initial offscreen HiDPI scale, 0.25-4.0; a connected viewer's devicePixelRatio takes over", Category: env.CategoryDev, Default: "1.0", }) // HeadlessEncoderArgs overrides the ffmpeg encode arguments between // the rawvideo input and the -f h264 output. Empty uses the VAAPI // default (h264_vaapi -bf 0 -qp:v 26 -g 100000); the documented // software fallback is "-c:v libopenh264 -rc_mode off -bf 0 -g 100000". HeadlessEncoderArgs = env.NewString(env.Spec{ Name: "IMZERO2_HEADLESS_ENCODER_ARGS", Description: "override ffmpeg encode args between rawvideo input and -f h264 output; empty uses the VAAPI default", Category: env.CategoryDev, }) // FfmpegBin pins the ffmpeg binary the Rust client spawns for both the // SD5 lane probe and the stream encoder (codeclane.rs, encoderpipe.rs), // replacing the bare PATH lookup. Set it when the host must use one // specific build — an airgapped target pointing at a bundled static // ffmpeg — without shadowing the system ffmpeg for other tools. Empty // keeps the PATH lookup. Read by the Rust client, not by Go. FfmpegBin = env.NewPath(env.Spec{ Name: "IMZERO2_FFMPEG_BIN", Description: "explicit path to the ffmpeg binary the headless encoder and lane probe spawn; empty uses the PATH lookup", Category: env.CategoryDev, }) // HeadlessCodec picks the startup video codec lane (ADR-0088 SD4): the host // muxes through NUT and the viewer decodes via WebCodecs. h264 (default) // also honours IMZERO2_HEADLESS_ENCODER_ARGS; vp9/av1 use the built-in // lanes. The active codec is then runtime-switchable from the Go "video // output" control. Read by the Rust client (codeclane.rs), not by Go. HeadlessCodec = env.NewCategorialString(env.Spec{ Name: "IMZERO2_HEADLESS_CODEC", Description: "startup stream lane: h264 (default; honours ENCODER_ARGS) | vp9 | av1 | av1-444 (AV1 4:4:4) | mesh (ADR-0128 draw-stream, WebGL2 viewer); runtime-switchable from the Go control", Category: env.CategoryDev, Default: HeadlessCodecH264, }, []string{HeadlessCodecH264, HeadlessCodecVP9, HeadlessCodecAV1, HeadlessCodecAV1444, HeadlessCodecMesh}) // HeadlessMaxFrames stops the host after N rendered frames (0 = // unbounded). A smoke-test hook. HeadlessMaxFrames = env.NewInt(env.Spec{ Name: "IMZERO2_HEADLESS_MAX_FRAMES", Description: "stop after N rendered frames (0 = unbounded); smoke-test hook", Category: env.CategoryDev, Default: "0", }) // HeadlessDumpDir, when set, dumps rendered frames as PNG into the // directory for verification. Empty disables. HeadlessDumpDir = env.NewPath(env.Spec{ Name: "IMZERO2_HEADLESS_DUMP_DIR", Description: "directory for per-frame PNG dumps (verification); empty disables", Category: env.CategoryDev, }) // HeadlessDumpEvery dumps every Nth frame when IMZERO2_HEADLESS_DUMP_DIR // is set. HeadlessDumpEvery = env.NewInt(env.Spec{ Name: "IMZERO2_HEADLESS_DUMP_EVERY", Description: "with IMZERO2_HEADLESS_DUMP_DIR, dump every Nth frame", Category: env.CategoryDev, Default: "60", }) // HeadlessH264Out appends the raw Annex-B H.264 elementary stream to // this file for verification. Empty disables. HeadlessH264Out = env.NewPath(env.Spec{ Name: "IMZERO2_HEADLESS_H264_OUT", Description: "append the raw Annex-B H.264 stream to this file (verification); empty disables", Category: env.CategoryDev, }) // HeadlessSelect, in a dual-feature (desktop + headless) build, picks // the headless host at runtime when set to "1" or "on"; ignored in // single-host builds (the compiled feature decides). HeadlessSelect = env.NewString(env.Spec{ Name: "IMZERO2_HEADLESS", Description: "dual-feature builds only: 1 or on selects the headless host at runtime; ignored in single-host builds", Category: env.CategoryDev, }) DeployRoot = env.NewPath(env.Spec{ Name: "IMZERO2_DEPLOY_ROOT", Description: "on-box deploy root (ADR-0085); workspace/releases/current derive from it unless overridden", Category: env.CategorySystem, Default: "/opt/imzero2", CliFlagName: "root", }) DeployWorkspace = env.NewPath(env.Spec{ Name: "IMZERO2_DEPLOY_WORKSPACE", Description: "persistent git clone + build caches; empty derives <root>/workspace", Category: env.CategorySystem, CliFlagName: "workspace", }) DeployReleasesDir = env.NewPath(env.Spec{ Name: "IMZERO2_DEPLOY_RELEASES_DIR", Description: "immutable release snapshots releases/<tag>/; empty derives <root>/releases", Category: env.CategorySystem, CliFlagName: "releases-dir", }) DeployCurrent = env.NewPath(env.Spec{ Name: "IMZERO2_DEPLOY_CURRENT", Description: "the `current` symlink the demo unit runs through; empty derives <root>/current", Category: env.CategorySystem, CliFlagName: "current", }) DeployRemote = env.NewString(env.Spec{ Name: "IMZERO2_DEPLOY_REMOTE", Description: "git remote name in the workspace clone (read-only)", Category: env.CategorySystem, Default: "origin", CliFlagName: "remote", }) DeployService = env.NewString(env.Spec{ Name: "IMZERO2_DEPLOY_SERVICE", Description: "systemd unit restarted on an atomic swap", Category: env.CategorySystem, Default: "imzero2-demo.service", CliFlagName: "service", }) DeployScratchPort = env.NewInt(env.Spec{ Name: "IMZERO2_DEPLOY_SCRATCH_PORT", Description: "loopback port the pre-swap gate binds the candidate carrier on", Category: env.CategorySystem, Default: "18089", CliFlagName: "scratch-port", }) DeployLivePort = env.NewInt(env.Spec{ Name: "IMZERO2_DEPLOY_LIVE_PORT", Description: "the demo service's listen port (post-restart health-probe target)", Category: env.CategorySystem, Default: "8089", CliFlagName: "live-port", }) DeployGateAUs = env.NewInt(env.Spec{ Name: "IMZERO2_DEPLOY_GATE_AUS", Description: "access units ws_probe must decode for the gate and post-restart health check to pass", Category: env.CategorySystem, Default: "30", CliFlagName: "gate-aus", }) DeployGateTimeout = env.NewDuration(env.Spec{ Name: "IMZERO2_DEPLOY_GATE_TIMEOUT", Description: "overall budget for the gate and the post-restart health probe", Category: env.CategorySystem, Default: "120s", CliFlagName: "gate-timeout", }) DeployKeep = env.NewInt(env.Spec{ Name: "IMZERO2_DEPLOY_KEEP", Description: "release dirs to retain for rollback history", Category: env.CategorySystem, Default: "5", CliFlagName: "keep", }) DeployRequireSignedTags = env.NewBool(env.Spec{ Name: "IMZERO2_DEPLOY_REQUIRE_SIGNED_TAGS", Description: "verify a tag's GPG/SSH signature (git verify-tag) before building; disable only on a trusted/loopback box", Category: env.CategorySystem, Default: "true", CliFlagName: "require-signed-tags", }) )
var PackageProps = packageprops.Props{ WASMWASI: packageprops.WASMCompiles, WASMJS: packageprops.WASMCompiles, WASMFreestanding: packageprops.WASMCompiles, }
PackageProps records this package's curated properties (ADR-0080). Seeded by `wasmsurvey props generate`; curate by hand, then `wasmsurvey props verify`.
Functions ¶
func ScreenshotSizeWH ¶
ScreenshotSizeWH parses ScreenshotSize as "WxH". Returns (0,0,false) when the env var is unset, empty, or malformed; ok=true implies both dimensions are strictly positive. The 'x' separator is case-insensitive ("1600x900" and "1600X900" both parse).
Types ¶
This section is empty.