#!/usr/bin/env node const assert = require("assert"); const fs = require("fs"); const path = require("path"); const repo = path.resolve(__dirname, ".."); function read(relativePath) { return fs.readFileSync(path.join(repo, relativePath), "utf8"); } function maybeRead(segments) { const fullPath = path.join(repo, ...segments); if (!fs.existsSync(fullPath)) return null; return fs.readFileSync(fullPath, "utf8"); } function expect(source, name, pattern) { assert.match(source, pattern, `missing resource metering evidence: ${name}`); } const coreLimits = read("crates/clusterflux-core/src/limits.rs"); // Phase 3 keeps the protocol dispatch in service.rs and the metered operation // implementations in focused service modules. Read the complete relevant // boundary so this contract follows the refactor instead of one mega-file. const coordinatorService = [ read("crates/clusterflux-coordinator/src/service.rs"), read("crates/clusterflux-coordinator/src/service/routing.rs"), read("crates/clusterflux-coordinator/src/service/processes.rs"), read("crates/clusterflux-coordinator/src/service/process_launch.rs"), read("crates/clusterflux-coordinator/src/service/artifacts.rs"), ].join("\n"); const coordinatorQuota = read("crates/clusterflux-coordinator/src/service/quota.rs"); const coordinatorLogs = read("crates/clusterflux-coordinator/src/service/logs.rs"); const coordinatorDebug = read("crates/clusterflux-coordinator/src/service/debug.rs"); const coordinatorTests = read("crates/clusterflux-coordinator/src/service/tests.rs"); const wasmRuntime = read("crates/clusterflux-wasm-runtime/src/lib.rs"); const wasmRuntimeTests = read("crates/clusterflux-wasm-runtime/src/tests.rs"); const artifactDownloadSmoke = read("scripts/artifact-download-smoke.js"); const operatorPanelSmoke = read("scripts/operator-panel-smoke.js"); const quicSmoke = read("scripts/quic-smoke.js"); for (const [name, pattern] of [ ["API call limit kind", /\bApiCall,/], ["spawn limit kind", /\bSpawn,/], ["log bytes limit kind", /\bLogBytes,/], ["metadata bytes limit kind", /\bMetadataBytes,/], ["debug read bytes limit kind", /\bDebugReadBytes,/], ["UI event limit kind", /\bUiEvent,/], ["rendezvous attempt limit kind", /\bRendezvousAttempt,/], ["artifact download bytes limit kind", /\bArtifactDownloadBytes,/], [ "preflight can check without consuming", /pub fn can_charge\([\s\S]*used\.saturating_add\(amount\) > limit/, ], [ "charge goes through preflight", /pub fn charge\([\s\S]*self\.can_charge\(limits, kind, amount\)\?/, ], ]) { expect(coreLimits, name, pattern); } for (const [name, pattern] of [ [ "Wasm stores enforce a concrete memory limit", /StoreLimitsBuilder::new\(\)[\s\S]*memory_size\(runtime\.memory_bytes\)/, ], [ "Wasm compute uses a refillable fuel token bucket", /struct FuelTokenBucket[\s\S]*fractional_fuel_numerator[\s\S]*fn refill_after/, ], ["Wasmtime fuel consumption is enabled", /config\.consume_fuel\(true\)/], ["Wasmtime epoch interruption is enabled", /config\.epoch_interruption\(true\)/], ]) { expect(wasmRuntime, name, pattern); } for (const [name, pattern] of [ [ "fuel refill preserves fractional credit", /frequent_refills_preserve_fractional_credit/, ], [ "linear memory growth is bounded per store", /wasm_linear_memory_growth_is_bounded_per_store/, ], [ "CPU-bound Wasm is interrupted without a host call", /epoch_interruption_aborts_cpu_bound_wasm_without_a_host_call/, ], ]) { expect(`${wasmRuntime}\n${wasmRuntimeTests}`, name, pattern); } for (const [name, pattern] of [ [ "rendezvous charges before transport planning", /handle_request_rendezvous[\s\S]*charge_rendezvous_attempt\([\s\S]*&scope\.tenant[\s\S]*&scope\.project[\s\S]*now_epoch_seconds[\s\S]*plan_authenticated_direct_bulk_transfer/, ], [ "artifact link creation preflights downloadable bytes before link creation", /handle_create_artifact_download_link[\s\S]*downloadable_size[\s\S]*can_charge_download\([\s\S]*&context\.tenant[\s\S]*&context\.project[\s\S]*downloadable_size[\s\S]*create_download_link/, ], [ "artifact delivery charges scoped bytes before advancing its offset", /handle_open_artifact_download_stream[\s\S]*stream_download_chunk\([\s\S]*charge_download\([\s\S]*&context\.tenant[\s\S]*&context\.project[\s\S]*streamed_bytes[\s\S]*delivered_offset = end/, ], ]) { expect(coordinatorService, name, pattern); } for (const [name, pattern] of [ [ "quota keys include tenant/project resource kind and window", /struct ProjectQuotaScope[\s\S]*tenant: TenantId[\s\S]*project: ProjectId[\s\S]*struct MeterKey[\s\S]*kind: LimitKind[\s\S]*window: u64/, ], [ "quota module discards expired windows for an accessed scope and kind", /fn meter_mut[\s\S]*self\.meters\.retain[\s\S]*existing\.scope != key\.scope[\s\S]*existing\.kind != kind[\s\S]*existing\.window == key\.window/, ], [ "quota module charges rendezvous attempts through the scoped window meter", /fn charge_rendezvous_attempt[\s\S]*self\.charge\([\s\S]*tenant[\s\S]*project[\s\S]*LimitKind::RendezvousAttempt/, ], [ "quota module charges authenticated API calls through the scoped window meter", /fn charge_api_call[\s\S]*self\.charge\(tenant, project, LimitKind::ApiCall, 1, now_epoch_seconds\)/, ], [ "quota module preflights and charges log bytes through the scoped window meter", /fn can_charge_log_bytes[\s\S]*LimitKind::LogBytes[\s\S]*fn charge_log_bytes[\s\S]*LimitKind::LogBytes/, ], [ "quota module preflights artifact download bytes through the scoped meter", /fn can_charge_download[\s\S]*self\.can_charge\([\s\S]*tenant[\s\S]*project[\s\S]*LimitKind::ArtifactDownloadBytes/, ], [ "quota status reports current scoped window usage", /fn project_status[\s\S]*for kind in LimitKind::ALL[\s\S]*self\.used\(tenant, project, kind, now_epoch_seconds\)/, ], ]) { expect(coordinatorQuota, name, pattern); } for (const [source, name, pattern] of [ [ coordinatorService, "authenticated API calls are charged after session authorization and before dispatch", /authenticate_cli_session[\s\S]*authorize_authenticated_user_operation[\s\S]*charge_api_call[\s\S]*match request/, ], [ coordinatorLogs, "signed node log ingestion preflights and charges bytes before accepting the report", /handle_report_task_log[\s\S]*authorize_node_for_process_or_termination[\s\S]*can_charge_log_bytes[\s\S]*charge_log_bytes[\s\S]*TaskLogRecorded/, ], [ coordinatorDebug, "debug reads charge the scoped debug-read budget before audit state is recorded", /record_debug_audit_event[\s\S]*charge_debug_read[\s\S]*DebugAuditEvent/, ], [ coordinatorTests, "tests prove API-call and log-byte quota enforcement and project isolation", /authenticated_api_calls_are_metered_per_tenant_and_project_before_dispatch[\s\S]*project-a[\s\S]*project-b[\s\S]*signed_node_log_ingestion_checks_scoped_quota_before_accepting_bytes[\s\S]*LogBytes/, ], ]) { expect(source, name, pattern); } for (const [name, source, patterns] of [ [ "rendezvous smoke", quicSmoke, [/charged_rendezvous_attempts, 1/, /coordinator bulk relay is disabled/], ], [ "artifact download smoke", artifactDownloadSmoke, [ /downloaded\.response\.charged_download_bytes,[\s\S]*packageEvent\.artifact_size_bytes/, /retaining_node_reverse_stream/, /revoked/, ], ], [ "operator panel smoke", operatorPanelSmoke, [ /type: "submit_panel_event"/, /max_events: 1/, /used_events, 1/, /rate limit/i, /max_download_bytes: 1/, /exceeds download limit/, ], ], ]) { for (const pattern of patterns) { expect(source, name, pattern); } } const privateHostedLibSource = maybeRead(["private", "hosted-policy", "src", "lib.rs"]); const privateHostedTests = maybeRead(["private", "hosted-policy", "src", "tests.rs"]); const privateHostedLib = privateHostedLibSource ? [privateHostedLibSource, privateHostedTests].filter(Boolean).join("\n") : null; if (privateHostedLib) { for (const [name, pattern] of [ [ "private hosted configuration owns exact control-plane limits and quota windows", /community_tier_resource_limits[\s\S]*LimitKind::ApiCall[\s\S]*LimitKind::ArtifactDownloadBytes[\s\S]*community_tier_quota_configuration[\s\S]*CoordinatorQuotaConfiguration::new/, ], [ "hosted zero-capability policy rejects native execution capabilities", /hosted_zero_capability_wasm_rejects_filesystem_and_command_capabilities[\s\S]*Capability::Command[\s\S]*Capability::Network[\s\S]*Capability::ArbitrarySyscalls/, ], ]) { expect(privateHostedLib, name, pattern); } assert.doesNotMatch( privateHostedLib, /HostedFuel|HostedMemoryBytes|HostedWallClockMs|HostedStateBytes/, "decorative hosted Wasm quota kinds must not return", ); } console.log("Resource metering contract smoke passed");