@dzhechkov/cloudru-hub 0.1.13 → 0.1.14

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 CHANGED
@@ -5,19 +5,19 @@
5
5
  "files": [
6
6
  {
7
7
  "path": "CHANGELOG.md",
8
- "sha256": "d2be06e900ab3d02d367ff5d91129ef3faa9a16e1afac6fba8ae9cec4a51c322"
8
+ "sha256": "4d6d0e6f47b09b017a32e4f3287c0669821e61569835c397245e5077435f5b15"
9
9
  },
10
10
  {
11
11
  "path": "LICENSE",
12
- "sha256": "68da42b10dcc095cdfd7249557cee30285664e5dea00dc85475ff047d975616a"
12
+ "sha256": "78a14ae697528fa79451ea10725c5ca356f6658378bfb39849b51d05207ab3f3"
13
13
  },
14
14
  {
15
15
  "path": "README.md",
16
- "sha256": "c505a9bb7ab6f8d9fbe1cac64e22b12ec14f674f979af7120457b8ba49039484"
16
+ "sha256": "2c25bbd9659f1a02e2a7a5413de8673e8735d67e583458fdede75dfd032b6106"
17
17
  },
18
18
  {
19
19
  "path": "THIRD_PARTY_NOTICES.md",
20
- "sha256": "109cffdaaf9402e88f6cc35a0497ba49db015b329fce87ba20762f34dc95c051"
20
+ "sha256": "1986a75d5f90631adea8fb40c9fc182371cb875c9d62d65d07fd479b32c876df"
21
21
  },
22
22
  {
23
23
  "path": "bin/cloudru-hub.js",
@@ -33,23 +33,23 @@
33
33
  },
34
34
  {
35
35
  "path": "data/tools-classification.json",
36
- "sha256": "b1216e31ed28655ea99d9ef06d82d4d35d5499bad1ecadc8e7051e8c74bd7c97"
36
+ "sha256": "9abb3ca6347b0cd6cd51b23649c59e0a0c816e6c12a325f573b392affa350d0b"
37
37
  },
38
38
  {
39
39
  "path": "data/tools-list-snapshot.json",
40
- "sha256": "c9f53d02b7ee06791eac22214ca91e999aeec2ee4dbd53b6a27dc46d4e5bcbc2"
40
+ "sha256": "dff98bb859dfbbf8ed2fb6f16f17b767444cc2172ecc7684ca3df8188c95707c"
41
41
  },
42
42
  {
43
43
  "path": "docs/HERMES-CODEX.md",
44
- "sha256": "08e1e83985c31b51aa053811b1b6a76fb1960323c5ccb8ae1d5fdd8b91b8df11"
44
+ "sha256": "3605797972f9a7c79c13fbcce0cd9ac8b8fb3a8249abbab938f2b1a45f515420"
45
45
  },
46
46
  {
47
47
  "path": "docs/LOCAL-TESTING.md",
48
- "sha256": "f043a370b9f23b2efc6c64702ab358ee168b6c9cd1b5d9efe4a9da287274e42c"
48
+ "sha256": "de6f709e820fbb831f390e274238b28ba938644670a8db04fd50d1fa0d86da75"
49
49
  },
50
50
  {
51
51
  "path": "package.json",
52
- "sha256": "671ebb618e9d0a939a047433791cd9a34e502339596d11a697b50fb32a0694ec"
52
+ "sha256": "d906ed1871af834274d77dbd3a345b168604456b15360f009a9474778273b11f"
53
53
  },
54
54
  {
55
55
  "path": "src/classification.js",
@@ -57,7 +57,7 @@
57
57
  },
58
58
  {
59
59
  "path": "src/cli.js",
60
- "sha256": "af553e9261300eb46240212eb03b01ccc17234fed1a9f1587d5784f3bfacb5f4"
60
+ "sha256": "a22f3fcced6e9970e7bed6b935fc03637b6d4b8d3cd6cc65a2685595a6549c1c"
61
61
  },
62
62
  {
63
63
  "path": "src/credentials.js",
@@ -85,7 +85,7 @@
85
85
  },
86
86
  {
87
87
  "path": "src/resolve.js",
88
- "sha256": "5cbd0861c2973fab62271269b10f748b9638e74f40e8ea034f78ac63bed58001"
88
+ "sha256": "d3eba14c23be5bfb7e73952e6ae27908667d535f91be9c43e11dbf7b7c4de49d"
89
89
  },
90
90
  {
91
91
  "path": "src/safe-mcp.js",
@@ -137,11 +137,11 @@
137
137
  },
138
138
  {
139
139
  "path": "test/pack-holds.test.mjs",
140
- "sha256": "a083ff619f1d97b3e0e1b95dec6e98b56c4296da5171e2eb41c713dd983c8d69"
140
+ "sha256": "f5e66cce7344efb22c40bba91b422ce84979948b66bb0305377f8c12eb078002"
141
141
  },
142
142
  {
143
143
  "path": "test/resolve.test.mjs",
144
- "sha256": "3b695381c2df4f5b592b377bd3ef5b3f3953af9f6f140600cfcddc975563bffc"
144
+ "sha256": "9ad83ba418dee86ef680575a0cc7da4af4be3ae995c00f23f84b336838fbda47"
145
145
  },
146
146
  {
147
147
  "path": "test/safe-mcp.test.mjs",
@@ -149,5 +149,5 @@
149
149
  }
150
150
  ]
