feat: add Itô compute sponsor routing and Phase 2 plan (#2546)

* feat: add Ito compute sponsor routing

* fix: harden Ito integration CI and framing
This commit is contained in:
Affaan Mustafa
2026-07-22 03:07:45 -04:00
committed by GitHub
parent 5deee34c93
commit 96789caaf9
17 changed files with 1053 additions and 38 deletions
+2
View File
@@ -15,3 +15,5 @@ export ANTHROPIC_BASE_URL=https://your-gateway.example.com
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.
+4
View File
@@ -20,3 +20,7 @@ bash ./install.sh --target kimi --profile minimal
- The `kimi` target installs into the project-level `./.kimi/` directory.
- Kimi Code CLI's own config (`~/.kimi-code/config.toml`, plugins) is **not** touched by ECC install.
- Use `npx ecc doctor --target kimi` to check install health.
## 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.
+10
View File
@@ -106,9 +106,17 @@ ECC v2.0.0 adds the public Hermes operator story on top of that reusable layer:
<strong>Atlas Cloud</strong>
</a>
</td>
<td align="center" width="220">
<a href="https://compute.itomarkets.com">
<img src="assets/images/sponsors/ito.svg" width="96" alt="Itô Markets logo" /><br />
<strong>Itô</strong>
</a>
</td>
</tr>
</table>
<sub><strong>Run or self-host any open-source model.</strong> Itô is ECC's preferred compute sponsor: <a href="https://compute.itomarkets.com">open the Itô dashboard to sign in and rent or manage GPUs</a>. Any GPU provider works. ECC only provides this link; it does not provision compute or serving. Managed inference through Itô is not live yet.</sub>
<sub><strong>Community sponsors:</strong> <a href="https://github.com/mikejmorgan-ai">Mike Morgan</a> · <a href="https://github.com/jasonwu513">@jasonwu513</a> · <a href="https://github.com/1anter">@1anter</a> · <a href="https://github.com/massimotodaro">@massimotodaro</a> · <a href="https://github.com/meadmccabe">@meadmccabe</a></sub>
<sub><a href="https://github.com/sponsors/affaan-m"><strong>Become a Sponsor</strong></a> · <a href="SPONSORS.md">Sponsor Tiers</a> · <a href="SPONSORING.md">Sponsorship Program</a></sub>
@@ -1188,6 +1196,8 @@ 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.
Official references:
- [Claude Code LLM gateway docs](https://docs.anthropic.com/en/docs/claude-code/llm-gateway)
- [Claude Code model configuration docs](https://docs.anthropic.com/en/docs/claude-code/model-config)
+3
View File
@@ -13,9 +13,12 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
| [**CodeRabbit**](https://www.coderabbit.ai) | <img src="assets/images/sponsors/coderabbit.png" width="60" alt="CodeRabbit logo" /> | 2026 |
| [**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 |
*[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.
## Team Sponsors — $200/mo
| Sponsor | Since |
+148
View File
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
version="1.1"
id="svg1"
width="1400"
height="799.43805"
viewBox="0 0 1400 799.43805"
sodipodi:docname="ito_lockup_light.svg"
xml:space="preserve"
inkscape:export-filename="ito_lockup_light.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#ffffff"
borderopacity="0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="false"
inkscape:deskcolor="#3e5574"
inkscape:export-bgcolor="#ffffff00"
showgrid="false"><inkscape:grid
id="grid2"
units="px"
originx="-188.88699"
originy="-1776.873"
spacingx="1"
spacingy="1"
empcolor="#0099e5"
empopacity="0.30196078"
color="#0099e5"
opacity="0.14901961"
empspacing="5"
enabled="true"
visible="false" /><inkscape:page
x="0"
y="0"
width="3984.4521"
height="799.43805"
id="page1"
margin="0"
bleed="0" /></sodipodi:namedview><rect width="1400" height="799.43805" rx="80" fill="#0F172A" /><g
id="g2"
transform="matrix(1.2424941,0,0,1.2424941,732.18761,-28.312159)"
style="display:inline;mix-blend-mode:normal;fill:#000000"><path
fill="#f8f8f8"
opacity="1"
stroke="none"
d="m -407.82151,138.90806 c -0.73456,19.04603 -1.75003,36.04295 -1.77581,53.04148 -0.14803,97.42416 -0.12019,194.84831 0.007,292.27269 0.0201,15.45653 0.57632,30.92594 1.41025,46.36123 0.41463,7.67407 2.0485,15.28015 3.08296,22.92311 3.11296,23.00145 17.4907,35.52667 38.97622,40.39315 14.20138,3.21711 28.753,4.88804 43.86346,7.36875 2.21332,8.15229 2.09141,16.33417 0.19604,24.4426 -17.77154,2.32172 -238.81413,2.85947 -265.12221,0.6907 -3.01226,-8.05514 -1.79819,-16.31154 -1.14387,-25.76714 5.13187,-0.6408 9.55163,-1.05671 13.92387,-1.76586 10.66923,-1.72989 21.47836,-2.94384 31.93871,-5.54244 21.60953,-5.36825 35.18697,-18.4896 37.31021,-41.61938 1.12935,-12.30231 3.30449,-24.59672 3.33523,-36.89868 0.2921,-116.75264 0.39515,-233.5068 0.0452,-350.25864 -0.0437,-14.58642 -2.40654,-29.26741 -4.80996,-43.71922 -3.06751,-18.44469 -14.16794,-30.673543 -32.27876,-35.631463 -9.64428,-2.64002 -19.60034,-4.22358 -29.48381,-5.87653 -5.98535,-1.00112 -12.10103,-1.22288 -19.01466,-1.87575 -2.7837,-9.000821 -2.01117,-17.172152 -1.02036,-24.95995 1.26458,-0.83889 1.85493,-1.290771 2.50012,-1.642039 0.67514,-0.367516 1.40233,-0.911071 2.10791,-0.912812 82.72572,-0.189502 165.45152,-0.340361 248.1773,-0.466967 3.0862,0 6.19302,0.08354 9.25053,0.454666 1.46587,0.17813 2.83903,1.120069 4.882,1.980545 0,7.984144 0,16.21477 0,25.884597 -6.8273,0.57152 -12.86896,0.68142 -18.76796,1.65562 -11.40111,1.88248 -23.06675,3.17545 -33.99317,6.67736 -15.65683,5.01767 -26.3228,15.797003 -29.74679,32.579583 -1.23483,6.0521 -2.44932,12.10816 -3.84916,20.21079 z"
id="path3"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#f8f8f8"
opacity="1"
stroke="none"
d="m -175.50826,592.31193 c -16.09124,-26.94941 -19.46077,-55.27164 -19.59272,-84.09461 -0.32921,-71.92819 -0.17374,-143.85895 -0.23487,-215.78854 -0.007,-8.42291 -0.15278,-16.8456 -0.24748,-26.62832 -19.08924,0 -36.70129,0 -55.12778,0 -3.95705,-11.29202 -3.70922,-19.50791 6.46272,-26.67115 45.69063,-32.17644 80.91103,-73.84666 108.45576,-122.14909 5.23615,-9.18208 11.71252,-11.28784 22.61412,-6.73562 0.12268,17.80749 0.2994,36.24893 0.3628,54.6906 0.0635,18.46826 0.0139,36.93697 0.0139,55.97176 11.35646,4.41667 22.198715,1.71259 32.708818,2.21507 10.032,0.47973 20.10448,0.11651 30.159201,0.11906 10.815969,0 21.632049,4.7e-4 33.59349,4.7e-4 4.188069,14.29572 -2.530351,27.01289 -3.22906,41.59735 -31.374611,1.3323 -61.373771,-0.21167 -91.942879,0.96317 -0.47725,6.38399 -1.21691,11.70768 -1.22136,17.03196 -0.058,68.83617 -0.25024,137.67374 0.20972,206.50667 0.0923,13.80787 1.37548,27.9249 4.52007,41.3338 8.165127,34.81635 38.159478,47.50487 69.741938,30.0216 9.287071,-5.14104 17.68211,-11.89289 28.9041102,-19.55849 4.7637788,6.21839 9.39363761,12.26203 14.789386,19.30516 -2.2162292,3.40013 -3.9757088,7.85034 -7.166838,10.69426 -14.3969972,12.83183 -28.5569272,26.07735 -44.0303682,37.51244 -16.46956,12.1714 -35.74838,17.93549 -56.435928,18.54287 -29.73341,0.8723 -54.73711,-8.26032 -73.30672,-34.88042 z"
id="path4"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#f4f4f4"
opacity="1"
stroke="none"
d="m 1128.584,356.44963 c -7.4315,16.25225 -12.2094,31.78213 -20.8952,45.92572 -9.5181,0 -18.5882,0 -28.343,0 -14.907,-26.29075 -23.2607,-55.28477 -37.2044,-81.41502 -6.8826,0.67457 -4.8861,5.55462 -4.898,8.58096 -0.1555,40.17417 -0.071,80.34973 -0.048,120.52469 0,8.47736 5e-4,16.95469 5e-4,26.20117 -11.4205,5.1603 -22.8457,2.25464 -33.6308,2.61924 -0.8862,-1.08002 -1.4333,-1.64039 -1.8498,-2.28515 -0.3986,-0.61793 -0.9426,-1.32314 -0.944,-1.99063 -0.1297,-66.43868 -0.2142,-132.87715 -0.2995,-199.31594 -0.012,-5.35572 -8e-4,-10.71144 -8e-4,-16.57148 7.9953,-4.28881 15.7539,-2.24165 23.1179,-2.545 7.6717,-0.31622 15.367,-0.0708 23.9634,-0.0708 2.5457,4.93308 5.2218,9.46755 7.3005,14.26056 9.515,21.93952 18.8012,43.97849 28.3129,65.9195 2.4154,5.57157 5.3558,10.91579 9.0469,18.36695 3.3433,-3.91375 6.299,-6.12673 7.579,-9.06894 10.4639,-24.05014 20.611,-48.23862 30.8639,-72.38124 2.1062,-4.95943 4.2506,-9.90317 7.039,-16.39359 15.5819,-1.5152 31.4945,-0.52303 47.2227,-0.47463 2.7015,19.53029 2.7778,198.37503 0.1474,221.90797 -11.0574,1.39161 -22.2553,1.9846 -34.8907,-0.89391 0,-52.45604 0,-104.62428 0,-160.74504 -4.4804,4.68127 -6.9422,6.25762 -7.964,8.49266 -4.4917,9.82102 -8.5674,19.83189 -13.6251,31.35205 z"
id="path5"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#eeeeee"
opacity="1"
stroke="none"
d="m 719.24251,453.24707 c -2.2e-4,-143.79039 -2.2e-4,-285.26009 -2.2e-4,-426.794416 11.14206,-6.25449 21.98418,-1.754024 31.24644,-3.666101 7.21605,6.966195 4.77655,14.346439 4.79824,20.94779 0.28212,85.855147 0.40441,171.711207 0.41347,257.566797 0.0116,112.92769 -0.10793,225.85502 -0.18777,338.7827 -0.0116,8.38415 -0.14958,16.76854 -0.23822,26.11668 -12.12987,0 -22.76193,0 -32.78487,0 -1.16916,-0.99044 -1.86647,-1.35646 -2.2116,-1.93355 -0.38156,-0.63837 -0.60158,-1.46645 -0.61619,-2.21728 -0.18174,-9.26853 -0.4339,-18.53857 -0.43784,-27.80803 -0.0256,-59.5579 0.0116,-119.11579 0.0185,-180.99459 z"
id="path6"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#eeeeee"
opacity="1"
stroke="none"
d="m 1755.7449,339.22545 c 0.3272,-28.4493 -0.7983,-54.61983 0.7248,-81.49067 12.6256,-2.67554 23.9589,-1.81379 36.6171,-0.83831 0.6561,5.31324 1.7934,10.46472 1.8424,15.62699 0.1987,20.87713 -0.021,41.75784 0.1307,62.63588 0.024,3.46151 1.128,6.91479 2.2393,13.26757 32.1517,-30.80955 59.1362,-62.3959 88.7093,-91.66645 13.6107,-1.44743 27.1238,-0.4708 43.2196,-0.75047 -5.7951,11.94246 -13.9498,17.89918 -20.4615,25.09989 -7.2594,8.02709 -14.7108,15.88115 -22.1311,23.76119 -6.89,7.31713 -13.8688,14.55045 -20.7722,21.85515 -6.8146,7.20978 -13.5844,14.4626 -20.993,22.35623 28.0222,44.03882 58.7096,84.62599 88.9464,127.56586 -15.3427,4.61802 -29.555,2.06143 -44.4756,2.46202 -23.5436,-33.7347 -46.8802,-67.17302 -71.0658,-101.82796 -4.557,4.31734 -7.6114,7.46356 -10.9273,10.30471 -9.4239,8.07524 -13.2785,17.80505 -12.604,30.56213 1.0175,19.24969 0.2653,38.59329 0.2653,58.51615 -12.6577,4.41286 -24.644,2.5617 -35.3929,1.84861 -1.795,-1.53958 -2.5217,-1.9245 -2.8714,-2.52805 -0.37,-0.63767 -0.5232,-1.48282 -0.5264,-2.2384 -0.1756,-44.0677 -0.3264,-88.13577 -0.4737,-134.52207 z"
id="path8"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#f4f4f4"
opacity="1"
stroke="none"
d="m 2040.4731,310.9528 c -0.012,11.6723 -0.012,20.90973 -0.012,30.72195 10.9971,4.62683 21.8046,1.86507 32.2483,2.37311 10.0143,0.48692 20.0714,0.10445 30.1094,0.10445 10.7812,-2.3e-4 21.5622,0 32.6047,0 4.0513,10.49455 2.4977,20.20998 1.2879,31.50165 -16.5872,1.4501 -32.613,0.30345 -48.5654,0.76891 -15.3385,0.44736 -30.769,-1.28962 -46.7988,1.39138 -2.1159,22.58321 -0.8199,44.74344 -0.8593,67.36008 18.6055,3.59555 36.356,1.19782 53.9784,1.70807 17.5634,0.50828 35.1903,-0.53717 53.1147,0.81231 3.1013,10.46589 1.752,19.49932 1.5309,27.4411 -1.3144,1.64355 -1.6774,2.32521 -2.2384,2.7374 -0.6059,0.44538 -1.3874,0.87939 -2.1077,0.90608 -7.6951,0.28733 -15.3931,0.67654 -23.0907,0.68955 -39.2522,0.0673 -78.5045,0.0313 -117.4961,0.0313 -3.1476,-17.94652 -3.9083,-193.37372 -1.07,-221.78554 23.3622,-2.86969 47.0875,-0.97233 70.7119,-1.24458 22.9759,-0.26459 45.9886,-0.56527 70.0376,0.41671 0,10.66712 0,19.61953 0,30.23641 -4.2512,0.54738 -8.5291,1.54514 -12.814,1.57577 -23.164,0.1649 -46.3296,0.0267 -69.4942,0.1425 -6.0131,0.0301 -12.0236,0.5981 -19.3322,0.98824 -0.6335,6.81905 -1.1845,12.75361 -1.7467,21.12326 z"
id="path9"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#f4f4f4"
opacity="1"
stroke="none"
d="m 2561.9876,395.47975 c -15.0294,-4.73848 -28.4607,-8.31128 -41.7783,-12.26807 -8.1235,-2.41386 -16.3735,-4.76029 -24.0396,-8.28354 -21.4254,-9.84796 -33.8133,-25.91522 -34.3005,-50.49106 -0.5055,-25.48341 9.0029,-44.93886 31.4622,-57.68967 11.0056,-6.24788 22.9161,-9.08786 35.3729,-10.10325 25.0432,-2.04159 49.2012,0.99439 72.8749,12.41824 1.8065,11.39621 1.279,22.60724 0.4738,33.46268 -7.2636,3.01764 -11.2977,-1.93505 -15.7743,-4.12391 -12.0184,-5.87699 -24.7316,-8.76396 -37.8125,-10.37583 -10.1375,-1.2491 -20.19,-0.1033 -29.6564,3.67005 -11.6583,4.64749 -19.1169,12.78377 -19.3387,26.16147 -0.2105,12.70498 5.3087,21.43414 18.4764,26.41341 7.8944,2.98525 16.4026,4.31908 24.5845,6.57884 11.8972,3.28581 24.2103,5.62656 35.5339,10.32581 33.7506,14.00619 48.8059,54.01662 33.4349,87.30907 -8.3753,18.14112 -23.1726,28.61131 -42.2488,33.08566 -35.8416,8.4062 -70.4921,4.7625 -104.443,-10.70959 -2.0823,-12.38016 -1.7666,-24.31936 0.1925,-38.15091 7.6186,3.73909 13.6825,6.80628 19.8229,9.71136 17.0475,8.06653 34.913,12.37088 53.8766,11.45471 2.3172,-0.1114 4.6457,-0.17512 6.9432,-0.46558 13.7753,-1.74066 25.8169,-6.59856 30.8083,-20.81305 5.3111,-15.12441 0.2595,-27.19834 -14.4649,-37.11684 z"
id="path11"
style="fill:#ffffff;stroke-width:1.16044" /><path
fill="#eeeeee"
opacity="1"
stroke="none"
d="m 2324.7213,408.70201 c 6e-4,23.93572 6e-4,45.55739 6e-4,67.81278 -12.458,4.8053 -24.4548,2.66682 -37.6697,1.91266 -2.543,-11.13443 -0.9878,-21.83775 -1.3115,-32.35633 -0.3085,-10.04034 -0.048,-20.09775 -0.047,-30.14773 0,-10.82309 -7e-4,-21.64604 -0.012,-32.46911 0,-10.04999 -0.012,-20.09996 -0.03,-30.14995 -0.023,-10.82319 -0.033,-21.64626 -0.1091,-32.46911 -0.069,-9.96445 -0.2183,-19.92855 -0.3438,-30.88636 -23.1014,-3.81986 -45.4664,0.78052 -68.0746,-3.07138 0,-9.76972 0,-18.81058 0,-26.91901 1.3992,-1.49814 1.8558,-2.16481 2.4752,-2.59883 0.5924,-0.41532 1.3437,-0.80175 2.043,-0.83553 5.3905,-0.26179 10.7857,-0.60377 16.1798,-0.60853 50.9551,-0.0441 101.9101,-0.0267 153.1125,-0.0267 5.2272,10.46334 3.0826,20.22239 2.1422,30.8157 -21.8288,3.94229 -43.479,0.13798 -66.2051,2.61949 -0.732,4.96744 -2.0889,9.98918 -2.1141,15.01764 -0.1714,34.01437 -0.062,68.03013 -0.042,104.35995 z"
id="path13"
style="fill:#ffffff;stroke-width:1.16044" /><g
id="g19"
transform="matrix(1.1604524,0,0,1.1604524,81.858938,-47.101746)"
style="fill:#ccb174;fill-opacity:1"><g
id="g3"
style="fill:#ccb174;fill-opacity:1"
transform="translate(0,12.70675)"><path
fill="#c9ae73"
opacity="1"
stroke="none"
d="M 131.60765,564.55455 C 60.990753,548.86015 17.730153,506.81935 -0.65754657,438.83965 -12.020747,396.83015 -9.8713466,355.38455 8.0249534,315.87405 35.193653,255.89145 81.930952,221.36605 148.00615,214.93185 c 29.4853,-2.8714 58.5662,-0.1619 86.1069,11.9181 61.5948,27.0166 95.2478,74.708 102.7977,140.9643 4.8972,42.978 -2.8901,83.7102 -26.2475,120.5305 -31.449,49.576 -76.6083,76.5689 -135.5877,78.8111 -13.8719,0.5271 -27.8386,-1.4361 -43.4679,-2.6013 m 65.5545,-29.344 c 22.0044,-6.3438 36.3966,-21.4908 46.5728,-41.0845 3.6551,-7.0379 6.3997,-14.6433 8.7727,-22.2356 10.5566,-33.7749 10.6811,-68.3523 6.1747,-102.9605 -3.3706,-25.8859 -10.6042,-50.852 -23.1531,-73.9812 -7.7003,-14.1926 -17.2535,-26.8676 -30.4987,-36.5083 -32.1785,-23.4209 -73.7716,-20.1635 -102.1538,7.8831 -13.773998,13.6111 -21.170798,30.6299 -26.078697,48.7576 -12.9316,47.7639 -9.6462,94.9355 6.137099,141.561 6.9186,20.438 16.2865,39.4504 31.367498,55.1072 21.9904,22.8298 48.1905,32.5124 82.8595,23.4612 z"
id="path2"
style="fill:#ccb174;fill-opacity:1" /><path
fill="#c9ae73"
opacity="1"
stroke="none"
d="m 269.48165,157.86465 c 3.6399,6.206 8.7502,10.1878 8.1538,18.0252 -10.7607,4.6734 -20.6228,5.2428 -30.5203,-3.5659 -21.363,-19.0125 -43.1731,-37.5225 -64.8189,-56.2166 -5.0067,-4.3237 -10.088,-8.5613 -15.8011,-13.4031 -4.6538,3.5194 -8.9832,6.4353 -12.9075,9.8208 -22.6631,19.5503 -45.4727,38.9425 -67.717898,58.9604 -9.651999,8.6855 -19.402499,9.9912 -30.939499,5.0429 -1.4927,-7.2374 2.9787,-11.6959 6.2688,-16.4012 17.530799,-25.0703 35.233299,-50.0203 52.828797,-75.045402 8.7633,-12.4635 17.4252,-24.9984 26.1172,-37.4784 16.7091,0 32.5818,0 50.2351,0 25.716,35.826 52.0095,72.456402 79.1015,110.261302 z"
id="path12"
style="fill:#ccb174;fill-opacity:1" /></g><path
fill="#000000"
opacity="1"
stroke="none"
d="m 195.60265,548.33085 c -33.1095,8.6377 -59.3096,-1.0449 -81.3,-23.8747 -15.080998,-15.6568 -24.448898,-34.6692 -31.367498,-55.1072 -15.783299,-46.6255 -19.068699,-93.7971 -6.137099,-141.561 4.907899,-18.1277 12.304699,-35.1465 26.078697,-48.7576 28.3822,-28.0466 69.9753,-31.304 102.1538,-7.8831 13.2452,9.6407 22.7984,22.3157 30.4987,36.5083 12.5489,23.1292 19.7825,48.0953 23.1531,73.9812 4.5064,34.6082 4.3819,69.1856 -6.1747,102.9605 -2.373,7.5923 -5.1176,15.1977 -8.7727,22.2356 -10.1762,19.5937 -24.5684,34.7407 -48.1323,41.498 z"
id="path14"
style="fill:none;fill-opacity:1" /></g><path
fill="#f4f4f4"
opacity="1"
stroke="none"
d="m 1512.7545,307.08622 c 0,-17.6542 0,-33.02474 0,-49.59065 5.9445,-0.52476 10.3121,-1.20838 14.6853,-1.24494 20.0898,-0.1671 40.1806,-0.18161 60.2713,-0.19542 14.0713,-0.0116 27.4574,3.05326 40.6328,8.05934 45.9433,17.45808 46.6284,82.57408 15.2122,105.51449 -3.7249,2.71987 -7.6262,5.19766 -11.8361,8.05261 9.987,16.54805 20.126,32.59757 29.4948,49.08411 9.134,16.07378 17.481,32.59468 26.9012,50.28566 -14.2438,4.23066 -27.7508,1.87912 -42.1066,1.67372 -7.9059,-15.26888 -15.5882,-30.32807 -23.4876,-45.27262 -4.3242,-8.18072 -8.6517,-16.39905 -13.6251,-24.18707 -7.6112,-11.91843 -18.8664,-17.8994 -33.0285,-18.14785 -7.6363,-0.13404 -15.2771,-0.0244 -24.2588,-0.0244 0,29.38324 0,57.0902 0,86.35937 -6.9209,0.72412 -12.6895,1.57484 -18.4863,1.86647 -6.0242,0.30369 -12.0757,0.0673 -16.4004,0.0673 -2.217,-2.13256 -2.9341,-2.58131 -3.2854,-3.22872 -0.3428,-0.63094 -0.4204,-1.46415 -0.4275,-2.21043 -0.1376,-14.67752 -0.3416,-29.35574 -0.3471,-44.03372 -0.014,-40.18148 0.057,-80.36273 0.093,-122.82797 m 50.6994,-18.65508 c -3.5865,0.46371 -7.1726,0.92719 -11.6002,1.49953 -0.5585,23.27566 -1.8954,45.19615 0.7434,67.7587 15.6967,0 30.2993,1.18912 44.6218,-0.30624 17.2494,-1.80079 27.4254,-14.21183 28.3078,-31.11834 1.0166,-19.47101 -6.8852,-31.17266 -25.7261,-35.14756 -10.4147,-2.19708 -21.3591,-1.88236 -36.3467,-2.68609 z"
id="path7"
style="fill:#ffffff;stroke-width:1.16045" /><path
fill="#000000"
opacity="1"
stroke="none"
d="m 1565.595,288.42429 c 12.8465,0.81058 23.7909,0.49586 34.2056,2.69294 18.8409,3.9749 26.7428,15.67655 25.7262,35.14756 -0.8825,16.90651 -11.0585,29.31755 -28.3079,31.11834 -14.3225,1.49536 -28.9251,0.30624 -44.6218,0.30624 -2.6388,-22.56255 -1.3018,-44.48304 -0.7433,-67.7587 4.4276,-0.57234 8.0137,-1.03582 13.7412,-1.50638 z"
id="path15"
style="fill:none;stroke-width:1.16045" /><path
fill="#f4f4f4"
opacity="1"
stroke="none"
d="m 1272.6324,421.65419 c 18.746,-55.81532 36.9981,-109.85794 55.3977,-164.33689 14.6762,-2.16169 28.3186,-0.70289 43.1079,-1.09244 24.842,73.7233 49.3809,146.54737 73.9918,219.5851 -6.0397,5.30244 -12.4607,2.85888 -18.2411,3.28326 -6.0752,0.44619 -12.2083,0.0998 -19.0293,0.0998 -9.486,-17.29121 -10.5595,-37.51302 -21.3256,-53.99028 -25.0966,0 -49.602,0 -74.7367,0 -9.2695,16.6229 -11.2084,35.52075 -19.4881,52.8123 -11.8971,2.17272 -24.0122,1.35646 -37.7874,0.52546 3.763,-19.68766 12.1523,-36.97237 18.1108,-56.88596 m 92.1307,-75.1936 c -5.4892,-13.92949 -6.6635,-29.5052 -16.1376,-43.87508 -10.0156,30.88115 -19.6013,60.01488 -28.0735,91.96411 20.1955,-0.63013 38.3275,0.7117 58.3136,-1.02074 -4.771,-15.669 -9.0062,-29.57854 -14.1025,-47.06829 z"
id="path10"
style="fill:#ffffff;stroke-width:1.16045" /><path
fill="#000000"
opacity="1"
stroke="none"
d="m 1365.1938,348.25047 c 4.6656,15.69987 8.9008,29.60941 13.6718,45.27841 -19.9861,1.73245 -38.1181,0.39061 -58.3136,1.02074 8.4722,-31.94923 18.0579,-61.08296 28.0735,-91.96411 9.4741,14.36988 10.6484,29.94559 16.5683,45.66496 z"
id="path16"
style="fill:none;stroke-width:1.16045" /></g></svg>

After

Width:  |  Height:  |  Size: 18 KiB

+2
View File
@@ -2,6 +2,8 @@
[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.
## Configuration
Set the following environment variables to use Atlas Cloud as your LLM backend:
+562
View File
@@ -0,0 +1,562 @@
# ECC × Itô Compute Integration
Status: **Proposed — requires Affaan approval before Phase 2 implementation**
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.
## Thesis
The distribution chain is:
GPU compute (Itô)
-> 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 |
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.
## Channel B: training and GPU operations
### Skill 2: training-run-operations
Path:
skills/training-run-operations/SKILL.md
Activate for launching, resuming, debugging, observing, or cost-planning a
training, fine-tuning, evaluation, retraining, or MLE run.
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.
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.
Workflow:
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.
### Skill 3: gpu-workload-splitting
Path:
skills/gpu-workload-splitting/SKILL.md
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.
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.
Required output: WorkloadSplitPlan
| 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 |
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.
### Skill 4: slurm-gpu-workloads
Path:
skills/slurm-gpu-workloads/SKILL.md
Activate for sbatch, srun, salloc, GPU GRES or TRES, pending jobs, arrays,
DDP/NCCL, queue time, low utilization, requeue, or Slurm GPU optimization.
Workflow:
- 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 5: kubernetes-gpu-workloads
Path:
skills/kubernetes-gpu-workloads/SKILL.md
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.
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:
- 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.
+14 -14
View File
@@ -1122,9 +1122,9 @@
"license": "MIT"
},
"node_modules/fast-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
"integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
"integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
"funding": [
{
"type": "github",
@@ -1472,9 +1472,9 @@
}
},
"node_modules/js-yaml": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz",
"integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
"dev": true,
"funding": [
{
@@ -1590,9 +1590,9 @@
}
},
"node_modules/linkify-it": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.1.tgz",
"integrity": "sha512-wVoTjP4Q6R0NW5hiZkVJaFZPWgtXfoGF+6LucL3/FtiNjmcHhYjEr5f1Kqjirc1nBW07J/ZuRFumqr2oqccEWg==",
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
"integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
"dev": true,
"funding": [
{
@@ -1652,9 +1652,9 @@
}
},
"node_modules/markdown-it": {
"version": "14.2.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.2.0.tgz",
"integrity": "sha512-1TGiQiJVRQ3NPmZH6sx5Cfnmg6GQm9jvC1ch4TK511NjSJvjzKLzn5pPfZRNZkRPZP0HqCioSndqH8v2nRaWVQ==",
"version": "14.3.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
"dev": true,
"funding": [
{
@@ -1669,8 +1669,8 @@
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1",
"entities": "^4.4.0",
"linkify-it": "^5.0.1",
"entities": "^4.5.0",
"linkify-it": "^5.0.2",
"mdurl": "^2.0.0",
"punycode.js": "^2.3.1",
"uc.micro": "^2.1.0"
+8 -5
View File
@@ -58,6 +58,7 @@
"agent.yaml",
"assets/ecc-icon.svg",
"assets/hero.png",
"assets/images/sponsors/",
"agents/",
"commands/",
"docs/de-DE/",
@@ -410,7 +411,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'",
"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'",
"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",
@@ -459,12 +460,14 @@
"node": ">=18"
},
"overrides": {
"markdown-it": ">=14.2.0",
"js-yaml": ">=4.2.0"
"fast-uri": "3.1.4",
"markdown-it": "14.3.0",
"js-yaml": "4.3.0"
},
"resolutions": {
"markdown-it": ">=14.2.0",
"js-yaml": ">=4.2.0"
"fast-uri": "3.1.4",
"markdown-it": "14.3.0",
"js-yaml": "4.3.0"
},
"packageManager": "yarn@4.9.2+sha512.1fc009bc09d13cfd0e19efa44cbfc2b9cf6ca61482725eb35bbc5e257e093ebf4130db6dfe15d604ff4b79efd8e1e8e99b25fa7d0a6197c9f9826358d4d65c3c"
}
+4
View File
@@ -3,6 +3,7 @@
const { spawnSync } = require('child_process');
const path = require('path');
const { listAvailableLanguages } = require('./lib/install-executor');
const { getComputeSponsorCopy } = require('./lib/compute-sponsor');
const COMMANDS = {
install: {
@@ -119,6 +120,9 @@ Compatibility:
Global Flags:
--dry-run Preview actions without executing (sets ECC_DRY_RUN=1)
Compute:
${getComputeSponsorCopy()}
Examples:
ecc typescript
ecc install --profile developer --target claude
+6
View File
@@ -17,6 +17,7 @@ const {
normalizeInstallRequest,
parseInstallArgs,
} = require('./lib/install/request');
const { getComputeSponsorCopy } = require('./lib/compute-sponsor');
function getHelpText() {
const languages = listLegacyCompatibilityLanguages();
@@ -60,6 +61,9 @@ Options:
--json Emit machine-readable plan/result JSON
--help Show this help text
Compute:
${getComputeSponsorCopy()}
Available languages:
${languages.map(language => ` - ${language}`).join('\n')}
@@ -115,6 +119,8 @@ function printHumanPlan(plan, dryRun) {
if (!dryRun) {
console.log(`\nDone. Install-state written to ${plan.installStatePath}`);
}
console.log('\nCompute: ' + getComputeSponsorCopy());
}
function main() {
+16
View File
@@ -0,0 +1,16 @@
'use strict';
const ITO_COMPUTE_URL = 'https://compute.itomarkets.com';
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.';
}
module.exports = Object.freeze({
ITO_COMPUTE_URL,
getComputeSponsorCopy,
});
+17
View File
@@ -31,6 +31,21 @@ def print_providers(providers: list[tuple[str, str]]) -> None:
print(f" {Color.GREEN}{i}{Color.RESET}. {Color.BOLD}{name}{Color.RESET} - {desc}")
def print_self_host_compute_notice(provider: str) -> None:
if provider != "ollama":
return
print(
"\nRun or self-host any open-source model. "
"Itô is ECC's preferred compute sponsor: "
"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."
)
def select_provider(providers: list[tuple[str, str]]) -> str | None:
if not providers:
print("No providers available.")
@@ -126,6 +141,8 @@ def interactive_select(
if not provider:
return None
print_self_host_compute_notice(provider)
models = models_per_provider.get(provider, [])
model = select_model(models)
if not model:
+178
View File
@@ -0,0 +1,178 @@
/**
* Tests for the Phase 1 Ito compute-sponsor surface.
*/
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 URL_TOKEN_PATTERN = /https?:\/\/[^\s<>"'`(){}\\]+/g;
const EXPECTED_COMPUTE_ROUTE = Object.freeze({
protocol: 'https:',
hostname: 'compute.itomarkets.com',
port: '',
username: '',
password: '',
pathname: '/',
search: '',
hash: '',
});
function read(relativePath) {
return fs.readFileSync(path.join(REPO_ROOT, relativePath), 'utf8');
}
function runTest(name, fn) {
try {
fn();
console.log(`${name}`);
return true;
} catch (error) {
console.log(`${name}`);
console.error(` ${error.message}`);
return false;
}
}
function isExactComputeRoute(candidate) {
try {
const parsed = new URL(candidate.replace(/[.,;:!?]+$/, ''));
return Object.entries(EXPECTED_COMPUTE_ROUTE).every(
([property, expected]) => parsed[property] === expected
);
} catch {
return false;
}
}
function assertExactComputeRoute(content) {
const candidates = content.match(URL_TOKEN_PATTERN) || [];
assert.ok(
candidates.some(isExactComputeRoute),
'Should include the exact Itô compute route'
);
}
function assertHonestComputeCopy(content) {
assertExactComputeRoute(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, /managed inference[^\n.]*not live/i);
}
function main() {
console.log('\n=== Testing Ito compute-sponsor surface ===\n');
let passed = 0;
let failed = 0;
const tests = [
['compute route validation rejects deceptive lookalike hosts', () => {
const deceptiveCopy = [
'Itô is the preferred compute sponsor:',
'https://compute.itomarkets.com.attacker.example',
'Any GPU provider works.',
'Managed inference through Itô is not live.',
].join(' ');
assert.throws(
() => assertHonestComputeCopy(deceptiveCopy),
/exact Itô compute route/
);
}],
['README exposes the sponsor logo and honest self-hosting route', () => {
const readme = read('README.md');
assert.ok(readme.includes('assets/images/sponsors/ito.svg'));
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/
);
const sponsorMark = read('assets/images/sponsors/ito.svg');
assert.match(sponsorMark, /<path\b/);
assert.match(sponsorMark, /fill="#0F172A"/);
assert.doesNotMatch(
sponsorMark,
/@import|<script|<foreignObject|\son[a-z]+=|(?:href|xlink:href)=/i
);
}],
['sponsor roster lists Ito alongside business sponsors', () => {
const sponsors = read('SPONSORS.md');
assert.ok(sponsors.includes('[**Itô**]'));
assert.ok(sponsors.includes('assets/images/sponsors/ito.svg'));
assertExactComputeRoute(sponsors);
}],
['inference guide distinguishes rental compute from managed serving', () => {
assertHonestComputeCopy(read('docs/ATLAS-CLOUD-GUIDE.md'));
}],
['harness docs route generic open-source model intent without lock-in', () => {
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/);
}],
['top-level CLI help exposes the provider-neutral compute route', () => {
const result = spawnSync('node', ['scripts/ecc.js', '--help'], {
cwd: REPO_ROOT,
encoding: 'utf8',
});
assert.strictEqual(result.status, 0, result.stderr);
assertHonestComputeCopy(result.stdout);
}],
['installer help and human dry-run expose the compute route', () => {
const help = spawnSync('node', ['scripts/install-apply.js', '--help'], {
cwd: REPO_ROOT,
encoding: 'utf8',
});
assert.strictEqual(help.status, 0, help.stderr);
assertHonestComputeCopy(help.stdout);
const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-ito-home-'));
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-ito-project-'));
try {
const dryRun = spawnSync(
'node',
[path.join(REPO_ROOT, 'scripts', 'install-apply.js'), '--profile', 'minimal', '--dry-run'],
{
cwd: projectDir,
env: { ...process.env, HOME: homeDir },
encoding: 'utf8',
}
);
assert.strictEqual(dryRun.status, 0, dryRun.stderr);
assertHonestComputeCopy(dryRun.stdout);
} finally {
fs.rmSync(homeDir, { recursive: true, force: true });
fs.rmSync(projectDir, { recursive: true, force: true });
}
}],
['npm package publishes the Ito mark and welcome route', () => {
const packageJson = JSON.parse(read('package.json'));
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.ok(fs.existsSync(path.join(REPO_ROOT, 'assets', 'images', 'sponsors', 'ito.svg')));
}],
];
for (const [name, fn] of tests) {
if (runTest(name, fn)) {
passed += 1;
} else {
failed += 1;
}
}
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);
}
main();
@@ -83,6 +83,7 @@ function buildExpectedPublishPaths(repoRoot) {
"VERSION",
"assets/ecc-icon.svg",
"assets/hero.png",
"assets/images/sponsors",
]
const exclusionPaths = [
"!**/__pycache__/**",
+59
View File
@@ -0,0 +1,59 @@
"""Tests for provider-selection compute guidance."""
import importlib.util
import re
from pathlib import Path
from urllib.parse import urlsplit
import pytest
SELECTOR_PATH = Path(__file__).parents[1] / "src" / "llm" / "cli" / "selector.py"
SPEC = importlib.util.spec_from_file_location("ecc_selector", SELECTOR_PATH)
assert SPEC is not None and SPEC.loader is not None
SELECTOR = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(SELECTOR)
print_self_host_compute_notice = SELECTOR.print_self_host_compute_notice
URL_TOKEN_PATTERN = re.compile(r"https?://[^\s<>\"'`()\[\]{}\\]+")
EXPECTED_COMPUTE_ROUTE = (
"https",
"compute.itomarkets.com",
"",
"",
"",
)
def assert_exact_compute_route(content: str) -> None:
candidates = URL_TOKEN_PATTERN.findall(content)
routes = (
urlsplit(candidate.rstrip(".,;:!?"))
for candidate in candidates
)
assert any(route == EXPECTED_COMPUTE_ROUTE for route in routes), (
"Should include the exact Itô compute route"
)
def test_compute_route_validation_rejects_deceptive_lookalike_host():
deceptive_output = "https://compute.itomarkets.com.attacker.example"
with pytest.raises(AssertionError, match="exact Itô compute route"):
assert_exact_compute_route(deceptive_output)
def test_ollama_notice_routes_to_ito_without_claiming_serving(capsys):
print_self_host_compute_notice("ollama")
output = capsys.readouterr().out
assert_exact_compute_route(output)
assert "preferred compute sponsor" in output
assert "Any GPU provider works" in output
assert "Managed inference through Itô is not live yet" in output
def test_managed_provider_does_not_show_self_host_compute_notice(capsys):
print_self_host_compute_notice("openai")
assert capsys.readouterr().out == ""
+19 -19
View File
@@ -622,7 +622,7 @@ __metadata:
languageName: node
linkType: hard
"entities@npm:^4.4.0":
"entities@npm:^4.5.0":
version: 4.5.0
resolution: "entities@npm:4.5.0"
checksum: 10c0/5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250
@@ -801,10 +801,10 @@ __metadata:
languageName: node
linkType: hard
"fast-uri@npm:^3.0.1":
version: 3.1.2
resolution: "fast-uri@npm:3.1.2"
checksum: 10c0/5b35641895959f3f7ab7a7b1b5542bded159346f25ec9f256817b206d50b64eda5828e90d605a2e2fc645c90519a7259c2bab2c942ee728c88b88e5be21b090d
"fast-uri@npm:3.1.4":
version: 3.1.4
resolution: "fast-uri@npm:3.1.4"
checksum: 10c0/f90948821ceb49980f64f89b8216ba498f5957f26035be813526a55b6145d26cbd63ef5618d5205a3292b31edc9c08589749350cd72bd86c7095eb434dceb757
languageName: node
linkType: hard
@@ -1066,14 +1066,14 @@ __metadata:
languageName: node
linkType: hard
"js-yaml@npm:>=4.2.0":
version: 4.2.0
resolution: "js-yaml@npm:4.2.0"
"js-yaml@npm:4.3.0":
version: 4.3.0
resolution: "js-yaml@npm:4.3.0"
dependencies:
argparse: "npm:^2.0.1"
bin:
js-yaml: bin/js-yaml.js
checksum: 10c0/1916456c118746603b067d74bbcbb0445d9a1d5e474ad4ae775e7b20525bed902e01d9d97dd0c81fcd8d4f596162309d0eb057f4aa38f3e9647f14075e9dea45
checksum: 10c0/058b30473d6915ca5b4feb11e2f7d4d97242f98d00a798ed48dd90b46b7c640398afe9128c5db22c5300f8c6528fe2a174b9a93f351a70ebc28c6203938d8bff
languageName: node
linkType: hard
@@ -1156,12 +1156,12 @@ __metadata:
languageName: node
linkType: hard
"linkify-it@npm:^5.0.1":
version: 5.0.1
resolution: "linkify-it@npm:5.0.1"
"linkify-it@npm:^5.0.2":
version: 5.0.2
resolution: "linkify-it@npm:5.0.2"
dependencies:
uc.micro: "npm:^2.0.0"
checksum: 10c0/d06d04f1ed03be131740fc900a5e74ea1f49886b052213599e306d469d5ffe2303db76dd8f771de9f28e2b0b38852de22ec46ae597d245f8b66439b0ceb19b10
checksum: 10c0/dd70b1735a13d41a2cff0a058ac3771166038f23f6aff004dd53873cf985c64b107902fe0b544a5b3d1ff6e63249cf9c648fb3ae9f285481db48f56887adb0d6
languageName: node
linkType: hard
@@ -1190,19 +1190,19 @@ __metadata:
languageName: node
linkType: hard
"markdown-it@npm:>=14.2.0":
version: 14.2.0
resolution: "markdown-it@npm:14.2.0"
"markdown-it@npm:14.3.0":
version: 14.3.0
resolution: "markdown-it@npm:14.3.0"
dependencies:
argparse: "npm:^2.0.1"
entities: "npm:^4.4.0"
linkify-it: "npm:^5.0.1"
entities: "npm:^4.5.0"
linkify-it: "npm:^5.0.2"
mdurl: "npm:^2.0.0"
punycode.js: "npm:^2.3.1"
uc.micro: "npm:^2.1.0"
bin:
markdown-it: bin/markdown-it.mjs
checksum: 10c0/1d3a50061d2fe4efbcf317aac853dbee6892ed6f5a217570eead723f2ef2dd1c9baaeef5a687cd283480c45c2d20724a73e84a9ed72843cf7b3b719067af40ef
checksum: 10c0/b2dea908968109d6e9088ac972254bca842157d85d2e6838d0eb263cd8106e7e6a72663b138366cc98f57441d9f3f2ebfb842bf7b2f9e1c13187ebe70e0af8f9
languageName: node
linkType: hard