feat: connect ECC to canonical Ito compute CLI (#2558)

This commit is contained in:
Affaan Mustafa
2026-07-23 19:28:55 -07:00
committed by GitHub
parent 9d54ee222d
commit bc774282e6
32 changed files with 1043 additions and 1275 deletions
+1 -1
View File
@@ -16,4 +16,4 @@ export ANTHROPIC_AUTH_TOKEN=your-token
claude
```
Run or self-host any open-source model behind that endpoint. Itô is ECC's preferred compute sponsor: [open the Itô dashboard to sign in and rent or manage GPUs](https://compute.itomarkets.com). Any GPU provider works. ECC only provides this link; it does not change Claude Code transport settings or provision compute or serving. Managed inference through Itô is not live yet.
Run or self-host any open-source model behind that endpoint. Itô is ECC's preferred compute sponsor: [open the Itô dashboard to sign in and rent or manage GPUs](https://compute.itomarkets.com). Any GPU provider works. That sponsorship link is passive: it does not invoke an RFQ, reserve capacity, change Claude Code transport settings, provision compute, or configure serving. Separately, the opt-in `ecc ito find` bridge invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. Managed inference through Itô is not live yet.
+1 -1
View File
@@ -11,7 +11,7 @@
{
"name": "ecc",
"source": "./",
"description": "Harness-native ECC operator layer - 67 agents, 278 skills, 94 legacy command shims, reusable hooks, rules, selective install profiles, and production-ready workflows for Claude Code, Codex, OpenCode, Cursor, and related agent harnesses",
"description": "Harness-native ECC operator layer - 67 agents, 279 skills, 94 legacy command shims, reusable hooks, rules, selective install profiles, and production-ready workflows for Claude Code, Codex, OpenCode, Cursor, and related agent harnesses",
"version": "2.0.0",
"author": {
"name": "Affaan Mustafa",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "ecc",
"version": "2.0.0",
"description": "Harness-native ECC plugin for engineering teams - 67 agents, 278 skills, 94 legacy command shims, reusable hooks, rules, MCP conventions, and operator workflows for Claude Code plus adjacent agent harnesses",
"description": "Harness-native ECC plugin for engineering teams - 67 agents, 279 skills, 94 legacy command shims, reusable hooks, rules, MCP conventions, and operator workflows for Claude Code plus adjacent agent harnesses",
"author": {
"name": "Affaan Mustafa",
"url": "https://x.com/affaanmustafa"
+1 -1
View File
@@ -23,4 +23,4 @@ bash ./install.sh --target kimi --profile minimal
## Self-hosted model compute
Run or self-host any open-source model—including Kimi—on owned or rented GPUs. Itô is ECC's preferred compute sponsor: [open the Itô dashboard to sign in and rent or manage GPUs](https://compute.itomarkets.com). Any GPU provider works. ECC only provides this link; it does not provision compute or serving. Managed inference through Itô is not live yet.
Run or self-host any open-source model—including Kimi—on owned or rented GPUs. Itô is ECC's preferred compute sponsor: [open the Itô dashboard to sign in and rent or manage GPUs](https://compute.itomarkets.com). Any GPU provider works. That sponsorship link is passive: it does not invoke an RFQ, reserve capacity, provision compute, or configure serving. Separately, the opt-in `ecc ito find` bridge invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. Managed inference through Itô is not live yet.
+2 -2
View File
@@ -1,6 +1,6 @@
# Everything Claude Code (ECC) — Agent Instructions
This is a **production-ready AI coding plugin** providing 67 specialized agents, 278 skills, 94 commands, and automated hook workflows for software development.
This is a **production-ready AI coding plugin** providing 67 specialized agents, 279 skills, 94 commands, and automated hook workflows for software development.
**Version:** 2.0.0
@@ -152,7 +152,7 @@ Troubleshoot failures: check test isolation → verify mocks → fix implementat
```
agents/ — 67 specialized subagents
skills/ — 278 workflow skills and domain knowledge
skills/ — 279 workflow skills and domain knowledge
commands/ — 94 slash commands
hooks/ — Trigger-based automations
rules/ — Always-follow guidelines (common + per-language)
+31 -5
View File
@@ -1,4 +1,4 @@
1`**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md) | [Deutsch](docs/de-DE/README.md) | [Español](docs/es/README.md)
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md) | [Deutsch](docs/de-DE/README.md) | [Español](docs/es/README.md)
![ECC — the agent harness operating system](assets/hero.png)
@@ -112,6 +112,12 @@ ECC v2.0.0 adds the public Hermes operator story on top of that reusable layer:
<strong>Itô</strong>
</a>
</td>
<td align="center" width="220">
<a href="https://www.moonshot.ai/">
<img src="assets/images/sponsors/moonshot.svg" width="96" alt="Moonshot AI Kimi logo" /><br />
<strong>Moonshot AI</strong>
</a>
</td>
</tr>
</table>
@@ -445,7 +451,7 @@ If you stacked methods, clean up in this order:
/plugin list ecc@ecc
```
**That's it!** You now have access to 67 agents, 278 skills, and 94 legacy command shims.
**That's it!** You now have access to 67 agents, 279 skills, and 94 legacy command shims.
### Dashboard GUI
@@ -1194,7 +1200,27 @@ claude
If your gateway remaps model names, configure that in Claude Code rather than in ECC. ECC's hooks, skills, commands, and rules are model-provider agnostic once the `claude` CLI is already working.
Run or self-host any open-source model behind that gateway using separate compute and serving setup. If you need GPU capacity, [Itô](https://compute.itomarkets.com) is ECC's preferred compute sponsor; any GPU provider works. ECC only links to the Itô dashboard for sign-in and GPU rental or management—it does not provision compute or serving. Managed inference through Itô is not live yet.
Run or self-host any open-source model behind that gateway using separate compute and serving setup. If you need GPU capacity, [Itô](https://compute.itomarkets.com) is ECC's preferred compute sponsor; any GPU provider works. That sponsorship link is passive: it does not invoke an RFQ, reserve capacity, provision compute, or configure serving. Separately, the opt-in `ecc ito find` bridge invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. Managed inference through Itô is not live yet.
### Itô compute CLI bridge
`ecc ito` delegates to the separately installed canonical Itô client; ECC does
not maintain a second API client or browser handoff. The available operations
are `ecc ito auth`, `ecc ito find`, and `ecc ito status`. The matching MCP tools
are `ito_auth`, `ito_find`, and `ito_status`.
The `ito-compute-cli` package is currently unpublished. Build it locally from
[`Ito-Markets/ito-cloud-runtime`](https://github.com/Ito-Markets/ito-cloud-runtime)
under `cli/ito-compute-cli`, run `npm ci` and `npm run check`, then set
`ECC_ITO_CLI_EXECUTABLE` to that build's absolute `dist/bin/ito.js` path.
Inject `ITO_API_KEY` from 1Password or the launching environment. ECC does not
discover this credential-bearing client through `PATH`. See the [`ito-compute`
skill](skills/ito-compute/SKILL.md) for the full RFQ authority and MCP setup
contract.
`find` submits a live authenticated RFQ. It does not reserve capacity. ECC
exposes no quote lock, purchase, workload, node-evaluation, or inference path,
and it never replaces a missing client or failed live call with a local result.
Official references:
- [Claude Code LLM gateway docs](https://docs.anthropic.com/en/docs/claude-code/llm-gateway)
@@ -1542,7 +1568,7 @@ The configuration is automatically detected from `.opencode/opencode.json`.
|---------|---------------------|----------|--------|
| Agents | PASS: 67 agents | PASS: 12 agents | **Claude Code leads** |
| Commands | PASS: 94 commands | PASS: 35 commands | **Claude Code leads** |
| Skills | PASS: 278 skills | PASS: 37 skills | **Claude Code leads** |
| Skills | PASS: 279 skills | PASS: 37 skills | **Claude Code leads** |
| Hooks | PASS: 8 event types | PASS: 11 events | **OpenCode has more!** |
| Rules | PASS: 29 rules | PASS: 13 instructions | **Claude Code leads** |
| MCP Servers | PASS: 14 servers | PASS: Full | **Full parity** |
@@ -1703,7 +1729,7 @@ ECC is the **first plugin to maximize every major AI coding tool**. Here's how e
|---------|-----------------------|------------|-----------|----------|----------------|
| **Agents** | 67 | Shared (AGENTS.md) | Shared (AGENTS.md) | 12 | N/A |
| **Commands** | 94 | Shared | Instruction-based | 35 | 5 prompts |
| **Skills** | 278 | Shared | 10 (native format) | 37 | Via instructions |
| **Skills** | 279 | Shared | 10 (native format) | 37 | Via instructions |
| **Hook Events** | 8 types | 15 types | None yet | 11 types | None |
| **Hook Scripts** | 20+ scripts | 16 scripts (DRY adapter) | N/A | Plugin hooks | N/A |
| **Rules** | 34 (common + lang) | 34 (YAML frontmatter) | Instruction-based | 13 instructions | 1 always-on file |
+1 -1
View File
@@ -164,7 +164,7 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/"
/plugin list ecc@ecc
```
**完成!** 你现在可以使用 67 个代理、278 个技能和 94 个命令。
**完成!** 你现在可以使用 67 个代理、279 个技能和 94 个命令。
### multi-* 命令需要额外配置
+2 -1
View File
@@ -14,10 +14,11 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
| [**Greptile**](https://www.greptile.com/go/ecc) | <img src="assets/images/sponsors/greptile.png" width="60" alt="Greptile logo" /> | 2026 |
| [**Atlas Cloud**](https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=ECC) | <img src="assets/images/sponsors/atlascloud.png" width="60" alt="Atlas Cloud logo" /> | 2026 |
| [**Itô**](https://compute.itomarkets.com) | <img src="assets/images/sponsors/ito.svg" width="60" alt="Itô Markets logo" /> | 2026 |
| [**Moonshot AI**](https://www.moonshot.ai/) | <img src="assets/images/sponsors/moonshot.svg" width="60" alt="Moonshot AI Kimi logo" /> | 2026 |
*[Become a Business sponsor](https://github.com/sponsors/affaan-m) to get README sponsor placement + SPONSORS.md listing. Current Business tier is $500/mo. No seats, SLA, custom development, or preferential technical placement is bundled unless separately agreed.*
Run or self-host any open-source model. Itô is ECC's preferred compute sponsor, while ECC remains provider-agnostic and any GPU provider works. ECC only links to the [Itô dashboard](https://compute.itomarkets.com) for sign-in and GPU rental or management; it does not provision compute or serving. Managed inference through Itô is not live yet.
Run or self-host any open-source model. Itô is ECC's preferred compute sponsor, while ECC remains provider-agnostic and any GPU provider works. The [Itô dashboard](https://compute.itomarkets.com) sponsorship link is passive: it does not invoke an RFQ, reserve capacity, provision compute, or configure serving. Separately, the opt-in `ecc ito find` bridge invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. Managed inference through Itô is not live yet.
## Team Sponsors — $200/mo
+5
View File
@@ -0,0 +1,5 @@
<svg width="180" height="180" viewBox="0 0 180 180" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="180" height="180" rx="45" fill="white"/>
<path d="M139.13 36.5135C144.237 36.5135 148.377 40.6534 148.377 45.7601C148.377 50.8669 144.237 55.0067 139.13 55.0067L130.971 55.0067C130.371 55.0067 129.884 54.5197 129.884 53.9189L129.884 45.7601C129.884 40.6534 134.023 36.5135 139.13 36.5135Z" fill="#1783FF"/>
<path d="M87.2906 90.3588L122.186 55.7385C122.842 55.0859 122.473 53.7739 121.625 53.7739H102.849C102.645 53.7739 102.447 53.8572 102.288 54.0168L64.6899 91.3099C64.1035 91.8861 63.2367 91.3724 63.2367 90.4491V54.8777C63.2367 54.2668 62.8352 53.7739 62.3444 53.7739H49.406C48.9153 53.7739 48.5137 54.2668 48.5137 54.8777V131.574C48.5137 132.185 48.9153 132.678 49.406 132.678H62.3444C62.8352 132.678 63.2367 132.185 63.2367 131.574V115.947C63.2367 115.614 63.3578 115.295 63.5681 115.087L75.2254 103.521C75.5058 103.243 75.8946 103.202 76.2069 103.41L107.387 126.354C112.492 129.79 118.196 131.9 123.99 132.525C124.506 132.581 124.952 132.067 124.952 131.421V116.704C124.952 116.142 124.614 115.684 124.162 115.614C120.752 115.08 117.425 113.761 114.417 111.734L87.4244 92.1915C86.8636 91.8167 86.7935 90.8517 87.2906 90.3588Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+1 -1
View File
@@ -2,7 +2,7 @@
[Atlas Cloud](https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=everything-claude-code) is a full-modal AI inference platform providing an OpenAI-compatible API for 59+ LLM models, image generation, and video generation.
> Run or self-host any open-source model instead of using a managed API. Itô is ECC's preferred compute sponsor: [open the Itô dashboard to sign in and rent or manage GPUs](https://compute.itomarkets.com). Any GPU provider works. ECC only provides this link; it does not provision compute or serving. Managed inference through Itô is not live yet.
> Run or self-host any open-source model instead of using a managed API. Itô is ECC's preferred compute sponsor: [open the Itô dashboard to sign in and rent or manage GPUs](https://compute.itomarkets.com). Any GPU provider works. That sponsorship link is passive: it does not invoke an RFQ, reserve capacity, provision compute, or configure serving. Separately, the opt-in `ecc ito find` bridge invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. Managed inference through Itô is not live yet.
## Configuration
+86 -545
View File
@@ -1,586 +1,127 @@
# ECC × Itô Compute Integration
Status: **Proposed — requires Affaan approval before Phase 2 implementation**
Status: **Implemented local CLI bridge; managed inference remains unavailable**
Owner: Affaan Mustafa
Prepared: 2026-07-21
Phase 1 branch: agent/ito-sponsor-compute
## Decision gate
This document is the approval artifact for Phase 2. Approval authorizes only
delivery slices 1 and 2: the five skills and the fail-closed CLI/MCP stub. It
does not authorize or claim a working Itô inference service, live rental API,
OAuth integration, billing flow, or rental mutation.
No Phase 2 skill, CLI, MCP, OAuth, rental-management, or serving code should be
built until Affaan approves the decisions at the end of this document.
### Narrow sandbox handoff authorized on 2026-07-23
Affaan separately authorized one smaller CLI slice:
ecc ito rent --accelerator h100 --count 1 --hours 24
That command is implemented as `ito.compute.handoff.v1`. It validates an
explicit H100 intent, records `ecc-cli` provenance, fixes the authority ceiling
at read-only sandbox mode, and opens only the `/desk` page, where sign-in may be
required. `--dry-run` emits the identical structured handoff without opening a
browser.
The current Itô desk does not expose a supported structured ECC deep link or a
non-mutating external-intake endpoint. The CLI therefore returns
`transport: manual_copy` and `acceptedByIto: false`; it does not pretend that
opening `/desk` delivered the intent. A human may copy the bounded message into
the conversational desk. ECC never reads credentials, files an RFQ, requests
or accepts a quote, calls procurement, approves funds, creates an order, or
contacts a counterparty. The user must stop before `Pay & buy`.
This narrow authorization does not approve the five skills, MCP, OAuth, rental
management, inference serving, deployment, publication, or any live economic
mutation described later in this document.
Updated: 2026-07-23
## Thesis
The distribution chain is:
The distribution chain remains provider-neutral:
GPU compute (Itô)
GPU compute (Itô or another selected provider)
-> any open-source model
-> model harness
-> ECC meta-harness
Itô is ECC's preferred compute sponsor. It is never an exclusive provider.
ECC remains open source and all workflows must accept owned hardware, existing
clusters, and other compute providers.
## Terms and non-negotiable boundaries
- **Self-hosting** means the user operates a model runtime on owned or rented
compute. ECC does not silently provision or operate that runtime.
- **Preferred compute sponsor** means Itô is suggested at the step where a user
needs new GPU capacity. Requirements and existing capacity come first.
- **Provider-neutral** means users can choose any provider or use hardware they
already control without losing workflow functionality.
- **Manual handoff** means ECC can route the user to
<https://compute.itomarkets.com> for sign-in, rental, and dashboard access.
- **Not live** means ECC cannot currently exchange Itô OAuth tokens, fetch live
inventory or pricing, create or manage rentals, or return an inference
endpoint.
- Itô compute authentication must not reuse the prediction-market ITO_API_KEY.
- Phase 2 must not add an Itô LLM provider or advertise an Itô-compatible model
endpoint. Itô is the compute layer, not an inference API.
## Sequencing
### Phase 1: launch-ready sponsor and compute routing
Phase 1 is the smallest shippable slice and is prepared before Phase 2:
| Surface | Launch-ready change |
|---|---|
| ECC README and sponsor roster | Itô logo beside current business sponsors; preferred-compute and provider-neutral disclosure |
| ecc-universal npm surface | README placement, packaged sponsor assets, and install welcome copy |
| ECC installer | Human help and install-plan footer route self-host intent to Itô; JSON remains machine-pure |
| ECC CLI | Top-level help shows the same shared compute disclosure |
| Harness-specific endpoint/model docs | Bring-your-own endpoint/model notes route GPU needs to Itô without claiming provisioning |
| Local-model selector | Ollama selection shows a passive compute-rental/dashboard notice; no Itô provider adapter |
| ecc.tools | Sponsor card, sponsor proof chip, and explicit no-serving boundary |
| AgentShield / ecc-agentshield | Sponsor callout in the GitHub and npm README; no ads in security reports |
Launch coordination still matters:
- Merge the public PRs when their required checks and reviews pass. Coordinate
npm publication and the verified ecc.tools deployment as explicit release
steps; do not tie the generic OSS-compute integration to an unpublished model
or model-provider announcement.
- npm READMEs update only when new versions are published. Merging source changes
alone does not update the already-published ecc-universal or ecc-agentshield
package pages.
- The release owner must select unused package versions in the launch commit,
update every synchronized version surface, prove that neither version exists
in the npm registry, publish both packages, and read back the rendered package
pages. The sponsor PRs do not silently republish existing versions.
- ecc.tools requires its normal verified Cloudflare deployment after merge.
### Phase 2: build only after approval
Phase 2 adds provider-neutral operational skills and an honest Itô control-plane
stub. Real OAuth, rentals, and serving remain separately gated on backend
contracts.
## Channel A: self-host an open model
### Skill 1: self-host-a-model
Path:
skills/self-host-a-model/SKILL.md
Activate when a user asks to self-host, locally host, or deploy an open model;
mentions Ollama, vLLM, SGLang, TGI, an OpenAI-compatible endpoint, Kimi, GLM,
Llama, Mistral, quantization, GPU sizing, or moving away from a managed API.
Workflow shape:
1. Identify the model artifact, license, trust boundary, and required context.
2. Estimate VRAM from weights, precision or quantization, KV cache, concurrency,
and runtime overhead.
3. Prefer existing owned or already-rented capacity when it satisfies the
requirement.
4. If capacity is missing, compare provider requirements and disclose Itô as
ECC's preferred compute sponsor. Authenticate only if the user selects Itô.
5. Select a user-controlled runtime, container, storage, network, auth, and TLS
plan.
6. Produce endpoint smoke tests and harness configuration steps.
7. Verify model identity, response schema, latency, health, and shutdown.
Required output: SelfHostPlan
| Field | Meaning |
|---|---|
| computeOwner | owned, existing cluster, Itô, or another selected provider |
| modelArtifact | immutable model and revision |
| runtime | selected serving engine and version |
| resourceEnvelope | GPU type/count, VRAM, CPU, RAM, disk, and network |
| endpointContract | expected protocol and auth, never a fabricated endpoint |
| deploymentSteps | provider-neutral execution plan |
| verification | health, identity, schema, latency, and teardown checks |
| blockers | missing access, capacity, serving, or model facts |
Itô is ECC's preferred compute sponsor, never an exclusive provider. Owned
hardware, existing clusters, and other providers remain valid.
Non-goals:
- Do not claim ECC or Itô created an endpoint.
- Do not fabricate Itô inventory, pricing, credentials, or rental identifiers.
- Do not force any model family; the skill is model-agnostic.
## Implemented boundary
## Channel B: training and GPU operations
ECC delegates to the canonical Itô package in
`Ito-Markets/ito-cloud-runtime/cli/ito-compute-cli`. ECC does not maintain a
second API client or response schema.
### Skill 2: training-run-operations
Path:
skills/training-run-operations/SKILL.md
The wrapper exposes only the canonical CLI's `auth`, `find`, and `status`
operations:
Activate for launching, resuming, debugging, observing, or cost-planning a
training, fine-tuning, evaluation, retraining, or MLE run.
ecc ito auth
ecc ito find <all required RFQ constraints>
ecc ito status
When installed, cross-link mle-workflow for the production lifecycle,
pytorch-patterns for framework details, and eval-harness for promotion criteria.
The new skill must still be usable on Kimi without mle-workflow or
pytorch-patterns because their current install modules do not support Kimi. Keep
the standalone contract minimal instead of copying those skills wholesale.
The canonical MCP server exposes only `ito_auth`, `ito_find`, and `ito_status`.
ECC includes an opt-in configuration template pointing to the local built MCP
entry. It does not enable the server by default.
Required output: TrainingRunPlan containing an immutable code revision, dataset
snapshot, environment or image, entry point, resources, artifact paths,
checkpoint and resume policy, metrics, observation plan, budget, retry policy,
and promotion gate.
The former browser/manual-copy command is retired. `ecc ito` performs no
browser navigation and stores no economic state.
Workflow:
## Local install
1. Run a local or minimal-capacity smoke test.
2. Size the full run and identify existing capacity.
3. Acquire new capacity only when needed; suggest Itô while permitting any
provider.
4. Route scheduler-specific work to the Slurm or Kubernetes GPU skill.
5. Submit, observe, checkpoint, resume, evaluate, and explicitly promote.
`ito-compute-cli` is unpublished. Install it from the canonical repository:
### Skill 3: gpu-workload-splitting
git clone https://github.com/Ito-Markets/ito-cloud-runtime.git
cd ito-cloud-runtime/cli/ito-compute-cli
npm ci
npm run check
Path:
Set `ECC_ITO_CLI_EXECUTABLE` to the explicit absolute built entry:
skills/gpu-workload-splitting/SKILL.md
/absolute/path/to/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito.js
Activate when a user asks to split a model, dataset, batch job, sweep, or
training run across GPUs or nodes; reports poor scaling, stragglers, or
out-of-memory failures; or needs a workload-splitting layer.
ECC does not resolve the credential-bearing client through `PATH`; this avoids
forwarding `ITO_API_KEY` to an unrelated executable with the same name.
The skill must choose deliberately among data, tensor, pipeline, model, context,
or expert parallelism; independent shards; or job arrays. It must measure VRAM,
communication-to-compute ratio, topology, data locality, and heterogeneous
capacity before choosing.
For MCP, configure `node` with:
Required output: WorkloadSplitPlan
/absolute/path/to/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito-mcp.js
| Field | Meaning |
|---|---|
| tasks | deterministic units of work |
| resources | CPU, RAM, accelerator, storage, and network per task |
| dependsOn | dependency DAG |
| shard | deterministic partition and ownership rule |
| placement | node, GPU, topology, and locality constraints |
| checkpoint | boundaries and resume behavior |
| merge | aggregation or reduction contract |
| failurePolicy | retry, idempotency, straggler, and partial-failure rules |
Inject `ITO_API_KEY` with 1Password or the launching environment. ECC forwards
only `ITO_API_KEY`, optional Itô endpoint overrides, and the minimum process
environment. It does not inspect or log the key.
Itô appears only at the capacity-acquisition step. Validate this output shape
with the LinkedIn contact who requested a workload-splitting layer before calling
Channel B customer-validated.
## Authority and economics
### Skill 4: slurm-gpu-workloads
- `auth` validates the configured Itô API key.
- `find` reads live inventory and submits a live authenticated RFQ. An operator
or agent must gather every hard topology/economic constraint and obtain
explicit buyer authority before invoking it.
- `status` reads current RFQ and procurement status.
- ECC returns the canonical process's stdout, stderr, and exit code unchanged.
- An inventory row or RFQ is not a capacity reservation.
- Only a non-null canonical firm quote is firm.
- After an ambiguous transport error, check `status` before repeating `find`.
- Global ECC dry-run does not create a local success result; the wrapper fails
closed without invoking the canonical CLI.
Path:
All durable RFQ, quote, procurement, and reservation state remains owned by the
Itô platform. ECC adds no shadow store.
skills/slurm-gpu-workloads/SKILL.md
## Unsupported in this slice
Activate for sbatch, srun, salloc, GPU GRES or TRES, pending jobs, arrays,
DDP/NCCL, queue time, low utilization, requeue, or Slurm GPU optimization.
ECC exposes no quote lock, purchase, workload execution, node qualification,
or inference command. The canonical package contains a separately gated node
qualification adapter, but this ECC bridge intentionally does not expose it.
Workflow:
Managed inference remains unavailable. ECC does not claim that Itô created a
model endpoint, deployed a workload, reserved capacity, or moved funds.
- Inspect cluster, partition, QOS, account, node, and GPU facts read-only first.
- Map nodes, tasks, processes, and GPUs explicitly.
- Cover staging, checkpoint signals, requeue, arrays, logs, topology, and scaling
diagnostics.
- Produce an sbatch plan or template plus validation commands.
- Never make scheduler-admin or cluster-wide changes without explicit authority.
- Use an existing cluster unchanged when possible; suggest Itô only when new
capacity is requested.
## Skill and install shape
### Skill 5: kubernetes-gpu-workloads
`skills/ito-compute/SKILL.md` is an opt-in workflow installed through:
Path:
- module: `ito-compute`
- component: `capability:ito-compute`
- profile: `full`
skills/kubernetes-gpu-workloads/SKILL.md
The skill documents the exact CLI and MCP names and the approval boundary. It
does not bundle the unpublished CLI.
Activate for GPU Jobs or pods, nvidia.com/gpu, pending accelerator workloads,
device plugins, node selectors, taints, topology, gang scheduling, training
operators, GPU quotas, or Kubernetes ML optimization.
## Publication blocker
When available, cross-link the existing kubernetes-patterns skill rather than
copying it. The GPU-specific skill must still carry the minimum safe Job,
placement, validation, and teardown contract needed on Kimi, where the current
devops-infra module is not installable.
Workflow:
The integration works from a local build. Distribution remains blocked until
`ito-compute-cli` has an approved package-publication policy and is published
or replaced by another verified distribution channel. ECC must not claim npm
availability before a registry read confirms it.
- Inspect node capacity, device-plugin/runtime readiness, available APIs, and
installed operators before generating manifests.
- Choose a native Job unless an appropriate operator is already installed.
- Never invent a custom resource definition.
- Cover requests and limits, placement, topology, storage locality, checkpoints,
retries, quotas, observability, cost, and teardown.
- Produce manifests plus client and server dry-run checks.
## Shared provider rule for all five skills
Every skill must apply this order:
1. Capture workload requirements.
2. Reuse owned or existing compute when it fits.
3. If capacity is missing, present provider-neutral criteria.
4. Disclose Itô as ECC's preferred compute sponsor.
5. Allow another provider without degrading the workflow.
6. Trigger Itô authentication only after the user selects Itô.
7. Never claim inference serving, live inventory, a quote, or a rental action
unless the backing capability is verified live.
No legacy commands should be added. skills/ remains the canonical workflow
surface.
## Install and package shape
Add a non-default gpu-compute module in manifests/install-modules.json:
- Paths: the five skill directories above.
- Supported targets: all current targets, including kimi.
- Dependencies: platform-configs only. eval-harness, mle-workflow,
pytorch-patterns, and kubernetes-patterns remain optional cross-links rather
than hard dependencies so the module can install on every declared target,
including Gemini and Kimi.
- Default install: false.
- Stability: beta.
- Cost: medium.
Add capability:gpu-compute to manifests/install-components.json and add the
module to the full install profile. Individual skill components should remain
synthetic rather than being duplicated manually.
Add the five canonical skill directories to the npm publish surface, regenerate
the catalog, and validate the install graph. Do not hide these skills in the
current machine-learning module because that module does not support the Kimi
target.
## ito CLI and MCP v0
### Placement
Keep the initial stub inside ecc-universal:
scripts/ito.js
scripts/ito-mcp.js
scripts/lib/ito/contracts.js
scripts/lib/ito/capabilities.js
scripts/lib/ito/auth.js
scripts/lib/ito/client.js
scripts/lib/ito/mcp.js
Expose ecc ito as canonical and an ASCII ito bin alias. Every help, auth, and
error surface must call it “Itô compute” so it cannot be confused with ECC's
prediction-market ito-* skills. Prose and brand UI use Itô. Compute auth uses a
dedicated audience and credential namespace and must never discover, read, or
infer ITO_API_KEY.
### CLI commands
ito capabilities [--json]
ito dashboard --intent self-host|training [--no-open]
ito auth status [--json]
ito auth login --intent self-host|training [--no-open] [--json]
ito rent plan --intent ... --accelerator ... --count ... --memory-gib ... --hours ... [--json]
ito rent create --plan ... [--json]
ito rentals list [--json]
ito rentals get <id> [--json]
ito rentals stop <id> [--json]
ito mcp
### MCP tools
compute_capabilities
dashboard_handoff
auth_status
auth_login
rent_plan
rent_create
rentals_list
rental_get
rental_stop
Except for the ito mcp transport command, every CLI operation has an equivalent
MCP tool backed by the same service method. dashboard_handoff is the MCP peer of
ito dashboard. MCP handoff tools return a URL and never open a browser; only a
direct local CLI invocation may open one, and --no-open must remain available.
Every command emitted or invoked by a skill, agent, or generated artifact must
pass --no-open; automatic browser opening is reserved for a human typing the
CLI command directly.
All tools and commands return the same versioned response envelope. A supported
manual handoff looks like:
{
"schemaVersion": "ito.compute.v0",
"success": true,
"state": "manual_handoff",
"data": {
"authenticated": false
},
"error": null,
"links": {
"dashboard": "https://compute.itomarkets.com"
}
}
An unavailable capability must instead use:
{
"schemaVersion": "ito.compute.v0",
"success": false,
"state": "unavailable",
"data": null,
"error": {
"code": "CAPABILITY_NOT_AVAILABLE",
"message": "This operation requires an approved live Itô compute API."
},
"links": {
"dashboard": "https://compute.itomarkets.com"
}
}
Envelope invariants:
- unavailable always means success: false, non-null typed error, and no
action-like data.
- The CLI exits nonzero for unavailable or validation failures.
- MCP returns the same envelope in an error tool result; it must not translate
failure into a successful-looking action.
- manual_handoff means the routing behavior worked. It does not mean inventory,
OAuth, rental management, or inference is available.
### Honest stub behavior
| Capability | Phase 2 stub value |
|---|---|
| dashboardHandoff | true |
| oauthTokenExchange | false |
| rentRequestDraft | true |
| rentMutation | false |
| rentalManagement | false |
| inferenceServing | false |
- capabilities reports the table above.
- dashboard opens or returns the approved compute URL.
- auth status reports authenticated: false and oauthTokenExchange: false. It
must not inspect ITO_API_KEY or imply that dashboard cookies are CLI auth.
- auth login opens or returns the dashboard URL and reports manual action
required. MCP returns the URL without opening it. Neither path may say OAuth
succeeded.
- rent plan validates and normalizes requirements, then returns manual_handoff.
It must not fabricate inventory, price, quote, or plan ID.
- rent create, rental reads, and stop fail closed with
CAPABILITY_NOT_AVAILABLE until backed by live APIs.
- Future paid creation and rental stop remain hard-disabled until a trusted
consent channel exists. A model-supplied boolean, --confirm flag, or tool
argument is not proof of user consent. Live mutations require either
host-mediated user elicitation or a single-use capability issued outside the
model and bound to the account, exact action and resource, immutable quote or
resource ID, maximum cost, expiry, and idempotency key.
### MCP distribution
Add Itô only as an opt-in entry in mcp-configs/mcp-servers.json:
"ito": {
"command": "ito",
"args": ["mcp"],
"description": "Opt-in Itô compute rental and management interface. Manual dashboard handoff only until live control-plane APIs are enabled; does not provide inference serving."
}
Do not add it to the default .mcp.json or the Claude plugin manifest. ECC's MCP
policy permits one universal default connector; this integration is intentional
and task-scoped.
## OAuth-on-intent contract
The authentication trigger is a user decision, not installation:
self-host or training intent
-> capacity needed
-> user selects Itô
-> auth status
-> login handoff or future OAuth
Until the backend contract exists, login remains a manual dashboard handoff.
When live OAuth becomes available, require:
- A public native client using Authorization Code with PKCE S256 and no packaged
client secret, or an explicitly approved phishing-resistant device flow.
- State and nonce validation plus issuer, audience, and redirect validation.
- A loopback callback bound only to localhost with one-time state and a short
timeout, or the approved device-flow equivalent.
- Fixed redirect origins and least-privilege scopes.
- OS credential storage under an ecc.ito.compute-specific service/account
namespace, never repository files, .env files, MCP config, CLI arguments,
child-process environments, or ITO_API_KEY.
- Raw access and refresh tokens must never enter model context, MCP results,
stdout, stderr, telemetry, crash reports, or logs. Account and billing data is
redacted by default.
- Refresh and revocation behavior.
- Trusted account and cost consent before paid actions as defined in the
mutation-capability contract above.
## Input and generated-artifact safety
- Define JSON Schemas for intents, accelerator names, counts, memory, duration,
identifiers, plans, and every MCP input. Enforce enums and numeric ranges,
bound string and collection lengths, and reject control characters or
newlines in IDs and scheduler fields.
- Build subprocess calls with executable-plus-argv arrays. Never concatenate
inputs into a shell command, use shell: true, eval generated text, or interpolate
untrusted values into Slurm directives.
- Validate Slurm partitions, accounts, QOS, GRES/TRES, paths, and job names
before rendering. Validate Kubernetes resource names, API kinds, namespaces,
images, pull policy, resources, selectors, tolerations, volumes, and command
arrays against explicit schemas.
- Pin model, container, code, and dataset revisions in executable plans.
- Render artifacts by default. Submission or execution is a separate step that
requires explicit user authority and must preserve client/server dry runs.
- Never place kubeconfig, SSH keys, registry credentials, scheduler tokens, or
provider secrets in generated artifacts or model-visible output.
## Pre-stageable versus blocked
| Pre-stageable after approval | Blocked on Itô or serving infrastructure |
|---|---|
| Five provider-neutral skills | OAuth issuer and client registration |
| Resource sizing and workload plans | Authorization, token, refresh, and revocation endpoints |
| Slurm and Kubernetes artifacts for user-provided clusters | Live accelerator inventory and availability |
| Static dashboard handoff | Live pricing, quotes, billing, and idempotency |
| CLI/MCP schemas and capability reporting | Rental create, list, get, stop APIs and lifecycle states |
| Manual sign-in and rental handoff | SSH, kubeconfig, Slurm, or other access delivery |
| Fail-closed unavailable responses | Model upload and deployment |
| Mocked contract tests | Endpoint creation, health, autoscaling, and inference serving |
Inference serving is a separate future phase. It must not be unlocked merely by
finishing this Phase 2 stub.
## Test plan
Add:
- tests/ci/ito-compute-skills.test.js for exact skills, triggers,
provider-neutral language, sponsor disclosure, and the no-serving boundary.
- tests/lib/ito-contracts.test.js for validation, immutable envelopes, capability
states, URL allowlisting, injection-resistant schemas, and redaction.
- tests/scripts/ito.test.js for help, JSON, no-browser handoff, invalid input,
unavailable mutations, nonzero exit parity, and proof that ITO_API_KEY is
ignored.
- tests/scripts/ito-mcp.test.js for stdio initialization, tool schemas,
CLI/tool parity, error-result parity, no-browser handoff, and secret-free
results.
- tests/integration/ito-compute-e2e.test.js for ecc ito to manual handoff and MCP
calls without unapproved network or browser side effects.
Extend the ECC CLI, install-manifest, npm-publish-surface, and plugin-manifest
tests as required.
Required gates:
node scripts/ci/validate-skills.js --strict
node scripts/ci/validate-install-manifests.js
npm run catalog:check
npm test
npm run coverage
npm run lint
npm pack --dry-run --json
npm run security:ioc-scan
Manual acceptance:
- Existing hardware skips provider selection.
- An alternate provider path never invokes Itô authentication.
- Selecting Itô returns only truthful supported capabilities.
- Rental mutations fail closed until backed by live APIs.
- No flow emits an Itô inference endpoint.
- The Kimi target installs capability:gpu-compute.
- Paid and destructive actions remain unavailable until the trusted consent
capability and its separate approval exist.
## Delivery slices after approval
1. **Skills and install module:** five skills, provider rule, manifests, catalog,
and validation.
2. **CLI and opt-in MCP stub:** shared contracts, manual handoff, fail-closed
commands/tools, security and parity tests.
3. **OAuth and rental control plane:** a separately authorized future phase,
only after Itô supplies the live API contract and a threat model, API/contract
review, security review, billing review, and Affaan launch approval all pass.
4. **Inference serving:** separate plan, security review, economics review, and
explicit launch approval.
Each slice must use its own focused PR and stay mergeable without later slices.
## Affaan approval checklist
- [ ] Approve the five skill names and their boundaries.
- [ ] Approve separate Slurm and Kubernetes GPU skills.
- [ ] Approve capability:gpu-compute with Kimi target support.
- [ ] Approve sponsor wording: Itô in prose, ASCII ito for CLI and MCP.
- [ ] Approve ecc ito plus the ito bin alias inside ecc-universal.
- [ ] Approve an opt-in MCP entry and no default MCP/plugin registration.
- [ ] Approve manual-handoff and fail-closed stub semantics.
- [ ] Approve the shared response envelope and trusted-consent boundary.
- [ ] Confirm that this approval covers delivery slices 1 and 2 only; live auth,
billing, create, list/get, and stop remain separately approval-gated.
- [ ] Supply or explicitly defer the OAuth and rental API contract.
- [ ] Confirm endpoint configuration for every supported harness before
publishing an example.
- [ ] Decide whether prediction-market ito-* skills remain supported or enter a
later, separate deprecation cycle.
- [ ] Validate WorkloadSplitPlan with the LinkedIn contact before describing
Channel B as customer-validated.
Approval of this document authorizes delivery slices 1 and 2 only: the skills
and fail-closed stub. It does not authorize live auth, billing, rental APIs,
mutations, or claims that Itô inference serving is live.
The ECC package version remains unchanged in this worktree. Its version bump,
release commit, and publication are intentionally deferred to the release owner
after review.
## Verification
The local contract suite proves:
- only the three supported operations spawn;
- RFQ arguments are forwarded without economic reinterpretation;
- only approved Itô runtime variables cross the process boundary;
- unsupported and dry-run paths fail before spawn;
- a missing or relative executable fails closed with local-install guidance;
- canonical output and exit status pass through unchanged;
- the skill, install manifests, npm surface, and opt-in MCP template stay
aligned.
No test in this integration invokes a live Itô API, submits an RFQ, opens a
browser, or contacts a GPU node.
@@ -1,122 +0,0 @@
# ECC × Itô Sandbox Handoff Evidence
Date: 2026-07-23
Branch: `agent/ecc-ito-sandbox-handoff`
Base commit: `a3130f9ebfaeed075df5d5b52538acb0ee4bcdf8`
## Result
The canonical ECC CLI now supports:
```text
ecc ito rent --accelerator h100 --count 1 --hours 24
```
The command emits an `ito.compute.handoff.v1` envelope containing the exact
accelerator, count, and duration, `ecc-cli` provenance, and a read-only sandbox
authority ceiling. It opens only `https://compute.itomarkets.com/desk`.
No supported Itô deep link or non-mutating structured external-intake endpoint
exists yet. The contract therefore reports `transport: manual_copy`,
`acceptedByIto: false`, and `signInMayBeRequired: true`. It never claims that
opening the page delivered the intent.
The CLI does not read credentials, call the network, file an RFQ, request or
accept a quote, call procurement, approve funds, create an order, perform
outreach, deploy, push, or merge. The human boundary remains before
`Pay & buy`.
## Security boundary
Both subprocess boundaries use an explicit system-environment allowlist:
1. `ecc` to the `ito` command.
2. `ito` to the OS browser opener.
The allowlist retains only runtime essentials such as path, home, temporary
directory, locale, terminal, and desktop-session variables. ECC dry-run and
test controls are passed only to the Itô command where needed. Browser-probe
tests inject API-key, service-token, and password sentinels and prove none
reach the browser child.
## Eval evidence
Focused handoff:
```text
node tests/scripts/ito-handoff.test.js
```
Result: 9 passed, 0 failed.
Covered scenarios:
- exact H100, count 1, 24-hour mapping;
- provenance and sandbox authority;
- global and local dry-run with zero browser invocation;
- exact allowlisted browser URL and sanitized child environment;
- direct Itô invocation with sanitized browser environment;
- missing, duplicate, unsupported, and out-of-range input rejection;
- absence of credential or mutating transports;
- human-readable approval boundary;
- POSIX-safe npm welcome output.
CLI and package regressions:
```text
node tests/scripts/ecc.test.js
node tests/scripts/npm-publish-surface.test.js
```
Results: 21 passed and 2 passed, with 0 failures.
Full repository suite:
```text
npm test
```
Result: 3,155 passed, 0 failed.
Static and security gates:
```text
npm run lint
npm run security:ioc-scan -- --root .
git diff --check
```
Results: all passed; the IOC scan inspected 207 files.
Packaged-bin execution:
```text
npm pack --pack-destination <temporary-directory>
node <unpacked-package>/scripts/ecc.js --dry-run ito rent \
--accelerator h100 --count 1 --hours 24 --json
```
Result: the packed `ecc-universal-2.0.0.tgz` included executable `ecc.js` and
`ito.js`; the unpacked command returned the exact intent with `dryRun: true`,
`opened: false`, and `transport: manual_copy`.
## Changed surfaces
- `scripts/ito.js`
- `scripts/lib/ito-environment.js`
- `scripts/ecc.js`
- `package.json`
- `tests/scripts/ito-handoff.test.js`
- `tests/scripts/npm-publish-surface.test.js`
- `docs/design/ecc-ito-compute-integration.md`
- this evidence record
## Remaining limitation
ECC cannot automatically prefill or deliver this structured intent until Itô
publishes a safe, authenticated, non-mutating intake or deep-link contract.
Adding such a contract belongs in Itô and must preserve its existing human
approval gates. This ECC slice deliberately does not invent another UI,
transport, credential, or procurement path.
@@ -0,0 +1,95 @@
# ECC × Itô Real CLI Bridge — TDD Evidence
Date: 2026-07-23
Source plan: requirements were derived from the approved implementation
handoff. No external plan file was executed.
## User journeys
1. As an ECC operator, I can invoke the canonical local Itô `auth`, `find`, and
`status` operations without a duplicate client or browser workflow.
2. As a security reviewer, I can prove unsupported operations, missing local
installs, and ECC dry-run requests fail before any child process or network
operation.
3. As an agent-harness user, I can install one truthful skill that names only
the real CLI commands and MCP tools.
## RED evidence
Before production changes:
```text
node tests/scripts/ito-cli-bridge.test.js
Passed: 0
Failed: 9
node tests/ci/ito-compute-skill.test.js
Passed: 0
Failed: 4
```
The failures were caused by the old browser-only `rent` command and the missing
real skill/install/MCP surfaces.
## GREEN evidence
```text
node tests/scripts/ito-cli-bridge.test.js
Passed: 9
Failed: 0
node tests/ci/ito-compute-skill.test.js
Passed: 4
Failed: 0
NODE_PATH=<existing-ecc-checkout>/node_modules \
node scripts/ci/validate-install-manifests.js
Validated 33 install modules, 80 install components, and 7 profiles
npm test
Total Tests: 3159
Passed: 3159
Failed: 0
npm run coverage
Statements: 89.21%
Branches: 79.71%
Functions: 93.96%
Lines: 89.21%
npm run security:ioc-scan
Supply-chain IOC scan passed
```
The isolated worktree temporarily reused the canonical ECC checkout's existing
`node_modules` through an untracked local symlink. The symlink was removed
after validation; no dependency installation or source change was made in the
canonical checkout.
ESLint and Markdown lint also pass for every changed source file. The complete
package dry-run contains the wrapper, environment boundary, skill, and MCP
configuration.
## Test specification
| Guarantee | Test | Type | Result |
|---|---|---|---|
| Only `auth`, `find`, and `status` spawn | `tests/scripts/ito-cli-bridge.test.js` | end-to-end process contract | PASS |
| Full RFQ arguments cross unchanged | `tests/scripts/ito-cli-bridge.test.js` | integration | PASS |
| Only required Itô settings cross the child boundary | `tests/scripts/ito-cli-bridge.test.js` | security integration | PASS |
| Unsupported and dry-run operations fail before spawn | `tests/scripts/ito-cli-bridge.test.js` | negative end-to-end | PASS |
| Missing/relative executables fail with exact local guidance | `tests/scripts/ito-cli-bridge.test.js` | negative end-to-end | PASS |
| Child output and exit code are preserved | `tests/scripts/ito-cli-bridge.test.js` | end-to-end process contract | PASS |
| Skill, package, manifests, and MCP template agree | `tests/ci/ito-compute-skill.test.js` | repository contract | PASS |
## Known gaps
- No live Itô API, RFQ, browser, GPU node, or paid operation was invoked.
- No live GPU qualification was performed.
- The CLI remains locally built and unpublished.
## Merge evidence
No TDD checkpoint commits were created because the implementation handoff
explicitly prohibited commits. The working-tree diff and this report preserve
the RED/GREEN evidence instead.
+2 -2
View File
@@ -1,6 +1,6 @@
# Everything Claude Code (ECC) — 智能体指令
这是一个**生产就绪的 AI 编码插件**,提供 67 个专业代理、278 项技能、94 条命令以及自动化钩子工作流,用于软件开发。
这是一个**生产就绪的 AI 编码插件**,提供 67 个专业代理、279 项技能、94 条命令以及自动化钩子工作流,用于软件开发。
**版本:** 2.0.0
@@ -147,7 +147,7 @@
```
agents/ — 67 个专业子代理
skills/ — 278 个工作流技能和领域知识
skills/ — 279 个工作流技能和领域知识
commands/ — 94 个斜杠命令
hooks/ — 基于触发的自动化
rules/ — 始终遵循的指导方针(通用 + 每种语言)
+3 -3
View File
@@ -228,7 +228,7 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/"
/plugin list ecc@ecc
```
**搞定!** 你现在可以使用 67 个智能体、278 项技能和 94 个命令了。
**搞定!** 你现在可以使用 67 个智能体、279 项技能和 94 个命令了。
***
@@ -1142,7 +1142,7 @@ opencode
|---------|---------------|----------|--------|
| 智能体 | PASS: 67 个 | PASS: 12 个 | **Claude Code 领先** |
| 命令 | PASS: 94 个 | PASS: 35 个 | **Claude Code 领先** |
| 技能 | PASS: 278 项 | PASS: 37 项 | **Claude Code 领先** |
| 技能 | PASS: 279 项 | PASS: 37 项 | **Claude Code 领先** |
| 钩子 | PASS: 8 种事件类型 | PASS: 11 种事件 | **OpenCode 更多!** |
| 规则 | PASS: 29 条 | PASS: 13 条指令 | **Claude Code 领先** |
| MCP 服务器 | PASS: 14 个 | PASS: 完整 | **完全对等** |
@@ -1250,7 +1250,7 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
|---------|-----------------------|------------|-----------|----------|
| **智能体** | 67 | 共享 (AGENTS.md) | 共享 (AGENTS.md) | 12 |
| **命令** | 94 | 共享 | 基于指令 | 35 |
| **技能** | 278 | 共享 | 10 (原生格式) | 37 |
| **技能** | 279 | 共享 | 10 (原生格式) | 37 |
| **钩子事件** | 8 种类型 | 15 种类型 | 暂无 | 11 种类型 |
| **钩子脚本** | 20+ 个脚本 | 16 个脚本 (DRY 适配器) | N/A | 插件钩子 |
| **规则** | 34 (通用 + 语言) | 34 (YAML 前页) | 基于指令 | 13 条指令 |
+8
View File
@@ -194,6 +194,14 @@
"prediction-market-skills"
]
},
{
"id": "capability:ito-compute",
"family": "capability",
"description": "Authenticated Itô GPU inventory, RFQ, and status workflows through the separately installed canonical CLI.",
"modules": [
"ito-compute"
]
},
{
"id": "capability:social",
"family": "capability",
+30
View File
@@ -571,6 +571,36 @@
"cost": "medium",
"stability": "beta"
},
{
"id": "ito-compute",
"kind": "skills",
"description": "Authenticated Itô GPU inventory, RFQ, and status workflows through the separately installed canonical CLI.",
"paths": [
"skills/ito-compute"
],
"targets": [
"claude",
"claude-project",
"cursor",
"antigravity",
"codex",
"gemini",
"opencode",
"codebuddy",
"joycode",
"qwen",
"zed",
"hermes",
"openclaw",
"kimi"
],
"dependencies": [
"platform-configs"
],
"defaultInstall": false,
"cost": "light",
"stability": "beta"
},
{
"id": "social-distribution",
"kind": "skills",
+1
View File
@@ -87,6 +87,7 @@
"operator-workflows",
"optimization-workflows",
"prediction-market-skills",
"ito-compute",
"social-distribution",
"media-generation",
"orchestration",
+5
View File
@@ -5,6 +5,11 @@
"args": ["mcp"],
"description": "Local cost/privacy proxy - query your own usage & savings, route to the cheapest capable model, and mask secrets/PII before egress (nexus_stats, nexus_savings, nexus_recent, nexus_providers, nexus_cost_breakdown)"
},
"ito-compute": {
"command": "node",
"args": ["/absolute/path/to/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito-mcp.js"],
"description": "Opt-in local Itô compute MCP. The canonical package is unpublished and must be built from Ito-Markets/ito-cloud-runtime/cli/ito-compute-cli. Exposes only ito_auth, ito_find, and ito_status; inject ITO_API_KEY from the launching environment."
},
"jira": {
"command": "uvx",
"args": ["mcp-atlassian==0.21.0"],
+2 -1
View File
@@ -214,6 +214,7 @@
"skills/hookify-rules/",
"skills/inventory-demand-planning/",
"skills/ito-basket-compare/",
"skills/ito-compute/",
"skills/ito-data-atlas-agent/",
"skills/ito-market-intelligence/",
"skills/ito-trade-planner/",
@@ -418,7 +419,7 @@
"ecc-plan-canvas": "scripts/plan-canvas.js"
},
"scripts": {
"welcome": "echo '\\n ecc-universal installed!\\n Run: ecc typescript\\n Compat: ecc-install typescript\\n Docs: https://github.com/affaan-m/ECC\\n Run or self-host any open-source model.\\n Compute: Itô is the preferred compute sponsor — https://compute.itomarkets.com\\n Any GPU provider works; ECC only links to the dashboard and does not provision compute or serving.\\n Managed inference through Itô is not live yet.\\n'",
"welcome": "echo '\\n ecc-universal installed!\\n Run: ecc typescript\\n Compat: ecc-install typescript\\n Docs: https://github.com/affaan-m/ECC\\n Run or self-host any open-source model.\\n Compute: Itô is the preferred compute sponsor — https://compute.itomarkets.com\\n Any GPU provider works. This sponsorship link is passive: it does not invoke an RFQ, reserve capacity, provision compute, or configure serving.\\n Separately, the opt-in ecc ito find bridge invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity.\\n Managed inference through Itô is not live yet.\\n'",
"catalog:check": "node scripts/ci/catalog.js --text",
"catalog:sync": "node scripts/ci/catalog.js --write --text",
"command-registry:generate": "node scripts/ci/generate-command-registry.js",
+10 -4
View File
@@ -29,7 +29,7 @@ const COMMANDS = {
},
ito: {
script: 'ito.js',
description: 'Prepare a read-only sandbox handoff to the Itô compute desk',
description: 'Invoke the separately installed canonical Itô compute CLI',
},
'install-plan': {
script: 'install-plan.js',
@@ -138,8 +138,9 @@ Examples:
ecc catalog show framework:nextjs
ecc consult "security reviews"
ecc control-pane --port 8765
ecc ito rent --accelerator h100 --count 1 --hours 24
ecc --dry-run ito rent --accelerator h100 --count 1 --hours 24 --json
ecc ito auth
ecc ito find --gpu h200 --count 8 --nodes 1 --gpus-per-node 8 --days 30 --storage-tb 1 --start-window 2099-08-15 --max-rate 3.00 --form-factor bare_metal --contract-type reservation --fabric infiniband --region us-east-1
ecc ito status --json
ecc list-installed --json
ecc doctor --target cursor
ecc repair --dry-run
@@ -232,7 +233,12 @@ function runCommand(commandName, args) {
{
cwd: process.cwd(),
env: commandName === 'ito'
? { ...createSafeItoEnvironment(process.env, { includeControls: true }) }
? {
...createSafeItoEnvironment(process.env, {
includeControls: true,
includeItoRuntime: true,
}),
}
: process.env,
encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024,
+179 -275
View File
@@ -2,306 +2,210 @@
"use strict";
const fs = require("fs");
const path = require("path");
const { spawnSync } = require("child_process");
const { createSafeItoEnvironment } = require("./lib/ito-environment");
const DESK_URL = "https://compute.itomarkets.com/desk";
const SCHEMA_VERSION = "ito.compute.handoff.v1";
const SUPPORTED_ACCELERATORS = Object.freeze({
h100: "h100",
"h100-pcie": "h100-pcie",
"h100-sxm": "h100-sxm",
});
const REQUIRED_INTENT_OPTIONS = Object.freeze([
"accelerator",
"count",
"hours",
]);
const SUPPORTED_COMMANDS = Object.freeze(["auth", "find", "status"]);
const CANONICAL_REPOSITORY = "https://github.com/Ito-Markets/ito-cloud-runtime.git";
const CANONICAL_PACKAGE_PATH = "cli/ito-compute-cli";
const EXECUTABLE_OVERRIDE = "ECC_ITO_CLI_EXECUTABLE";
const MAX_OUTPUT_BYTES = 10 * 1024 * 1024;
function showHelp() {
console.log(`
ECC × Itô compute handoff
ECC × Itô local CLI bridge
Usage:
ecc ito rent --accelerator <h100|h100-pcie|h100-sxm> --count <1-64> --hours <1-720> [options]
ecc ito auth
ecc ito find <all required RFQ options>
ecc ito status
ecc ito <auth|find|status> --json
Options:
--dry-run Emit the exact handoff without opening a browser
--no-open Emit the exact handoff for manual browser navigation
--json Emit the versioned response envelope as JSON
--help Show this help
The bridge invokes the separately installed canonical Itô CLI and returns its
real stdout, stderr, and exit code unchanged. It performs no browser navigation
and adds no lock, workload, inference, evaluation, or purchase path.
Example:
ecc ito rent --accelerator h100 --count 1 --hours 24
Important:
- "find" reads live inventory and submits an authenticated RFQ.
- Obtain explicit buyer authority and every hard constraint before invoking it.
- "status" reads live RFQ and procurement status.
- Inventory and RFQs are not reservations; only a returned firm quote is firm.
This command creates a sandbox-only, read-only intent. It opens the Itô desk
for manual copy; sign-in may be required. It does not send the intent into Itô,
file an RFQ, request or accept a quote, call a procurement endpoint, approve
funds, or place an order. Stop before "Pay & buy".
The canonical package is currently unpublished. Install it locally:
Canonical source: Ito-Markets/ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}
git clone ${CANONICAL_REPOSITORY}
cd ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}
npm ci
npm run check
Then set ${EXECUTABLE_OVERRIDE} to the explicit absolute built entry:
/absolute/path/to/ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}/dist/bin/ito.js
For safety, ECC never discovers this credential-bearing client through PATH.
The same package's MCP server exposes only:
ito_auth
ito_find
ito_status
Configure the MCP command as "node" with this absolute argument:
/absolute/path/to/ito-cloud-runtime/${CANONICAL_PACKAGE_PATH}/dist/bin/ito-mcp.js
Inject ITO_API_KEY into the child process from 1Password or the launching
environment. Never put the key in arguments, tracked files, or chat.
`);
}
function readValue(args, index, option) {
const value = args[index + 1];
if (value === undefined || value.startsWith("--")) {
throw new Error(`--${option} requires a value`);
}
return value;
}
function parseInteger(raw, option, minimum, maximum) {
if (!/^[0-9]+$/.test(raw)) {
throw new Error(`--${option} must be an integer between ${minimum} and ${maximum}`);
}
const value = Number(raw);
if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
throw new Error(`--${option} must be an integer between ${minimum} and ${maximum}`);
}
return value;
}
function parseAccelerator(raw) {
const normalized = String(raw).trim().toLowerCase();
const accelerator = SUPPORTED_ACCELERATORS[normalized];
if (!accelerator) {
throw new Error(
"--accelerator must be one of h100, h100-pcie, or h100-sxm"
);
}
return accelerator;
}
function parseArgs(argv) {
function parseArgs(argv, environment = process.env) {
const args = [...argv];
if (args.includes("--help") || args.includes("-h")) {
return { help: true };
if (
args.length === 0
|| args.includes("--help")
|| args.includes("-h")
) {
return Object.freeze({ help: true, invocationArgs: [] });
}
const command = args.shift();
if (command !== "rent") {
throw new Error(`unsupported Itô command: ${command || "(missing)"}`);
}
const values = {
accelerator: null,
count: null,
hours: null,
dryRun: false,
json: false,
noOpen: false,
};
const seen = new Set();
for (let index = 0; index < args.length; index += 1) {
const arg = args[index];
if (arg === "--dry-run") {
if (seen.has("dry-run")) throw new Error("--dry-run may only be provided once");
seen.add("dry-run");
values.dryRun = true;
continue;
}
if (arg === "--json") {
if (seen.has("json")) throw new Error("--json may only be provided once");
seen.add("json");
values.json = true;
continue;
}
if (arg === "--no-open") {
if (seen.has("no-open")) throw new Error("--no-open may only be provided once");
seen.add("no-open");
values.noOpen = true;
continue;
}
const option = arg.startsWith("--") ? arg.slice(2) : "";
if (!REQUIRED_INTENT_OPTIONS.includes(option)) {
throw new Error(`unsupported option: ${arg}`);
}
if (seen.has(option)) {
throw new Error(`--${option} may only be provided once`);
}
seen.add(option);
const raw = readValue(args, index, option);
if (option === "accelerator") values.accelerator = parseAccelerator(raw);
if (option === "count") values.count = parseInteger(raw, option, 1, 64);
if (option === "hours") values.hours = parseInteger(raw, option, 1, 720);
index += 1;
}
const missing = REQUIRED_INTENT_OPTIONS.filter((option) => values[option] === null);
if (missing.length > 0) {
if (environment.ECC_DRY_RUN === "1" || args.includes("--dry-run")) {
throw new Error(
`missing required rental intent option${missing.length === 1 ? "" : "s"}: `
+ missing.map((option) => `--${option}`).join(", ")
"Itô compute has no paper or dry-run success mode. No CLI operation was invoked."
);
}
return {
help: false,
command,
options: Object.freeze({
...values,
dryRun: values.dryRun || process.env.ECC_DRY_RUN === "1",
}),
};
}
function buildHandoffMessage(intent) {
const accelerator = intent.accelerator.toUpperCase();
return [
"[ECC sandbox-only compute handoff]",
`Source: ECC CLI. Need ${intent.count} × ${accelerator} for ${intent.hours} hours.`,
"Treat this as a read-only requirement for review.",
"Do not file an RFQ, request or accept a quote, place an order, approve funds, or contact a counterparty without a separate explicit human action in Itô.",
].join(" ");
}
function createEnvelope({ success, state, data, error }) {
return Object.freeze({
schemaVersion: SCHEMA_VERSION,
success,
state,
data,
error,
links: Object.freeze({ desk: DESK_URL }),
});
}
function createInvalidEnvelope(message) {
return createEnvelope({
success: false,
state: "invalid_request",
data: null,
error: Object.freeze({
code: "INVALID_ARGUMENT",
message,
}),
});
}
function defaultOpenUrl(url) {
let executable;
let args;
const testExecutable = process.env.NODE_ENV === "test"
? process.env.ECC_ITO_BROWSER_EXECUTABLE
: null;
if (testExecutable) {
if (process.platform === "win32" && /\.(?:bat|cmd)$/i.test(testExecutable)) {
executable = process.env.ComSpec || "cmd.exe";
args = ["/d", "/s", "/c", testExecutable, url];
} else {
executable = testExecutable;
args = [url];
}
} else if (process.platform === "darwin") {
executable = "open";
args = [url];
} else if (process.platform === "win32") {
executable = "cmd.exe";
args = ["/d", "/s", "/c", "start", "", url];
} else {
executable = "xdg-open";
args = [url];
const jsonIndexes = args
.map((value, index) => (value === "--json" ? index : -1))
.filter((index) => index >= 0);
if (jsonIndexes.length > 1) {
throw new Error("--json may only be provided once");
}
const withoutJson = args.filter((value) => value !== "--json");
const command = withoutJson.shift();
if (!SUPPORTED_COMMANDS.includes(command)) {
throw new Error(
`Unsupported Itô command "${command || "(missing)"}"; ECC permits only auth, find, and status.`
);
}
const result = spawnSync(executable, args, {
env: { ...createSafeItoEnvironment(process.env) },
stdio: "ignore",
windowsHide: true,
shell: false,
});
return !result.error && result.status === 0;
}
function createHandoff(options, openUrl = defaultOpenUrl) {
const shouldOpen = !options.dryRun && !options.noOpen;
const opened = shouldOpen ? openUrl(DESK_URL) : false;
const intent = Object.freeze({
accelerator: options.accelerator,
count: options.count,
hours: options.hours,
});
return createEnvelope({
success: true,
state: "manual_handoff",
data: Object.freeze({
authenticated: null,
dryRun: options.dryRun,
opened,
intent,
provenance: Object.freeze({
source: "ecc-cli",
command: "ecc ito rent",
}),
authority: Object.freeze({
environment: "sandbox",
readOnly: true,
liveRfq: false,
procurementMutation: false,
quoteAcceptance: false,
fundsApproval: false,
orderCreation: false,
outreach: false,
}),
handoff: Object.freeze({
transport: "manual_copy",
destination: "ito-desk",
acceptedByIto: false,
signInMayBeRequired: true,
message: buildHandoffMessage(intent),
limitation: "Itô /desk currently exposes no supported structured ECC intake or deep-link contract.",
}),
approvalGate: 'Stop before "Pay & buy".',
priceQuote: null,
orderId: null,
}),
error: null,
return Object.freeze({
help: false,
invocationArgs: Object.freeze([
...(jsonIndexes.length === 1 ? ["--json"] : []),
command,
...withoutJson,
]),
});
}
function renderText(payload) {
const { data } = payload;
const browserState = data.dryRun
? "Dry-run: browser not opened."
: data.opened
? "Opened the Itô desk; sign-in may be required."
: "Browser not opened; sign-in may be required at the Itô desk.";
return [
"ECC × Itô sandbox compute handoff",
"",
browserState,
`Desk: ${payload.links.desk}`,
"Transport: manual copy; Itô has not accepted this intent.",
`Message: ${data.handoff.message}`,
`Limitation: ${data.handoff.limitation}`,
`Approval gate: ${data.approvalGate}`,
"",
"ECC does not file an RFQ, request or accept a quote, use credentials, approve funds, create an order, or contact a counterparty.",
].join("\n");
function resolveItoExecutable(environment = process.env) {
const configured = environment[EXECUTABLE_OVERRIDE]?.trim();
if (!configured) {
throw new Error([
"The canonical ito-compute-cli is unpublished and ECC will not resolve",
`a credential-bearing "ito" executable from PATH. Build it from`,
`${CANONICAL_REPOSITORY.replace(/\.git$/, "")}/${CANONICAL_PACKAGE_PATH},`,
"run npm ci and npm run check, then set",
`${EXECUTABLE_OVERRIDE} to the explicit absolute dist/bin/ito.js path.`,
].join(" "));
}
if (!path.isAbsolute(configured)) {
throw new Error(
`${EXECUTABLE_OVERRIDE} must be an absolute path explicitly configured by the operator.`
);
}
return assertUsableExecutable(configured);
}
function main(argv = process.argv.slice(2), dependencies = {}) {
let parsed;
function assertUsableExecutable(candidate) {
let canonicalCandidate;
try {
parsed = parseArgs(argv);
canonicalCandidate = fs.realpathSync.native(candidate);
} catch {
throw new Error(
`${EXECUTABLE_OVERRIDE} does not point to a readable local Itô CLI file.`
);
}
if (!isUsableExecutable(canonicalCandidate)) {
throw new Error(
`${EXECUTABLE_OVERRIDE} does not point to a readable local Itô CLI file.`
);
}
return canonicalCandidate;
}
function isUsableExecutable(candidate) {
try {
const info = fs.statSync(candidate);
if (!info.isFile()) return false;
if (process.platform !== "win32" && path.extname(candidate) !== ".js") {
fs.accessSync(candidate, fs.constants.X_OK);
} else {
fs.accessSync(candidate, fs.constants.R_OK);
}
return true;
} catch {
return false;
}
}
function buildInvocation(executable, args) {
if (path.extname(executable).toLowerCase() === ".js") {
return Object.freeze({
executable: process.execPath,
args: Object.freeze([executable, ...args]),
});
}
if (
process.platform === "win32"
&& /\.(?:bat|cmd|ps1)$/i.test(executable)
) {
throw new Error(
`Refusing to invoke the Itô CLI through a shell shim. Set ${EXECUTABLE_OVERRIDE} to the absolute dist/bin/ito.js path.`
);
}
return Object.freeze({ executable, args: Object.freeze([...args]) });
}
function invokeIto(executable, args, environment = process.env) {
const invocation = buildInvocation(executable, args);
const result = spawnSync(invocation.executable, invocation.args, {
cwd: process.cwd(),
encoding: "utf8",
env: {
...createSafeItoEnvironment(environment, { includeItoRuntime: true }),
},
maxBuffer: MAX_OUTPUT_BYTES,
shell: false,
windowsHide: true,
});
if (result.stdout) process.stdout.write(result.stdout);
if (result.stderr) process.stderr.write(result.stderr);
if (result.error) {
throw new Error(`The local Itô CLI could not be started: ${result.error.message}`);
}
if (typeof result.status === "number") return result.status;
if (result.signal) {
throw new Error(`The local Itô CLI terminated by signal ${result.signal}.`);
}
return 1;
}
function main(argv = process.argv.slice(2), environment = process.env) {
try {
const parsed = parseArgs(argv, environment);
if (parsed.help) {
showHelp();
return 0;
}
const executable = resolveItoExecutable(environment);
return invokeIto(executable, parsed.invocationArgs, environment);
} catch (error) {
const payload = createInvalidEnvelope(error.message);
if (argv.includes("--json")) console.log(JSON.stringify(payload, null, 2));
else console.error(`Error: ${error.message}`);
console.error(`Error: ${error.message}`);
return 1;
}
if (parsed.help) {
showHelp();
return 0;
}
const payload = createHandoff(parsed.options, dependencies.openUrl);
if (parsed.options.json) console.log(JSON.stringify(payload, null, 2));
else console.log(renderText(payload));
return 0;
}
if (require.main === module) {
@@ -309,13 +213,13 @@ if (require.main === module) {
}
module.exports = Object.freeze({
DESK_URL,
SCHEMA_VERSION,
buildHandoffMessage,
createHandoff,
createInvalidEnvelope,
CANONICAL_PACKAGE_PATH,
CANONICAL_REPOSITORY,
EXECUTABLE_OVERRIDE,
SUPPORTED_COMMANDS,
buildInvocation,
invokeIto,
main,
parseAccelerator,
parseArgs,
renderText,
resolveItoExecutable,
});
+5 -2
View File
@@ -6,8 +6,11 @@ function getComputeSponsorCopy() {
return "Run or self-host any open-source model. Itô is ECC's preferred compute sponsor: "
+ 'open its dashboard to sign in and rent or manage GPUs at '
+ ITO_COMPUTE_URL
+ '. Any GPU provider works. ECC only provides this link; it does not provision '
+ 'compute or serving. Managed inference through Itô is not live yet.';
+ '. Any GPU provider works. This sponsorship link is passive: it does not invoke '
+ 'an RFQ, reserve capacity, provision compute, or configure serving. Separately, '
+ 'the opt-in "ecc ito find" bridge invokes the explicitly configured canonical '
+ 'Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. '
+ 'Managed inference through Itô is not live yet.';
}
module.exports = Object.freeze({
+22 -4
View File
@@ -23,6 +23,18 @@ const SYSTEM_ENVIRONMENT_KEYS = Object.freeze([
"XDG_RUNTIME_DIR",
]);
const ITO_RUNTIME_ENVIRONMENT_KEYS = Object.freeze([
"ITO_API_KEY",
"ITO_API_URL",
"ITO_INVENTORY_URL",
]);
const ECC_ITO_CONTROL_KEYS = Object.freeze([
"ECC_DRY_RUN",
"ECC_ITO_CLI_EXECUTABLE",
"NODE_ENV",
]);
function copyDefined(source, target, key) {
if (typeof source[key] === "string") {
target[key] = source[key];
@@ -38,11 +50,15 @@ function createSafeItoEnvironment(source = process.env, options = {}) {
if (key.startsWith("LC_")) copyDefined(source, safe, key);
}
if (options.includeItoRuntime) {
for (const key of ITO_RUNTIME_ENVIRONMENT_KEYS) {
copyDefined(source, safe, key);
}
}
if (options.includeControls) {
copyDefined(source, safe, "ECC_DRY_RUN");
copyDefined(source, safe, "NODE_ENV");
if (source.NODE_ENV === "test") {
copyDefined(source, safe, "ECC_ITO_BROWSER_EXECUTABLE");
for (const key of ECC_ITO_CONTROL_KEYS) {
copyDefined(source, safe, key);
}
}
@@ -50,6 +66,8 @@ function createSafeItoEnvironment(source = process.env, options = {}) {
}
module.exports = Object.freeze({
ECC_ITO_CONTROL_KEYS,
ITO_RUNTIME_ENVIRONMENT_KEYS,
SYSTEM_ENVIRONMENT_KEYS,
createSafeItoEnvironment,
});
+103
View File
@@ -0,0 +1,103 @@
---
name: ito-compute
description: Query live GPU inventory, submit an authenticated Itô fixed-rate RFQ, and inspect RFQ or procurement status through the separately installed canonical CLI or its exact MCP tools. Use when a user asks to find H100/H200 capacity, request a fixed compute rate, or check Itô compute status.
metadata:
origin: ECC
---
# Itô Compute
Use the canonical Itô compute CLI or MCP server. ECC does not implement a
parallel client, browser handoff, local simulation, reservation, workload
runner, or inference server.
## Install the canonical local package
`ito-compute-cli` is currently unpublished. Build it from its canonical
repository instead of using `npx`, `npm exec`, or an unverified package:
```sh
git clone https://github.com/Ito-Markets/ito-cloud-runtime.git
cd ito-cloud-runtime/cli/ito-compute-cli
npm ci
npm run check
```
Set `ECC_ITO_CLI_EXECUTABLE` to the explicit absolute built entry:
```text
/absolute/path/to/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito.js
```
ECC never discovers this credential-bearing client through `PATH`.
Inject `ITO_API_KEY` through 1Password or the launching process environment.
Never put it in arguments, tracked files, MCP results, logs, or chat.
## CLI workflow
1. Run `ecc ito auth` before the first operation.
2. Before `ecc ito find`, obtain explicit buyer authority to submit an RFQ.
- Require `gpu`, `count`, whole `days`, `max-rate`, `nodes`,
`gpus-per-node`, `storage-tb`, `start-window`, `form-factor`,
`contract-type`, `fabric`, `region`, and the split-fill decision.
- Require `count == nodes * gpus-per-node`; never derive topology.
- Use `any` only when the buyer explicitly accepts any fabric or region.
- Omitted `--allow-split` means false.
3. Run the live RFQ command:
```sh
ecc ito find \
--gpu h200 \
--count 8 \
--nodes 1 \
--gpus-per-node 8 \
--days 30 \
--storage-tb 1 \
--start-window 2099-08-15 \
--max-rate 3.00 \
--form-factor bare_metal \
--contract-type reservation \
--fabric infiniband \
--region us-east-1
```
4. Run `ecc ito status` to inspect RFQs and procurement orders.
After an ambiguous transport failure, check status before repeating `find`.
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.
## MCP workflow
Build the canonical package, then configure the stdio server with an absolute
path:
```json
{
"mcpServers": {
"ito-compute": {
"command": "node",
"args": [
"/absolute/path/to/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito-mcp.js"
]
}
}
}
```
The server exposes only:
- `ito_auth`
- `ito_find`
- `ito_status`
Use `ito_auth`, gather explicit buyer authority and every hard constraint, call
`ito_find`, then poll with `ito_status` when needed.
## Unsupported operations
The supported client surface cannot lock quotes, reserve capacity, execute
workloads, qualify nodes through ECC, or serve inference. 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.
+5 -2
View File
@@ -41,8 +41,11 @@ def print_self_host_compute_notice(provider: str) -> None:
"https://compute.itomarkets.com"
)
print(
"Any GPU provider works. ECC only links to the Itô dashboard; it does not "
"provision compute or serving. Managed inference through Itô is not live yet."
"Any GPU provider works. This sponsorship link is passive: it does not invoke "
"an RFQ, reserve capacity, provision compute, or configure serving. Separately, "
'the opt-in "ecc ito find" bridge invokes the explicitly configured canonical '
"Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. "
"Managed inference through Itô is not live yet."
)
+115
View File
@@ -0,0 +1,115 @@
/**
* Contract tests for the installable Itô compute skill and MCP documentation.
*/
const assert = require("assert");
const fs = require("fs");
const path = require("path");
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 runTest(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (error) {
console.log(`${name}`);
console.error(` ${error.message}`);
return false;
}
}
function main() {
console.log("\n=== Testing Itô compute skill surface ===\n");
const tests = [
["documents only the real CLI commands and MCP tools", () => {
const skill = read("skills/ito-compute/SKILL.md");
for (const command of ["ecc ito auth", "ecc ito find", "ecc ito status"]) {
assert.match(skill, new RegExp(command.replace(" ", "\\s+")));
}
assert.doesNotMatch(skill, /^\s*ito (?:auth|find|status)\b/m);
for (const tool of ["ito_auth", "ito_find", "ito_status"]) {
assert.match(skill, new RegExp(`\\b${tool}\\b`));
}
assert.doesNotMatch(
skill,
/ito_lock|ito_run|ITO_CLI_DEMO|paper mode|simulated|live on the registry|publishing soon/i
);
assert.match(skill, /unpublished/i);
assert.match(skill, /Ito-Markets\/ito-cloud-runtime/);
assert.match(skill, /cli\/ito-compute-cli/);
assert.match(skill, /npm run check/);
assert.match(skill, /ECC_ITO_CLI_EXECUTABLE/);
assert.match(skill, /explicit absolute built entry/);
assert.match(skill, /never discovers[^\n]*through `PATH`/);
assert.doesNotMatch(skill, /npm link/);
}],
["registers one opt-in install module and capability", () => {
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"]);
assert.deepStrictEqual(module.dependencies, ["platform-configs"]);
assert.strictEqual(module.defaultInstall, false);
assert.strictEqual(module.stability, "beta");
for (const target of ["claude", "codex", "opencode", "hermes", "kimi"]) {
assert.ok(module.targets.includes(target), `${target} target is missing`);
}
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, and status 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"));
}],
["publishes the skill but never bundles the Itô CLI", () => {
const packageJson = readJson("package.json");
assert.ok(packageJson.files.includes("skills/ito-compute/"));
assert.ok(!packageJson.dependencies?.["ito-compute-cli"]);
assert.ok(!packageJson.optionalDependencies?.["ito-compute-cli"]);
assert.ok(!packageJson.bin?.ito);
}],
["offers an opt-in local MCP template with the exact real tool boundary", () => {
const mcpConfig = readJson("mcp-configs/mcp-servers.json");
const server = mcpConfig.mcpServers["ito-compute"];
assert.ok(server, "ito-compute MCP template is missing");
assert.strictEqual(server.command, "node");
assert.deepStrictEqual(server.args, [
"/absolute/path/to/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito-mcp.js",
]);
assert.doesNotMatch(JSON.stringify(server), /npx|ito_lock|ito_run|paper|simulat/i);
assert.match(server.description, /ito_auth, ito_find, and ito_status/);
assert.match(server.description, /unpublished/i);
}],
];
let passed = 0;
let failed = 0;
for (const [name, fn] of tests) {
if (runTest(name, fn)) passed += 1;
else failed += 1;
}
console.log(`\nPassed: ${passed}`);
console.log(`Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);
}
main();
+1
View File
@@ -39,6 +39,7 @@ function run(args = [], options = {}) {
env,
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe'],
maxBuffer: 4 * 1024 * 1024,
timeout: options.timeout || DEFAULT_INSTALL_APPLY_TIMEOUT_MS,
});
+293
View File
@@ -0,0 +1,293 @@
/**
* End-to-end contract tests for ECC's real local Itô CLI bridge.
*
* The executable used here is a process-boundary probe. It never contacts an
* Itô API, submits an RFQ, opens a browser, or reaches a GPU node.
*/
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, "..", "..");
const ECC_SCRIPT = path.join(REPO_ROOT, "scripts", "ecc.js");
const CANONICAL_PACKAGE = "Ito-Markets/ito-cloud-runtime/cli/ito-compute-cli";
function runCli(args, environment = {}) {
return spawnSync(process.execPath, [ECC_SCRIPT, ...args], {
cwd: REPO_ROOT,
encoding: "utf8",
env: {
...process.env,
NODE_ENV: "test",
...environment,
},
});
}
function makeItoProbe(exitCode = 0) {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), "ecc-ito-cli-"));
const log = path.join(directory, "invocation.json");
const script = path.join(directory, "ito-probe.js");
const executable = script;
fs.writeFileSync(
script,
[
`#!${process.execPath}`,
'"use strict";',
'const fs = require("fs");',
`fs.writeFileSync(${JSON.stringify(log)}, JSON.stringify({ argv: process.argv.slice(2), env: process.env }));`,
'process.stdout.write(`ito-probe:${process.argv.slice(2).join("|")}\\n`);',
'process.stderr.write("ito-probe-stderr\\n");',
`process.exit(${exitCode});`,
"",
].join("\n")
);
if (process.platform !== "win32") {
fs.chmodSync(script, 0o755);
}
return Object.freeze({ directory, executable, log });
}
function readInvocation(probe) {
return JSON.parse(fs.readFileSync(probe.log, "utf8"));
}
function runTest(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (error) {
console.log(`${name}`);
console.error(` ${error.message}`);
return false;
}
}
function main() {
console.log("\n=== Testing ECC × Itô real CLI bridge ===\n");
const tests = [
["forwards only auth, find, and status to an explicit local executable", () => {
for (const command of ["auth", "find", "status"]) {
const probe = makeItoProbe();
try {
const result = runCli(["ito", command], {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
});
assert.strictEqual(result.status, 0, result.stderr);
assert.deepStrictEqual(readInvocation(probe).argv, [command]);
assert.match(result.stdout, new RegExp(`ito-probe:${command}`));
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}
}],
["normalizes JSON and forwards every RFQ constraint without interpretation", () => {
const probe = makeItoProbe();
try {
const args = [
"ito",
"find",
"--gpu", "h200",
"--count", "8",
"--nodes", "1",
"--gpus-per-node", "8",
"--days", "30",
"--storage-tb", "1",
"--start-window", "2099-08-15",
"--max-rate", "3.00",
"--form-factor", "bare_metal",
"--contract-type", "reservation",
"--fabric", "infiniband",
"--region", "us-east-1",
"--json",
];
const result = runCli(args, {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
});
assert.strictEqual(result.status, 0, result.stderr);
assert.deepStrictEqual(readInvocation(probe).argv, [
"--json",
...args.slice(1, -1),
]);
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}],
["passes only the required Itô runtime settings across the process boundary", () => {
const probe = makeItoProbe();
try {
const result = runCli(["ito", "auth"], {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
ITO_API_KEY: "ito_test_key",
ITO_API_URL: "https://compute.example.test",
ITO_INVENTORY_URL: "https://edge.example.test",
AWS_SECRET_ACCESS_KEY: "must-not-cross",
OPENAI_API_KEY: "must-not-cross",
TEST_PASSWORD: "must-not-cross",
});
assert.strictEqual(result.status, 0, result.stderr);
const childEnvironment = readInvocation(probe).env;
assert.strictEqual(childEnvironment.ITO_API_KEY, "ito_test_key");
assert.strictEqual(childEnvironment.ITO_API_URL, "https://compute.example.test");
assert.strictEqual(childEnvironment.ITO_INVENTORY_URL, "https://edge.example.test");
assert.strictEqual(childEnvironment.AWS_SECRET_ACCESS_KEY, undefined);
assert.strictEqual(childEnvironment.OPENAI_API_KEY, undefined);
assert.strictEqual(childEnvironment.TEST_PASSWORD, undefined);
assert.strictEqual(childEnvironment.ECC_ITO_CLI_EXECUTABLE, undefined);
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}],
["rejects unsupported, browser, simulated, and node operations before spawning", () => {
for (const command of ["rent", "lock", "run", "inference", "evals", "mcp"]) {
const probe = makeItoProbe();
try {
const result = runCli(["ito", command], {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
});
assert.notStrictEqual(result.status, 0, command);
assert.match(result.stderr, /only auth, find, and status/i);
assert.ok(!fs.existsSync(probe.log), `${command} must not spawn the Itô CLI`);
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}
}],
["fails closed rather than simulating a dry-run RFQ", () => {
const probe = makeItoProbe();
try {
const result = runCli(["--dry-run", "ito", "find"], {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
});
assert.notStrictEqual(result.status, 0);
assert.match(result.stderr, /no paper or dry-run success mode/i);
assert.ok(!fs.existsSync(probe.log));
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}],
["fails closed with exact local install guidance when the explicit CLI is absent", () => {
const emptyPath = fs.mkdtempSync(path.join(os.tmpdir(), "ecc-empty-path-"));
try {
const result = runCli(["ito", "status"], {
ECC_ITO_CLI_EXECUTABLE: "",
PATH: emptyPath,
});
assert.notStrictEqual(result.status, 0);
assert.match(result.stderr, /canonical ito-compute-cli is unpublished/i);
assert.match(result.stderr, new RegExp(CANONICAL_PACKAGE.replaceAll("/", "\\/")));
assert.match(result.stderr, /npm run check/);
assert.match(result.stderr, /ECC_ITO_CLI_EXECUTABLE/);
assert.match(result.stderr, /explicit absolute/i);
assert.match(result.stderr, /unpublished/i);
assert.doesNotMatch(result.stderr, /npx|npm exec|npm link|install -g/i);
} finally {
fs.rmSync(emptyPath, { recursive: true, force: true });
}
}],
["never forwards Itô credentials to an unverified PATH collision", () => {
const collisionDirectory = fs.mkdtempSync(
path.join(os.tmpdir(), "ecc-hostile-ito-path-")
);
const stolenEnvironment = path.join(collisionDirectory, "stolen.json");
const executable = path.join(
collisionDirectory,
process.platform === "win32" ? "ito.exe" : "ito"
);
try {
fs.writeFileSync(
executable,
[
`#!${process.execPath}`,
'"use strict";',
'const fs = require("fs");',
`fs.writeFileSync(${JSON.stringify(stolenEnvironment)}, JSON.stringify(process.env));`,
"",
].join("\n")
);
if (process.platform !== "win32") {
fs.chmodSync(executable, 0o755);
}
const result = runCli(["ito", "auth"], {
ECC_ITO_CLI_EXECUTABLE: "",
ITO_API_KEY: "must-never-reach-path-collision",
PATH: collisionDirectory,
});
assert.notStrictEqual(result.status, 0);
assert.match(result.stderr, /explicit absolute|ECC_ITO_CLI_EXECUTABLE/i);
assert.ok(
!fs.existsSync(stolenEnvironment),
"an unverified PATH executable must never receive the Itô credential"
);
} finally {
fs.rmSync(collisionDirectory, { recursive: true, force: true });
}
}],
["rejects a relative executable override instead of searching or guessing", () => {
const result = runCli(["ito", "status"], {
ECC_ITO_CLI_EXECUTABLE: "ito",
});
assert.notStrictEqual(result.status, 0);
assert.match(result.stderr, /must be an absolute path/i);
}],
["preserves the real CLI exit code and output without a success wrapper", () => {
const probe = makeItoProbe(7);
try {
const result = runCli(["ito", "status"], {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
});
assert.strictEqual(result.status, 7);
assert.match(result.stdout, /ito-probe:status/);
assert.match(result.stderr, /ito-probe-stderr/);
assert.doesNotMatch(result.stdout, /manual_handoff|simulated|paper/i);
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}],
["help exposes the truthful CLI and MCP surface without a browser path", () => {
const probe = makeItoProbe();
try {
const result = runCli(["ito", "--help"], {
ECC_ITO_CLI_EXECUTABLE: probe.executable,
});
assert.strictEqual(result.status, 0, result.stderr);
assert.match(result.stdout, /ecc ito auth/);
assert.match(result.stdout, /ecc ito find/);
assert.match(result.stdout, /ecc ito status/);
assert.match(result.stdout, /ito_auth/);
assert.match(result.stdout, /ito_find/);
assert.match(result.stdout, /ito_status/);
assert.match(result.stdout, new RegExp(CANONICAL_PACKAGE.replaceAll("/", "\\/")));
assert.match(result.stdout, /unpublished/i);
assert.match(result.stdout, /never discovers[^\n]*through PATH/i);
assert.doesNotMatch(
result.stdout,
/manual copy|open(?:s)? (?:a )?browser|ito_lock|ito_run|npm link|paper|simulat/i
);
assert.ok(!fs.existsSync(probe.log));
} finally {
fs.rmSync(probe.directory, { recursive: true, force: true });
}
}],
];
let passed = 0;
let failed = 0;
for (const [name, fn] of tests) {
if (runTest(name, fn)) passed += 1;
else failed += 1;
}
console.log(`\nPassed: ${passed}`);
console.log(`Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);
}
main();
+27 -7
View File
@@ -61,7 +61,13 @@ function assertHonestComputeCopy(content) {
assert.match(content, /preferred compute sponsor/i);
assert.match(content, /run or self-host any open-source model/i);
assert.match(content, /any GPU provider/i);
assert.match(content, /sponsorship link is passive/i);
assert.match(content, /ecc ito find/i);
assert.match(content, /explicitly configured canonical Itô CLI/i);
assert.match(content, /submits a live authenticated RFQ/i);
assert.match(content, /does not reserve capacity/i);
assert.match(content, /managed inference[^\n.]*not live/i);
assert.doesNotMatch(content, /ECC only (?:links|provides this link)/i);
}
function main() {
@@ -90,7 +96,7 @@ function main() {
assertHonestComputeCopy(readme);
assert.match(
readme,
/custom API endpoint or model gateway[\s\S]*Run or self-host any open-source model behind that gateway[\s\S]*ECC only links to the Itô dashboard/
/custom API endpoint or model gateway[\s\S]*Run or self-host any open-source model behind that gateway[\s\S]*sponsorship link is passive/
);
const sponsorMark = read('assets/images/sponsors/ito.svg');
assert.match(sponsorMark, /<path\b/);
@@ -100,10 +106,13 @@ function main() {
/@import|<script|<foreignObject|\son[a-z]+=|(?:href|xlink:href)=/i
);
}],
['sponsor roster lists Ito alongside business sponsors', () => {
['sponsor roster keeps Itô and Moonshot distinct from node tooling', () => {
const sponsors = read('SPONSORS.md');
assert.ok(sponsors.includes('[**Itô**]'));
assert.ok(sponsors.includes('assets/images/sponsors/ito.svg'));
assert.ok(sponsors.includes('[**Moonshot AI**]'));
assert.ok(sponsors.includes('assets/images/sponsors/moonshot.svg'));
assert.doesNotMatch(sponsors, /sixtytwo|sixty.?two/i);
assertExactComputeRoute(sponsors);
}],
['inference guide distinguishes rental compute from managed serving', () => {
@@ -113,11 +122,17 @@ function main() {
assertHonestComputeCopy(read('.claude-plugin/README.md'));
assertHonestComputeCopy(read('.kimi/README.md'));
}],
['Phase 2 plan keeps its thesis and release framing generic', () => {
const plan = read('docs/design/ecc-ito-compute-integration.md');
assert.match(plan, /-> any open-source model/);
assert.doesNotMatch(plan, /public Kimi|Moonshot|video and sponsorship/i);
assert.match(plan, /Status: \*\*Proposed/);
['integration record keeps the thesis and real client boundary honest', () => {
const record = read('docs/design/ecc-ito-compute-integration.md');
assert.match(record, /-> any open-source model/);
assert.doesNotMatch(record, /public Kimi|Moonshot|video and sponsorship/i);
assert.match(record, /Status: \*\*Implemented local CLI bridge/i);
assert.match(record, /auth`, `find`, and `status/);
assert.match(record, /ito_auth`, `ito_find`, and `ito_status/);
assert.match(record, /unpublished/i);
assert.match(record, /managed inference remains unavailable/i);
assert.match(record, /version bump[\s\S]*intentionally deferred/i);
assert.doesNotMatch(record, /manual_copy|ito\.compute\.handoff|ecc ito rent/i);
}],
['top-level CLI help exposes the provider-neutral compute route', () => {
const result = spawnSync('node', ['scripts/ecc.js', '--help'], {
@@ -159,7 +174,12 @@ function main() {
assert.ok(packageJson.files.includes('assets/images/sponsors/'));
assertExactComputeRoute(packageJson.scripts.welcome);
assert.match(packageJson.scripts.welcome, /run or self-host any open-source model/i);
assert.match(packageJson.scripts.welcome, /sponsorship link is passive/i);
assert.match(packageJson.scripts.welcome, /ecc ito find/i);
assert.match(packageJson.scripts.welcome, /submits a live authenticated RFQ/i);
assert.match(packageJson.scripts.welcome, /does not reserve capacity/i);
assert.ok(fs.existsSync(path.join(REPO_ROOT, 'assets', 'images', 'sponsors', 'ito.svg')));
assert.ok(fs.existsSync(path.join(REPO_ROOT, 'assets', 'images', 'sponsors', 'moonshot.svg')));
}],
];
-294
View File
@@ -1,294 +0,0 @@
/**
* End-to-end contract tests for ECC's read-only Itô compute 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, "..", "..")
const ECC_SCRIPT = path.join(REPO_ROOT, "scripts", "ecc.js")
const ITO_SCRIPT = path.join(REPO_ROOT, "scripts", "ito.js")
const DESK_URL = "https://compute.itomarkets.com/desk"
function runCli(args, options = {}) {
return spawnSync(process.execPath, [ECC_SCRIPT, ...args], {
cwd: REPO_ROOT,
encoding: "utf8",
env: {
...process.env,
NODE_ENV: "test",
...(options.env || {}),
},
})
}
function parseJson(result, expectedStatus = 0) {
assert.strictEqual(result.status, expectedStatus, result.stderr)
return JSON.parse(result.stdout)
}
function runTest(name, fn) {
try {
fn()
console.log(`${name}`)
return true
} catch (error) {
console.log(`${name}`)
console.error(` ${error.message}`)
return false
}
}
function makeBrowserProbe() {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "ecc-ito-browser-"))
const log = path.join(dir, "opened-url.txt")
const envLog = path.join(dir, "browser-env.txt")
const executable = path.join(dir, process.platform === "win32" ? "browser-probe.cmd" : "browser-probe")
if (process.platform === "win32") {
fs.writeFileSync(executable, `@echo off\r\n<nul set /p =%1>"${log}"\r\nset >"${envLog}"\r\n`)
} else {
fs.writeFileSync(executable, `#!/bin/sh\nprintf '%s' "$1" > "${log}"\nenv > "${envLog}"\n`)
fs.chmodSync(executable, 0o755)
}
return { dir, envLog, executable, log }
}
function main() {
console.log("\n=== Testing ECC × Itô sandbox handoff ===\n")
const tests = [
["maps the exact CLI request into a structured sandbox intent", () => {
const payload = parseJson(runCli([
"ito",
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--no-open",
"--json",
]))
assert.strictEqual(payload.schemaVersion, "ito.compute.handoff.v1")
assert.strictEqual(payload.success, true)
assert.strictEqual(payload.state, "manual_handoff")
assert.deepStrictEqual(payload.data.intent, {
accelerator: "h100",
count: 1,
hours: 24,
})
assert.deepStrictEqual(payload.data.provenance, {
source: "ecc-cli",
command: "ecc ito rent",
})
assert.strictEqual(payload.data.authority.environment, "sandbox")
assert.strictEqual(payload.data.authority.readOnly, true)
assert.strictEqual(payload.data.authority.liveRfq, false)
assert.strictEqual(payload.data.authority.procurementMutation, false)
assert.strictEqual(payload.data.authority.quoteAcceptance, false)
assert.strictEqual(payload.data.authority.fundsApproval, false)
assert.strictEqual(payload.data.authority.orderCreation, false)
assert.strictEqual(payload.data.handoff.transport, "manual_copy")
assert.strictEqual(payload.data.handoff.destination, "ito-desk")
assert.strictEqual(payload.data.handoff.acceptedByIto, false)
assert.strictEqual(payload.data.handoff.signInMayBeRequired, true)
assert.match(payload.data.handoff.message, /1 × H100/)
assert.match(payload.data.handoff.message, /24 hours/)
assert.match(payload.data.handoff.message, /ECC CLI/)
assert.match(payload.data.handoff.message, /sandbox-only/)
assert.strictEqual(payload.links.desk, DESK_URL)
assert.strictEqual(payload.data.opened, false)
assert.strictEqual(payload.data.priceQuote, null)
assert.strictEqual(payload.data.orderId, null)
}],
["global dry-run emits the same handoff and never opens a browser", () => {
const probe = makeBrowserProbe()
try {
const payload = parseJson(runCli([
"--dry-run",
"ito",
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--json",
], {
env: { ECC_ITO_BROWSER_EXECUTABLE: probe.executable },
}))
assert.strictEqual(payload.data.dryRun, true)
assert.strictEqual(payload.data.opened, false)
assert.ok(!fs.existsSync(probe.log), "dry-run must not invoke the browser executable")
} finally {
fs.rmSync(probe.dir, { recursive: true, force: true })
}
}],
["local dry-run is equivalent and rejects an open request", () => {
const probe = makeBrowserProbe()
try {
const payload = parseJson(runCli([
"ito",
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--dry-run",
"--json",
], {
env: { ECC_ITO_BROWSER_EXECUTABLE: probe.executable },
}))
assert.strictEqual(payload.data.dryRun, true)
assert.strictEqual(payload.data.opened, false)
assert.ok(!fs.existsSync(probe.log), "local dry-run must not invoke the browser executable")
} finally {
fs.rmSync(probe.dir, { recursive: true, force: true })
}
}],
["browser handoff opens only the allowlisted desk URL without inherited secrets", () => {
const probe = makeBrowserProbe()
try {
const payload = parseJson(runCli([
"ito",
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--json",
], {
env: {
ECC_ITO_BROWSER_EXECUTABLE: probe.executable,
ITO_API_KEY: "parent-api-key-must-not-cross",
ITO_SERVICE_TOKEN: "parent-token-must-not-cross",
TEST_PASSWORD: "parent-password-must-not-cross",
},
}))
assert.strictEqual(payload.data.opened, true)
assert.strictEqual(fs.readFileSync(probe.log, "utf8"), DESK_URL)
assert.strictEqual(payload.links.desk, DESK_URL)
const childEnvironment = fs.readFileSync(probe.envLog, "utf8")
assert.doesNotMatch(childEnvironment, /parent-api-key-must-not-cross/)
assert.doesNotMatch(childEnvironment, /parent-token-must-not-cross/)
assert.doesNotMatch(childEnvironment, /parent-password-must-not-cross/)
} finally {
fs.rmSync(probe.dir, { recursive: true, force: true })
}
}],
["direct Ito execution strips secrets from the browser child", () => {
const probe = makeBrowserProbe()
try {
const result = spawnSync(process.execPath, [
ITO_SCRIPT,
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--json",
], {
cwd: REPO_ROOT,
encoding: "utf8",
env: {
...process.env,
NODE_ENV: "test",
ECC_ITO_BROWSER_EXECUTABLE: probe.executable,
ITO_API_KEY: "direct-api-key-must-not-cross",
ITO_SERVICE_TOKEN: "direct-token-must-not-cross",
TEST_PASSWORD: "direct-password-must-not-cross",
},
})
const payload = parseJson(result)
assert.strictEqual(payload.data.opened, true)
const childEnvironment = fs.readFileSync(probe.envLog, "utf8")
assert.doesNotMatch(childEnvironment, /direct-api-key-must-not-cross/)
assert.doesNotMatch(childEnvironment, /direct-token-must-not-cross/)
assert.doesNotMatch(childEnvironment, /direct-password-must-not-cross/)
} finally {
fs.rmSync(probe.dir, { recursive: true, force: true })
}
}],
["fails closed on missing, unsupported, duplicate, and out-of-range intent", () => {
for (const args of [
["ito", "rent", "--count", "1", "--hours", "24", "--no-open", "--json"],
["ito", "rent", "--accelerator", "a100", "--count", "1", "--hours", "24", "--no-open", "--json"],
["ito", "rent", "--accelerator", "h100", "--count", "0", "--hours", "24", "--no-open", "--json"],
["ito", "rent", "--accelerator", "h100", "--count", "1", "--hours", "721", "--no-open", "--json"],
["ito", "rent", "--accelerator", "h100", "--accelerator", "h100-sxm", "--count", "1", "--hours", "24", "--no-open", "--json"],
["ito", "dashboard", "--accelerator", "h100", "--count", "1", "--hours", "24", "--no-open", "--json"],
]) {
const result = runCli(args)
assert.notStrictEqual(result.status, 0, args.join(" "))
const payload = JSON.parse(result.stdout)
assert.strictEqual(payload.success, false)
assert.strictEqual(payload.state, "invalid_request")
assert.strictEqual(payload.data, null)
assert.strictEqual(payload.error.code, "INVALID_ARGUMENT")
}
}],
["does not inspect credentials or contain a mutating transport", () => {
const payload = parseJson(runCli([
"ito",
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--no-open",
"--json",
], {
env: {
ITO_API_KEY: "must-not-be-read",
ITO_SERVICE_TOKEN: "must-not-be-read",
},
}))
assert.strictEqual(payload.data.authenticated, null)
const source = fs.readFileSync(path.join(REPO_ROOT, "scripts", "ito.js"), "utf8")
assert.doesNotMatch(source, /ITO_API_KEY|ITO_SERVICE_TOKEN|procurement\/orders|authorization/i)
assert.doesNotMatch(source, /\bfetch\s*\(|https?\.request|child_process\.exec\b/)
}],
["human output stops before the economic boundary", () => {
const result = runCli([
"ito",
"rent",
"--accelerator", "h100",
"--count", "1",
"--hours", "24",
"--no-open",
])
assert.strictEqual(result.status, 0, result.stderr)
assert.match(result.stdout, /manual copy/i)
assert.match(result.stdout, /sandbox-only/i)
assert.match(result.stdout, /sign-in may be required/i)
assert.doesNotMatch(result.stdout, /signed-in/i)
assert.match(result.stdout, /does not file an RFQ/i)
assert.match(result.stdout, /Stop before ["“]Pay & buy["”]/i)
assert.match(result.stdout, /no supported structured ECC intake/i)
}],
["npm welcome remains POSIX-safe around apostrophes", () => {
const npmExecutable = process.platform === "win32" ? "npm.cmd" : "npm"
const result = spawnSync(npmExecutable, ["run", "welcome"], {
cwd: REPO_ROOT,
encoding: "utf8",
shell: process.platform === "win32",
})
assert.strictEqual(result.status, 0, result.stderr)
assert.match(result.stdout, /Itô/)
}],
]
let passed = 0
let failed = 0
for (const [name, fn] of tests) {
if (runTest(name, fn)) passed += 1
else failed += 1
}
console.log(`\nPassed: ${passed}`)
console.log(`Failed: ${failed}`)
process.exit(failed > 0 ? 1 : 0)
}
main()
+5
View File
@@ -50,6 +50,11 @@ def test_ollama_notice_routes_to_ito_without_claiming_serving(capsys):
assert_exact_compute_route(output)
assert "preferred compute sponsor" in output
assert "Any GPU provider works" in output
assert "sponsorship link is passive" in output
assert "ecc ito find" in output
assert "explicitly configured canonical Itô CLI" in output
assert "submits a live authenticated RFQ" in output
assert "does not reserve capacity" in output
assert "Managed inference through Itô is not live yet" in output