Files
papers/kai/sections/07-programs.tex

234 lines
13 KiB
TeX

\section{Programs and packages}
\label{sec:programs}
\begin{definition}[Decision Program]
A Decision Program is a named, versioned, immutable record of options,
objectives (a weight, direction and metric each), hard constraints (bounds on
metrics), assumptions (a value and declared range each), risks (likelihood and
severity), bias checks, evidence, and a DAG of typed nodes: a deterministic
expression, a Kai question, a Zen prompt, a solver, a human approval, or a
policy gate (Section~\ref{sec:authority}). A node reads assumptions, evidence
or other nodes' outputs, and writes JSON.
\end{definition}
A program is the only place a question's wording lives, and any change to
wording, options, a threshold, the model or the calibration is a new version,
because a threshold means something only for the probabilities it was validated
against. The executor runs nodes in dependency order with models, solvers and
people behind interfaces, scores each option as weighted min-max-normalised
metrics minus expected risk (likelihood times severity), and recommends the
best option meeting every constraint \shipped. Refining a program's Kai
questions inside the executor as the typed variables of
Section~\ref{sec:diffusion} is \proposed; today refinement runs beside it.
Table~\ref{tab:programs} lists an agent loop's programs: the Jev notes'
decision points~\cite{jevnote}, plus preflight, progress and completion. Other
shipped programs decide Enso's operations (Section~\ref{sec:enso}) and a
business's marketing, sales and commerce actions, each gated by a deterministic
contact policy (consent per jurisdiction, opt-outs, suppression lists,
frequency caps, quiet hours in local time, age, sensitive attributes) and
evaluated off-policy from outcome records before it acts \shipped. On a
synthetic shop whose best policy is worth 0.4305, inverse-propensity and doubly
robust estimates from 200{,}000 logged decisions give 0.4388 and 0.4404, and
both rank that policy above all 25 one-segment deviations \meas.
\begin{table}[h]
\centering
\small
\begin{tabular}{@{}p{0.25\linewidth}p{0.55\linewidth}l@{}}
\toprule
Program & Questions & Mode \\
\midrule
\op{agent.preflight@1} & task type; complexity (4); model tier; needs the
user; needs repository context; sensitivity (4); private model & advisory \\
\op{agent.command-risk@1} & verdict (\allow, \ask, \deny); secret exposure;
production impact; network & advisory \\
\op{agent.model-route@1} & tier; reasoning depth (4); long context; private
model & shadow \\
\op{agent.context@1} & scope (5); needs repository; needs web; needs memory
& shadow \\
\op{agent.tool-select@1} & next tool (7); steps can run in parallel & shadow \\
\op{agent.progress@1} & status (advancing, stalled, looping, blocked); needs
the user & advisory \\
\op{agent.complete@1} & done; verified rather than claimed; work remaining
(3) & advisory \\
\bottomrule
\end{tabular}
\caption{Agent-loop programs, as defined in \texttt{program/programs}
\shipped. Unmarked questions are \op{noul};
levels or options in parentheses. A deployment may run a program below its
mode, never above.}
\label{tab:programs}
\end{table}
\subsection{The Decision Package}
A run's record is a Decision Package: program and version; assumptions,
constraints and evidence references with content hashes; each node's
definition, backend revision, calibration and output, with every answer's full
distribution; human overrides beside what they override, with author and
reason; policy results; ranking, recommendation and sensitivity; approvals. Its
hash, SHA-256 over canonical JSON (sorted keys, shortest round-trip floats),
covers every field but the timing trace. Replay re-runs the program on the
recorded evidence, recomputing Kai and solver nodes under the recorded
revisions and taking Zen and human outputs, which are observations, from the
record; under the same revisions it reproduces the hash. A diff lists the
values that changed and the flip conditions the later package moved past. The
report is rendered only from computed results, so each number in it resolves
to a field \shipped; rejecting a Zen-written narrative that states a number no
field holds, as our assertion graph rejects an uncited
claim~\cite{hanzographpaper}, is \proposed.
\begin{proposition}[Exact reuse]
\label{prop:refresh}
Cache each node's output under the hash of its definition, inputs and backend
revision \shipped. If a key is unchanged and the backend deterministic, reuse yields the
package a full rerun would; a refresh after $c$ nodes' inputs change recomputes
those nodes and their descendants, and nothing else.
\end{proposition}
\begin{proof}
A node's output is a function of its definition, inputs and backend revision
(Section~\ref{sec:decisions}). An input's hash is the evidence's content, the
assumption's value, or the upstream node's output and revision, so a node whose
recomputed output is unchanged leaves its dependents' keys unchanged.
\end{proof}
\subsection{What flips the decision}
\label{sec:flip}
For each parameter, the others held, the package reports where the top option
changes \shipped. For a \emph{weight}, scaling all scores by the weight plus
the others' sum makes each a line, so the top option is an upper envelope of
lines and crossovers are exact; a \emph{risk}'s likelihood or severity enters
linearly, also exact; a \emph{constraint bound} changes the feasible set only
at the options' metric values. An \emph{assumption} is swept on a 32-interval
grid with each change bisected, which misses a flip and flip-back inside one
interval; downstream non-expression nodes are held at their recorded outputs
and listed as held. A sweep point that fails to evaluate is reported as an
error segment, never a failed run.
All weights at once have a closed form \proposed. For a challenger $b$ let
$\delta_b = U_{a^\star} - U_b \in \mathbb{R}^m$ be the difference of the two
options' normalised metrics, so $V(a^\star) - V(b) = w^{\top}\delta_b > 0$, and
$P = I - \tfrac{1}{m}\mathbf{1}\mathbf{1}^{\top}$.
\begin{proposition}[Smallest weight change]
\label{prop:weights}
The smallest $\Delta$ in Euclidean norm with $\mathbf{1}^{\top}\Delta = 0$ that
makes $b$ tie $a^\star$ is
\begin{equation}
\Delta^\star_b = -\frac{w^{\top}\delta_b}{\lVert P\delta_b\rVert^2}\,P\delta_b,
\qquad
\lVert \Delta^\star_b \rVert = \frac{w^{\top}\delta_b}{\lVert P\delta_b\rVert},
\end{equation}
provided $P\delta_b \ne 0$; if $w + \Delta^\star_b \ge 0$ it is the smallest
change within the simplex, otherwise a lower bound.
\end{proposition}
\begin{proof}
Minimise $\lVert\Delta\rVert^2$ subject to $\mathbf{1}^{\top}\Delta = 0$ and
$\delta_b^{\top}\Delta = -w^{\top}\delta_b$. On the range of $P$,
$\delta_b^{\top}\Delta = (P\delta_b)^{\top}\Delta$: the distance from the origin
to a hyperplane with normal $P\delta_b$. Adding $w + \Delta \ge 0$ can only raise
the minimum. If $P\delta_b = 0$, no weight change reorders $a^\star$ and $b$.
\end{proof}
$\rho_w = \min_b \lVert\Delta^\star_b\rVert$ is how far a stakeholder must
disagree with the weights to change the answer. Sampling each Kai cell from its
distribution estimates the probability that resolving the cells would change
the recommendation, as well as the cells are calibrated \proposed.
\subsection{Studies, SysML and the engineering graph}
\label{sec:studies}
A trade study is typed judgments over evidence aggregated into a
recommendation; kept as slides, it is redone a year later because no one can
say which conclusion rested on the number that moved. The U.S.\ Army's SBIR
topic ARM26BX06-NV012~\cite{armysbir} asks for studies that are
schema-defined, agent-assisted, auditable and refreshable. Here that is a
program, a package, a diff, a refresh, and what flips the decision. The
additive score assumes preferentially independent criteria~\cite{keeney1976}.
A SysML~v2~\cite{sysmlv2} model, in a subset of the textual notation or as
Systems Modeling API JSON, imports into one element model that keeps each
element's id, metaclass and owner; an element's id survives layout, comment and
value edits, and the pilot implementation's JSON export of a test model imports
to the same model and graph as its text \shipped. An engineering knowledge
graph built from it holds typed entities and relations, each with provenance
and a validity interval, and answers neighbours, shortest paths, BM25
retrieval, the evidence behind a decision, the graph as of a time, and the diff
between two revisions \shipped. Tags drive it: a vendor, risk, evidence,
decision or assumption tag, or a class of the ground-vehicle ontology, sets an
element's kind, a tagged dependency is an edge, and a validity annotation
bounds a node or edge.
\paragraph{The JLTV powertrain trade.}
A SysML~v2 model of a light tactical vehicle's powertrain trade, the fielded
diesel JLTV against the diesel-electric eJLTV, cites a public source on the
line of every figure: Wikipedia's JLTV and Humvee-replacement articles,
Oshkosh Defense's product page and hybrid announcement, reporting by Breaking
Defense, Defense News and Janes, and the Congressional Research Service's
reports RS22942 and IF11729. The trade program over it has five equally
weighted objectives (fuel economy, added mass, field capability, record,
maturity), an airlift constraint, an assumption for the share of the hybrid's
company-reported fuel gain that holds on the Army's duty cycle, an anchoring
bias check, a Zen brief and a program manager's approval. Its example run, with
fixed example probabilities in place of Kai's since no trained Kai is claimed,
ranks the diesel first (0.6 to 0.4); the package reports that raising fuel
economy's or field capability's weight from 0.2 to 0.4 makes the hybrid first,
both exact, and records the approval held because the fuel figure is a company
figure \shipped. It is a demonstration of the mechanism, not an acquisition
result. Read through Hanzo's bitemporal assertion graph~\cite{hanzographpaper},
a package would replay as known on the day it was decided, separating what
changed in the world from what changed in the record \proposed.
\subsection{Kai controls Enso}
\label{sec:enso}
Enso is Hanzo's adaptive model family, served by the Zen engine. Kai is its
controller, in process: seven programs, each with a mode and thresholds kept
as data in Enso's catalog, decide the model tier, the reasoning budget, which
context chunks and which tools the next call sees, whether the task is
advancing, whether it is done or needs escalation, and an action's risk. A call
runs one program over many states, every question of every state in one batch,
and a host acts only on a row whose mode is enforced and whose answer is
accepted; a calibration other than the program's pin runs the gate in shadow
\shipped. The \texttt{control} crate exposes this as a C library
(\op{kai\_open}, \op{kai\_decide}, \op{kai\_error}, \op{kai\_free},
\op{kai\_close}) that Zen's server loads at run time; without it, Enso serves
as before \shipped.
The evaluation is designed and not run \proposed. Its thesis is that Kai does
not make Zen generate faster but makes it generate less. Per task the cost is
$C = C_{\mathrm{Kai}} + C_{\mathrm{prefill}} + C_{\mathrm{decode}} +
C_{\mathrm{retrieval}} + C_{\mathrm{tools}}$, and Kai spends
$C_{\mathrm{Kai}}$, one encoder pass per decision, to shrink the rest with a
smaller model, fewer prompt and decode tokens and fewer steps. Conditions add
one decision at a time: B0 the largest Zen model for every step, B1 a static
router, R1 Zen as its own router, K1 Kai routing the model, K2 plus context
pruning, K3 plus a tool and skill shortlist, K4 plus progress and early stop,
K5 the full plane. Every metric is per successful task, so no condition looks
cheap by failing: success rate, GPU-seconds, prompt and decode tokens, KV-cache
GB-seconds, peak VRAM, latency and dollars, with routing regret against the
cheapest model that succeeds. Synthetic tasks with a known cheapest model,
public agent benchmarks and replayed Hanzo traces are reported apart. Kai
enters Enso in shadow, recording its pick beside what Enso did, and each
operation is promoted on its own shadow record (Proposition~\ref{prop:friction}).
\subsection{The wire and where it runs}
\op{POST /v1/decisions} speaks OpenRouter's Decisions
API~\cite{openrouterdecisions} field for field (Appendix~\ref{app:wire}). The
\op{model} field selects the backend: Kai and Laya run in process;
\op{typesafe/jev-1.13} is forwarded to OpenRouter only when the server was
started with it, each answer checked for its type and each choice restored to
the caller's order. Hanzo adds \op{answer\_confidence} and \op{routing}, which
records the checkpoint, revision, weights' SHA-256, calibration, device and the
reason for the route \shipped; a program form, a request naming \op{program}
and \op{state} and returning verdict and mode, is \proposed. The service is one Rust binary with no
network dependency and no Python: its image bakes a pinned checkpoint and loads
it with outbound network denied, so it serves a workstation, a cluster or a
disconnected site, where a server started without Jev has no OpenRouter client
at all \shipped. Runnable examples, each a program, its evidence, a request and
the run it must produce, cover the agent loop, support, sales, commerce,
vehicle readiness, the JLTV trade and a sensor anomaly, and every one is run and
replayed under a fake Kai in the test suite \shipped.