Files
papers/morpheus/onepagers/lp-316-routed-disclosure.tex
zeekayandHanzo Dev cf44d44756 morpheus: the ADOPT series, omnibus, rubric, LOI and one-pagers
ADOPT-00 through ADOPT-10, the 18-page omnibus, the decentralization rubric,
the whitepaper and the LOI — every paper written for the Morpheus engagement,
with the shared cover and proposal styles, versioned here beside the LP series.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-03 21:12:23 -07:00

86 lines
4.5 KiB
TeX

\documentclass[10pt,a4paper]{article}
\usepackage{../shared/proposal}
\usepackage[utf8]{inputenc}\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb}\usepackage{listings}\usepackage{xcolor}
\input{../shared/lstlang}
\begin{document}
\sloppy
\proposalhead{Declaring a Router}{A \texttt{modelId} is a promise that a name denotes a model. A
router can keep it only by committing, before the request, to the set it may serve from.}{LP-316}
\section*{The problem}
\texttt{Bid} carries \texttt{provider}, \texttt{modelId}, \texttt{pricePerSecond} and three
bookkeeping fields (\texttt{IBidStorage.sol}:14--21); none says what serves. A backend is a line of
local JSON (\texttt{ai\_engine.go}:58--64), and the requested model name is overwritten with the
provider's configured one inside the adapter (\texttt{openai.go}:58).
\texttt{providers/resale/overview.mdx} already tells a resale provider to bid on somebody else's
model without the \texttt{tee} tag, since ``you do not control the backend'': candid, but not a
protocol. Publishing the pool deletes routers, since pool and policy \emph{are} the product;
publishing nothing keeps the adverse selection of LP-315.
\section*{Commit to an admissible set}
A provider registers a commitment $C = (\textit{root}, \textit{floor}, \textit{class}, k)$ against
its bid.
\begin{itemize}
\item \textbf{root}: a Merkle root over salted leaves $H(\textit{manifest}_i \| s_i)$, one per
servable model, a manifest fixing weights or upstream model, version, context length,
quantisation; salt keeps an unopened leaf opaque.
\item \textbf{floor}: a quality floor on a named public benchmark, claimed for every leaf.
\item \textbf{class}: the class of selection rule, not the rule. Cheapest-above-floor,
lowest-latency-above-floor and learned-score differ observably; parameters stay private.
\item $k$: the size of the set. Public, because it bounds every privacy claim below.
\end{itemize}
Each response carries an opening: the leaf, its path, and a signature over chain id, diamond,
\texttt{sessionId}, \texttt{requestId} and the response hash, which stops a flattering opening
being replayed or moved between requests. Verification is one hash chain and one
\texttt{secp256k1} recover, a few hundred bytes on a response already kilobytes wide.
\section*{What leaks, said plainly}
Openings accumulate into the multiset of served leaves and their frequencies, the realised policy
over the prompts a customer sent. $k$ is the dial: $k=4$ under a stable rule is public within a
day, $k=60$ stays a distribution, though hiding among sixty concedes the floor does little work. Estimating the policy to accuracy $\varepsilon$ costs about $k/\varepsilon^{2}$ paid
requests per prompt class, and re-salting each epoch restarts that bill.
\section*{Type the bid, not the model}
Routing belongs to a provider's serving path, but \texttt{Model.tags}
(\texttt{IModelStorage.sol}:22) is written by the model owner, and \texttt{isTeeModel}
(\texttt{proxy\_receiver.go}:123) already reads those tags to gate a check on a provider's backend.
Put \emph{fixed} against \emph{routed} on the bid; buyers filter on a field, not a convention.
\begin{stake}{What each side gets}
\item \textbf{Routed providers} keep pool and policy, give up $k$, a floor and a rule class, and
gain something to sell against competitors who disclose nothing.
\item \textbf{Consumers} get a per-response proof that whatever answered sat inside a set fixed
before the request, and a choice: filter routed out, or price it.
\item \textbf{The network} keeps \texttt{modelId} meaning something, and admits routing
deliberately.
\end{stake}
\section*{First step}
Nothing on chain has to move first. Whoever maintains \texttt{models-config.json} and the
\texttt{aiengine} adapters can put $C$ in the manifest at the model's \texttt{ipfsCID} and emit the
opening as an added response field, the way \texttt{PongRes.Models} rides outside the signed
payload so older consumers drop it and keep verifying (\texttt{request.go}:132--140). After a month
of openings verified in the wild the root moves into a diamond slot. Hanzo runs the first router
under this rule; we operate a learned router, so it constrains us most.
\section*{What it does not solve}
It proves membership in a declared set: not that the set is good, not that the floor or the rule
class held, which needs the challenge and stake layer of LP-313, and not that inference happened.
\vspace{0.6ex}
\noindent{\color{muted}\footnotesize\sffamily LP-316, full paper available. Code checked against
\texttt{MorpheusAIs/Morpheus-Lumerin-Node}; line numbers drift, names do not.}
\end{document}