@crowdedkingdoms/ckx-kit 0.0.0-stage → 0.1.0-dev.1

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.
Files changed (55) hide show
  1. package/LICENSE-APACHE +176 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +76 -2
  4. package/checks/compute-toolchain/host-catalog.json +68 -0
  5. package/crates/ckx-sdk/Cargo.toml +17 -0
  6. package/crates/ckx-sdk/LICENSE-APACHE +176 -0
  7. package/crates/ckx-sdk/LICENSE-MIT +21 -0
  8. package/crates/ckx-sdk/README.md +47 -0
  9. package/crates/ckx-sdk/src/abi.rs +115 -0
  10. package/crates/ckx-sdk/src/cron.rs +717 -0
  11. package/crates/ckx-sdk/src/emit.rs +140 -0
  12. package/crates/ckx-sdk/src/lib.rs +588 -0
  13. package/crates/ckx-sdk/src/model.rs +482 -0
  14. package/crates/ckx-sdk/src/node.rs +942 -0
  15. package/crates/ckx-sdk/src/rt.rs +519 -0
  16. package/crates/crowdy-client-sdk/Cargo.toml +15 -0
  17. package/crates/crowdy-client-sdk/LICENSE-APACHE +176 -0
  18. package/crates/crowdy-client-sdk/LICENSE-MIT +21 -0
  19. package/crates/crowdy-client-sdk/README.md +25 -0
  20. package/crates/crowdy-client-sdk/src/lib.rs +698 -0
  21. package/dist/checks/src/build/client-capabilities.js +123 -0
  22. package/dist/checks/src/build/exec-source.js +343 -0
  23. package/dist/checks/src/build/rust-source-guard.js +165 -0
  24. package/dist/checks/src/build/wasm-inspect.js +249 -0
  25. package/dist/cli/src/build.js +99 -0
  26. package/dist/cli/src/crate.js +64 -0
  27. package/dist/cli/src/doctor.js +51 -0
  28. package/dist/cli/src/kit.js +66 -0
  29. package/dist/cli/src/main.js +109 -0
  30. package/dist/cli/src/new.js +74 -0
  31. package/dist/cli/src/tools.js +104 -0
  32. package/kit.pin +9 -0
  33. package/package.json +81 -4
  34. package/rust-toolchain.toml +6 -0
  35. package/starters/ckx.json +9 -0
  36. package/starters/grid-mod/Cargo.toml +13 -0
  37. package/starters/grid-mod/src/lib.rs +82 -0
  38. package/starters/matchmaker/Cargo.toml +13 -0
  39. package/starters/matchmaker/src/lib.rs +362 -0
  40. package/starters/npc-mobs/Cargo.toml +14 -0
  41. package/starters/npc-mobs/src/lib.rs +469 -0
  42. package/starters/session/Cargo.toml +13 -0
  43. package/starters/session/src/lib.rs +395 -0
  44. package/starters/world-tick/Cargo.toml +14 -0
  45. package/starters/world-tick/src/lib.rs +346 -0
  46. package/templates/client/Cargo.toml +16 -0
  47. package/templates/client/src/lib.rs +31 -0
  48. package/templates/hub/Cargo.toml +11 -0
  49. package/templates/hub/src/lib.rs +73 -0
  50. package/templates/spoke/Cargo.toml +11 -0
  51. package/templates/spoke/src/lib.rs +53 -0
  52. package/tools/instrument/Cargo.lock +140 -0
  53. package/tools/instrument/Cargo.toml +11 -0
  54. package/tools/instrument/src/main.rs +165 -0
  55. package/vendor.lock +167 -0
