docs: formalize Itô inference serving contract (#2708)

This commit is contained in:
Affaan Mustafa
2026-08-07 14:55:22 -04:00
committed by GitHub
parent b844a9edb8
commit a73deb211e
3 changed files with 255 additions and 37 deletions

View File

@@ -110,6 +110,34 @@ adapter; the ECC bridge does not expose its paper fixture mode.
Managed inference remains unavailable. ECC does not claim that Itô created a
model endpoint, deployed a workload, reserved capacity, or moved funds.
### Inference-serving contract
`skills/ito-inference` is the only canonical serving skill; `ito-serve` is
trigger language, not a second installed skill. The current ECC bridge has no
`serve` verb and rejects it before resolving or spawning the canonical client.
The canonical runtime documents `inference` only as an unsupported compatibility
probe, and MCP remains limited to auth, find, and status. Serving requests
therefore stop before login.
A future `serve` operation is not releasable until it verifies a completed
booking and fresh serving eligibility, accepts an immutable reviewed manifest,
requires a short-lived single-use confirmation bound to account, action,
manifest digest, and maximum cost, and atomically reserves a caller-provided
idempotency key. CLI arguments carry only an opaque non-authorizing confirmation
reference; bearer confirmation is resolved and consumed server-side.
Manifest handling must canonicalize the path, reject symlinks, open a regular
file without following links, validate ownership/permissions and bounded size,
and hash bytes from the opened descriptor. The digest must match the value bound
into confirmation before mutation, preventing path-swap and digest-mismatch
attacks. Authentication alone is never workload authority.
The same canonical client must expose structured, tenant-scoped status, logs,
metrics, cancel, and cleanup with bounded timeouts and revocation-aware errors.
After an ambiguous transport failure, callers reconcile by idempotency key
before retrying. ECC must never replace that control plane with root SSH, local
serving scripts, browser automation, or an unreviewed purchase endpoint.
## Skill and install shape
`skills/ito-compute/SKILL.md` is an opt-in workflow installed through:

View File

@@ -1,59 +1,119 @@
---
name: ito-inference
description: Serve a model on a completed Itô compute booking through the canonical Itô backend. Use after ito-compute has booked GPU nodes and the user wants an OpenAI-compatible endpoint on that metal. Chains off a booking record; ECC implements no serving stack of its own.
description: Inspect the availability of model serving on a completed Itô compute booking and, when the canonical backend becomes available, hand off an explicitly confirmed serving manifest. Use after ito-compute has booked GPU nodes and the user asks for an OpenAI-compatible endpoint, ito-serve, hosted Kimi, or self-hosted open-weights inference. ECC implements no serving stack of its own.
metadata:
origin: ECC
status: scaffold
aliases: ito-serve, hosted-open-weights
---
# Itô Inference
Serve a model on rented Itô metal by delegating to the canonical Itô compute
backend (Layer 0.2). ECC does not implement a parallel serving stack, launch
adapter, or inference server, and does no browser automation. This skill chains
off a **completed booking** produced by `ito-compute`; it never books, reserves,
or spends.
`ito-inference` is the sole canonical ECC skill for inference serving on Itô
compute. Requests naming `ito-serve` route here; do not create or install a
second `ito-serve` skill. ECC never SSHes to nodes, downloads weights, launches
an engine, or exposes an endpoint; it never books, reserves, or spends.
## Prerequisite
## Current production boundary
A completed booking from the `ito-compute` skill: booking id, node IPs, SSH
access, GPU SKU, node count, and fabric, already recorded in harness memory.
Without a booking record, stop — this skill does not provision.
Managed serving is unavailable today. The ECC bridge exposes only `login`,
`auth`, `find`, `status`, and explicitly gated `evals`. It has no `serve` verb.
The canonical runtime documents `inference` only as an unsupported compatibility
probe; ECC does not invoke or depend on it. The MCP surface exposes only auth,
find, and status. The locally enforceable guarantee is that ECC rejects `serve`
before resolving or spawning the credential-bearing canonical client.
## Delegation
Therefore stop before authentication or any command invocation. Report the
missing capability and return to the originating agent. Never substitute a
local runner, SSH helper, browser workflow, purchase endpoint, or any untracked
local `ito-serve` draft.
ECC calls the canonical backend through the `ecc ito` bridge; it never
re-implements serving. Authenticate once with `ecc ito login` (device
authorization; no key in arguments, files, logs, or chat), exactly as
`ito-compute` documents.
## Required entitlement
When serving is implemented, its first gate is a server-verified completed
booking. Harness memory, an RFQ, a quote, node IPs, or SSH access are not proof
of entitlement. The backend must return fresh serving eligibility bound to the
authenticated account, booking, GPU topology, region, fabric, term, and model
policy. Expired, revoked, mismatched, incomplete, or already-released bookings
fail closed before confirmation.
## Future CLI and API contract
The intended command name is `serve`; `inference` may remain only as an
explicitly deprecated compatibility alias after the production contract lands.
The future handoff must be equivalent to:
```sh
ecc ito serve \
--booking <booking-id> \
--model <hf-model-id> \
[--quantization <scheme>] \
[--ttft-ms <target>] [--tpot-ms <target>]
--booking <server-verified-booking-id> \
--manifest <absolute-reviewed-json-file> \
--confirmation-ref <opaque-non-authorizing-reference> \
--idempotency-key <stable-retry-key> \
--json
```
The `--ttft-ms` / `--tpot-ms` SLO is optional; supplying it turns on
disaggregated prefill/decode, which is off by default.
The reviewed manifest must identify the model revision, engine and version,
quantization, tensor/pipeline topology, endpoint exposure policy, artifact
checksums, storage ceiling, runtime limits, optional TTFT/TPOT objectives, and
maximum incremental cost. No raw API key, SSH key, node password, or bearer
token belongs in arguments, manifests, logs, MCP results, or chat.
## What the backend does (Layer 0.2)
The client must canonicalize the manifest path, reject symlinks, open a regular
file without following links, require appropriate ownership and restrictive
permissions, enforce a bounded size, and hash bytes from the opened descriptor.
That digest must exactly equal the digest bound into confirmation before any
workload mutation. A path swap, digest mismatch, oversized file, or mutable
unsafe file fails closed.
The desk backend, not ECC, runs the stages, and this skill only reports them:
The canonical API—not ECC—must own workload creation and return structured JSON
with `ok`, `live_api_contacted`, `notice`, and either `data` or `error`. Serving
data must include stable booking, workload, manifest, and idempotency IDs plus a
state enum; it must not claim an endpoint is live until health and model checks
pass. Errors must include a stable code and safe message without secrets.
1. Fabric gate — never launch on unverified metal. Blocks below 80% of
fabric-expected bus bandwidth; advisory between 80% and 92%; fails loud on
silent NCCL socket fallback.
2. Weights download and shard to the serving layout (desk-side sharded cache
keyed by model, quantization, TP degree).
3. Topology plan (AIConfigurator): TP inside the NVLink domain, PP across nodes;
engine flags emitted as a reviewable file before launch.
4. Launch (vLLM, Dynamo when disaggregating) under systemd, warmup, SLO canary,
and registration of the endpoint URL and config to Graphiti memory.
## Confirmation and execution gates
## Unavailable today
Before workload creation, require all of the following:
The serving operation is not yet wired: the canonical CLI's `inference` verb and
the desk `serve-on-booking` backend are scaffolds. Until they land, this skill
reports the missing capability and stops. Never substitute a local runner or a
purchase endpoint.
1. Fresh entitlement and serving eligibility from the canonical backend.
2. A reviewable immutable manifest and deterministic digest.
3. A separate single-use confirmation bound to account, action, manifest, and
cost, with a short expiry and replay protection. CLI arguments carry only an
opaque, non-authorizing confirmation reference; the server resolves and
consumes the bearer capability out of band.
4. A caller-supplied idempotency key reserved atomically with the workload.
5. Server-side fabric, capacity, model-policy, storage, and cost validation.
Authentication is identity, not workload authority. A login, API key, quote,
or completed booking never substitutes for the serving confirmation. Inspection
and plan generation must not create a workload. Cancel and cleanup are separate
mutations with their own scoped confirmation and idempotency boundaries.
## Lifecycle and recovery
The production surface is incomplete until the same canonical client exposes
tenant-scoped status, logs, metrics, cancel, and cleanup operations. Every
operation needs bounded connect and overall timeouts, revocation-aware errors,
and structured output. After an ambiguous transport failure, query status by
the idempotency key before retrying; never create a second workload merely
because the first response was lost. A revoked credential stops polling and
returns control to the originating agent without starting login automatically.
Only report `ready` after endpoint health, model identity, and canary inference
all pass. Report intermediate and terminal failure states honestly. Cleanup must
be observable and must not release or modify the underlying booking unless that
separate economic action was explicitly authorized.
## Proposed backend stages
These stages describe the future backend, not code that exists in ECC:
1. Verify entitlement, topology, fabric, and cost gates.
2. Fetch checksum-pinned weights into backend-managed storage.
3. Emit and validate a reviewable topology/engine plan.
4. Launch through the provider control plane, never direct root SSH from ECC.
5. Warm up, test health and model identity, run an SLO canary, then register the
endpoint and redacted configuration.
Until every gate and lifecycle operation above exists in the canonical runtime,
this skill remains a fail-closed availability check and documentation handoff.

View File

@@ -0,0 +1,130 @@
/**
* Contract tests for the installable, fail-closed Itô inference handoff.
*/
const assert = require("assert");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { spawnSync } = require("child_process");
const REPO_ROOT = path.join(__dirname, "..", "..");
function read(relativePath) {
return fs.readFileSync(path.join(REPO_ROOT, relativePath), "utf8");
}
function readJson(relativePath) {
return JSON.parse(read(relativePath));
}
function test(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (error) {
console.log(`${name}`);
console.error(` ${error.message}`);
return false;
}
}
console.log("\n=== Testing Itô inference skill lifecycle ===\n");
const results = [
test("uses the canonical serving trigger and fails closed while unavailable", () => {
const skill = read("skills/ito-inference/SKILL.md");
assert.match(skill, /^name: ito-inference$/m);
assert.match(skill, /self-host|serve a model|OpenAI-compatible endpoint/i);
assert.match(skill, /requests naming .*ito-serve/i);
assert.match(skill, /completed booking/i);
assert.match(skill, /never books, reserves,\s+or spends/i);
assert.match(skill, /serving is unavailable today/i);
assert.match(skill, /report the\s+missing capability and return/i);
assert.match(skill, /stop before authentication/i);
assert.match(skill, /no `serve` verb/i);
assert.match(skill, /`inference`.*unsupported compatibility\s+probe/i);
assert.match(skill, /never substitute a\s+local runner, SSH helper, browser workflow, purchase endpoint/i);
assert.doesNotMatch(skill, /ssh\s+root@|serve-status\.sh/i);
for (const gate of [
/server-verified completed\s+booking/i,
/fresh serving eligibility/i,
/single-use confirmation/i,
/account, action, manifest, and\s+cost/i,
/idempotency/i,
/status, logs, metrics, cancel, and cleanup/i,
/structured JSON/i,
/ambiguous transport/i,
/reject symlinks/i,
/without following links/i,
/hash bytes from the opened descriptor/i,
/digest must exactly equal/i,
]) assert.match(skill, gate);
assert.match(skill, /--confirmation-ref <opaque-non-authorizing-reference>/i);
assert.doesNotMatch(skill, /--confirmation-token|--api-key|--access-token/i);
}),
test("keeps unsupported serving outside the executable bridge", () => {
const bridge = read("scripts/ito.js");
assert.match(bridge, /SUPPORTED_COMMANDS[^\n]+login[^\n]+auth[^\n]+find[^\n]+status[^\n]+evals/);
assert.doesNotMatch(bridge, /SUPPORTED_COMMANDS[^\n]+serve/);
assert.match(bridge, /Unsupported Itô command/);
const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ecc-ito-serve-reject-"));
try {
const canonicalDir = path.join(fixtureRoot, "cli", "ito-compute-cli", "dist", "bin");
fs.mkdirSync(canonicalDir, { recursive: true });
const marker = path.join(fixtureRoot, "spawned");
const executable = path.join(canonicalDir, "ito.js");
fs.writeFileSync(executable, `require("fs").writeFileSync(${JSON.stringify(marker)}, "spawned");\n`);
const result = spawnSync(process.execPath, [
path.join(REPO_ROOT, "scripts", "ecc.js"), "ito", "serve",
"--booking", "booking_test", "--model", "model_test",
], {
encoding: "utf8",
env: { ...process.env, ECC_ITO_CLI_EXECUTABLE: executable },
});
assert.notStrictEqual(result.status, 0);
assert.match(result.stderr, /Unsupported Itô command "serve"/);
assert.ok(!fs.existsSync(marker), "unsupported serve spawned the canonical child");
} finally {
fs.rmSync(fixtureRoot, { recursive: true, force: true });
}
}),
test("ships canonical inference through the existing opt-in compute module", () => {
const modules = readJson("manifests/install-modules.json").modules;
const module = modules.find((candidate) => candidate.id === "ito-compute");
assert.ok(module, "ito-compute install module is missing");
assert.deepStrictEqual(module.paths, [
"skills/ito-compute",
"skills/ito-inference",
"skills/ito-training",
]);
assert.deepStrictEqual(module.dependencies, ["platform-configs"]);
assert.strictEqual(module.defaultInstall, false);
assert.strictEqual(module.stability, "beta");
const components = readJson("manifests/install-components.json").components;
assert.deepStrictEqual(
components.find((candidate) => candidate.id === "capability:ito-compute"),
{
id: "capability:ito-compute",
family: "capability",
description: "Authenticated Itô GPU inventory, RFQ, status, and explicitly gated node-qualification workflows through the separately installed canonical CLI.",
modules: ["ito-compute"],
}
);
const profiles = readJson("manifests/install-profiles.json").profiles;
assert.ok(profiles.full.modules.includes("ito-compute"));
const packageFiles = readJson("package.json").files;
assert.ok(packageFiles.includes("skills/ito-inference/"));
assert.ok(packageFiles.includes("skills/ito-training/"));
}),
];
const failed = results.filter((passed) => !passed).length;
console.log(`\nPassed: ${results.length - failed}`);
console.log(`Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);