diff --git a/Cargo.lock b/Cargo.lock index ec77b955..1d03fd4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -478,7 +478,7 @@ checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "c0mpute-api" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "c0mpute-proto", @@ -493,7 +493,7 @@ dependencies = [ [[package]] name = "c0mpute-bench" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "blake3", @@ -504,7 +504,7 @@ dependencies = [ [[package]] name = "c0mpute-cli" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "axum", @@ -534,7 +534,7 @@ dependencies = [ [[package]] name = "c0mpute-core" -version = "0.2.63" +version = "0.2.64" dependencies = [ "aes-gcm", "anyhow", @@ -578,7 +578,7 @@ dependencies = [ [[package]] name = "c0mpute-doctor" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "serde", @@ -590,7 +590,7 @@ dependencies = [ [[package]] name = "c0mpute-envelope" -version = "0.2.63" +version = "0.2.64" dependencies = [ "blake3", "bs58", @@ -603,7 +603,7 @@ dependencies = [ [[package]] name = "c0mpute-gateway" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "axum", @@ -625,7 +625,7 @@ dependencies = [ [[package]] name = "c0mpute-market" -version = "0.2.63" +version = "0.2.64" dependencies = [ "c0mpute-envelope", "serde", @@ -635,7 +635,7 @@ dependencies = [ [[package]] name = "c0mpute-net" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "async-trait", @@ -652,7 +652,7 @@ dependencies = [ [[package]] name = "c0mpute-placement" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "async-trait", @@ -673,7 +673,7 @@ dependencies = [ [[package]] name = "c0mpute-proto" -version = "0.2.63" +version = "0.2.64" dependencies = [ "blake3", "hex", @@ -685,7 +685,7 @@ dependencies = [ [[package]] name = "c0mpute-secure-chat" -version = "0.2.63" +version = "0.2.64" dependencies = [ "aes-gcm", "anyhow", @@ -708,7 +708,7 @@ dependencies = [ [[package]] name = "c0mpute-store" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "blake3", @@ -726,7 +726,7 @@ dependencies = [ [[package]] name = "c0mpute-transcode" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "c0mpute-proto", @@ -739,7 +739,7 @@ dependencies = [ [[package]] name = "c0mpute-update" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "hex", @@ -753,7 +753,7 @@ dependencies = [ [[package]] name = "c0mpute-verify" -version = "0.2.63" +version = "0.2.64" dependencies = [ "anyhow", "blake3", diff --git a/Cargo.toml b/Cargo.toml index 4be75783..49f1853f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ ] [workspace.package] -version = "0.2.63" +version = "0.2.64" edition = "2024" license = "MIT" repository = "https://github.com/profullstack/c0mpute" diff --git a/apps/tui/package.json b/apps/tui/package.json index 26c4f127..00b97ee3 100644 --- a/apps/tui/package.json +++ b/apps/tui/package.json @@ -1,6 +1,6 @@ { "name": "@c0mpute/tui", - "version": "0.2.63", + "version": "0.2.64", "private": true, "type": "module", "bin": { diff --git a/apps/web/package.json b/apps/web/package.json index 6b8849bf..e541ec39 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "c0mpute", - "version": "0.2.63", + "version": "0.2.64", "private": true, "type": "module", "scripts": { diff --git a/apps/web/src/app/releases/latest.json/route.ts b/apps/web/src/app/releases/latest.json/route.ts index 71213de7..fe41d399 100644 --- a/apps/web/src/app/releases/latest.json/route.ts +++ b/apps/web/src/app/releases/latest.json/route.ts @@ -28,7 +28,7 @@ export const dynamic = "force-dynamic"; * this in sync with the workspace version in `Cargo.toml` on each release so a * freshly built CLI reports "already latest" rather than a phantom upgrade. */ -const FALLBACK_VERSION = "0.2.63"; +const FALLBACK_VERSION = "0.2.64"; const FALLBACK_MIN_REQUIRED = "0.0.1"; type Channel = "stable" | "beta" | "nightly"; diff --git a/node/crates/c0mpute-core/src/config.rs b/node/crates/c0mpute-core/src/config.rs index 0216b51e..dd7b5f41 100644 --- a/node/crates/c0mpute-core/src/config.rs +++ b/node/crates/c0mpute-core/src/config.rs @@ -61,6 +61,11 @@ pub struct DiffusionConfig { pub min_free_ram_gb: u64, #[serde(default = "default_diffusion_min_free_disk_gb")] pub min_free_disk_gb: u64, + /// Smallest per-job CPU thread budget (`resources::cpu_threads_per_job`, + /// half the box by default) worth serving images with. At 8 threads a + /// 768x512 image takes ~2-4 min; at 3 it passes the 15-minute job limit. + #[serde(default = "default_diffusion_min_cpu_threads")] + pub min_cpu_threads: usize, } impl Default for DiffusionConfig { @@ -70,6 +75,7 @@ impl Default for DiffusionConfig { min_ram_gb: default_diffusion_min_ram_gb(), min_free_ram_gb: default_diffusion_min_free_ram_gb(), min_free_disk_gb: default_diffusion_min_free_disk_gb(), + min_cpu_threads: default_diffusion_min_cpu_threads(), } } } @@ -81,11 +87,15 @@ fn default_diffusion_min_ram_gb() -> u64 { 16 } fn default_diffusion_min_free_ram_gb() -> u64 { - 10 + // A job holds ~9 GB; keep ~3 GB for whatever else the box runs. + 12 } fn default_diffusion_min_free_disk_gb() -> u64 { 25 } +fn default_diffusion_min_cpu_threads() -> usize { + 8 +} impl DiffusionConfig { pub fn auto_install_enabled(&self) -> bool { diff --git a/node/crates/c0mpute-core/src/diffusion.rs b/node/crates/c0mpute-core/src/diffusion.rs index 821ff0fd..4fc986f6 100644 --- a/node/crates/c0mpute-core/src/diffusion.rs +++ b/node/crates/c0mpute-core/src/diffusion.rs @@ -17,6 +17,7 @@ //! - Linux x86_64 only (the only CPU build of the pinned release we run; it is //! built on Ubuntu 26.04 and needs glibc 2.43, which the self-test checks); //! - at least `min_ram_gb` total RAM and `min_free_ram_gb` available right now; +//! - a per-job CPU budget of at least `min_cpu_threads` (a 16-thread box); //! - at least `min_free_disk_gb` free before installing; //! - opt-out: `C0MPUTE_DIFFUSION_AUTO=0` or `[diffusion] auto_install = false`. @@ -139,10 +140,22 @@ pub fn has_headroom_with(config: &crate::config::DiffusionConfig, mem: MemorySna && mem.available >= config.min_free_ram_gb.saturating_mul(GIB) } +/// Pure decision: is this per-job thread budget fast enough to serve images? +pub fn fast_enough_with(config: &crate::config::DiffusionConfig, job_threads: usize) -> bool { + job_threads >= config.min_cpu_threads +} + +fn fast_enough(config: &crate::config::DiffusionConfig) -> bool { + fast_enough_with(config, crate::resources::cpu_threads_per_job()) +} + /// Installed, enabled, and enough free memory to run a job without swapping. /// Called on every advertise tick, so a busy node stops bidding within a minute. pub fn can_serve(config: &crate::config::DiffusionConfig) -> bool { - config.auto_install_enabled() && installed() && has_headroom_with(config, memory()) + config.auto_install_enabled() + && installed() + && fast_enough(config) + && has_headroom_with(config, memory()) } fn now_secs() -> u64 { @@ -187,6 +200,14 @@ pub async fn ensure(config: &crate::config::DiffusionConfig) -> bool { tracing::debug!("diffusion auto-provisioning is off; not installing"); return false; } + if !fast_enough(config) { + info!( + job_threads = crate::resources::cpu_threads_per_job(), + required = config.min_cpu_threads, + "skipping diffusion: CPU budget too small for images in reasonable time" + ); + return false; + } if installed() { return true; } @@ -612,6 +633,17 @@ mod tests { assert!(!has_headroom_with(&config, small)); } + #[test] + fn a_small_cpu_budget_does_not_serve_images() { + let config = DiffusionConfig::default(); + assert!(fast_enough_with(&config, 8)); + assert!(fast_enough_with(&config, 16)); + assert!( + !fast_enough_with(&config, 3), + "a 6-core box at the 50% share is too slow" + ); + } + #[test] fn png_magic_is_checked() { assert!(is_png(b"\x89PNG\r\n\x1a\n0000")); diff --git a/package.json b/package.json index 520f9bc4..0a8c99b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "c0mpute-monorepo", - "version": "0.2.63", + "version": "0.2.64", "private": true, "workspaces": [ "apps/*", diff --git a/packages/shared/package.json b/packages/shared/package.json index 41a58498..89c929e5 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@c0mpute/shared", - "version": "0.2.63", + "version": "0.2.64", "private": true, "type": "module", "main": "./dist/index.js", diff --git a/plugins/ad-generator-agent/module.toml b/plugins/ad-generator-agent/module.toml index 218e0b61..1f440db3 100644 --- a/plugins/ad-generator-agent/module.toml +++ b/plugins/ad-generator-agent/module.toml @@ -21,7 +21,7 @@ [module] id = "ad-generator-agent" name = "Ad Generator Agent — every ad type from one URL" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "applications" description = "Turns a landing-page URL into a complete ad set (display banners, text link, terminal, feed item, image, GIF, 5-second video pre-roll and audio) by buying c0mpute work: copy from Infernet inference, voiceover from CPU text-to-speech, artwork from diffusion when workers offer it. No paid AI API by default." diff --git a/plugins/ads-manager/module.toml b/plugins/ads-manager/module.toml index 41a6d722..9df82fd7 100644 --- a/plugins/ads-manager/module.toml +++ b/plugins/ads-manager/module.toml @@ -18,7 +18,7 @@ [module] id = "ads-manager" name = "Ads Manager — shared ad operations layer" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "applications" description = "Unified ad operations for the c0mpute network: campaign management, creative registry, publisher inventory, OpenRTB auction primitives, CoinPay escrow, and reporting. Required dependency for ctv-ads and all future ad format plugins." diff --git a/plugins/coinpay/module.toml b/plugins/coinpay/module.toml index 429ff05b..f19bfedb 100644 --- a/plugins/coinpay/module.toml +++ b/plugins/coinpay/module.toml @@ -7,7 +7,7 @@ [module] id = "coinpay" name = "CoinPay — DID, payments, escrow, reputation" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "applications" description = "Decentralized identifiers, wallet linking, escrow, signed receipts, and worker reputation. The trust spine of the c0mpute network." diff --git a/plugins/crawl/module.toml b/plugins/crawl/module.toml index f82e66fd..a2039c51 100644 --- a/plugins/crawl/module.toml +++ b/plugins/crawl/module.toml @@ -14,7 +14,7 @@ [module] id = "crawl" name = "Crawl — distributed web fetching" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "data" description = "Decentralized web crawling and page-rendering pool. Static fetches and JS-rendered pages, robots-aware, WARC-capable." diff --git a/plugins/ctv-ads/module.toml b/plugins/ctv-ads/module.toml index c9deb778..95a9d728 100644 --- a/plugins/ctv-ads/module.toml +++ b/plugins/ctv-ads/module.toml @@ -20,7 +20,7 @@ [module] id = "ctv-ads" name = "CTV Ads — Connected TV ad marketplace" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "applications" description = "Decentralised Connected TV advertising on the c0mpute network. VAST 4.x endpoint, OpenRTB real-time auction, cryptographically verified impressions, CoinPay settlement. Supports Roku, Fire TV, Apple TV, Smart TVs, and FAST channels. Live-stream integration for ad-monetised broadcasts." diff --git a/plugins/diffusion/module.toml b/plugins/diffusion/module.toml index 0f5a42a8..9c4f536d 100644 --- a/plugins/diffusion/module.toml +++ b/plugins/diffusion/module.toml @@ -3,14 +3,15 @@ # CPU image generation. Every node with >=16 GiB RAM and >=25 GB free disk # provisions it itself (node/crates/c0mpute-core/src/diffusion.rs): a pinned # stable-diffusion.cpp release (MIT) plus Apache-2.0 weights from Hugging -# Face, all SHA-256 checked. A node bids only while >=10 GiB RAM is free. +# Face, all SHA-256 checked. Needs a per-job CPU budget of >=8 threads +# (a 16-thread box); bids only while >=12 GiB RAM is free. # ~90-120 s per 768x512 image on a 16-core CPU. Buyers call the speech # gateway's POST /v1/images. Opt out: C0MPUTE_DIFFUSION_AUTO=0. [module] id = "diffusion" name = "Diffusion — image generation" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "Decentralized text-to-image on plain CPUs: Z-Image-Turbo through stable-diffusion.cpp, provisioned by every node with the RAM for it." diff --git a/plugins/embed/module.toml b/plugins/embed/module.toml index 2d8d8ad8..5d66053d 100644 --- a/plugins/embed/module.toml +++ b/plugins/embed/module.toml @@ -13,7 +13,7 @@ [module] id = "embed" name = "Embeddings — vector generation" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "Bulk text-embedding generation (sentence-transformers, BGE, Nomic) with CPU fallback and optional GPU acceleration." diff --git a/plugins/gameserver/module.toml b/plugins/gameserver/module.toml index a1e70267..5cba0b7c 100644 --- a/plugins/gameserver/module.toml +++ b/plugins/gameserver/module.toml @@ -14,7 +14,7 @@ [module] id = "gameserver" name = "Game server — Minecraft / Factorio / Valheim" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "infrastructure" description = "Continuous-reservation hosting for game servers. Multi-replica placement, persistent world state on c0mpute storage, proof-of-serve settlement." diff --git a/plugins/hosting/module.toml b/plugins/hosting/module.toml index ecfcb603..1158875c 100644 --- a/plugins/hosting/module.toml +++ b/plugins/hosting/module.toml @@ -12,7 +12,7 @@ [module] id = "hosting" name = "Hosting — censorship-resistant static sites" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "data" description = "Static-site hosting with multi-replica placement, mutable naming, epoch settlement, and slashable proof-of-serve. See DIP-0015." diff --git a/plugins/infernet/module.toml b/plugins/infernet/module.toml index 6511e87b..f57ff203 100644 --- a/plugins/infernet/module.toml +++ b/plugins/infernet/module.toml @@ -10,7 +10,7 @@ [module] id = "infernet" name = "Infernet Protocol — AI inference" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "Decentralized AI inference workloads on c0mpute. Runs models on consumer/prosumer GPUs with model-hash and runtime-image verification. Also trains and serves temporal policies (CfC/LTC liquid networks, GRU baseline) and fine-tunes language models (LoRA) with live progress, on CPU or GPU." diff --git a/plugins/live-stream/module.toml b/plugins/live-stream/module.toml index 99c5bf04..4f099aa7 100644 --- a/plugins/live-stream/module.toml +++ b/plugins/live-stream/module.toml @@ -23,7 +23,7 @@ [module] id = "live-stream" name = "Live Stream — p2p HLS live streaming" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "media" description = "Decentralized live video streaming via BitTorrent-style HLS segment swarming. Broadcaster pushes RTMP/SRT; c0mpute nodes swarm segments to viewers. No central CDN. Censorship-resistant. Per-GB micropayments via CoinPay." diff --git a/plugins/ocr/module.toml b/plugins/ocr/module.toml index 35c5310e..33e00f3a 100644 --- a/plugins/ocr/module.toml +++ b/plugins/ocr/module.toml @@ -12,7 +12,7 @@ [module] id = "ocr" name = "OCR — document text extraction" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "Decentralized OCR for PDFs and scanned documents (Tesseract, PaddleOCR, docTR) with CPU or GPU runners." diff --git a/plugins/podcast-ads/module.toml b/plugins/podcast-ads/module.toml index 7904e429..67b7838f 100644 --- a/plugins/podcast-ads/module.toml +++ b/plugins/podcast-ads/module.toml @@ -22,7 +22,7 @@ [module] id = "podcast-ads" name = "Podcast Ads — audio ad marketplace" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "applications" description = "Decentralised audio advertising for c0mpute-hosted podcasts. DAAST 1.0 endpoint, dynamic ad insertion, Podcasting 2.0 revenue splits, and CoinPay settlement. Publishers sell ad slots; advertisers run campaigns — zero platform cut beyond protocol split." diff --git a/plugins/podcasting/module.toml b/plugins/podcasting/module.toml index 064e9551..f257d241 100644 --- a/plugins/podcasting/module.toml +++ b/plugins/podcasting/module.toml @@ -20,7 +20,7 @@ [module] id = "podcasting" name = "Podcasting — p2p podcast publishing" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "media" description = "Censorship-resistant podcast hosting on the c0mpute network. Upload episodes, stream live shows, auto-transcribe, and monetise via CoinPay subscriptions, pay-per-episode, value-for-value, and audio ads — with zero platform cut. RSS 2.0 + Podcasting 2.0 compatible with all major podcast apps." diff --git a/plugins/podcasts/module.toml b/plugins/podcasts/module.toml index ac02d775..466b643a 100644 --- a/plugins/podcasts/module.toml +++ b/plugins/podcasts/module.toml @@ -19,7 +19,7 @@ [module] id = "podcasts" name = "Podcasts — p2p podcast listener" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "media" description = "Discover, subscribe to, and play podcasts hosted on the c0mpute network or any standard RSS feed. Stream live episodes, tip creators directly via CoinPay, and participate in value-for-value streaming payments. Works alongside any existing podcast app via OPML export and local RSS proxy." diff --git a/plugins/render/module.toml b/plugins/render/module.toml index 65997622..5ff898b3 100644 --- a/plugins/render/module.toml +++ b/plugins/render/module.toml @@ -13,7 +13,7 @@ [module] id = "render" name = "Render — Blender 3D rendering" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "media" description = "Decentralized 3D rendering using Blender headless (Cycles/Eevee) across consumer GPUs and CPUs." diff --git a/plugins/secure-chat/module.toml b/plugins/secure-chat/module.toml index 164b1e15..19948b66 100644 --- a/plugins/secure-chat/module.toml +++ b/plugins/secure-chat/module.toml @@ -18,7 +18,7 @@ [module] id = "secure-chat" name = "Secure Chat — E2E encrypted p2p messaging" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "applications" description = "End-to-end encrypted peer-to-peer messaging across the c0mpute network. No central server. Keys stay with the user. Identity and reputation via CoinPay DID. Group chats, sealed-sender mode, and offline store-and-forward included." diff --git a/plugins/storage/module.toml b/plugins/storage/module.toml index 8eb7eead..82fb2306 100644 --- a/plugins/storage/module.toml +++ b/plugins/storage/module.toml @@ -12,7 +12,7 @@ [module] id = "storage" name = "Storage — Reed-Solomon shard service" -version = "0.2.63" +version = "0.2.64" kind = "service" category = "data" description = "Reed-Solomon 10/14 shard storage with auto-repair. Compute-locality, E2E encryption, content-addressed, pay-as-you-go. See DIP-0012." diff --git a/plugins/train/module.toml b/plugins/train/module.toml index 9af2077a..30f9f1c6 100644 --- a/plugins/train/module.toml +++ b/plugins/train/module.toml @@ -13,7 +13,7 @@ [module] id = "train" name = "Fine-tune — LoRA/QLoRA training" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "Decentralized model fine-tuning (LoRA, QLoRA) on consumer/prosumer GPUs using axolotl or unsloth." diff --git a/plugins/transcode/module.toml b/plugins/transcode/module.toml index a18ba1a4..d7d60286 100644 --- a/plugins/transcode/module.toml +++ b/plugins/transcode/module.toml @@ -7,7 +7,7 @@ [module] id = "transcode" name = "FFmpeg Transcoding" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "media" description = "Decentralized audio/video transcoding via FFmpeg with hardware acceleration (NVENC, QSV, AMF, VideoToolbox, AV1)." diff --git a/plugins/tts/module.toml b/plugins/tts/module.toml index a654f731..f2c87f07 100644 --- a/plugins/tts/module.toml +++ b/plugins/tts/module.toml @@ -15,7 +15,7 @@ [module] id = "tts" name = "TTS — text-to-speech" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "CPU text-to-speech inference over c0mpute using Piper, Kokoro, or Pocket TTS." diff --git a/plugins/video/module.toml b/plugins/video/module.toml index 3d39282f..385e08fe 100644 --- a/plugins/video/module.toml +++ b/plugins/video/module.toml @@ -44,7 +44,7 @@ [module] id = "video" name = "Video — generation (Wan 2.2, LTX-2.3 with audio)" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "Decentralized video generation on consumer/prosumer GPUs: Wan 2.2 text/image-to-video, and LTX-2.3 video with a synchronized soundtrack." diff --git a/plugins/webhook/module.toml b/plugins/webhook/module.toml index 31c125fc..541d178d 100644 --- a/plugins/webhook/module.toml +++ b/plugins/webhook/module.toml @@ -7,7 +7,7 @@ [module] id = "webhook" name = "Webhooks — paid, end-to-end encrypted delivery" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "infrastructure" description = "Send webhooks from c0mpute workers, paid per delivery. The URL, headers, body and signing secret are sealed to the one worker that wins the job; relays and the market see only ciphertext. Standard Webhooks signatures, bounded retries with backoff, SSRF-guarded delivery (public addresses only, no redirects)." diff --git a/plugins/whisper/module.toml b/plugins/whisper/module.toml index eb52a84d..c77739c8 100644 --- a/plugins/whisper/module.toml +++ b/plugins/whisper/module.toml @@ -7,7 +7,7 @@ [module] id = "whisper" name = "Whisper — speech-to-text" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "ai" description = "CPU speech-to-text inference over c0mpute using faster-whisper." diff --git a/plugins/workflow-step/module.toml b/plugins/workflow-step/module.toml index a7b678a6..132ee699 100644 --- a/plugins/workflow-step/module.toml +++ b/plugins/workflow-step/module.toml @@ -14,7 +14,7 @@ [module] id = "workflow-step" name = "Workflow step — webhook workflow steps (meshhook)" -version = "0.2.63" +version = "0.2.64" kind = "workload" category = "infrastructure" description = "Runs one step of a webhook workflow on a c0mpute worker: a JMESPath transform or a guarded HTTP call. Applications reach it through `c0mpute jobs serve`."