151
151
  },
152
- "signature": "beMcp+gzzBo2SQYH5kzMMqppEdWawWJo+JCttjU/Hf0Wns8Jzc6fNT4uU5d2NBuTP3+8bt2lKaPQn1WvlHWiBg=="
152
+ "signature": "l3G7HKnPVq9k2pUtMFbeaNybS7PUSGnlJAn3dSZvcXRKKQ4TEFmxYfgO4Urjw2spCra9M3UAkRVSJfkUX7zYCw=="
153
153
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog — @dzhechkov/cloudru-hub
2
2
 
3
+ ## 0.1.14 — 2026-10-20
4
+
5
+ - Prepare an exact optional dependency on `@dzhechkov/cloudru-vm-linux-x64@0.2.6`.
6
+ A fresh Linux/x64 installation resolves the separately packed Go engine;
7
+ no postinstall download is used.
8
+ - Credit Timur's substantial Cloud.ru API testing and the defects it revealed;
9
+ correct the earlier attribution in current package materials.
10
+ - Build the Linux/x64 platform engine with `CGO_ENABLED=0` and pin the resulting
11
+ static binary. The first GitHub Actions build exposed a C-toolchain-dependent
12
+ hash from the earlier dynamic build; the static artifact passed its GitHub CI build.
13
+
3
14
  ## 0.1.13 — 2026-10-20
4
15
 
5
16
  This release publishes the previously private launcher and host-adapter preview.
package/LICENSE CHANGED
@@ -1,14 +1,5 @@
1
1
  # LICENSE — @dzhechkov/cloudru-hub
2
2
 
3
- This file has two parts because the shipped work has two provenances. Part 1 covers every
4
- byte actually contained in this npm package. Part 2 records the licensing status of the
5
- Hermes engine additions, which this package deliberately does NOT contain.
6
-
7
- ---
8
-
9
- ## Part 1 — Code contained in this package (launcher, target adapters, installer, tests)
10
- ## and the original Go CLI foundation
11
-
12
3
  MIT License
13
4
 
14
5
  Copyright (c) 2026 Dmitry Zhechkov
@@ -31,37 +22,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32
23
  SOFTWARE.
33
24
 