@@ -0,0 +1,165 @@
1
+ //! Compute-module instrumentation CLI (production version of the Phase 0
2
+ //! spike tool). Pipeline stage between `cargo build` and `wasm-opt`:
3
+ //!
4
+ //! Usage: instrument <input.wasm> <output.wasm> [--max-memory-mb N]
5
+ //!
6
+ //! 1. Validates the module's import surface against the platform allowlist
7
+ //! (the `ck` host API + the minimal deterministic WASI stub set).
8
+ //! 2. Clamps the module's linear-memory maximum to `--max-memory-mb` (worker
9
+ //! resourceLimits do NOT cover wasm memory — this is the real cap).
10
+ //! 3. Injects mutable-global gas metering (exported global `ck_fuel`):
11
+ //! every metered block decrements the global; on exhaustion the global is
12
+ //! set to the u64::MAX sentinel and the module traps (`unreachable`).
13
+ //! The host sets/reads `ck_fuel` around each entry call.
14
+
15
+ use anyhow::{bail, Context, Result};
16
+ use radix_wasm_instrument::gas_metering::{inject, mutable_global, ConstantCostRules};
17
+ use radix_wasm_instrument::utils::module_info::ModuleInfo;
18
+ use wasmparser::{Parser, Payload, TypeRef};
19
+
20
+ const WASM_PAGE_BYTES: u64 = 65536;
21
+
22
+ const ALLOWED_CK_IMPORTS: &[&str] =
23
+ &["log", "now_ms", "state_get", "state_set", "host_call"];
24
+ const ALLOWED_WASI_IMPORTS: &[&str] = &[
25
+ "environ_get",
26
+ "environ_sizes_get",
27
+ "fd_write",
28
+ "proc_exit",
29
+ "clock_time_get",
30
+ "random_get",
31
+ ];
32
+
33
+ fn validate_imports(wasm: &[u8]) -> Result<()> {
34
+ for payload in Parser::new(0).parse_all(wasm) {
35
+ if let Payload::ImportSection(reader) = payload? {
36
+ for import in reader {
37
+ let import = import?;
38
+ if !matches!(import.ty, TypeRef::Func(_)) {
39
+ bail!("non-function import {}::{} not allowed", import.module, import.name);
40
+ }
41
+ let allowed = match import.module {
42
+ "ck" => ALLOWED_CK_IMPORTS.contains(&import.name),
43
+ "wasi_snapshot_preview1" => ALLOWED_WASI_IMPORTS.contains(&import.name),
44
+ _ => false,
45
+ };
46
+ if !allowed {
47
+ bail!("import {}::{} not in allowlist", import.module, import.name);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ Ok(())
53
+ }
54
+
55
+ /// Rewrite the memory section so every defined memory carries a maximum of at
56
+ /// most `max_pages`. Rebuilds just the memory section bytes and splices them
57
+ /// into the module (sections are independently sized, so this is safe).
58
+ fn clamp_memory(wasm: &[u8], max_pages: u64) -> Result<Vec<u8>> {
59
+ let mut mem_section_range: Option<std::ops::Range<usize>> = None;
60
+ let mut memories: Vec<wasmparser::MemoryType> = Vec::new();
61
+
62
+ for payload in Parser::new(0).parse_all(wasm) {
63
+ if let Payload::MemorySection(reader) = payload? {
64
+ mem_section_range = Some(reader.range());
65
+ for mem in reader {
66
+ memories.push(mem?);
67
+ }
68
+ }
69
+ }
70
+ let Some(range) = mem_section_range else {
71
+ // No defined memory (e.g. imported) -- nothing to clamp; the import
72
+ // gate already rejects non-function imports, so this cannot happen
73
+ // for accepted modules.
74
+ return Ok(wasm.to_vec());
75
+ };
76
+
77
+ let mut section = wasm_encoder::MemorySection::new();
78
+ for mem in &memories {
79
+ if mem.memory64 || mem.shared {
80
+ bail!("memory64/shared memories are not allowed");
81
+ }
82
+ if mem.initial > max_pages {
83
+ bail!(
84
+ "module declares initial memory of {} pages (> clamp of {} pages)",
85
+ mem.initial,
86
+ max_pages
87
+ );
88
+ }
89
+ let clamped_max = mem.maximum.map_or(max_pages, |m| m.min(max_pages));
90
+ section.memory(wasm_encoder::MemoryType {
91
+ minimum: mem.initial,
92
+ maximum: Some(clamped_max),
93
+ memory64: false,
94
+ shared: false,
95
+ });
96
+ }
97
+
98
+ // Encode the replacement section (id byte + LEB size + payload).
99
+ let mut replacement = Vec::new();
100
+ wasm_encoder::Section::append_to(&section, &mut replacement);
101
+
102
+ // `range` covers the section payload (not the id/size header). Locate the
103
+ // header: it ends where the payload begins. The id byte for the memory
104
+ // section is 5; scan backwards over the LEB128 size.
105
+ let payload_start = range.start;
106
+ let mut header_start = payload_start - 1;
107
+ // size LEB: walk back while continuation bit set on the previous byte.
108
+ while header_start > 0 && wasm[header_start - 1] & 0x80 != 0 {
109
+ header_start -= 1;
110
+ }
111
+ header_start -= 1; // the section id byte
112
+ if wasm[header_start] != 5 {
113
+ bail!("failed to locate memory section header");
114
+ }
115
+
116
+ let mut out = Vec::with_capacity(wasm.len() + 8);
117
+ out.extend_from_slice(&wasm[..header_start]);
118
+ out.extend_from_slice(&replacement);
119
+ out.extend_from_slice(&wasm[range.end..]);
120
+ Ok(out)
121
+ }
122
+
123
+ fn main() -> Result<()> {
124
+ let args: Vec<String> = std::env::args().collect();
125
+ let (input, output, max_memory_mb) = match args.as_slice() {
126
+ [_, i, o] => (i.clone(), o.clone(), 64u64),
127
+ [_, i, o, flag, n] if flag == "--max-memory-mb" => (
128
+ i.clone(),
129
+ o.clone(),
130
+ n.parse::<u64>().context("parsing --max-memory-mb")?,
131
+ ),
132
+ _ => bail!("usage: instrument <input.wasm> <output.wasm> [--max-memory-mb N]"),
133
+ };
134
+ if max_memory_mb == 0 {
135
+ bail!("--max-memory-mb must be >= 1");
136
+ }
137
+ let max_pages = (max_memory_mb * 1024 * 1024) / WASM_PAGE_BYTES;
138
+
139
+ let wasm = std::fs::read(&input).with_context(|| format!("reading {input}"))?;
140
+ validate_imports(&wasm)?;
141
+ let clamped = clamp_memory(&wasm, max_pages)?;
142
+ wasmparser::validate(&clamped).context("validating memory-clamped module")?;
143
+
144
+ let mut info =
145
+ ModuleInfo::new(&clamped).map_err(|e| anyhow::anyhow!("parsing module: {e:?}"))?;
146
+ let backend = mutable_global::Injector::new("env", "ck_fuel");
147
+ // Uniform cost of 1 per instruction; production per-instruction weights
148
+ // are Phase 10 load-test work (the fuel scale is calibrated in policy).
149
+ let instrumented = inject(&mut info, backend, &ConstantCostRules::default())
150
+ .context("injecting gas metering")?;
151
+
152
+ wasmparser::validate(&instrumented).context("validating instrumented module")?;
153
+
154
+ std::fs::write(&output, &instrumented).with_context(|| format!("writing {output}"))?;
155
+ eprintln!(
156
+ "instrumented {} ({} bytes) -> {} ({} bytes, +{:.1}%, memory max {} pages)",
157
+ input,
158
+ wasm.len(),
159
+ output,
160
+ instrumented.len(),
161
+ (instrumented.len() as f64 / wasm.len() as f64 - 1.0) * 100.0,
162
+ max_pages
163
+ );
164
+ Ok(())
165
+ }
package/vendor.lock ADDED
@@ -0,0 +1,167 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
10
+
11
+ [[package]]
12
+ name = "base64"
13
+ version = "0.22.1"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
16
+
17
+ [[package]]
18
+ name = "ckx-sdk"
19
+ version = "0.8.0"
20
+ dependencies = [
21
+ "base64",
22
+ "rmp-serde",
23
+ "serde",
24
+ "serde_json",
25
+ ]
26
+
27
+ [[package]]
28
+ name = "crowdy-client-sdk"
29
+ version = "0.1.0"
30
+ dependencies = [
31
+ "serde",
32
+ "serde_json",
33
+ ]
34
+
35
+ [[package]]
36
+ name = "itoa"
37
+ version = "1.0.18"
38
+ source = "registry+https://github.com/rust-lang/crates.io-index"
39
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
40
+
41
+ [[package]]
42
+ name = "memchr"
43
+ version = "2.8.3"
44
+ source = "registry+https://github.com/rust-lang/crates.io-index"
45
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
46
+
47
+ [[package]]
48
+ name = "num-traits"
49
+ version = "0.2.19"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
52
+ dependencies = [
53
+ "autocfg",
54
+ ]
55
+
56
+ [[package]]
57
+ name = "proc-macro2"
58
+ version = "1.0.107"
59
+ source = "registry+https://github.com/rust-lang/crates.io-index"
60
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
61
+ dependencies = [
62
+ "unicode-ident",
63
+ ]
64
+
65
+ [[package]]
66
+ name = "quote"
67
+ version = "1.0.47"
68
+ source = "registry+https://github.com/rust-lang/crates.io-index"
69
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
70
+ dependencies = [
71
+ "proc-macro2",
72
+ ]
73
+
74
+ [[package]]
75
+ name = "rmp"
76
+ version = "0.8.15"
77
+ source = "registry+https://github.com/rust-lang/crates.io-index"
78
+ checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c"
79
+ dependencies = [
80
+ "num-traits",
81
+ ]
82
+
83
+ [[package]]
84
+ name = "rmp-serde"
85
+ version = "1.3.1"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155"
88
+ dependencies = [
89
+ "rmp",
90
+ "serde",
91
+ ]
92
+
93
+ [[package]]
94
+ name = "serde"
95
+ version = "1.0.229"
96
+ source = "registry+https://github.com/rust-lang/crates.io-index"
97
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
98
+ dependencies = [
99
+ "serde_core",
100
+ "serde_derive",
101
+ ]
102
+
103
+ [[package]]
104
+ name = "serde_core"
105
+ version = "1.0.229"
106
+ source = "registry+https://github.com/rust-lang/crates.io-index"
107
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
108
+ dependencies = [
109
+ "serde_derive",
110
+ ]
111
+
112
+ [[package]]
113
+ name = "serde_derive"
114
+ version = "1.0.229"
115
+ source = "registry+https://github.com/rust-lang/crates.io-index"
116
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
117
+ dependencies = [
118
+ "proc-macro2",
119
+ "quote",
120
+ "syn",
121
+ ]
122
+
123
+ [[package]]
124
+ name = "serde_json"
125
+ version = "1.0.151"
126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
127
+ checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
128
+ dependencies = [
129
+ "itoa",
130
+ "memchr",
131
+ "serde",
132
+ "serde_core",
133
+ "zmij",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "syn"
138
+ version = "3.0.6"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
141
+ dependencies = [
142
+ "proc-macro2",
143
+ "quote",
144
+ "unicode-ident",
145
+ ]
146
+
147
+ [[package]]
148
+ name = "unicode-ident"
149
+ version = "1.0.26"
150
+ source = "registry+https://github.com/rust-lang/crates.io-index"
151
+ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
152
+
153
+ [[package]]
154
+ name = "vendor-superset"
155
+ version = "0.0.1"
156
+ dependencies = [
157
+ "ckx-sdk",
158
+ "crowdy-client-sdk",
159
+ "serde",
160
+ "serde_json",
161
+ ]
162
+
163
+ [[package]]
164
+ name = "zmij"
165
+ version = "1.0.23"
166
+ source = "registry+https://github.com/rust-lang/crates.io-index"
167
+ checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"