Gates

The gate is the universal logic construct. Signal passes or doesn't. Not a branch in a road — a valve in a pipe. Everything that was if/else in the old world is a gate in Z+.

Basic Gate

Gates filter by threshold, range, match, or negation. The signal either passes through or it doesn't.

.zpbasic gates
// threshold
signal -> gate(> 80C) -> alarm

// range
signal -> gate(0.6 ~ 0.9) -> tier_general

// match by property
signal -> gate(type: error) -> errors

// negation
signal -> gate(not: "*.tmp", ".git/*") -> clean

// multi-match
signal -> gate(command: any("set", "del")) -> writes

Knee (Smooth Transition)

Every gate can have a knee. The knee creates a smooth transition zone instead of a hard cutoff. A gate with a knee doesn't output boolean — it outputs a value between 0.0 and 1.0 based on where the signal sits in the transition zone.

This comes from audio engineering. A compressor's knee is the smooth curve between uncompressed and compressed signal. Hard cutoffs create artifacts. Smooth transitions preserve the signal.

.zpknee
// hard gate: off at 71F, on at 72F (oscillates)
temp -> gate(< 72F) -> heater

// knee gate: fades smoothly from 69F to 72F (no oscillation)
temp -> gate(< 72F, knee: 3F) -> heater

Knee Shapes

.zpknee shapes
// linear ramp (default)
gate(< 72F, knee: 3F)

// S-curve
gate(< 72F, knee: 3F, curve: soft)

// asymmetric — enters slowly, exits fast
gate(< 72F, knee_in: 3F, knee_out: 1F)

The knee is how Z+ does proportional control. Every piece of control logic that has ever been written with hysteresis bands, PID tuning, exponential smoothing, or moving averages was working around the fact that if/else is a cliff. The knee makes the cliff a slope. At the language level.

Temporal Gates

sustained

The signal must hold above threshold for a given duration before the gate passes. Ignores momentary spikes.

.zpsustained
// won't fire on a momentary spike — must be sustained
errors -> rate(per: 1m) -> gate(> 10, sustained: 5m) -> alarm

on_silence

Fires when nothing arrives for a specified duration. Silence is information. Quiet is different from gone. Gone is different from dead.

.zpon_silence
// graded silence
sensor -> on_silence(> 100ms) -> failover
sensor -> on_silence(> 5s) -> decommission

on_block

Fires when a gate rejects a signal. What happens to the signal that didn't pass.

.zpon_block
// rate limiter — respond 429 when blocked
rate_limit -> on_block -> respond(429)

Composite Gates

Advanced gate patterns for complex signal evaluation.

.zpcomposite gates
// outside range — inverse of range gate
ph -> gate(outside: 6.5 ~ 8.5) -> alarm

// crossing — fires once on transition, not continuously
temp -> gate(crossing: 80C) -> event

// rising / falling — directional change
grade -> gate(rising, > 0.3) -> recovery
grade -> gate(falling, > 10%, sustained: 30d) -> degradation

The crossing gate is particularly useful — it fires at the moment a signal crosses a threshold, not continuously while the signal is above it. One event per transition.

Gate as Proportional Control

PID control is three Z+ constructs combined. The knee provides proportional response (P). Delta provides rate-of-change dampening (D). Baseline deviation provides accumulated error correction (I).

.zpPID in Z+
// P = knee (proportional response)
temp -> gate(< 72F, knee: 3F) -> heater

// D = delta (rate of change dampening)
delta(temp) -> gate(> 2F) -> reduce_output

// I = baseline deviation (accumulated error)
temp -> deviation(from: setpoint) -> integrate -> trim