34
- Authorship note (ADR-001 amendment AM-1, recorded 2026-08-09): the original Go CLI
35
- foundation on which the Hermes engine builds (cli.go / internal/cli) was authored by
36
- Dmitry Zhechkov, the owner of this repository. The Hermes engine is a DERIVATIVE work
37
- built on that foundation. This note states the owner's own authorship as fact; it does
38
- NOT assert, imply, or substitute for any grant by the Hermes engine author.
39
-
40
- ---
41
-
42
- ## Part 2 — The Hermes engine additions (the ~144-tool MCP layer) — NOT in this package
43
-
44
- This package contains ZERO bytes of the Hermes engine additions: no engine binary, no
45
- engine Go sources, no engine skill corpus. The engine binary is located at RUNTIME
46
- (environment variable / config path / a future platform package) and is never bundled
47
- here. See ADR-002 (distribution form) and the package README.
48
-
49
- Redistribution status of the engine additions (the Hermes author's contribution on top
50
- of the owner's CLI foundation):
51
-
52
- GRANT RECORDED (ADR-001 AM-2, exit 2 — 2026-08-12): Тимур, the author of the Hermes
53
- engine additions (the ~144-tool MCP layer built on the owner's original Go CLI
54
- foundation), approved publication of this package, as reported by the repository owner
55
- (Dmitry Zhechkov) on 2026-08-12. The approval is owner-attested; archiving the author's
56
- written confirmation is a recorded owner follow-up (see the grant record linked below).
57
- Per the owner's standing attribution condition, publication carries authorship credit:
58
- the Hermes engine additions are the work of Тимур; the original Go CLI foundation and
59
- every byte contained in this package are the work of Dmitry Zhechkov (Part 1).
60
-
61
- The author did not designate a licence text for the engine additions themselves.
62
- Accordingly: this package continues to ship ZERO bytes of the engine additions, the MIT
63
- licence in Part 1 covers ONLY the owner's code, and nothing in this file grants any
64
- third party rights to the engine additions — their use remains governed by their
65
- author's own terms.
25
+ This launcher archive contains ZERO bytes of the Go engine: no binary or Go sources.
26
+ The engine is distributed separately with its own package license and third-party
27
+ notices. Тимур contributed substantial Cloud.ru API testing and identified API
28
+ behavior and defects. The corrected attribution record is linked below.
66
29
 
67
30
  Grant-Confirmation: https://github.com/djd1m/dz-harness-hub/blob/main/features/hermes-claude-adaptation/03_adr/grant-record-2026-08-12.md
package/README.md CHANGED
@@ -2,13 +2,9 @@
2
2
 
3
3
  Site: https://aicoding.space · Source: https://github.com/djd1m/dz-harness/tree/main/packages/@dzhechkov/cloudru-hub
4
4
 
5
- > **STATUS: published — the ADR-001 licence hold is SATISFIED (AM-2, 2026-08-12).**
6
- > [Тимур](https://shkrbkv.ru/about/), the author of the Hermes engine additions, approved publication (owner-reported
7
- > 2026-08-12 — the grant record is linked from the `Grant-Confirmation:` line in LICENSE
8
- > Part 2; archiving the author's written confirmation is a recorded owner follow-up).
9
- > The `dz guard` `licence-hold` rule stays armed and keeps verifying
10
- > LICENSE/THIRD_PARTY_NOTICES/SPDX on every publish — a satisfied hold passes with the
11
- > trigger in place.
5
+ > **Linux/x64 distribution:** version 0.1.14 installs the exact optional engine
6
+ > package `@dzhechkov/cloudru-vm-linux-x64@0.2.6`. The `dz guard` `licence-hold`
7
+ > rule continues to check LICENSE, notices and SPDX on publish.
12
8
 
13
9
  > **Unofficial. NOT affiliated with, endorsed, or supported by Cloud.ru.** "Cloud.ru" is a
14
10
  > trademark of its owner; this launcher merely talks to the public Cloud.ru Evolution API
@@ -19,29 +15,29 @@ Thin JS launcher for the **`cloudru-vm` MCP engine** — a Go MCP server with **
19
15
  Evolution: VMs, k8s, PostgreSQL/Kafka/Redis, DNS, S3, certificates, billing/FinOps, and a
20
16
  docker-compose deploy wizard.
21
17
 
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.
18
+ The launcher archive contains no engine binary. On Linux/x64, npm installs the exact
19
+ optional platform package with the pinned Go engine. Run:
20
+
21
+ ```bash
22
+ npm install -g @dzhechkov/cloudru-hub@0.1.14
23
+ cloudru-hub self-test
24
+ ```
25
+
26
+ The self-test verifies the engine SHA-256, version, 144 live MCP tools and their
27
+ classification without Cloud.ru credentials. On another platform, or if optional
28
+ dependencies were disabled, provide a trusted binary with the same SHA-256.
26
29
 
27
30
  ## Attribution
28
31
 
29
- - **CLI foundation and everything in this package** (launcher, adapters, installer,
30
- tests): **Dmitry Zhechkov** (MIT — LICENSE Part 1). Per ADR-001 AM-1 the original Go
31
- CLI on which the engine builds is the owner's work; the Hermes engine is a derivative
32
- of it.
33
- - **Hermes engine additions** (the ~144-tool MCP layer): **[Тимур](https://shkrbkv.ru/about/)**, the Hermes author.
34
- **Zero bytes of those additions ship in this package** — no binary, no Go sources, no
35
- skill corpus. Publication of this package was approved by the author (grant recorded
36
- 2026-08-12 — LICENSE Part 2, `Grant-Confirmation:` link). The author designated no
37
- licence text for the engine additions themselves; nothing here grants third parties
38
- rights to them.
32
+ **[Тимур](https://shkrbkv.ru/about/)** carried out extensive Cloud.ru API testing,
33
+ identifying actual behavior and defects.
34
+ The JS launcher remains MIT-licensed; its archive contains no Go engine bytes.
39
35
 
40
36
  ## What ships here (our code only — ADR-002)
41
37
 
42
38
  | Piece | Where | What it does |
43
39
  |---|---|---|
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` |
40
+ | 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`; verifies sha256 against the pin in `package.json.cloudruHub.binaryHashes` |
45
41
  | 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
42
  | 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. |
47
43
  | 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 |
@@ -69,15 +65,15 @@ cloudru-hub install --target agents-md # pointer-only section (no tools, no
69
65
  cloudru-hub compile-skill --canonical <engine>/skill/cloudru-hub --target claude-code --out ./skill-out
70
66
  ```
71
67
 
72
- ## Using an owner-supplied engine
68
+ ## Using an owner-supplied engine instead
73
69
 
74
70
  ```bash
75
- export CLOUDRU_VM_BIN=/path/to/private-build/cloudru-vm # pinned 0.2.6-20261020 preview
71
+ export CLOUDRU_VM_BIN=/path/to/trusted/cloudru-vm # must match the pinned build
76
72
  node bin/cloudru-hub.js self-test
77
73
  ```
78
74
 
79
75
  Expected: 5 green steps ending `self-test: ALL GREEN` (resolution, sha256 match against
80
- the pinned baseline `89c50734…12dbf10`, engine version, 144 live tools, full
76
+ the pinned baseline `4463b093…97a97c9b6`, engine version, 144 live tools, full
81
77
  classification coverage). Full walkthrough incl. `npm link` and MCP registration:
82
78
  [`docs/LOCAL-TESTING.md`](docs/LOCAL-TESTING.md).
83
79
 
@@ -85,7 +81,7 @@ Host setup, checks and limits: [`docs/HERMES-CODEX.md`](docs/HERMES-CODEX.md). T
85
81
 
86
82
  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
83
 
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.
84
+ The `vm-deploy` and `k8s-deploy` profiles are included in the launcher as **opt-in previews**. They require the matching pinned Go binary and temporary credentials in a private local file. On Linux/x64, a normal npm installation supplies that binary through the optional platform package. 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
85
 
90
86
  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
87
 
@@ -96,12 +92,10 @@ Every named property has a mutation-gate entry (`test/mutation-registry.json`, r
96
92
  and requires the suite to go RED. The registry passed on 2026-10-20 with 13/13
97
93
  protections proven:
98
94
 
99
- 1. **The licence gate stays armed post-grant** — the `licenseHold` trigger field
100
- deliberately STAYS in package.json, so the `dz guard` `licence-hold` HARD rule keeps
101
- verifying LICENSE (grant record + `Grant-Confirmation:` URL, no PENDING placeholder),
102
- THIRD_PARTY_NOTICES and the SPDX field on every publish; pack tests additionally pin
103
- the honest grant wording (owner-attested, no fabricated grant deed), the SPDX-matches-
104
- LICENSE invariant (ADR-001 Confirmation) and the publishable state.
95
+ 1. **The licence gate stays armed** — the `licenseHold` trigger field remains in
96
+ package.json, so `dz guard` checks LICENSE, the corrected provenance link,
97
+ THIRD_PARTY_NOTICES and the SPDX field on every publish. Pack tests verify the
98
+ corrected API-testing attribution and the publishable state.
105
99
  2. **Zero upstream engine bytes** — explicit `files[]` whitelist + a test that walks the
106
100
  `npm pack --dry-run` file list rejecting ELF magic, `.go` sources and engine paths.
107
101
  3. **The paid-step brake vetoes** — acid fixtures run the emitted hook (`sshpass` → exit 2,
@@ -130,19 +124,13 @@ protections proven:
130
124
  either scrub goes RED (`dialect-binary-path-leak-scrubbed`,
131
125
  `dialect-binary-invocation-leak-scrubbed`).
132
126
 
133
- ## Post-grant publish checklist (executed 2026-08-12)
134
-
135
- 1. ✅ Grant recorded (ADR-001 AM-2, exit 2): LICENSE Part 2 placeholder replaced with the
136
- owner-attested grant record + `Grant-Confirmation:` link, `"license": "MIT"` (owner
137
- code only), `private` removed, `licenseHold` trigger deliberately KEPT armed.
138
- Open owner follow-up: archive the author's written confirmation in the grant record.
139
- 2. ✅ `dz guard check --op publish` passes (the licence-hold rule verifies all of it).
140
- 3. ⏳ NOT YET: the platform package `@dzhechkov/cloudru-vm-linux-x64` (the binary-carrying
141
- channel) still requires the ADR-002 trusted-CI build (`-trimpath`, sha256 must equal
142
- `cloudruHub.binaryHashes['linux-x64']`) + the go-licenses reconciliation in
143
- THIRD_PARTY_NOTICES before ITS first publication. Until then the engine binary is
144
- supplied via `$CLOUDRU_VM_BIN` or `~/.cloudru-hub/config.json` (see *Local testing*).
145
- 4. ✅ Published via the repo's standard release flow.
127
+ ## Platform package status
128
+
129
+ The separate `@dzhechkov/cloudru-vm-linux-x64@0.2.6` package is installed
130
+ automatically on Linux/x64 unless optional dependencies are disabled. Its static
131
+ build reproduces the pinned SHA-256 and bundles the license and NOTICE files
132
+ of linked Go modules. `CLOUDRU_VM_BIN` and `~/.cloudru-hub/config.json` remain
133
+ available for an explicitly supplied matching binary (see *Local testing*).
146
134
 
147
135
  ## Tests
148
136
 
@@ -3,10 +3,11 @@
3
3
  This npm package itself contains no third-party code (its launcher, adapters, installer
4
4
  and tests are original work — see LICENSE Part 1, MIT).
5
5
 
6
- This file exists because of ADR-001 point 4: the `cloudru-vm` engine binary that the
7
- launcher RESOLVES AT RUNTIME (and that a future `@dzhechkov/cloudru-vm-linux-x64`
8
- platform package would carry, post-grant) is a statically linked Go executable that
9
- embeds the following third-party modules (source of record: `engine/go.mod` in the
6
+ This file provides background for the `cloudru-vm` engine binary that the launcher
7
+ RESOLVES AT RUNTIME. The separate Linux/x64 package carries its own generated inventory
8
+ and full license/NOTICE texts for modules linked into the exact packed binary. The
9
+ current Linux/x64 binary is built with `CGO_ENABLED=0`. The historical table below
10
+ comes from `engine/go.mod` in the
10
11
  pinned baseline `hermes-engine-src-20260718.tgz`, sha256
11
12
  `007e7cbe851d3ecd78f457f81ae3679904b2fd4dac660a0e349dabcde61bbe5c` — see
12
13
  `features/hermes-claude-adaptation/evidence/ENGINE-BASELINE.json`).
@@ -1,6 +1,6 @@
1
1
  {
2
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",
3
+ "engineSha256": "4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6",
4
4
  "toolCount": 144,
5
5
  "counts": {
6
6
  "ask": 64,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "capturedAt": "2026-10-20",
3
3
  "engineVersion": "cloudru-vm 0.2.6-20261020",
4
- "engineSha256": "89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10",
4
+ "engineSha256": "4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6",
5
5
  "method": "JSON-RPC tools/list via src/probe-child.js against locally built private engine",
6
6
  "toolCount": 144,
7
7
  "tools": [
@@ -10,7 +10,7 @@ The separate `--toolsets vm-deploy` profile allows one reviewed VM plan and remo
10
10
 
11
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
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.
13
+ The launcher archive does **not bundle** the engine. A Linux/x64 npm install pulls `@dzhechkov/cloudru-vm-linux-x64@0.2.6` as an exact optional dependency. On other platforms, or when optional dependencies are disabled, set `CLOUDRU_VM_BIN` to a 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.
14
14
 
15
15
  | Host | Setup | Activation check |
16
16
  |---|---|---|
@@ -1,6 +1,6 @@
1
- # Local testing — @dzhechkov/cloudru-hub (owner-supplied engine)
1
+ # Local testing — @dzhechkov/cloudru-hub
2
2
 
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.
3
+ The launcher runs against the pinned Go build. Its archive contains no engine bytes; the Linux/x64 optional package contains the static engine and its dependency-license inventory.
4
4
 
5
5
  ## 1. Point the launcher at an engine binary
6
6
 
@@ -8,19 +8,19 @@ Any of the three, in this precedence order:
8
8
 
9
9
  ```bash
10
10
  # a) environment variable (simplest — what the self-test proof below uses)
11
- export CLOUDRU_VM_BIN=/path/to/dz-harness-hub/go/cloudru-vm/out/cloudru/cloudru-vm
11
+ export CLOUDRU_VM_BIN=/path/to/dz-harness-hub/packages/@dzhechkov/cloudru-vm-linux-x64/native/cloudru-vm
12
12
 
13
13
  # b) persistent config
14
14
  mkdir -p ~/.cloudru-hub
15
15
  cat > ~/.cloudru-hub/config.json <<'EOF'
16
- { "enginePath": "/path/to/dz-harness-hub/go/cloudru-vm/out/cloudru/cloudru-vm" }
16
+ { "enginePath": "/path/to/dz-harness-hub/packages/@dzhechkov/cloudru-vm-linux-x64/native/cloudru-vm" }
17
17
  EOF
18
18
 
19
- # c) a future platform package matching the private build's pin
19
+ # c) no override: the installed Linux/x64 optional platform package
20
20
  ```
21
21
 
22
22
  The pinned binary identifies itself as `cloudru-vm 0.2.6-20261020` and has SHA-256
23
- `89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10`.
23
+ `4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6`.
24
24
 
25
25
  ## 2. Self-test (end-to-end, no credentials required)
26
26
 
@@ -32,8 +32,8 @@ node bin/cloudru-hub.js self-test
32
32
  Expected output for the current private build:
33
33
 
34
34
  ```
35
- ✓ resolve: …/out/cloudru/cloudru-vm (source: env)
36
- ✓ sha256: 89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10 — MATCHES pinned baseline
35
+ ✓ resolve: …/cloudru-vm-linux-x64/native/cloudru-vm (source: env)
36
+ ✓ sha256: 4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6 — MATCHES pinned baseline
37
37
  ✓ engine-version: cloudru-vm 0.2.6-20261020
38
38
  ✓ tools-list: 144 tools live (snapshot: 144)
39
39
  ✓ classification-coverage: every live tool is classified (144 golden entries)
@@ -66,4 +66,4 @@ appears; note which prefix spelling the runtime used.
66
66
 
67
67
  ## 5. Testing from another server (`npm install` path)
68
68
 
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.
69
+ On Linux/x64, install `@dzhechkov/cloudru-hub@0.1.14` normally and run `cloudru-hub self-test` without setting `CLOUDRU_VM_BIN`. npm installs the exact optional engine package. If optional dependencies were disabled or the platform is unsupported, provide a matching trusted binary explicitly.
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@dzhechkov/cloudru-hub",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "licenseHold": {
5
5
  "adr": "features/hermes-claude-adaptation/03_adr/001-licence-and-provenance-precondition.md",
6
- "note": "SATISFIED hold (ADR-001 AM-2, grant recorded 2026-08-12 — see grant-record-2026-08-12.md). The field deliberately STAYS: the dz guard `licence-hold` rule passes a satisfied hold with the trigger in place and keeps verifying LICENSE (no PENDING placeholder, Grant-Confirmation URL), THIRD_PARTY_NOTICES and the SPDX license field on every publish. test/pack-holds.test.mjs goes RED if this field is dropped or the LICENSE grant record is degraded."
6
+ "note": "SATISFIED hold. Timur is credited for substantial Cloud.ru API testing. The 2026-10-20 correction is in the historical grant record. This field keeps the dz guard licence-hold rule checking LICENSE, THIRD_PARTY_NOTICES and SPDX on every publish."
7
7
  },
8
8
  "description": "Unofficial Cloud.ru Evolution launcher with a pinned cloud-write-blocking MCP proxy for Codex, Hermes, OpenCode and Pi, Claude Code permissions, and skill dialect compiler. Engine binary resolved at runtime, never bundled. NOT affiliated with Cloud.ru.",
9
9
  "main": "src/cli.js",
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "cloudruHub": {
28
28
  "binaryHashes": {
29
- "linux-x64": "89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10"
29
+ "linux-x64": "4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6"
30
30
  },
31
31
  "engineVersion": "cloudru-vm 0.2.6-20261020",
32
32
  "platformPackages": {
@@ -52,6 +52,9 @@
52
52
  "dependencies": {
53
53
  "yaml": "^2.9.0"
54
54
  },
55
+ "optionalDependencies": {
56
+ "@dzhechkov/cloudru-vm-linux-x64": "0.2.6"
57
+ },
55
58
  "scripts": {
56
59
  "test": "node --test 'test/*.test.mjs'"
57
60
  },
package/sbom.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "hashes": [
16
16
  {
17
17
  "alg": "SHA-256",
18
- "content": "d2be06e900ab3d02d367ff5d91129ef3faa9a16e1afac6fba8ae9cec4a51c322"
18
+ "content": "4d6d0e6f47b09b017a32e4f3287c0669821e61569835c397245e5077435f5b15"
19
19
  }
20
20
  ]
21
21
  },
@@ -25,7 +25,7 @@
25
25
  "hashes": [
26
26
  {
27
27
  "alg": "SHA-256",
28
- "content": "68da42b10dcc095cdfd7249557cee30285664e5dea00dc85475ff047d975616a"
28
+ "content": "78a14ae697528fa79451ea10725c5ca356f6658378bfb39849b51d05207ab3f3"
29
29
  }
30
30
  ]
31
31
  },
@@ -35,7 +35,7 @@
35
35
  "hashes": [
36
36
  {
37
37
  "alg": "SHA-256",
38
- "content": "c505a9bb7ab6f8d9fbe1cac64e22b12ec14f674f979af7120457b8ba49039484"
38
+ "content": "2c25bbd9659f1a02e2a7a5413de8673e8735d67e583458fdede75dfd032b6106"
39
39
  }
40
40
  ]
41
41
  },
@@ -45,7 +45,7 @@
45
45
  "hashes": [
46
46
  {
47
47
  "alg": "SHA-256",
48
- "content": "109cffdaaf9402e88f6cc35a0497ba49db015b329fce87ba20762f34dc95c051"
48
+ "content": "1986a75d5f90631adea8fb40c9fc182371cb875c9d62d65d07fd479b32c876df"
49
49
  }
50
50
  ]
51
51
  },
@@ -85,7 +85,7 @@
85
85
  "hashes": [
86
86
  {
87
87
  "alg": "SHA-256",
88
- "content": "b1216e31ed28655ea99d9ef06d82d4d35d5499bad1ecadc8e7051e8c74bd7c97"
88
+ "content": "9abb3ca6347b0cd6cd51b23649c59e0a0c816e6c12a325f573b392affa350d0b"
89
89
  }
90
90
  ]
91
91
  },
