mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-01 04:38:47 +02:00
feat: add entitlement-gated Ito workloads
This commit is contained in:
+55
-4
@@ -10,7 +10,10 @@ const {
|
||||
getInvocationCommand,
|
||||
} = require("./lib/ito-environment");
|
||||
|
||||
const SUPPORTED_COMMANDS = Object.freeze(["login", "logout", "auth", "find", "status", "evals"]);
|
||||
const SUPPORTED_COMMANDS = Object.freeze([
|
||||
"login", "logout", "auth", "find", "status", "evals",
|
||||
"serve", "train", "workload-status", "workload-cancel", "workload-cleanup",
|
||||
]);
|
||||
const CANONICAL_REPOSITORY = "https://github.com/Ito-Markets/ito-cloud-runtime.git";
|
||||
const CANONICAL_PACKAGE_PATH = "cli/ito-compute-cli";
|
||||
const CANONICAL_ENTRY_SEGMENTS = Object.freeze([
|
||||
@@ -34,14 +37,18 @@ Usage:
|
||||
ecc ito find <all required RFQ options>
|
||||
ecc ito status
|
||||
ecc ito evals --cluster <id> --live-sixtytwo --nodes <list> --config-dir <dir>
|
||||
ecc ito <login|logout|auth|find|status|evals> --json
|
||||
ecc ito <serve|train> --entitlement <id> <typed workload options>
|
||||
ecc ito workload-status --run <id>
|
||||
ecc ito workload-cancel --run <id>
|
||||
ecc ito workload-cleanup --run <id>
|
||||
ecc ito <login|logout|auth|find|status|evals|serve|train|workload-status|workload-cancel|workload-cleanup> --json
|
||||
|
||||
The bridge invokes the separately installed canonical Itô CLI and returns its
|
||||
real stdout, stderr, and exit code unchanged. "ecc ito login" delegates to the
|
||||
canonical CLI's device authorization. It opens the Itô verification page by default
|
||||
and persists its device token in macOS Keychain. Pass --no-browser to
|
||||
suppress that handoff. ECC itself performs no browser automation and adds no
|
||||
lock, workload, inference, or purchase path.
|
||||
lock, arbitrary-command, direct-SSH, or purchase path.
|
||||
"ecc ito auth" is validation-only and never starts device login.
|
||||
"ecc ito logout" asks the canonical CLI to revoke the current device credential
|
||||
and remove its local copy only after remote revocation is confirmed.
|
||||
@@ -53,6 +60,9 @@ Important:
|
||||
- "evals" invokes only the canonical CLI's double-opt-in, pinned
|
||||
sixtytwo-cli node-qualification adapter against explicit nodes.
|
||||
- Node qualification cannot rent, launch, recover, repair, or purchase.
|
||||
- Serve/train require an existing server-verified entitlement and a short-lived
|
||||
portal-issued human confirmation in ITO_WORKLOAD_CONFIRMATION_TOKEN.
|
||||
- Workload cancellation and cleanup never terminate the paid entitlement.
|
||||
- Inventory and RFQs are not reservations; only a returned firm quote is firm.
|
||||
|
||||
The canonical package is currently unpublished. Install it locally:
|
||||
@@ -103,6 +113,33 @@ function requiredOptionValue(args, option) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function validateTypedOptions(args, requiredOptions, optionalOptions = []) {
|
||||
const allowed = new Set([...requiredOptions, ...optionalOptions]);
|
||||
for (let index = 0; index < args.length; index += 2) {
|
||||
const option = args[index];
|
||||
const value = args[index + 1];
|
||||
if (!allowed.has(option) || !value?.trim() || value.startsWith("--")) {
|
||||
throw new Error(
|
||||
"Serve/train accept only typed workload options; node addresses, SSH material, secrets, positional commands, and arbitrary flags are forbidden."
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const option of requiredOptions) requiredOptionValue(args, option);
|
||||
for (const option of optionalOptions) {
|
||||
const count = args.filter((value) => value === option).length;
|
||||
if (count > 1) throw new Error(`${option} may be provided at most once.`);
|
||||
}
|
||||
}
|
||||
|
||||
function validateRunLifecycleArgs(args) {
|
||||
if (args.length !== 2 || args[0] !== "--run") {
|
||||
throw new Error(
|
||||
"Workload cancellation and cleanup accept only --run <id>; they do not accept confirmation, entitlement termination, node access, or force options."
|
||||
);
|
||||
}
|
||||
requiredOptionValue(args, "--run");
|
||||
}
|
||||
|
||||
function validateNodeQualificationArgs(args, environment) {
|
||||
if (environment.ITO_ENABLE_SIXTYTWO_LIVE !== "1") {
|
||||
throw new Error(
|
||||
@@ -164,7 +201,7 @@ function parseArgs(argv, environment = process.env) {
|
||||
const command = withoutJson.shift();
|
||||
if (!SUPPORTED_COMMANDS.includes(command)) {
|
||||
throw new Error(
|
||||
`Unsupported Itô command "${command || "(missing)"}"; ECC permits only login, logout, auth, find, status, and evals.`
|
||||
`Unsupported Itô command "${command || "(missing)"}"; ECC permits only login, logout, auth, find, status, evals, serve, train, workload-status, workload-cancel, and workload-cleanup.`
|
||||
);
|
||||
}
|
||||
if (command === "auth" && withoutJson.includes("--no-browser")) {
|
||||
@@ -173,6 +210,20 @@ function parseArgs(argv, environment = process.env) {
|
||||
if (command === "evals") {
|
||||
validateNodeQualificationArgs(withoutJson, environment);
|
||||
}
|
||||
if (command === "serve" || command === "train") {
|
||||
if (!environment.ITO_WORKLOAD_CONFIRMATION_TOKEN?.trim()) {
|
||||
throw new Error(
|
||||
`${command} requires a portal-issued ITO_WORKLOAD_CONFIRMATION_TOKEN before any process is started.`
|
||||
);
|
||||
}
|
||||
validateTypedOptions(withoutJson, [
|
||||
"--entitlement", "--artifact-ref", "--image-digest",
|
||||
"--max-runtime-seconds", "--max-incremental-cost-usd", "--idempotency-key",
|
||||
], ["--checkpoint-ref"]);
|
||||
}
|
||||
if (command === "workload-status" || command === "workload-cancel" || command === "workload-cleanup") {
|
||||
validateRunLifecycleArgs(withoutJson);
|
||||
}
|
||||
|
||||
return Object.freeze({
|
||||
help: false,
|
||||
|
||||
@@ -45,7 +45,10 @@ const ECC_ITO_CONTROL_KEYS = Object.freeze([
|
||||
"ECC_ITO_CLI_EXECUTABLE",
|
||||
"NODE_ENV",
|
||||
]);
|
||||
const ITO_RUNTIME_COMMANDS = new Set(["login", "logout", "auth", "find", "status"]);
|
||||
const ITO_RUNTIME_COMMANDS = new Set([
|
||||
"login", "logout", "auth", "find", "status",
|
||||
"serve", "train", "workload-status", "workload-cancel", "workload-cleanup",
|
||||
]);
|
||||
|
||||
function copyDefined(source, target, key) {
|
||||
if (typeof source[key] === "string") {
|
||||
@@ -75,6 +78,10 @@ function createSafeItoEnvironment(source = process.env, options = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
if (options.includeWorkloadConfirmation) {
|
||||
copyDefined(source, safe, "ITO_WORKLOAD_CONFIRMATION_TOKEN");
|
||||
}
|
||||
|
||||
if (options.includeControls) {
|
||||
for (const key of ECC_ITO_CONTROL_KEYS) {
|
||||
copyDefined(source, safe, key);
|
||||
@@ -97,8 +104,9 @@ function createSafeItoInvocationEnvironment(
|
||||
return createSafeItoEnvironment(source, {
|
||||
includeControls: options.includeControls === true,
|
||||
includeItoRuntime: ITO_RUNTIME_COMMANDS.has(command),
|
||||
includeItoApiKey: ["auth", "find", "status"].includes(command),
|
||||
includeItoApiKey: ["auth", "find", "status", "serve", "train", "workload-status", "workload-cancel", "workload-cleanup"].includes(command),
|
||||
includeItoEvals: command === "evals",
|
||||
includeWorkloadConfirmation: command === "serve" || command === "train",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+32
-14
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: ito-compute
|
||||
description: Query live GPU inventory, submit an authenticated Itô fixed-rate RFQ, inspect RFQ or procurement status, revoke device credentials, and run explicitly gated node qualification through the separately installed canonical CLI. Use when a user asks to find H100/H200 capacity, request a fixed compute rate, check Itô compute status, validate GPU nodes, revoke Itô access, or rent or purchase GPU compute and needs the supported boundary explained.
|
||||
description: Query live GPU inventory, submit an authenticated Itô fixed-rate RFQ, inspect RFQ or procurement status, revoke device credentials, run explicitly gated node qualification, and hand an active entitlement to typed inference or training workflows through the separately installed canonical CLI. Use when a user asks to find GPU capacity, check or revoke Itô access, or rent or purchase GPU compute and needs the supported boundary explained.
|
||||
---
|
||||
|
||||
# Itô Compute
|
||||
@@ -80,6 +80,30 @@ key or token in arguments, tracked files, MCP results, logs, or chat.
|
||||
Inventory prices are indicative. An RFQ is not reserved capacity. Treat a rate
|
||||
as fixed only when the canonical result contains a non-null firm quote.
|
||||
|
||||
## Entitlement-to-workload handoff
|
||||
|
||||
After procurement, require the canonical control plane to return a
|
||||
server-verified, active entitlement. An RFQ, booking identifier, portal memory,
|
||||
node address, or SSH material is not workload authority. The portal must show
|
||||
the exact immutable manifest, runtime ceiling, incremental-cost ceiling, and
|
||||
entitlement to the user before issuing a short-lived, single-use
|
||||
`ITO_WORKLOAD_CONFIRMATION_TOKEN`.
|
||||
|
||||
Use `ecc ito serve` or `ecc ito train` only through the corresponding skill.
|
||||
Confirmation is required only to start a workload. Later lifecycle operations
|
||||
are typed by the server-issued run reference:
|
||||
|
||||
```sh
|
||||
ecc ito workload-cancel --run <run-id>
|
||||
ecc ito workload-cleanup --run <run-id>
|
||||
```
|
||||
|
||||
Cancellation requests that execution stop; cleanup revokes workload-scoped
|
||||
credentials and removes eligible ephemeral artifacts. Neither operation
|
||||
terminates the paid compute entitlement. Use
|
||||
`ecc ito workload-status --run <run-id>` for typed state reads. Logs remain
|
||||
portal/control-plane audit evidence and must never be retrieved by direct SSH.
|
||||
|
||||
## Live node qualification
|
||||
|
||||
`ecc ito evals` exposes the canonical CLI's narrow live adapter to a separately
|
||||
@@ -134,18 +158,12 @@ The server exposes only:
|
||||
`ito_auth`, gather explicit buyer authority and every hard constraint, call
|
||||
`ito_find`, then poll with `ito_status` when needed.
|
||||
|
||||
## Rent or purchase semantics
|
||||
|
||||
`find` submits an RFQ and may return a firm quote, but it does not rent,
|
||||
purchase, reserve, provision, or move funds. `status` is read-oriented, though
|
||||
the provider endpoint may reconcile an existing procurement order. The passive
|
||||
dashboard link in ECC help is a separate user-operated web route; do not open or
|
||||
operate it as a substitute for a missing CLI capability.
|
||||
|
||||
## Unsupported operations
|
||||
|
||||
The supported client surface cannot lock quotes, reserve capacity, execute
|
||||
workloads, or serve inference. The MCP server does not expose qualification;
|
||||
use the explicit CLI command above. Do not invent additional tools or a
|
||||
purchase path. Do not substitute a browser or fixture when the local CLI is
|
||||
missing or a live operation fails. Report the missing capability and stop.
|
||||
The supported client surface cannot lock quotes, reserve capacity, terminate an
|
||||
entitlement, expose raw cluster credentials, or provide arbitrary node access.
|
||||
The MCP server does not expose qualification or workloads; use the explicit CLI
|
||||
commands above. Never use direct SSH or pass node addresses, secret values, or
|
||||
arbitrary commands through the workload bridge. Do not invent additional tools
|
||||
or a purchase path. If the canonical adapter is unavailable, report that exact
|
||||
boundary and stop.
|
||||
|
||||
@@ -1,119 +1,79 @@
|
||||
---
|
||||
name: ito-inference
|
||||
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
|
||||
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.
|
||||
---
|
||||
|
||||
# Itô Inference
|
||||
|
||||
`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.
|
||||
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.
|
||||
|
||||
## Current production boundary
|
||||
## Prerequisite
|
||||
|
||||
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.
|
||||
A server-verified, active compute entitlement for an already-paid booking or
|
||||
cluster. Harness memory, a booking id by itself, node IPs, and SSH access are
|
||||
not authority. Without an entitlement, stop — this skill does not provision.
|
||||
|
||||
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.
|
||||
## Delegation
|
||||
|
||||
## 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:
|
||||
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.
|
||||
|
||||
```sh
|
||||
ecc ito serve \
|
||||
--booking <server-verified-booking-id> \
|
||||
--manifest <absolute-reviewed-json-file> \
|
||||
--confirmation-ref <opaque-non-authorizing-reference> \
|
||||
--idempotency-key <stable-retry-key> \
|
||||
--json
|
||||
--entitlement <entitlement-id> \
|
||||
--artifact-ref <immutable-model-ref> \
|
||||
--image-digest <sha256:image-digest> \
|
||||
--max-runtime-seconds <ceiling> \
|
||||
--max-incremental-cost-usd <ceiling> \
|
||||
--idempotency-key <opaque-id>
|
||||
```
|
||||
|
||||
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.
|
||||
The user must approve the exact manifest and ceilings in the portal. Supply the
|
||||
short-lived, single-use result as `ITO_WORKLOAD_CONFIRMATION_TOKEN`; never put
|
||||
it in arguments, files, logs, or chat. ECC never accepts node addresses, raw
|
||||
SSH keys, arbitrary commands, or ambient cloud/model credentials here.
|
||||
|
||||
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.
|
||||
## Lifecycle and portal handoff
|
||||
|
||||
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.
|
||||
The start result is a server-issued run reference. Return it to the portal so
|
||||
the user can follow the audit trail and endpoint readiness. Confirmation is
|
||||
consumed only by `serve`; do not request or forward it for lifecycle actions.
|
||||
|
||||
## Confirmation and execution gates
|
||||
```sh
|
||||
ecc ito workload-cancel --run <run-id>
|
||||
ecc ito workload-cleanup --run <run-id>
|
||||
```
|
||||
|
||||
Before workload creation, require all of the following:
|
||||
Cancellation and cleanup are typed control-plane requests and do not terminate
|
||||
the paid entitlement. Cleanup revokes workload-scoped credentials; ECC never
|
||||
receives them. Inspect state with `ecc ito workload-status --run <run-id>`.
|
||||
Logs remain in the portal/control-plane view; never use direct SSH or node
|
||||
addresses, and do not claim endpoint readiness without functional evidence.
|
||||
|
||||
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.
|
||||
## What the backend does (Layer 0.2)
|
||||
|
||||
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.
|
||||
The desk backend, not ECC, runs the stages, and this skill only reports them:
|
||||
|
||||
## Lifecycle and recovery
|
||||
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.
|
||||
|
||||
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.
|
||||
## Availability boundary
|
||||
|
||||
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.
|
||||
The canonical CLI contains an executable contract and mock-tested orchestrator,
|
||||
but production entitlement, confirmation, credential-broker, and executor
|
||||
adapters are not yet configured. Without them it fails closed before contacting
|
||||
a node or provider. Never substitute direct SSH, a local runner, or a purchase
|
||||
endpoint.
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
name: ito-training
|
||||
description: Run an ML training job on a completed Itô compute booking through the canonical Itô backend. Use after ito-compute has booked GPU nodes and the user wants pre-training, fine-tuning, or RL on that metal. Chains off a booking record; ECC implements no training stack of its own.
|
||||
metadata:
|
||||
origin: ECC
|
||||
---
|
||||
|
||||
# Itô Training
|
||||
@@ -14,8 +12,9 @@ or scheduler, and does no browser automation. This skill chains off a
|
||||
|
||||
## Prerequisite
|
||||
|
||||
A completed booking from the `ito-compute` skill (booking id, node IPs, SSH,
|
||||
GPU SKU, node count, fabric) in harness memory. Without one, stop.
|
||||
A server-verified, active compute entitlement for an already-paid booking or
|
||||
cluster. Harness memory, node IPs, and SSH material are not authority. Without
|
||||
an entitlement, stop.
|
||||
|
||||
## Delegation
|
||||
|
||||
@@ -26,14 +25,39 @@ chat.
|
||||
|
||||
```sh
|
||||
ecc ito train \
|
||||
--booking <booking-id> \
|
||||
--model-size <e.g. 8B> \
|
||||
--data <data-ref> \
|
||||
--target <capability> \
|
||||
--budget-usd <ceiling> \
|
||||
[--post-training sft|dpo|rlvr]
|
||||
--entitlement <entitlement-id> \
|
||||
--artifact-ref <immutable-training-manifest-ref> \
|
||||
--image-digest <sha256:image-digest> \
|
||||
--max-runtime-seconds <ceiling> \
|
||||
--max-incremental-cost-usd <ceiling> \
|
||||
--idempotency-key <opaque-id> \
|
||||
[--checkpoint-ref <server-managed-ref>]
|
||||
|
||||
The exact manifest and ceilings require a short-lived, single-use human
|
||||
confirmation from the portal in `ITO_WORKLOAD_CONFIRMATION_TOKEN`. Never put
|
||||
that token, dataset/model secrets, raw paths, node addresses, or SSH material in
|
||||
arguments, files, logs, or chat.
|
||||
```
|
||||
|
||||
## Lifecycle, checkpoints, and portal handoff
|
||||
|
||||
Return the server-issued run reference to the portal for its audit trail.
|
||||
Checkpoint inputs and outputs are opaque server-managed references; ECC never
|
||||
receives storage credentials or raw cluster paths. Confirmation is consumed
|
||||
only by `train` and must not be forwarded to lifecycle actions.
|
||||
|
||||
```sh
|
||||
ecc ito workload-cancel --run <run-id>
|
||||
ecc ito workload-cleanup --run <run-id>
|
||||
```
|
||||
|
||||
Cancellation asks the executor to stop and preserve checkpoint policy; cleanup
|
||||
revokes workload-scoped credentials and removes eligible ephemeral artifacts.
|
||||
Neither operation terminates the paid entitlement. Inspect state with
|
||||
`ecc ito workload-status --run <run-id>`. Logs remain portal/control-plane
|
||||
evidence; never use direct SSH, SSH material, or node addresses, and do not
|
||||
claim training success without terminal checkpoint/evaluation evidence.
|
||||
|
||||
## What the backend does (Layer 0.3)
|
||||
|
||||
The desk backend runs a staged, eval-gated pipeline; this skill reports stage
|
||||
@@ -53,8 +77,10 @@ gates and never overrides one:
|
||||
Emits desk telemetry (goodput, interruption rate, checkpoint bandwidth) so the
|
||||
desk prices training blocks honestly.
|
||||
|
||||
## Unavailable today
|
||||
## Availability boundary
|
||||
|
||||
Not yet wired: the canonical CLI's `run` verb and the desk `training-run`
|
||||
backend are scaffolds. Until they land, this skill reports the missing
|
||||
capability and stops. Never substitute a local trainer or a purchase endpoint.
|
||||
The canonical CLI contains an executable contract and mock-tested orchestrator,
|
||||
but production entitlement, confirmation, credential-broker, and executor
|
||||
adapters are not yet configured. Without them it fails closed before contacting
|
||||
a node or provider. Never substitute direct SSH, a local trainer, an arbitrary
|
||||
`run` command, or a purchase endpoint.
|
||||
|
||||
@@ -80,6 +80,28 @@ function main() {
|
||||
assert.match(interfaceMetadata, /display_name: "Itô Compute"/);
|
||||
assert.match(interfaceMetadata, /default_prompt: .*\$ito-compute/);
|
||||
}],
|
||||
["documents the entitlement-gated workload lifecycle without inventing node access", () => {
|
||||
const compute = read("skills/ito-compute/SKILL.md");
|
||||
const inference = read("skills/ito-inference/SKILL.md");
|
||||
const training = read("skills/ito-training/SKILL.md");
|
||||
for (const source of [compute, inference, training]) {
|
||||
assert.match(source, /server-verified[^.]*entitlement/i);
|
||||
assert.match(source, /workload-cancel/i);
|
||||
assert.match(source, /workload-cleanup/i);
|
||||
assert.match(source, /does not terminate|do not terminate|never terminate|neither operation\s+terminates/i);
|
||||
assert.match(source, /status/i);
|
||||
assert.match(source, /logs/i);
|
||||
assert.match(source, /workload-status/i);
|
||||
assert.match(source, /logs remain portal\/control-plane|logs remain[^.]*portal/i);
|
||||
assert.match(source, /portal/i);
|
||||
assert.match(source, /never.*(?:direct SSH|SSH material|node addresses)/is);
|
||||
}
|
||||
assert.match(inference, /ecc ito serve/);
|
||||
assert.match(training, /ecc ito train/);
|
||||
assert.match(training, /checkpoint-ref/);
|
||||
assert.match(inference, /ITO_WORKLOAD_CONFIRMATION_TOKEN/);
|
||||
assert.match(training, /ITO_WORKLOAD_CONFIRMATION_TOKEN/);
|
||||
}],
|
||||
["keeps README and integration docs aligned with the separated auth contract", () => {
|
||||
for (const relativePath of [
|
||||
"README.md",
|
||||
|
||||
@@ -153,6 +153,110 @@ async function main() {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
}
|
||||
}],
|
||||
["gates typed workloads on a portal confirmation and strips unrelated secrets", () => {
|
||||
const args = [
|
||||
"ito", "serve",
|
||||
"--entitlement", "ent_001",
|
||||
"--artifact-ref", "model:hf-test@sha256:abc",
|
||||
"--image-digest", `sha256:${"d".repeat(64)}`,
|
||||
"--max-runtime-seconds", "300",
|
||||
"--max-incremental-cost-usd", "0",
|
||||
"--idempotency-key", "idem_001",
|
||||
];
|
||||
const denied = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(args, { ECC_ITO_CLI_EXECUTABLE: denied.executable });
|
||||
assert.notStrictEqual(result.status, 0);
|
||||
assert.match(result.stderr, /portal-issued ITO_WORKLOAD_CONFIRMATION_TOKEN/i);
|
||||
assert.ok(!fs.existsSync(denied.log));
|
||||
} finally {
|
||||
fs.rmSync(denied.directory, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
const allowed = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(args, {
|
||||
ECC_ITO_CLI_EXECUTABLE: allowed.executable,
|
||||
ITO_WORKLOAD_CONFIRMATION_TOKEN: "one-time-human-confirmation",
|
||||
ITO_API_KEY: `ito_${"a".repeat(32)}`,
|
||||
AWS_SECRET_ACCESS_KEY: "must-not-cross",
|
||||
HF_TOKEN: "must-not-cross",
|
||||
SSH_AUTH_SOCK: "/tmp/must-not-cross.sock",
|
||||
});
|
||||
assert.strictEqual(result.status, 0, result.stderr);
|
||||
const invocation = readInvocation(allowed);
|
||||
assert.deepStrictEqual(invocation.argv, args.slice(1));
|
||||
assert.strictEqual(invocation.env.ITO_WORKLOAD_CONFIRMATION_TOKEN, "one-time-human-confirmation");
|
||||
assert.strictEqual(invocation.env.AWS_SECRET_ACCESS_KEY, undefined);
|
||||
assert.strictEqual(invocation.env.HF_TOKEN, undefined);
|
||||
assert.strictEqual(invocation.env.SSH_AUTH_SOCK, undefined);
|
||||
} finally {
|
||||
fs.rmSync(allowed.directory, { recursive: true, force: true });
|
||||
}
|
||||
}],
|
||||
["rejects untyped workload, node-access, and secret arguments before spawning", () => {
|
||||
const base = [
|
||||
"ito", "train",
|
||||
"--entitlement", "ent_001",
|
||||
"--artifact-ref", "training:manifest_001",
|
||||
"--image-digest", `sha256:${"d".repeat(64)}`,
|
||||
"--max-runtime-seconds", "300",
|
||||
"--max-incremental-cost-usd", "0",
|
||||
"--idempotency-key", "idem_001",
|
||||
];
|
||||
for (const extra of [
|
||||
["--ssh-key", "/tmp/id_ed25519"],
|
||||
["--node", "gpu-01"],
|
||||
["--token", "secret-in-argv"],
|
||||
["--command", "curl metadata"],
|
||||
["positional-command"],
|
||||
]) {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
const result = runCli([...base, ...extra], {
|
||||
ECC_ITO_CLI_EXECUTABLE: probe.executable,
|
||||
ITO_WORKLOAD_CONFIRMATION_TOKEN: "one-time-human-confirmation",
|
||||
});
|
||||
assert.notStrictEqual(result.status, 0, extra.join(" "));
|
||||
assert.match(result.stderr, /only typed workload options/i);
|
||||
assert.ok(!fs.existsSync(probe.log), `${extra[0]} must be rejected before spawn`);
|
||||
} finally {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
}],
|
||||
["keeps confirmation start-only and types cancellation and cleanup", () => {
|
||||
for (const command of ["workload-status", "workload-cancel", "workload-cleanup"]) {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(["ito", command, "--run", "run_001"], {
|
||||
ECC_ITO_CLI_EXECUTABLE: probe.executable,
|
||||
ITO_API_KEY: "ito_test_key",
|
||||
ITO_WORKLOAD_CONFIRMATION_TOKEN: "must-not-cross",
|
||||
SSH_AUTH_SOCK: "/tmp/must-not-cross.sock",
|
||||
});
|
||||
assert.strictEqual(result.status, 0, result.stderr);
|
||||
const invocation = readInvocation(probe);
|
||||
assert.deepStrictEqual(invocation.argv, [command, "--run", "run_001"]);
|
||||
assert.strictEqual(invocation.env.ITO_WORKLOAD_CONFIRMATION_TOKEN, undefined);
|
||||
assert.strictEqual(invocation.env.SSH_AUTH_SOCK, undefined);
|
||||
} finally {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
const denied = makeItoProbe();
|
||||
try {
|
||||
const result = runCli(["ito", command, "--run", "run_001", "--force"], {
|
||||
ECC_ITO_CLI_EXECUTABLE: denied.executable,
|
||||
});
|
||||
assert.notStrictEqual(result.status, 0);
|
||||
assert.match(result.stderr, /only --run <id>/i);
|
||||
assert.ok(!fs.existsSync(denied.log));
|
||||
} finally {
|
||||
fs.rmSync(denied.directory, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
}],
|
||||
["forwards the canonical login browser opt-out without performing browser automation", () => {
|
||||
const probe = makeItoProbe();
|
||||
try {
|
||||
@@ -445,6 +549,13 @@ async function main() {
|
||||
"ITO_ALLOW_FILE_TOKEN",
|
||||
"ITO_TOKEN_FILE",
|
||||
]);
|
||||
for (const command of ["login", "auth", "find", "status", "workload-status", "workload-cancel", "workload-cleanup"]) {
|
||||
const isolated = createSafeItoInvocationEnvironment(
|
||||
{ ITO_WORKLOAD_CONFIRMATION_TOKEN: "must-not-cross" },
|
||||
[command],
|
||||
);
|
||||
assert.strictEqual(isolated.ITO_WORKLOAD_CONFIRMATION_TOKEN, undefined, command);
|
||||
}
|
||||
const safe = createSafeItoInvocationEnvironment(
|
||||
{
|
||||
PATH: process.env.PATH,
|
||||
@@ -480,7 +591,7 @@ async function main() {
|
||||
ECC_ITO_CLI_EXECUTABLE: probe.executable,
|
||||
});
|
||||
assert.notStrictEqual(result.status, 0, command);
|
||||
assert.match(result.stderr, /only login, logout, auth, find, status, and evals/i);
|
||||
assert.match(result.stderr, /only login, logout, auth, find, status, evals, serve, train/i);
|
||||
assert.ok(!fs.existsSync(probe.log), `${command} must not spawn the Itô CLI`);
|
||||
} finally {
|
||||
fs.rmSync(probe.directory, { recursive: true, force: true });
|
||||
|
||||
Reference in New Issue
Block a user