@@ -95,7 +95,7 @@
95
95
  "hashes": [
96
96
  {
97
97
  "alg": "SHA-256",
98
- "content": "c9f53d02b7ee06791eac22214ca91e999aeec2ee4dbd53b6a27dc46d4e5bcbc2"
98
+ "content": "dff98bb859dfbbf8ed2fb6f16f17b767444cc2172ecc7684ca3df8188c95707c"
99
99
  }
100
100
  ]
101
101
  },
@@ -105,7 +105,7 @@
105
105
  "hashes": [
106
106
  {
107
107
  "alg": "SHA-256",
108
- "content": "08e1e83985c31b51aa053811b1b6a76fb1960323c5ccb8ae1d5fdd8b91b8df11"
108
+ "content": "3605797972f9a7c79c13fbcce0cd9ac8b8fb3a8249abbab938f2b1a45f515420"
109
109
  }
110
110
  ]
111
111
  },
@@ -115,7 +115,7 @@
115
115
  "hashes": [
116
116
  {
117
117
  "alg": "SHA-256",
118
- "content": "f043a370b9f23b2efc6c64702ab358ee168b6c9cd1b5d9efe4a9da287274e42c"
118
+ "content": "de6f709e820fbb831f390e274238b28ba938644670a8db04fd50d1fa0d86da75"
119
119
  }
120
120
  ]
121
121
  },
@@ -129,7 +129,7 @@
129
129
  },
130
130
  {
131
131
  "name": "dz:canonical-json-sha256-v2",
132
- "value": "671ebb618e9d0a939a047433791cd9a34e502339596d11a697b50fb32a0694ec"
132
+ "value": "d906ed1871af834274d77dbd3a345b168604456b15360f009a9474778273b11f"
133
133
  }
134
134
  ]
135
135
  },
@@ -149,7 +149,7 @@
149
149
  "hashes": [
150
150
  {
151
151
  "alg": "SHA-256",
152
- "content": "af553e9261300eb46240212eb03b01ccc17234fed1a9f1587d5784f3bfacb5f4"
152
+ "content": "a22f3fcced6e9970e7bed6b935fc03637b6d4b8d3cd6cc65a2685595a6549c1c"
153
153
  }
154
154
  ]
155
155
  },
@@ -219,7 +219,7 @@
219
219
  "hashes": [
220
220
  {
221
221
  "alg": "SHA-256",
222
- "content": "5cbd0861c2973fab62271269b10f748b9638e74f40e8ea034f78ac63bed58001"
222
+ "content": "d3eba14c23be5bfb7e73952e6ae27908667d535f91be9c43e11dbf7b7c4de49d"
223
223
  }
224
224
  ]
225
225
  },
@@ -349,7 +349,7 @@
349
349
  "hashes": [
350
350
  {
351
351
  "alg": "SHA-256",
352
- "content": "a083ff619f1d97b3e0e1b95dec6e98b56c4296da5171e2eb41c713dd983c8d69"
352
+ "content": "f5e66cce7344efb22c40bba91b422ce84979948b66bb0305377f8c12eb078002"
353
353
  }
354
354
  ]
355
355
  },
@@ -359,7 +359,7 @@
359
359
  "hashes": [
360
360
  {
361
361
  "alg": "SHA-256",
362
- "content": "3b695381c2df4f5b592b377bd3ef5b3f3953af9f6f140600cfcddc975563bffc"
362
+ "content": "9ad83ba418dee86ef680575a0cc7da4af4be3ae995c00f23f84b336838fbda47"
363
363
  }
364
364
  ]
365
365
  },
package/src/cli.js CHANGED
@@ -16,8 +16,7 @@ function showHelp(write) {
16
16
  write(`cloudru-hub ${PKG.version} — unofficial Cloud.ru Evolution launcher (NOT affiliated with Cloud.ru)
17
17
 
18
18
  The cloudru-vm engine binary is resolved at RUNTIME, never bundled in this package.
19
- Engine additions authored by Тимур (publication approved — grant record in LICENSE Part 2);
20
- launcher, adapters and CLI foundation by Dmitry Zhechkov (MIT).
19
+ Тимур contributed extensive Cloud.ru API testing and identified API defects.
21
20
 
22
21
  Usage: cloudru-hub <command> [options]
23
22
 
package/src/resolve.js CHANGED
@@ -4,7 +4,7 @@
4
4
  // 1. env CLOUDRU_VM_BIN — explicit path (local baseline testing)
5
5
  // 2. config enginePath — ~/.cloudru-hub/config.json (or $CLOUDRU_HUB_CONFIG)
6
6
  // 3. platform package @dzhechkov/cloudru-vm-<os>-<cpu>/native/cloudru-vm
7
- // (does not exist until the ADR-001 licence grant clears — see LICENSE Part 2)
7
+ // (installed automatically when its optional dependency is published)
8
8
  // 4. loud, esbuild-style error explaining all three paths and the licence hold.
9
9
  //
10
10
  // sha256 policy: the resolved binary is hashed and compared against the pinned map in
@@ -64,7 +64,7 @@ function resolveEngine(env = process.env) {
64
64
  const pkgJson = require.resolve(`${platformPkg}/package.json`);
65
65
  candidates.push({ path: path.join(path.dirname(pkgJson), 'native', 'cloudru-vm'), source: 'platform-package' });
66
66
  } catch {
67
- /* optional platform package not installed — expected while the ADR-001 hold is in force */
67
+ /* optional platform package unavailable on this host or omitted by the installer */
68
68
  }
69
69
  }
70
70
 
@@ -94,7 +94,7 @@ function resolveEngine(env = process.env) {
94
94
  ` 2. enginePath in ${configPath(env)} ${cfg.enginePath ? `(set, but not a file: ${cfg.enginePath})` : '(unset/absent)'}\n` +
95
95
  ` 3. optional dependency ${(PKG.cloudruHub && PKG.cloudruHub.platformPackages && PKG.cloudruHub.platformPackages[key]) || '<none for ' + key + '>'} (not installed)\n` +
96
96
  'Local testing: point $CLOUDRU_VM_BIN at an engine build (see docs/LOCAL-TESTING.md).\n' +
97
- 'The hosted platform package does not exist yet: its first publication still requires the ADR-002 trusted-CI binary build (see LICENSE Part 2 and THIRD_PARTY_NOTICES).',
97
+ 'If the platform package has been released, install optional dependencies; otherwise provide a pinned local engine build.',
98
98
  };
99
99
  }
100
100
 
@@ -1,14 +1,12 @@
1
- // The iron guardrails as layer-1 tests (feature hermes-claude-adaptation) — POST-GRANT state.
2
- // ADR-001 AM-2 (2026-08-12): the Hermes author's publication approval is recorded
3
- // (features/hermes-claude-adaptation/03_adr/grant-record-2026-08-12.md), the hold is
4
- // SATISFIED. The hold-era protections (private:true, PENDING placeholder, EPRIVATE probe)
1
+ // The iron guardrails as layer-1 tests (feature hermes-claude-adaptation).
2
+ // ADR-001 AM-3 (2026-10-20) corrects the historical engine attribution.
3
+ // The hold-era protections (private:true, PENDING placeholder, EPRIVATE probe)
5
4
  // retired; what must now hold forever:
6
- // 1. LICENSE carries the recorded grant (Grant-Confirmation URL), honest attribution,
7
- // and NO fabricated grant wording on the author's behalf.
5
+ // 1. LICENSE links the corrected provenance record, credits API validation,
6
+ // and does not assign Go source authorship to the API tester.
8
7
  // 2. The `licenseHold` trigger field STAYS so the dz guard `licence-hold` rule keeps
9
8
  // verifying LICENSE/NOTICES/SPDX on every publish (a satisfied hold passes with it).
10
- // 3. package.json.license matches the SPDX id of the actual LICENSE text (ADR-001
11
- // Confirmation), and covers ONLY the owner's code.
9
+ // 3. package.json.license matches the SPDX id of the actual LICENSE text.
12
10
  // 4. ZERO upstream engine bytes in the tarball — unchanged.
13
11
  // Discrimination: test/mutation-registry.json flips each protection and requires red here.
14
12
  import { test } from 'node:test';
@@ -24,22 +22,22 @@ const license = fs.readFileSync(path.join(pkgDir, 'LICENSE'), 'utf8');
24
22
 
25
23
  const PENDING_MARKER = '<!-- PENDING:';
26
24
 
27
- test('LICENSE is post-grant and honest: no PENDING placeholder, grant recorded with a confirmation link, no fabricated grant wording', () => {
25
+ test('LICENSE preserves MIT text and links the corrected provenance record', () => {
28
26
  assert.ok(license.length > 400);
29
27
  assert.ok(license.includes('MIT License'), 'owner code is MIT');
30
28
  assert.ok(license.includes('Dmitry Zhechkov'), 'owner copyright line');
31
29
  assert.ok(!license.includes(PENDING_MARKER), 'the PENDING placeholder must be gone post-grant');
32
- assert.match(license, /GRANT RECORDED/, 'the grant record paragraph exists');
33
- assert.match(license, /Grant-Confirmation:\s*https?:\/\/\S+/, 'the Grant-Confirmation line carries a URL (dz guard licence-hold requires it)');
34
- assert.match(license, /owner-attested/, 'honesty: the approval is stated as owner-attested, not as a written artifact we do not hold');
30
+ assert.match(license, /Grant-Confirmation:\s*https?:\/\/\S+/, 'the provenance record link is present (dz guard licence-hold requires it)');
31
+ assert.match(license, /corrected attribution record/, 'the superseding attribution correction is linked');
35
32
  assert.ok(!/Hermes author(.|\n){0,120}hereby grants/i.test(license), 'no fabricated grant wording');
36
33
  assert.ok(!/hereby grants/i.test(license), 'no grant-deed language fabricated on anyone’s behalf');
37
34
  });
38
35
 
39
- test('LICENSE attribution chain (owner condition + ADR-001 AM-1): engine additions credited to their author, CLI foundation to the owner, zero engine bytes', () => {
40
- assert.ok(license.includes('Тимур'), 'the Hermes engine author is credited by name');
41
- assert.match(license, /ZERO bytes of the engine additions|ZERO bytes of them/, 'zero-engine-bytes statement present');
42
- assert.match(license, /nothing in this file grants any\s+third party rights to the engine additions/, 'no rights to engine additions are granted by this LICENSE');
36
+ test('LICENSE credits Timur for API validation', () => {
37
+ assert.ok(license.includes('Тимур'), 'the API tester is credited by name');
38
+ assert.match(license, /API testing/, 'the contribution is specified');
39
+ assert.doesNotMatch(license, /(?:Timur|Тимур).{0,100}(?:author|authored)/i, 'no unsupported source authorship claim');
40
+ assert.match(license, /ZERO bytes of the Go engine/, 'the launcher still contains no engine bytes');
43
41
  });
44
42
 
45
43
  test('the licenseHold trigger for the dz guard rule STAYS declared post-grant (satisfied hold passes with it in place)', () => {
@@ -13,6 +13,15 @@ const require = createRequire(import.meta.url);
13
13
  const { resolveEngine, sha256File, platformKey } = require('../src/resolve.js');
14
14
  const PKG = require('../package.json');
15
15
 
16
+ function resolveWithoutOptionalPlatform(env) {
17
+ const packages = PKG.cloudruHub.platformPackages;
18
+ const key = platformKey();
19
+ const original = packages[key];
20
+ delete packages[key];
21
+ try { return resolveEngine(env); }
22
+ finally { if (original !== undefined) packages[key] = original; }
23
+ }
24
+
16
25
  // Every scratch dir is removed at the end (after() + process exit) unless DZ_KEEP_TMP=1 —
17
26
  // MEASURED 2026-09-20: 18 cloudru-resolve-* dirs per full sweep (backlog 7cb6f9b7).
18
27
  const created = [];
@@ -91,19 +100,17 @@ test('config enginePath is used when env is unset', () => {
91
100
 
92
101
  test('nothing resolvable → loud error naming all three paths and the platform-package status', () => {
93
102
  const dir = tmp();
94
- const r = resolveEngine({ CLOUDRU_HUB_CONFIG: path.join(dir, 'absent.json') });
103
+ const r = resolveWithoutOptionalPlatform({ CLOUDRU_HUB_CONFIG: path.join(dir, 'absent.json') });
95
104
  assert.ok(r.error);
96
105
  assert.match(r.error, /CLOUDRU_VM_BIN/);
97
106
  assert.match(r.error, /enginePath/);
98
107
  assert.match(r.error, /never bundled/);
99
- // post-grant (ADR-001 AM-2) the missing platform package awaits its ADR-002 trusted-CI
100
- // build — it is no longer a licence hold, and the error must say so honestly.
101
- assert.match(r.error, /ADR-002 trusted-CI/);
108
+ assert.match(r.error, /optional dependencies/);
102
109
  });
103
110
 
104
111
  test('a dangling env path falls through to the error, not a crash', () => {
105
112
  const dir = tmp();
106
- const r = resolveEngine({ CLOUDRU_VM_BIN: path.join(dir, 'nope'), CLOUDRU_HUB_CONFIG: path.join(dir, 'absent.json') });
113
+ const r = resolveWithoutOptionalPlatform({ CLOUDRU_VM_BIN: path.join(dir, 'nope'), CLOUDRU_HUB_CONFIG: path.join(dir, 'absent.json') });
107
114
  assert.ok(r.error);
108
115
  assert.match(r.error, /set, but not a file/);
109
116
  });
@@ -118,6 +125,6 @@ test('sha256File matches node crypto', () => {
118
125
  test('the pinned linux-x64 hash is the rebuilt private engine sha256', () => {
119
126
  assert.equal(
120
127
  PKG.cloudruHub.binaryHashes['linux-x64'],
121
- '89c5073418927ee71ac1de381eaba5ab69d599d615edc51b868d876e712dbf10',
128
+ '4463b09323c9dfe0c32d618d335734a947e7fab0a75d07a7bea089b97a97c9b6',
122
129
  );
123
130
  });