Public release source-69fccd306838

Source commit: 69fccd306838141ba9b1730f4ac4afb1a617bb4e

Public tree identity: sha256:8c03637496d3f7ee1b625aa1c823cd69bfcf0247a061d8cb571e05d537329691
This commit is contained in:
Clusterflux release 2026-07-25 17:53:21 +02:00
parent f4590ca576
commit ba749b9e47
88 changed files with 204 additions and 18991 deletions

4
.gitignore vendored
View file

@ -2,7 +2,3 @@
/.clusterflux/ /.clusterflux/
**/.clusterflux/ **/.clusterflux/
/vscode-extension/node_modules/ /vscode-extension/node_modules/
/private/*/Cargo.lock
!/private/hosted-policy/Cargo.lock
/private/*/target/
/scripts/containers-home/

View file

@ -1,22 +0,0 @@
{
"kind": "clusterflux-filtered-public-tree",
"source_commit": "7fcdc75d8eaf4dc03b09086568dbb184f903f6a4",
"release_name": "release-7fcdc75d8eaf",
"filtered_out": [
"private/**",
"internal/**",
"experiments/**",
".git",
"target",
"git-ignored source paths",
"root/*.md except README.md",
"**/.clusterflux/**",
".forgejo/**"
],
"public_export": {
"host_neutral": true,
"include_forgejo_workflows": false
},
"forgejo_host": "git.michelpaulissen.com",
"default_hosted_coordinator_endpoint": "https://clusterflux.michelpaulissen.com"
}

View file

@ -12,13 +12,12 @@ members = [
"crates/clusterflux-wasm-runtime", "crates/clusterflux-wasm-runtime",
"examples/hello-build", "examples/hello-build",
"examples/recovery-build", "examples/recovery-build",
"tests/fixtures/runtime-conformance",
] ]
[workspace.package] [workspace.package]
edition = "2021" edition = "2021"
license = "Apache-2.0 OR MIT" license = "Apache-2.0 OR MIT"
repository = "https://git.michelpaulissen.com/michel/clusterflux-public" repository = "https://clusterflux.lesstuff.com"
[workspace.dependencies] [workspace.dependencies]
anyhow = "1.0" anyhow = "1.0"

View file

@ -1,9 +1,57 @@
# Clusterflux # Clusterflux
Clusterflux runs a Rust-defined workflow as one distributed virtual process. A Clusterflux runs a Rust-defined workflow as one distributed virtual process. The
coordinator hosts the async main, while attached nodes execute Wasm tasks, async main runs serverless, provisioning nodes to run tasks through rootless
rootless containers, and native commands. Tasks exchange canonical values and containers. Tasks on nodes exchange data simply and efficiently.
portable typed handles instead of sharing host memory.
The user experience is built to be as much as possible like building a regular
program. The processes are debuggable as normal through a debugger adapter.
The primary use case is to consolidate build processes into a single streamlined
developer experience. An example program can be seen below:
~~~rust
use clusterflux::prelude::*;
#[clusterflux::task(capabilities = "command")]
pub async fn compile(source: SourceSnapshot) -> Result<Artifact> {
let executable = fs::output("hello-clusterflux")?;
Command::new("cc")
.args([
"-Os",
"-static",
"-s",
"fixture/hello-clusterflux.c",
"-o",
executable.as_str(),
])
.cwd(source.mount()?)
.env("SOURCE_DATE_EPOCH", "0")
.network_disabled()
.run()
.await?;
fs::publish(&executable).await
}
#[clusterflux::main]
pub async fn build() -> Result<Artifact> {
let source = source::current_project().snapshot().await?;
let compile = clusterflux::spawn!(compile(source))
.on(clusterflux::env!("linux"))
.await?;
compile.join().await
}
~~~
After setup, this build pipeline could be deployed as easily as launching it
through your IDE. This repository includes a VS Code extension to make
development as straightforward as possible. A full collection of CLI tools is
included for advanced usage.
Clusterflux is explicitly local-first. It is trivial to provision existing
hardware as resources. Bulk data will typically not leave the local network,
allowing maximum throughput. The same capability, however, also makes it
possible to leverage cloud resources easily.
Start with [Getting started](docs/getting-started.md). It takes you through Start with [Getting started](docs/getting-started.md). It takes you through
authentication, project setup, node enrollment, a run, debugging, task restart, authentication, project setup, node enrollment, a run, debugging, task restart,

View file

@ -7,7 +7,7 @@ published Clusterflux release. Older preview releases are not maintained.
## Report a vulnerability ## Report a vulnerability
Email security@michelpaulissen.com with a concise description, affected version Email security@clusterflux.lesstuff.com with a concise description, affected version
or source revision, reproduction steps, and impact. Do not open a public issue or source revision, reproduction steps, and impact. Do not open a public issue
for an unpatched vulnerability or include credentials, session tokens, private for an unpatched vulnerability or include credentials, session tokens, private
keys, provider tokens, customer data, or operator secrets in a public report. keys, provider tokens, customer data, or operator secrets in a public report.

View file

@ -48,7 +48,7 @@ pub(crate) fn admin_status_report(args: AdminStatusArgs) -> Result<Value> {
.unwrap_or(json!(false)), .unwrap_or(json!(false)),
"response": response, "response": response,
"safe_default": "read_only", "safe_default": "read_only",
"private_website_required": false, "external_website_required": false,
"coordinator_session_requests": session.requests(), "coordinator_session_requests": session.requests(),
})); }));
} }
@ -56,7 +56,7 @@ pub(crate) fn admin_status_report(args: AdminStatusArgs) -> Result<Value> {
"command": "admin status", "command": "admin status",
"mode": "self_hosted_local", "mode": "self_hosted_local",
"safe_default": "read_only", "safe_default": "read_only",
"private_website_required": false, "external_website_required": false,
})) }))
} }
@ -86,7 +86,7 @@ pub(crate) fn admin_bootstrap_report(args: AdminBootstrapArgs, cwd: PathBuf) ->
"project": project.clone(), "project": project.clone(),
"user": user, "user": user,
"coordinator": scope.coordinator, "coordinator": scope.coordinator,
"private_website_required": false, "external_website_required": false,
"self_hosted_cli_only": true, "self_hosted_cli_only": true,
"project_config_written": project_init "project_config_written": project_init
.get("project_config_written") .get("project_config_written")
@ -107,13 +107,13 @@ pub(crate) fn admin_bootstrap_report(args: AdminBootstrapArgs, cwd: PathBuf) ->
{ {
"step": "start_self_hosted_coordinator", "step": "start_self_hosted_coordinator",
"command": "clusterflux-coordinator --listen 127.0.0.1:0", "command": "clusterflux-coordinator --listen 127.0.0.1:0",
"private_website_required": false, "external_website_required": false,
}, },
{ {
"step": "create_or_link_project", "step": "create_or_link_project",
"command": "clusterflux project init --yes", "command": "clusterflux project init --yes",
"completed": true, "completed": true,
"private_website_required": false, "external_website_required": false,
}, },
{ {
"step": "create_node_enrollment_grant", "step": "create_node_enrollment_grant",
@ -121,7 +121,7 @@ pub(crate) fn admin_bootstrap_report(args: AdminBootstrapArgs, cwd: PathBuf) ->
"clusterflux node enroll --coordinator {coordinator} --tenant {} --project-id {}", "clusterflux node enroll --coordinator {coordinator} --tenant {} --project-id {}",
tenant, project tenant, project
), ),
"private_website_required": false, "external_website_required": false,
}, },
{ {
"step": "attach_worker_node", "step": "attach_worker_node",
@ -129,7 +129,7 @@ pub(crate) fn admin_bootstrap_report(args: AdminBootstrapArgs, cwd: PathBuf) ->
"clusterflux node attach --coordinator {coordinator} --tenant {} --project-id {} --worker", "clusterflux node attach --coordinator {coordinator} --tenant {} --project-id {} --worker",
tenant, project tenant, project
), ),
"private_website_required": false, "external_website_required": false,
}, },
{ {
"step": "run_process", "step": "run_process",
@ -137,7 +137,7 @@ pub(crate) fn admin_bootstrap_report(args: AdminBootstrapArgs, cwd: PathBuf) ->
"clusterflux run --coordinator {coordinator} --tenant {} --project-id {}", "clusterflux run --coordinator {coordinator} --tenant {} --project-id {}",
tenant, project tenant, project
), ),
"private_website_required": false, "external_website_required": false,
}, },
{ {
"step": "inspect_status_logs_artifacts", "step": "inspect_status_logs_artifacts",
@ -148,12 +148,12 @@ pub(crate) fn admin_bootstrap_report(args: AdminBootstrapArgs, cwd: PathBuf) ->
"clusterflux artifact list", "clusterflux artifact list",
"clusterflux quota status", "clusterflux quota status",
], ],
"private_website_required": false, "external_website_required": false,
}, },
{ {
"step": "revoke_access", "step": "revoke_access",
"command": "clusterflux admin revoke-node --node <node-id> --yes", "command": "clusterflux admin revoke-node --node <node-id> --yes",
"private_website_required": false, "external_website_required": false,
} }
], ],
})) }))
@ -209,7 +209,7 @@ pub(crate) fn admin_suspend_tenant_report(args: AdminSuspendTenantArgs) -> Resul
"actor_tenant": actor_tenant, "actor_tenant": actor_tenant,
"actor_user": actor_user, "actor_user": actor_user,
"suspended": response.get("type").and_then(Value::as_str) == Some("tenant_suspended"), "suspended": response.get("type").and_then(Value::as_str) == Some("tenant_suspended"),
"private_website_required": false, "external_website_required": false,
"response": response, "response": response,
"coordinator_session_requests": session.requests(), "coordinator_session_requests": session.requests(),
})); }));
@ -219,7 +219,7 @@ pub(crate) fn admin_suspend_tenant_report(args: AdminSuspendTenantArgs) -> Resul
"status": "requires_coordinator", "status": "requires_coordinator",
"requires_confirmation": !args.yes, "requires_confirmation": !args.yes,
"tenant": tenant, "tenant": tenant,
"private_website_required": false, "external_website_required": false,
})) }))
} }

View file

@ -227,7 +227,7 @@ pub(crate) fn auth_status_report(args: AuthStatusArgs, cwd: PathBuf) -> Result<V
"suspension_known": false, "suspension_known": false,
"account_state_known": false, "account_state_known": false,
"account_status": "unknown", "account_status": "unknown",
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
}) })
}); });
@ -263,7 +263,7 @@ fn coordinator_auth_status_summary(
"account_status": "unknown", "account_status": "unknown",
"suspension_known": false, "suspension_known": false,
"account_state_known": false, "account_state_known": false,
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"machine_error": cli_error_summary(&message), "machine_error": cli_error_summary(&message),
"error": message, "error": message,
@ -296,7 +296,7 @@ fn coordinator_auth_status_summary(
"account_status": "unknown", "account_status": "unknown",
"suspension_known": false, "suspension_known": false,
"account_state_known": false, "account_state_known": false,
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"machine_error": cli_error_summary(&message), "machine_error": cli_error_summary(&message),
"error": message, "error": message,
@ -316,7 +316,7 @@ fn coordinator_auth_status_summary(
"account_status": "unknown", "account_status": "unknown",
"suspension_known": false, "suspension_known": false,
"account_state_known": false, "account_state_known": false,
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"machine_error": cli_error_summary(&message), "machine_error": cli_error_summary(&message),
"error": message, "error": message,
@ -338,7 +338,7 @@ fn coordinator_auth_status_summary(
"account_status": "unknown", "account_status": "unknown",
"suspension_known": false, "suspension_known": false,
"account_state_known": false, "account_state_known": false,
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"machine_error": cli_error_summary(message), "machine_error": cli_error_summary(message),
"coordinator_response_type": "error", "coordinator_response_type": "error",
@ -403,7 +403,7 @@ fn coordinator_auth_status_summary(
"manual_review": manual_review, "manual_review": manual_review,
"sanitized_reason": sanitized_reason, "sanitized_reason": sanitized_reason,
"next_actions": next_actions, "next_actions": next_actions,
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"coordinator_response_type": response.get("type").and_then(Value::as_str).unwrap_or("auth_status"), "coordinator_response_type": response.get("type").and_then(Value::as_str).unwrap_or("auth_status"),
"coordinator_session_requests": coordinator_session_requests, "coordinator_session_requests": coordinator_session_requests,

View file

@ -60,7 +60,7 @@ pub(crate) fn session_scope_mismatch_status(fields: &[&str]) -> Value {
"account_status": "unknown", "account_status": "unknown",
"suspension_known": false, "suspension_known": false,
"account_state_known": false, "account_state_known": false,
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"next_actions": ["clusterflux login --browser"], "next_actions": ["clusterflux login --browser"],
}) })

View file

@ -5,8 +5,7 @@ use serde::{Deserialize, Serialize};
use crate::CliScopeArgs; use crate::CliScopeArgs;
pub(crate) const DEFAULT_HOSTED_COORDINATOR_ENDPOINT: &str = pub(crate) const DEFAULT_HOSTED_COORDINATOR_ENDPOINT: &str = "https://clusterflux.lesstuff.com";
"https://clusterflux.michelpaulissen.com";
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub(crate) struct ProjectConfig { pub(crate) struct ProjectConfig {

View file

@ -15,7 +15,7 @@ pub(crate) fn dap_plan(args: DapArgs) -> Result<Value> {
"command": "dap", "command": "dap",
"adapter": dap_binary_path()?.display().to_string(), "adapter": dap_binary_path()?.display().to_string(),
"args": args.args, "args": args.args,
"private_website_required": false, "external_website_required": false,
})) }))
} }
@ -102,7 +102,7 @@ pub(crate) fn debug_attach_report_with_dap_and_session(
.cloned() .cloned()
.unwrap_or_else(|| json!(0)), .unwrap_or_else(|| json!(0)),
"debug_reads_quota_limited": true, "debug_reads_quota_limited": true,
"private_website_required": false, "external_website_required": false,
"coordinator_session_requests": session.requests(), "coordinator_session_requests": session.requests(),
})); }));
} }
@ -115,6 +115,6 @@ pub(crate) fn debug_attach_report_with_dap_and_session(
"dap": dap, "dap": dap,
"authorized": "unknown_without_coordinator", "authorized": "unknown_without_coordinator",
"debug_reads_quota_limited": "unknown_without_coordinator", "debug_reads_quota_limited": "unknown_without_coordinator",
"private_website_required": false, "external_website_required": false,
})) }))
} }

View file

@ -38,7 +38,10 @@ pub(crate) fn cli_error_summary_for_category(category: &'static str, message: &s
); );
object.insert("community_tier_language".to_owned(), json!(true)); object.insert("community_tier_language".to_owned(), json!(true));
object.insert("community_tier_label".to_owned(), json!("community tier")); object.insert("community_tier_label".to_owned(), json!("community tier"));
object.insert("private_abuse_heuristics_exposed".to_owned(), json!(false)); object.insert(
"sensitive_abuse_heuristics_exposed".to_owned(),
json!(false),
);
} }
} }
summary summary

View file

@ -152,7 +152,7 @@ pub(crate) fn node_enroll_report(args: NodeEnrollArgs, cwd: PathBuf) -> Result<V
"tenant": tenant, "tenant": tenant,
"project": project, "project": project,
"user": user, "user": user,
"private_website_required": false, "external_website_required": false,
"enrollment_grant": enrollment_grant, "enrollment_grant": enrollment_grant,
"response": response, "response": response,
"coordinator_session_requests": session.requests(), "coordinator_session_requests": session.requests(),
@ -161,7 +161,7 @@ pub(crate) fn node_enroll_report(args: NodeEnrollArgs, cwd: PathBuf) -> Result<V
Ok(json!({ Ok(json!({
"command": "node enroll", "command": "node enroll",
"status": "requires_coordinator", "status": "requires_coordinator",
"private_website_required": false, "external_website_required": false,
"requested_ttl_seconds": args.ttl_seconds, "requested_ttl_seconds": args.ttl_seconds,
"enrollment_grant": null, "enrollment_grant": null,
"reason": "enrollment grants are generated by the coordinator and cannot be planned client-side", "reason": "enrollment grants are generated by the coordinator and cannot be planned client-side",

View file

@ -217,10 +217,10 @@ pub(crate) fn human_report(value: &Value) -> String {
} }
push_nested_string_field(&mut lines, account, "sanitized_reason", "account reason"); push_nested_string_field(&mut lines, account, "sanitized_reason", "account reason");
if let Some(exposed) = account if let Some(exposed) = account
.get("private_moderation_details_exposed") .get("sensitive_moderation_details_exposed")
.and_then(Value::as_bool) .and_then(Value::as_bool)
{ {
lines.push(format!("private moderation details exposed: {exposed}")); lines.push(format!("sensitive moderation details exposed: {exposed}"));
} }
} }
if let Some(coordinator_selection) = value.get("coordinator") { if let Some(coordinator_selection) = value.get("coordinator") {
@ -277,10 +277,10 @@ pub(crate) fn human_report(value: &Value) -> String {
)); ));
} }
if let Some(flag) = value if let Some(flag) = value
.get("private_website_required") .get("external_website_required")
.and_then(Value::as_bool) .and_then(Value::as_bool)
{ {
lines.push(format!("private website required: {flag}")); lines.push(format!("external website required: {flag}"));
} }
if let Some(next_actions) = value.get("next_actions").and_then(Value::as_array) { if let Some(next_actions) = value.get("next_actions").and_then(Value::as_array) {
let actions = next_actions let actions = next_actions

View file

@ -557,7 +557,7 @@ pub(crate) fn artifact_download_grant_disclosures(response: &Value) -> Value {
"cross_tenant_reuse_allowed": false, "cross_tenant_reuse_allowed": false,
"unauthorized_project_reuse_allowed": false, "unauthorized_project_reuse_allowed": false,
"default_durable_store_assumed": false, "default_durable_store_assumed": false,
"private_website_required": false, "external_website_required": false,
}]) }])
} }
@ -613,7 +613,7 @@ pub(crate) fn project_quota_posture(attached_nodes: &Value, task_events: Option<
"current_usage": current_usage, "current_usage": current_usage,
"limits": quota_limits_value(), "limits": quota_limits_value(),
"next_blocked_action": next_blocked_action, "next_blocked_action": next_blocked_action,
"private_abuse_heuristics_exposed": false, "sensitive_abuse_heuristics_exposed": false,
}) })
} }

View file

@ -92,7 +92,7 @@ pub(crate) fn project_init_report(args: ProjectInitArgs, cwd: PathBuf) -> Result
Ok(json!({ Ok(json!({
"command": "project init", "command": "project init",
"source": if coordinator.is_some() { "public_coordinator_api" } else { "local_project_config" }, "source": if coordinator.is_some() { "public_coordinator_api" } else { "local_project_config" },
"private_website_required": false, "external_website_required": false,
"project_config_written": true, "project_config_written": true,
"project_config_write_after_coordinator_acceptance": coordinator.is_some(), "project_config_write_after_coordinator_acceptance": coordinator.is_some(),
"coordinator_create_before_local_write": coordinator.is_some(), "coordinator_create_before_local_write": coordinator.is_some(),
@ -104,7 +104,7 @@ pub(crate) fn project_init_report(args: ProjectInitArgs, cwd: PathBuf) -> Result
"config_format": "clusterflux_project_config_v1", "config_format": "clusterflux_project_config_v1",
"links_current_directory": true, "links_current_directory": true,
"writes_current_directory_only": true, "writes_current_directory_only": true,
"private_website_required": false, "external_website_required": false,
}, },
"safe_defaults": { "safe_defaults": {
"tenant": config.tenant.clone(), "tenant": config.tenant.clone(),
@ -115,7 +115,7 @@ pub(crate) fn project_init_report(args: ProjectInitArgs, cwd: PathBuf) -> Result
"default_project_id_used": args.new_project == "project", "default_project_id_used": args.new_project == "project",
"default_project_name_used": args.name == "Clusterflux Project", "default_project_name_used": args.name == "Clusterflux Project",
"browser_interaction_required": false, "browser_interaction_required": false,
"private_website_required": false, "external_website_required": false,
}, },
"project_config": config, "project_config": config,
"config_file": project_config_file(&cwd), "config_file": project_config_file(&cwd),
@ -283,7 +283,7 @@ pub(crate) fn project_list_report(args: ProjectListArgs, cwd: PathBuf) -> Result
"user": user, "user": user,
"projects": projects, "projects": projects,
"project_count": project_count, "project_count": project_count,
"private_website_required": false, "external_website_required": false,
"response": response, "response": response,
"coordinator_session_requests": session.requests(), "coordinator_session_requests": session.requests(),
})); }));
@ -295,7 +295,7 @@ pub(crate) fn project_list_report(args: ProjectListArgs, cwd: PathBuf) -> Result
"source": "local_project_config", "source": "local_project_config",
"projects": projects, "projects": projects,
"project_count": project_count, "project_count": project_count,
"private_website_required": false, "external_website_required": false,
})) }))
} }
@ -361,7 +361,7 @@ pub(crate) fn project_select_report(args: ProjectSelectArgs, cwd: PathBuf) -> Re
"source": if coordinator.is_some() { "public_coordinator_api" } else { "local_project_config" }, "source": if coordinator.is_some() { "public_coordinator_api" } else { "local_project_config" },
"selected_project": selected_project, "selected_project": selected_project,
"project_config_written": true, "project_config_written": true,
"private_website_required": false, "external_website_required": false,
"project_config": config, "project_config": config,
"coordinator_response": coordinator_response, "coordinator_response": coordinator_response,
})) }))

View file

@ -96,7 +96,7 @@ pub(crate) fn quota_status_report(args: QuotaStatusArgs, cwd: PathBuf) -> Result
"user": effective_scope.user, "user": effective_scope.user,
"coordinator": coordinator, "coordinator": coordinator,
"project_config": config, "project_config": config,
"policy_surface": "generic public quota categories; hosted tuning remains private policy", "policy_surface": "generic public quota categories; hosted tuning is coordinator-defined",
"limits": limits, "limits": limits,
"window_seconds": window_seconds, "window_seconds": window_seconds,
"current_usage": current_usage, "current_usage": current_usage,
@ -105,7 +105,7 @@ pub(crate) fn quota_status_report(args: QuotaStatusArgs, cwd: PathBuf) -> Result
"next_blocked_action": quota_next_blocked_action(&current_usage), "next_blocked_action": quota_next_blocked_action(&current_usage),
"quota_configuration_source": if quota_status.is_some() { "coordinator" } else { "unavailable_offline" }, "quota_configuration_source": if quota_status.is_some() { "coordinator" } else { "unavailable_offline" },
"quota_tier": quota_tier, "quota_tier": quota_tier,
"private_abuse_heuristics_exposed": false, "sensitive_abuse_heuristics_exposed": false,
"quota_response": quota_status, "quota_response": quota_status,
})) }))
} }

View file

@ -142,7 +142,7 @@ fn non_interactive_run_requires_auth_report(args: RunArgs, cwd: PathBuf) -> Valu
"safe_failure": true, "safe_failure": true,
"message": message, "message": message,
"next_actions": next_actions, "next_actions": next_actions,
"private_website_required": false, "external_website_required": false,
"machine_error": machine_error, "machine_error": machine_error,
}) })
} }
@ -329,7 +329,7 @@ fn coordinator_run_report(plan: RunPlan) -> Result<Value> {
"task_launch": launch_task_response, "task_launch": launch_task_response,
"coordinator_response": response, "coordinator_response": response,
"coordinator_session_requests": session.requests(), "coordinator_session_requests": session.requests(),
"private_website_required": false, "external_website_required": false,
})) }))
} }

View file

@ -124,7 +124,7 @@ fn cli_error_classifier_distinguishes_mvp_failure_categories() {
assert_eq!(summary["resource_category"], "api_calls"); assert_eq!(summary["resource_category"], "api_calls");
assert_eq!(summary["community_tier_language"], true); assert_eq!(summary["community_tier_language"], true);
assert_eq!(summary["community_tier_label"], "community tier"); assert_eq!(summary["community_tier_label"], "community tier");
assert_eq!(summary["private_abuse_heuristics_exposed"], false); assert_eq!(summary["sensitive_abuse_heuristics_exposed"], false);
let rendered = human_report(&json!({ let rendered = human_report(&json!({
"command": "run", "command": "run",
"machine_error": summary, "machine_error": summary,
@ -207,7 +207,7 @@ fn non_interactive_run_without_session_requires_explicit_auth_or_local() {
assert_eq!(report["status"], "authentication_required"); assert_eq!(report["status"], "authentication_required");
assert_eq!(report["non_interactive"], true); assert_eq!(report["non_interactive"], true);
assert_eq!(report["browser_opened"], false); assert_eq!(report["browser_opened"], false);
assert_eq!(report["private_website_required"], false); assert_eq!(report["external_website_required"], false);
assert_eq!(report["machine_error"]["category"], "authentication"); assert_eq!(report["machine_error"]["category"], "authentication");
assert_eq!(report["machine_error"]["stable_exit_code"], 20); assert_eq!(report["machine_error"]["stable_exit_code"], 20);
assert_eq!(report["machine_error"]["browser_opened"], false); assert_eq!(report["machine_error"]["browser_opened"], false);
@ -827,7 +827,7 @@ fn run_rejection_reports_machine_readable_error_category() {
assert_eq!(rejected["machine_error"]["resource_category"], "api_calls"); assert_eq!(rejected["machine_error"]["resource_category"], "api_calls");
assert_eq!(rejected["machine_error"]["community_tier_language"], true); assert_eq!(rejected["machine_error"]["community_tier_language"], true);
assert_eq!( assert_eq!(
rejected["machine_error"]["private_abuse_heuristics_exposed"], rejected["machine_error"]["sensitive_abuse_heuristics_exposed"],
false false
); );
assert!(rejected["machine_error"]["next_actions"] assert!(rejected["machine_error"]["next_actions"]
@ -1665,12 +1665,11 @@ fn node_attach_refuses_a_symlink_credential_target() {
fn hosted_coordinator_remains_a_real_https_control_endpoint() { fn hosted_coordinator_remains_a_real_https_control_endpoint() {
assert_eq!( assert_eq!(
control_endpoint_identity(DEFAULT_HOSTED_COORDINATOR_ENDPOINT).unwrap(), control_endpoint_identity(DEFAULT_HOSTED_COORDINATOR_ENDPOINT).unwrap(),
"https://clusterflux.michelpaulissen.com/api/v1/control" "https://clusterflux.lesstuff.com/api/v1/control"
); );
assert_eq!( assert_eq!(
control_endpoint_identity("https://clusterflux.michelpaulissen.com/api/v1/control") control_endpoint_identity("https://clusterflux.lesstuff.com/api/v1/control").unwrap(),
.unwrap(), "https://clusterflux.lesstuff.com/api/v1/control"
"https://clusterflux.michelpaulissen.com/api/v1/control"
); );
assert!(control_endpoint_identity("http://operator.example.test").is_err()); assert!(control_endpoint_identity("http://operator.example.test").is_err());
assert_eq!( assert_eq!(
@ -1788,7 +1787,7 @@ fn auth_status_reads_stored_cli_session_without_provider_tokens() {
assert!(!line.contains(r#""actor_user":"user-session""#)); assert!(!line.contains(r#""actor_user":"user-session""#));
stream stream
.write_all( .write_all(
br#"{"type":"auth_status","tenant":"tenant-session","project":"project-session","actor":"user-session","authenticated":true,"account_status":"active","suspended":false,"disabled":false,"sanitized_reason":null,"next_actions":[],"private_moderation_details_exposed":false,"signup_failure_details_exposed":false}"#, br#"{"type":"auth_status","tenant":"tenant-session","project":"project-session","actor":"user-session","authenticated":true,"account_status":"active","suspended":false,"disabled":false,"sanitized_reason":null,"next_actions":[],"sensitive_moderation_details_exposed":false,"signup_failure_details_exposed":false}"#,
) )
.unwrap(); .unwrap();
stream.write_all(b"\n").unwrap(); stream.write_all(b"\n").unwrap();
@ -1851,7 +1850,7 @@ fn auth_status_reads_stored_cli_session_without_provider_tokens() {
"active" "active"
); );
assert_eq!( assert_eq!(
report["coordinator_account_status"]["private_moderation_details_exposed"], report["coordinator_account_status"]["sensitive_moderation_details_exposed"],
false false
); );
} }
@ -1933,7 +1932,7 @@ fn auth_status_reports_expired_or_revoked_cli_session_as_login_required() {
} }
#[test] #[test]
fn auth_status_queries_coordinator_account_state_without_private_moderation_details() { fn auth_status_queries_coordinator_account_state_without_sensitive_moderation_details() {
let listener = TcpListener::bind("127.0.0.1:0").unwrap(); let listener = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = listener.local_addr().unwrap().to_string(); let addr = listener.local_addr().unwrap().to_string();
let server = std::thread::spawn(move || { let server = std::thread::spawn(move || {
@ -1947,7 +1946,7 @@ fn auth_status_queries_coordinator_account_state_without_private_moderation_deta
assert!(line.contains(r#""actor_user":"user-live""#)); assert!(line.contains(r#""actor_user":"user-live""#));
stream stream
.write_all( .write_all(
br#"{"type":"auth_status","tenant":"tenant-live","project":"project-live","actor":"user-live","authenticated":true,"account_status":"suspended","suspended":true,"disabled":false,"sanitized_reason":"account or tenant is suspended by hosted policy","next_actions":["contact the hosted operator"],"private_moderation_details_exposed":false,"signup_failure_details_exposed":false,"abuse_score":99,"moderation_notes":"private moderation note"}"#, br#"{"type":"auth_status","tenant":"tenant-live","project":"project-live","actor":"user-live","authenticated":true,"account_status":"suspended","suspended":true,"disabled":false,"sanitized_reason":"account or tenant is suspended by hosted policy","next_actions":["contact the hosted operator"],"sensitive_moderation_details_exposed":false,"signup_failure_details_exposed":false,"abuse_score":99,"moderation_notes":"sensitive moderation note"}"#,
) )
.unwrap(); .unwrap();
stream.write_all(b"\n").unwrap(); stream.write_all(b"\n").unwrap();
@ -1987,7 +1986,7 @@ fn auth_status_queries_coordinator_account_state_without_private_moderation_deta
"account or tenant is suspended by hosted policy" "account or tenant is suspended by hosted policy"
); );
assert_eq!( assert_eq!(
report["coordinator_account_status"]["private_moderation_details_exposed"], report["coordinator_account_status"]["sensitive_moderation_details_exposed"],
false false
); );
assert_eq!( assert_eq!(
@ -2005,13 +2004,13 @@ fn auth_status_queries_coordinator_account_state_without_private_moderation_deta
let serialized = serde_json::to_string(&report).unwrap(); let serialized = serde_json::to_string(&report).unwrap();
assert!(!serialized.contains("abuse_score")); assert!(!serialized.contains("abuse_score"));
assert!(!serialized.contains("moderation_notes")); assert!(!serialized.contains("moderation_notes"));
assert!(!serialized.contains("private moderation note")); assert!(!serialized.contains("sensitive moderation note"));
let rendered = human_report(&report); let rendered = human_report(&report);
assert!(rendered.contains("account status: suspended")); assert!(rendered.contains("account status: suspended"));
assert!(rendered.contains("account suspended: true")); assert!(rendered.contains("account suspended: true"));
assert!(rendered.contains("private moderation details exposed: false")); assert!(rendered.contains("sensitive moderation details exposed: false"));
assert!(!rendered.contains("private moderation note")); assert!(!rendered.contains("sensitive moderation note"));
} }
#[test] #[test]
@ -2062,11 +2061,11 @@ fn auth_status_reports_disabled_deleted_and_manual_review_safely() {
"manual_review": manual_review, "manual_review": manual_review,
"sanitized_reason": reason, "sanitized_reason": reason,
"next_actions": ["contact the hosted operator"], "next_actions": ["contact the hosted operator"],
"private_moderation_details_exposed": false, "sensitive_moderation_details_exposed": false,
"signup_failure_details_exposed": false, "signup_failure_details_exposed": false,
"abuse_score": 99, "abuse_score": 99,
"moderation_notes": "private moderation note", "moderation_notes": "sensitive moderation note",
"signup_policy_trace": "private signup trace", "signup_policy_trace": "sensitive signup trace",
}) })
) )
.unwrap(); .unwrap();
@ -2105,7 +2104,7 @@ fn auth_status_reports_disabled_deleted_and_manual_review_safely() {
true true
); );
assert_eq!( assert_eq!(
report["coordinator_account_status"]["private_moderation_details_exposed"], report["coordinator_account_status"]["sensitive_moderation_details_exposed"],
false false
); );
assert_eq!( assert_eq!(
@ -2116,11 +2115,11 @@ fn auth_status_reports_disabled_deleted_and_manual_review_safely() {
assert!(!serialized.contains("abuse_score")); assert!(!serialized.contains("abuse_score"));
assert!(!serialized.contains("moderation_notes")); assert!(!serialized.contains("moderation_notes"));
assert!(!serialized.contains("signup_policy_trace")); assert!(!serialized.contains("signup_policy_trace"));
assert!(!serialized.contains("private moderation note")); assert!(!serialized.contains("sensitive moderation note"));
let rendered = human_report(&report); let rendered = human_report(&report);
assert!(rendered.contains(&format!("account status: {status}"))); assert!(rendered.contains(&format!("account status: {status}")));
assert!(rendered.contains(rendered_marker)); assert!(rendered.contains(rendered_marker));
assert!(!rendered.contains("private moderation note")); assert!(!rendered.contains("sensitive moderation note"));
} }
server.join().unwrap(); server.join().unwrap();
} }
@ -2235,11 +2234,11 @@ fn admin_bootstrap_reports_self_hosted_cli_only_path() {
assert_eq!(report["command"], "admin bootstrap"); assert_eq!(report["command"], "admin bootstrap");
assert_eq!(report["mode"], "self_hosted_local"); assert_eq!(report["mode"], "self_hosted_local");
assert_eq!(report["private_website_required"], false); assert_eq!(report["external_website_required"], false);
assert_eq!(report["self_hosted_cli_only"], true); assert_eq!(report["self_hosted_cli_only"], true);
assert_eq!(report["project_config_written"], true); assert_eq!(report["project_config_written"], true);
assert_eq!(report["project_init"]["command"], "project init"); assert_eq!(report["project_init"]["command"], "project init");
assert_eq!(report["project_init"]["private_website_required"], false); assert_eq!(report["project_init"]["external_website_required"], false);
assert_eq!( assert_eq!(
report["project_init"]["project_config"]["project"], report["project_init"]["project_config"]["project"],
"self-hosted" "self-hosted"
@ -2265,7 +2264,7 @@ fn admin_bootstrap_reports_self_hosted_cli_only_path() {
} }
assert!(steps.iter().all(|step| { assert!(steps.iter().all(|step| {
!step !step
.get("private_website_required") .get("external_website_required")
.and_then(Value::as_bool) .and_then(Value::as_bool)
.unwrap_or(false) .unwrap_or(false)
})); }));
@ -2893,13 +2892,13 @@ fn admin_status_and_suspend_use_public_coordinator_api() {
assert_eq!(status["command"], "admin status"); assert_eq!(status["command"], "admin status");
assert_eq!(status["safe_default"], "read_only"); assert_eq!(status["safe_default"], "read_only");
assert_eq!(status["private_website_required"], false); assert_eq!(status["external_website_required"], false);
assert_eq!(status["suspended"], false); assert_eq!(status["suspended"], false);
assert_eq!(suspended["command"], "admin suspend-tenant"); assert_eq!(suspended["command"], "admin suspend-tenant");
assert_eq!(suspended["tenant"], "tenant"); assert_eq!(suspended["tenant"], "tenant");
assert_eq!(suspended["actor_tenant"], "admin-tenant"); assert_eq!(suspended["actor_tenant"], "admin-tenant");
assert_eq!(suspended["suspended"], true); assert_eq!(suspended["suspended"], true);
assert_eq!(suspended["private_website_required"], false); assert_eq!(suspended["external_website_required"], false);
} }
#[test] #[test]
@ -2968,7 +2967,7 @@ fn debug_attach_reports_public_authorization() {
assert_eq!(report["charged_debug_read_bytes"], 1024); assert_eq!(report["charged_debug_read_bytes"], 1024);
assert_eq!(report["used_debug_read_bytes"], 1024); assert_eq!(report["used_debug_read_bytes"], 1024);
assert_eq!(report["debug_reads_quota_limited"], true); assert_eq!(report["debug_reads_quota_limited"], true);
assert_eq!(report["private_website_required"], false); assert_eq!(report["external_website_required"], false);
} }
#[test] #[test]
@ -3311,7 +3310,7 @@ fn project_init_uses_public_create_before_writing_local_config() {
created["safe_defaults"]["browser_interaction_required"], created["safe_defaults"]["browser_interaction_required"],
false false
); );
assert_eq!(created["private_website_required"], false); assert_eq!(created["external_website_required"], false);
assert_eq!( assert_eq!(
read_project_config(temp_success.path()) read_project_config(temp_success.path())
.unwrap() .unwrap()
@ -3411,7 +3410,7 @@ fn project_list_and_select_use_public_api_without_website() {
assert_eq!(list["source"], "public_coordinator_api"); assert_eq!(list["source"], "public_coordinator_api");
assert_eq!(list["project_count"], 1); assert_eq!(list["project_count"], 1);
assert_eq!(list["projects"][0]["id"], "project-a"); assert_eq!(list["projects"][0]["id"], "project-a");
assert_eq!(list["private_website_required"], false); assert_eq!(list["external_website_required"], false);
assert_eq!(list["coordinator_session_requests"], 1); assert_eq!(list["coordinator_session_requests"], 1);
let selected = project_select_report( let selected = project_select_report(
@ -3426,7 +3425,7 @@ fn project_list_and_select_use_public_api_without_website() {
assert_eq!(selected["source"], "public_coordinator_api"); assert_eq!(selected["source"], "public_coordinator_api");
assert_eq!(selected["selected_project"]["id"], "project-a"); assert_eq!(selected["selected_project"]["id"], "project-a");
assert_eq!(selected["project_config_written"], true); assert_eq!(selected["project_config_written"], true);
assert_eq!(selected["private_website_required"], false); assert_eq!(selected["external_website_required"], false);
assert_eq!( assert_eq!(
read_project_config(temp.path()).unwrap().unwrap().project, read_project_config(temp.path()).unwrap().unwrap().project,
"project-a" "project-a"
@ -4455,7 +4454,7 @@ fn build_command_reuses_bundle_inspection_without_full_repo_upload() {
let temp = tempfile::tempdir().unwrap(); let temp = tempfile::tempdir().unwrap();
let project = PathBuf::from(env!("CARGO_MANIFEST_DIR")) let project = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..") .join("../..")
.join("tests/fixtures/runtime-conformance"); .join("examples/hello-build");
let output = temp.path().join("bundle"); let output = temp.path().join("bundle");
let report = build_report( let report = build_report(
@ -4473,8 +4472,8 @@ fn build_command_reuses_bundle_inspection_without_full_repo_upload() {
assert_eq!(report["command"], "build"); assert_eq!(report["command"], "build");
assert_eq!(report["content_addressed"], true); assert_eq!(report["content_addressed"], true);
assert_eq!(report["contains_full_repository_upload"], false); assert_eq!(report["contains_full_repository_upload"], false);
assert_eq!(report["bundle_artifact"]["task_descriptor_count"], 12); assert_eq!(report["bundle_artifact"]["task_descriptor_count"], 2);
assert_eq!(report["bundle_artifact"]["entrypoint_count"], 6); assert_eq!(report["bundle_artifact"]["entrypoint_count"], 1);
assert!(output.join("module.wasm").is_file()); assert!(output.join("module.wasm").is_file());
assert!(output.join("manifest.json").is_file()); assert!(output.join("manifest.json").is_file());
assert!(output.join("task-descriptors.json").is_file()); assert!(output.join("task-descriptors.json").is_file());
@ -4485,9 +4484,9 @@ fn build_command_reuses_bundle_inspection_without_full_repo_upload() {
.unwrap() .unwrap()
.iter() .iter()
.any(|descriptor| { .any(|descriptor| {
descriptor["name"] == "task_add_one" descriptor["name"] == "compile"
&& descriptor["argument_schema"] == "input : i32" && descriptor["argument_schema"] == "source : SourceSnapshot"
&& descriptor["result_schema"] == "i32" && descriptor["result_schema"] == "Result < Artifact >"
&& descriptor["restart_compatibility_hash"] && descriptor["restart_compatibility_hash"]
.as_str() .as_str()
.unwrap() .unwrap()
@ -4648,7 +4647,7 @@ fn node_enroll_reports_short_lived_public_api_grant() {
assert_eq!(report["command"], "node enroll"); assert_eq!(report["command"], "node enroll");
assert_eq!(report["status"], "created"); assert_eq!(report["status"], "created");
assert_eq!(report["private_website_required"], false); assert_eq!(report["external_website_required"], false);
assert_eq!(report["tenant"], "tenant"); assert_eq!(report["tenant"], "tenant");
assert_eq!(report["project"], "project"); assert_eq!(report["project"], "project");
assert_eq!(report["user"], "user"); assert_eq!(report["user"], "user");
@ -4791,7 +4790,7 @@ fn node_enroll_and_process_commands_have_safe_plan_without_coordinator() {
) )
.unwrap(); .unwrap();
assert_eq!(enroll["status"], "requires_coordinator"); assert_eq!(enroll["status"], "requires_coordinator");
assert_eq!(enroll["private_website_required"], false); assert_eq!(enroll["external_website_required"], false);
assert_eq!(enroll["enrollment_grant"], serde_json::Value::Null); assert_eq!(enroll["enrollment_grant"], serde_json::Value::Null);
assert_eq!(enroll["requested_ttl_seconds"], 60); assert_eq!(enroll["requested_ttl_seconds"], 60);

View file

@ -1046,7 +1046,7 @@ mod tests {
} }
#[test] #[test]
fn account_policy_state_summarizes_private_admin_records_safely() { fn account_policy_state_summarizes_sensitive_admin_records_safely() {
let tenant = TenantId::from("tenant"); let tenant = TenantId::from("tenant");
let mut coordinator = Coordinator::boot(&InMemoryDurableStore::default(), 1); let mut coordinator = Coordinator::boot(&InMemoryDurableStore::default(), 1);

View file

@ -213,7 +213,7 @@ pub enum CoordinatorResponse {
manual_review: bool, manual_review: bool,
sanitized_reason: Option<String>, sanitized_reason: Option<String>,
next_actions: Vec<String>, next_actions: Vec<String>,
private_moderation_details_exposed: bool, sensitive_moderation_details_exposed: bool,
signup_failure_details_exposed: bool, signup_failure_details_exposed: bool,
}, },
AdminStatus { AdminStatus {

View file

@ -45,7 +45,7 @@ impl CoordinatorService {
manual_review: account_state.manual_review, manual_review: account_state.manual_review,
sanitized_reason: account_state.sanitized_reason, sanitized_reason: account_state.sanitized_reason,
next_actions: account_state.next_actions, next_actions: account_state.next_actions,
private_moderation_details_exposed: false, sensitive_moderation_details_exposed: false,
signup_failure_details_exposed: false, signup_failure_details_exposed: false,
}) })
} }
@ -609,7 +609,7 @@ impl CoordinatorService {
manual_review: account_state.manual_review, manual_review: account_state.manual_review,
sanitized_reason: account_state.sanitized_reason, sanitized_reason: account_state.sanitized_reason,
next_actions: account_state.next_actions, next_actions: account_state.next_actions,
private_moderation_details_exposed: false, sensitive_moderation_details_exposed: false,
signup_failure_details_exposed: false, signup_failure_details_exposed: false,
}) })
} }

View file

@ -1499,7 +1499,7 @@ fn service_reports_and_enforces_public_admin_tenant_suspension() {
suspended, suspended,
disabled, disabled,
sanitized_reason, sanitized_reason,
private_moderation_details_exposed, sensitive_moderation_details_exposed,
signup_failure_details_exposed, signup_failure_details_exposed,
.. ..
} = service } = service
@ -1520,7 +1520,7 @@ fn service_reports_and_enforces_public_admin_tenant_suspension() {
assert!(!suspended); assert!(!suspended);
assert!(!disabled); assert!(!disabled);
assert!(sanitized_reason.is_none()); assert!(sanitized_reason.is_none());
assert!(!private_moderation_details_exposed); assert!(!sensitive_moderation_details_exposed);
assert!(!signup_failure_details_exposed); assert!(!signup_failure_details_exposed);
for (tenant, policy_name, expected_status, expected_reason) in [ for (tenant, policy_name, expected_status, expected_reason) in [
@ -1556,7 +1556,7 @@ fn service_reports_and_enforces_public_admin_tenant_suspension() {
manual_review, manual_review,
sanitized_reason, sanitized_reason,
next_actions, next_actions,
private_moderation_details_exposed, sensitive_moderation_details_exposed,
signup_failure_details_exposed, signup_failure_details_exposed,
.. ..
} = service } = service
@ -1578,7 +1578,7 @@ fn service_reports_and_enforces_public_admin_tenant_suspension() {
assert!(next_actions assert!(next_actions
.iter() .iter()
.any(|action| action.contains("hosted operator"))); .any(|action| action.contains("hosted operator")));
assert!(!private_moderation_details_exposed); assert!(!sensitive_moderation_details_exposed);
assert!(!signup_failure_details_exposed); assert!(!signup_failure_details_exposed);
} }
@ -1717,7 +1717,7 @@ fn service_reports_and_enforces_public_admin_tenant_suspension() {
disabled, disabled,
sanitized_reason, sanitized_reason,
next_actions, next_actions,
private_moderation_details_exposed, sensitive_moderation_details_exposed,
signup_failure_details_exposed, signup_failure_details_exposed,
.. ..
} = service } = service
@ -1740,7 +1740,7 @@ fn service_reports_and_enforces_public_admin_tenant_suspension() {
assert!(next_actions assert!(next_actions
.iter() .iter()
.any(|action| action.contains("hosted operator"))); .any(|action| action.contains("hosted operator")));
assert!(!private_moderation_details_exposed); assert!(!sensitive_moderation_details_exposed);
assert!(!signup_failure_details_exposed); assert!(!signup_failure_details_exposed);
let create = service let create = service

View file

@ -704,11 +704,40 @@ fn terminal_record_without_snapshots_clears_active_threads() {
#[test] #[test]
fn source_locals_infer_clusterflux_api_values_from_runtime_state() { fn source_locals_infer_clusterflux_api_values_from_runtime_state() {
let mut state = AdapterState::default(); let project = std::env::temp_dir().join(format!(
let project = Path::new(env!("CARGO_MANIFEST_DIR")) "clusterflux-dap-source-locals-{}",
.join("../../tests/fixtures/runtime-conformance") std::process::id()
.canonicalize() ));
let src = project.join("src");
fs::create_dir_all(&src).unwrap();
fs::write(
src.join("lib.rs"),
r#"async fn run_build_workflow() {
let source = prepare_source_snapshot();
let linux = clusterflux::spawn::async_task_with_arg(source.clone(), compile_linux)
.name("compile linux")
.env(linux_env())
.start()
.await
.unwrap(); .unwrap();
let linux_thread = linux.virtual_thread_id();
let linux_artifact = linux.join().await.unwrap();
let package = clusterflux::spawn::async_task_with_arg(
vec![linux_artifact.clone()],
package_release,
)
.name("package artifacts")
.env(linux_env())
.start()
.await
.unwrap();
let package_artifact = package.join().await.unwrap();
}
"#,
)
.unwrap();
let mut state = AdapterState::default();
state.project = project.to_string_lossy().into_owned(); state.project = project.to_string_lossy().into_owned();
state.source_path = "src/lib.rs".to_owned(); state.source_path = "src/lib.rs".to_owned();
let source = fs::read_to_string(project.join(&state.source_path)).unwrap(); let source = fs::read_to_string(project.join(&state.source_path)).unwrap();
@ -744,6 +773,8 @@ fn source_locals_infer_clusterflux_api_values_from_runtime_state() {
variable["name"] == "unavailable-local-diagnostic" variable["name"] == "unavailable-local-diagnostic"
&& variable["type"] == "unavailable-local" && variable["type"] == "unavailable-local"
})); }));
let _ = fs::remove_dir_all(project);
} }
#[test] #[test]
@ -863,11 +894,20 @@ fn package_release(inputs: Vec<Artifact>) -> Artifact {
#[test] #[test]
fn wasm_frame_locals_expose_only_values_from_the_node_snapshot() { fn wasm_frame_locals_expose_only_values_from_the_node_snapshot() {
let project = std::env::temp_dir().join(format!(
"clusterflux-dap-wasm-locals-{}",
std::process::id()
));
let src = project.join("src");
fs::create_dir_all(&src).unwrap();
fs::write(
src.join("lib.rs"),
"pub extern \"C\" fn task_add_one(input: i32) -> i32 {\n input + 1\n}\n",
)
.unwrap();
let mut state = AdapterState::default(); let mut state = AdapterState::default();
state.project = Path::new(env!("CARGO_MANIFEST_DIR")) state.project = project.to_string_lossy().into_owned();
.join("../../tests/fixtures/runtime-conformance")
.to_string_lossy()
.into_owned();
state.source_path = "src/lib.rs".to_owned(); state.source_path = "src/lib.rs".to_owned();
let source = fs::read_to_string(Path::new(&state.project).join(&state.source_path)).unwrap(); let source = fs::read_to_string(Path::new(&state.project).join(&state.source_path)).unwrap();
state.threads.get_mut(&MAIN_THREAD).unwrap().line = source state.threads.get_mut(&MAIN_THREAD).unwrap().line = source
@ -895,6 +935,8 @@ fn wasm_frame_locals_expose_only_values_from_the_node_snapshot() {
assert!(!locals assert!(!locals
.iter() .iter()
.any(|variable| variable["name"] == "wasm-local-diagnostic")); .any(|variable| variable["name"] == "wasm-local-diagnostic"));
let _ = fs::remove_dir_all(project);
} }
#[test] #[test]

View file

@ -114,7 +114,7 @@ impl Default for AdapterState {
project, project,
source_path: "src/lib.rs".to_owned(), source_path: "src/lib.rs".to_owned(),
runtime_backend: RuntimeBackend::Simulated, runtime_backend: RuntimeBackend::Simulated,
coordinator_endpoint: "https://clusterflux.michelpaulissen.com".to_owned(), coordinator_endpoint: "https://clusterflux.lesstuff.com".to_owned(),
tenant: TenantId::from("tenant"), tenant: TenantId::from("tenant"),
project_id: ProjectId::from("project"), project_id: ProjectId::from("project"),
actor_user: UserId::from("dap"), actor_user: UserId::from("dap"),

View file

@ -634,13 +634,12 @@ mod tests {
#[test] #[test]
fn hosted_url_remains_an_https_control_endpoint() { fn hosted_url_remains_an_https_control_endpoint() {
assert_eq!( assert_eq!(
control_endpoint_identity("https://clusterflux.michelpaulissen.com").unwrap(), control_endpoint_identity("https://clusterflux.lesstuff.com").unwrap(),
"https://clusterflux.michelpaulissen.com/api/v1/control" "https://clusterflux.lesstuff.com/api/v1/control"
); );
assert_eq!( assert_eq!(
control_endpoint_identity("https://clusterflux.michelpaulissen.com/api/v1/control") control_endpoint_identity("https://clusterflux.lesstuff.com/api/v1/control").unwrap(),
.unwrap(), "https://clusterflux.lesstuff.com/api/v1/control"
"https://clusterflux.michelpaulissen.com/api/v1/control"
); );
assert_eq!( assert_eq!(
control_endpoint_identity("127.0.0.1:7999").unwrap(), control_endpoint_identity("127.0.0.1:7999").unwrap(),

View file

@ -1029,7 +1029,7 @@ mod tests {
} }
#[test] #[test]
fn public_node_crate_does_not_require_hosted_private_types() { fn public_node_crate_does_not_require_hosted_service_types() {
let _tenant = TenantId::from("tenant"); let _tenant = TenantId::from("tenant");
let _project = ProjectId::from("project"); let _project = ProjectId::from("project");
let _backend = LinuxRootlessPodmanBackend; let _backend = LinuxRootlessPodmanBackend;

View file

@ -1,60 +0,0 @@
# Release candidates
This is a contributor and release-engineering procedure, not an end-user setup
path. Publication is a three-stage transaction:
1. `candidate` builds immutable archives and a manifest with paths relative to
the manifest directory.
2. `live-test` downloads that exact candidate in a clean job, deploys it, and
records the full named production-shaped acceptance result plus deployment,
runtime configuration, and proxy configuration identities.
3. `final` downloads the candidate and evidence in another clean job, verifies
every binding, and publishes without rebuilding any binary.
Set `CLUSTERFLUX_RELEASE_STAGE=candidate` while creating the candidate and
`CLUSTERFLUX_RELEASE_STAGE=final` while finalizing it. The final stage requires
`CLUSTERFLUX_RELEASE_CANDIDATE_MANIFEST` and complete live evidence. There is no
incomplete-evidence publication override.
The `clusterflux-release` runner must provide `CLUSTERFLUX_DEPLOY_COMMAND` as a
protected secret. The command runs locally with
`CLUSTERFLUX_CANDIDATE_ARCHIVE`, `CLUSTERFLUX_CANDIDATE_COORDINATOR`, and their
SHA-256 identities exported. It must deploy that executable and restart the
configured service. `scripts/deploy-release-candidate.sh` then independently
compares the running `/proc/<MainPID>/exe` digest with the candidate and records
the service and proxy unit identities; a mismatch stops the release.
Clusterflux release binaries are built once. The public client/node archive and
the private-source hosted-service archive are both digest-bound to the same
candidate. The hosted archive is deployed, the strict production-shaped batch
uses the public archive against it, and finalization copies both archives
without rebuilding.
Create the candidate in a dedicated directory:
~~~bash
CLUSTERFLUX_PUBLIC_RELEASE_DIR=target/release-candidate \
CLUSTERFLUX_RELEASE_STAGE=candidate \
./scripts/prepare-public-release.js
~~~
Deploy `target/release-candidate/assets/clusterflux-public-binaries-*.tar.gz`.
Set `CLUSTERFLUX_PUBLIC_RELEASE_MANIFEST` to the candidate manifest while
running the strict batch. Set `CLUSTERFLUX_QUALITY_GATE_EVIDENCE_PATH` to the
JSON record from the private and public acceptance commands. The result records
the source commit, source-tree and
public-tree identities, candidate binary digests, deployment generation, and
configuration identity.
Finalize into a different directory after the strict result passes:
~~~bash
CLUSTERFLUX_PUBLIC_RELEASE_DIR=target/public-release \
CLUSTERFLUX_RELEASE_CANDIDATE_MANIFEST=target/release-candidate/public-release-manifest.json \
CLUSTERFLUX_FINAL_RESULT_PATH=target/acceptance/cli-happy-path-live.json \
./scripts/prepare-public-release.js
~~~
Finalization rejects a changed commit, source tree, public tree, candidate
archive, binary digest set, deployment binding, or strict result. It never runs
the release binary build when a candidate manifest is supplied.

View file

@ -52,7 +52,7 @@ same stored identity:
~~~bash ~~~bash
clusterflux-node \ clusterflux-node \
--coordinator https://clusterflux.michelpaulissen.com \ --coordinator https://clusterflux.lesstuff.com \
--tenant "$TENANT" \ --tenant "$TENANT" \
--project-id <hosted-project-id> \ --project-id <hosted-project-id> \
--node workstation \ --node workstation \

View file

@ -23,7 +23,7 @@ key pair.
~~~bash ~~~bash
clusterflux-node \ clusterflux-node \
--coordinator https://clusterflux.michelpaulissen.com \ --coordinator https://clusterflux.lesstuff.com \
--tenant "$TENANT" \ --tenant "$TENANT" \
--project-id <project-id> \ --project-id <project-id> \
--node workstation \ --node workstation \

View file

@ -1,27 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$repo"
if [[ ! -d private/hosted-policy ]]; then
exit 0
fi
scripts/check-old-name.sh
node scripts/check-docs.js
scripts/check-code-size.sh
cargo fmt --all --manifest-path private/hosted-policy/Cargo.toml --check
cargo clippy --manifest-path private/hosted-policy/Cargo.toml --all-targets -- -D warnings
cargo test --locked --manifest-path private/hosted-policy/Cargo.toml --all-targets
node private/hosted-policy/scripts/prepare-hosted-deployment.js
if command -v podman >/dev/null 2>&1; then
node private/hosted-policy/scripts/postgres-durable-smoke.js
elif command -v nix >/dev/null 2>&1; then
nix shell nixpkgs#podman --command node private/hosted-policy/scripts/postgres-durable-smoke.js
else
node private/hosted-policy/scripts/postgres-durable-smoke.js
fi
if [[ -n "${CLUSTERFLUX_PUBLIC_RELEASE_SERVICE_ADDR:-}" ]]; then
node private/hosted-policy/scripts/hosted-service-live-check.js
fi

View file

@ -1,54 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$repo"
scripts/check-old-name.sh
node scripts/check-docs.js
scripts/check-code-size.sh
scripts/release-source-scan.sh
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --all-targets
cargo build --workspace --all-targets
cargo build -p runtime-conformance --target wasm32-unknown-unknown
cargo build -p hello-build --target wasm32-unknown-unknown
cargo build -p recovery-build --target wasm32-unknown-unknown
node scripts/resource-metering-contract-smoke.js
node scripts/hostile-input-contract-smoke.js
node scripts/tenant-isolation-contract-smoke.js
node scripts/self-hosted-coordinator-smoke.js
node scripts/public-local-demo-matrix-smoke.js
node scripts/cli-output-mode-smoke.js
node scripts/cli-login-smoke.js
node scripts/cli-error-exit-smoke.js
node scripts/cli-browser-login-flow-smoke.js
node scripts/cli-install-smoke.js
node scripts/user-session-token-boundary-smoke.js
node scripts/sdk-spawn-runtime-smoke.js
node scripts/node-lifecycle-contract-smoke.js
node scripts/wasmtime-node-smoke.js
node scripts/wasmtime-assignment-smoke.js
if command -v podman >/dev/null 2>&1; then
node scripts/podman-backend-smoke.js
elif command -v nix >/dev/null 2>&1; then
nix shell nixpkgs#podman --command node scripts/podman-backend-smoke.js
else
node scripts/podman-backend-smoke.js
fi
node scripts/vscode-extension-smoke.js
node scripts/vscode-f5-smoke.js
node scripts/node-attach-smoke.js
node scripts/cli-local-run-smoke.js
node scripts/artifact-download-smoke.js
node scripts/artifact-export-smoke.js
node scripts/operator-panel-smoke.js
node scripts/source-preparation-smoke.js
node scripts/scheduler-placement-smoke.js
node scripts/windows-best-effort-smoke.js
node scripts/quic-smoke.js
node scripts/dap-smoke.js
node scripts/recovery-build-smoke.js
node scripts/flagship-demo-smoke.js
scripts/verify-public-split.sh

View file

@ -1,99 +0,0 @@
const crypto = require("crypto");
const { nodeIdentity, signedRequestPayloadDigest } = require("./node-signing");
function agentIdentity(seedPrefix, agent) {
const identity = nodeIdentity(seedPrefix, agent);
return {
...identity,
publicKeyFingerprint: `sha256:${crypto
.createHash("sha256")
.update(identity.publicKey)
.digest("hex")}`,
};
}
function agentWorkflowSignatureMessage({
tenant,
project,
agent,
requestKind,
process: processId,
task = "",
payloadDigest,
nonce,
issuedAtEpochSeconds,
}) {
const parts = [
"clusterflux-agent-workflow-signature:v2",
tenant,
project,
agent,
requestKind,
processId,
task,
payloadDigest,
nonce,
String(issuedAtEpochSeconds),
];
return Buffer.concat(
parts.flatMap((part) => [
Buffer.from(`${Buffer.byteLength(part)}:`),
Buffer.from(part),
Buffer.from("\n"),
])
);
}
function signedAgentWorkflowProof(identity, request, options = {}) {
const nonce =
options.nonce ??
`${request.type}-${process.pid}-${Date.now()}-${crypto
.randomBytes(8)
.toString("hex")}`;
const issuedAtEpochSeconds =
options.issuedAtEpochSeconds ?? Math.floor(Date.now() / 1000);
const processId =
request.type === "launch_task" ? request.task_spec?.process : request.process;
const task =
request.type === "launch_task" ? request.task_spec?.task_instance : request.task || "";
const signature = crypto.sign(
null,
agentWorkflowSignatureMessage({
tenant: request.tenant,
project: request.project,
agent: request.actor_agent,
requestKind: request.type,
process: processId,
task,
payloadDigest: signedRequestPayloadDigest(request),
nonce,
issuedAtEpochSeconds,
}),
identity.privateKeyObject
);
return {
nonce,
issued_at_epoch_seconds: issuedAtEpochSeconds,
signature: `ed25519:${signature.toString("base64")}`,
};
}
function signedAgentWorkflowRequest(identity, request, options = {}) {
const unsignedRequest = {
...request,
agent_public_key_fingerprint:
options.publicKeyFingerprint || identity.publicKeyFingerprint,
};
return {
...unsignedRequest,
agent_signature: signedAgentWorkflowProof(identity, unsignedRequest, options),
};
}
module.exports = {
agentIdentity,
agentWorkflowSignatureMessage,
signedAgentWorkflowProof,
signedAgentWorkflowRequest,
};

View file

@ -1,401 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { nodeIdentity, signedNodeRequest } = require("./node-signing");
const {
ensureRootlessPodman,
flagshipNodeCapabilities,
launchFlagship,
repo,
runFlagshipWorker,
send,
waitForJsonLine,
} = require("./real-flagship-harness");
const downloadNode = "node-download";
const downloadNodeIdentity = nodeIdentity("artifact-download-smoke", downloadNode);
const delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
async function downloadRetainedBytes(addr, link, artifact, expectedSize) {
const chunks = [];
let offset = 0;
for (let attempt = 0; attempt < 500; attempt += 1) {
const response = await send(addr, {
type: "open_artifact_download_stream",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
token_digest: link.link.scoped_token_digest,
chunk_bytes: 256 * 1024,
});
assert.strictEqual(response.type, "artifact_download_stream");
if (!response.content_bytes_available) {
assert.strictEqual(response.content_source, "retaining_node_reverse_stream_pending");
await delay(10);
continue;
}
assert.strictEqual(response.content_source, "retaining_node_reverse_stream");
assert.strictEqual(response.content_offset, offset);
const bytes = Buffer.from(response.content_base64, "base64");
assert.strictEqual(response.streamed_bytes, bytes.length);
chunks.push(bytes);
offset += bytes.length;
if (response.content_eof) {
const content = Buffer.concat(chunks);
assert.strictEqual(content.length, expectedSize);
return { content, response };
}
}
throw new Error("timed out waiting for retained artifact reverse stream");
}
function downloadNodeCapabilities() {
return flagshipNodeCapabilities();
}
(async () => {
ensureRootlessPodman();
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback",
],
{ cwd: repo }
);
let worker;
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
worker = await runFlagshipWorker(addr, downloadNode, downloadNodeIdentity);
const workerReady = await worker.ready;
assert.strictEqual(workerReady.node_status, "ready");
assert.strictEqual(workerReady.mode, "worker");
const { compileEvent, packageEvent, process: virtualProcess } = await launchFlagship(addr);
assert.strictEqual(compileEvent.status_code, 0);
assert.strictEqual(packageEvent.status_code, 0);
assert.deepStrictEqual(compileEvent.result, {
Artifact: {
id: compileEvent.artifact_path.slice("/vfs/artifacts/".length),
digest: compileEvent.artifact_digest,
size_bytes: compileEvent.artifact_size_bytes,
},
});
assert.deepStrictEqual(packageEvent.result, {
Artifact: {
id: packageEvent.artifact_path.slice("/vfs/artifacts/".length),
digest: packageEvent.artifact_digest,
size_bytes: packageEvent.artifact_size_bytes,
},
});
assert.ok(compileEvent.artifact_size_bytes > 0);
assert.strictEqual(packageEvent.artifact_size_bytes, compileEvent.artifact_size_bytes);
assert.match(compileEvent.artifact_digest, /^sha256:[0-9a-f]{64}$/);
assert.match(packageEvent.artifact_digest, /^sha256:[0-9a-f]{64}$/);
const artifactPath = packageEvent.artifact_path;
assert.match(
artifactPath,
/^\/vfs\/artifacts\/hello-clusterflux-[0-9a-f]{64}$/
);
const artifact = artifactPath.slice("/vfs/artifacts/".length);
const disconnectedReport = await send(addr, signedNodeRequest(downloadNode, downloadNodeIdentity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: downloadNode,
capabilities: downloadNodeCapabilities(),
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [artifact],
direct_connectivity: false,
online: true,
}));
assert.strictEqual(disconnectedReport.type, "node_capabilities_recorded");
const disconnectedLink = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
ttl_seconds: 60,
});
assert.strictEqual(disconnectedLink.type, "artifact_download_link");
const connectedReport = await send(addr, signedNodeRequest(downloadNode, downloadNodeIdentity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: downloadNode,
capabilities: downloadNodeCapabilities(),
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [artifact],
direct_connectivity: true,
online: true,
}));
assert.strictEqual(connectedReport.type, "node_capabilities_recorded");
const link = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
ttl_seconds: 60,
});
assert.strictEqual(link.type, "artifact_download_link");
assert.strictEqual(link.link.tenant, "tenant");
assert.strictEqual(link.link.project, "project");
assert.strictEqual(link.link.process, virtualProcess);
assert.deepStrictEqual(link.link.actor, { User: "user" });
assert.match(link.link.policy_context_digest, /^sha256:[0-9a-f]{64}$/);
assert.ok(link.link.expires_at_epoch_seconds > Math.floor(Date.now() / 1000));
assert.ok(link.link.expires_at_epoch_seconds <= Math.floor(Date.now() / 1000) + 60);
assert.ok(
link.link.url_path.endsWith(
`/artifacts/tenant/project/${virtualProcess}/${artifact}`
)
);
assert.deepStrictEqual(link.link.source, { RetainedNode: "node-download" });
const crossTenant = await send(addr, {
type: "create_artifact_download_link",
tenant: "other",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
ttl_seconds: 60,
});
assert.strictEqual(crossTenant.type, "error");
assert.match(crossTenant.message, /artifact does not exist/);
const crossProject = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "other-project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
ttl_seconds: 60,
});
assert.strictEqual(crossProject.type, "error");
assert.match(crossProject.message, /artifact does not exist/);
const crossTenantOpen = await send(addr, {
type: "open_artifact_download_stream",
tenant: "other",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
token_digest: link.link.scoped_token_digest,
chunk_bytes: 1,
});
assert.strictEqual(crossTenantOpen.type, "error");
assert.match(crossTenantOpen.message, /artifact does not exist/);
const crossProjectOpen = await send(addr, {
type: "open_artifact_download_stream",
tenant: "tenant",
project: "other-project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
token_digest: link.link.scoped_token_digest,
chunk_bytes: 1,
});
assert.strictEqual(crossProjectOpen.type, "error");
assert.match(crossProjectOpen.message, /artifact does not exist/);
const guessed = await send(addr, {
type: "open_artifact_download_stream",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
token_digest: "sha256:guessed",
chunk_bytes: 1,
});
assert.strictEqual(guessed.type, "error");
assert.match(guessed.message, /token is invalid/);
const crossActorOpen = await send(addr, {
type: "open_artifact_download_stream",
tenant: "tenant",
project: "project",
actor_user: "other-user",
artifact,
max_bytes: 1024 * 1024,
token_digest: link.link.scoped_token_digest,
chunk_bytes: 1,
});
assert.strictEqual(crossActorOpen.type, "error");
assert.match(crossActorOpen.message, /token is invalid/);
const downloaded = await downloadRetainedBytes(
addr,
link,
artifact,
packageEvent.artifact_size_bytes,
);
const downloadedDigest = `sha256:${crypto
.createHash("sha256")
.update(downloaded.content)
.digest("hex")}`;
assert.strictEqual(downloadedDigest, packageEvent.artifact_digest);
const inspect = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-release-"));
try {
const executable = path.join(inspect, "hello-clusterflux");
fs.writeFileSync(executable, downloaded.content);
fs.chmodSync(executable, 0o755);
assert.strictEqual(
cp.execFileSync(executable, { encoding: "utf8" }),
"hello from a real Clusterflux build\n"
);
} finally {
fs.rmSync(inspect, { recursive: true, force: true });
}
const cliDownloadDirectory = fs.mkdtempSync(
path.join(os.tmpdir(), "clusterflux-cli-download-")
);
try {
const cliDownloadPath = path.join(cliDownloadDirectory, "hello-clusterflux");
const cliDownload = JSON.parse(
cp.execFileSync(
"cargo",
[
"run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--",
"artifact", "download", artifact,
"--to", cliDownloadPath,
"--max-bytes", "1048576",
"--coordinator", `clusterflux+tcp://${addr.host}:${addr.port}`,
"--tenant", "tenant",
"--project-id", "project",
"--user", "user",
"--json",
],
{ cwd: repo, env: process.env, encoding: "utf8" }
)
);
assert.strictEqual(cliDownload.command, "artifact download");
assert.strictEqual(cliDownload.local_download.status, "local_bytes_written");
assert.strictEqual(
cliDownload.local_download.verified_digest,
packageEvent.artifact_digest
);
assert.strictEqual(
`sha256:${crypto
.createHash("sha256")
.update(fs.readFileSync(cliDownloadPath))
.digest("hex")}`,
packageEvent.artifact_digest
);
} finally {
fs.rmSync(cliDownloadDirectory, { recursive: true, force: true });
}
assert.strictEqual(downloaded.response.content_eof, true);
assert.strictEqual(
downloaded.response.charged_download_bytes,
packageEvent.artifact_size_bytes
);
assert.strictEqual(downloaded.response.link.artifact, artifact);
const crossActorRevoke = await send(addr, {
type: "revoke_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "other-user",
artifact,
token_digest: link.link.scoped_token_digest,
});
assert.strictEqual(crossActorRevoke.type, "error");
assert.match(crossActorRevoke.message, /token is invalid/);
const revoked = await send(addr, {
type: "revoke_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
token_digest: link.link.scoped_token_digest,
});
assert.strictEqual(revoked.type, "artifact_download_link_revoked");
assert.strictEqual(revoked.link.scoped_token_digest, link.link.scoped_token_digest);
const revokedOpen = await send(addr, {
type: "open_artifact_download_stream",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
token_digest: link.link.scoped_token_digest,
chunk_bytes: 1,
});
assert.strictEqual(revokedOpen.type, "error");
assert.match(revokedOpen.message, /revoked/);
const gcReport = await send(addr, signedNodeRequest(downloadNode, downloadNodeIdentity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: downloadNode,
capabilities: downloadNodeCapabilities(),
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: false,
online: true,
}));
assert.strictEqual(gcReport.type, "node_capabilities_recorded");
const collectedLink = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
max_bytes: 1024 * 1024,
ttl_seconds: 60,
});
assert.strictEqual(collectedLink.type, "error");
assert.match(collectedLink.message, /unavailable from current retention/);
} finally {
worker?.child.kill("SIGTERM");
coordinator.kill("SIGTERM");
}
console.log("Artifact download smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,275 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { nodeIdentity, signedNodeRequest } = require("./node-signing");
const {
ensureRootlessPodman,
flagshipNodeCapabilities,
launchFlagship,
repo,
runFlagshipWorker,
send,
waitForJsonLine,
waitForNodeStatus,
} = require("./real-flagship-harness");
const sourceNode = "node-export-source";
const sourceIdentity = nodeIdentity("artifact-export-smoke", sourceNode);
function nodeCapabilities() {
return flagshipNodeCapabilities();
}
function runJson(command, args, options = {}) {
return new Promise((resolve, reject) => {
const child = cp.spawn(command, args, { cwd: repo, ...options });
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString();
});
child.once("error", reject);
child.once("exit", (code) => {
if (code !== 0) {
reject(
new Error(
`${command} ${args.join(" ")} failed with code ${code}\n${stderr}\n${stdout}`
)
);
return;
}
try {
resolve(JSON.parse(stdout));
} catch (error) {
reject(new Error(`${command} did not return JSON\n${stdout}\n${error.message}`));
}
});
});
}
async function reportNode(
addr,
node,
identity,
{ directConnectivity = true, online = true, artifacts = [] } = {}
) {
const response = await send(addr, signedNodeRequest(node, identity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node,
capabilities: nodeCapabilities(),
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: artifacts,
direct_connectivity: directConnectivity,
online,
}));
assert.strictEqual(response.type, "node_capabilities_recorded");
assert.strictEqual(response.node, node);
}
(async () => {
ensureRootlessPodman();
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback",
],
{
cwd: repo,
env: { ...process.env, CLUSTERFLUX_NODE_STALE_AFTER_SECONDS: "1" },
}
);
let worker;
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
worker = await runFlagshipWorker(addr, sourceNode, sourceIdentity);
const workerReady = await worker.ready;
assert.strictEqual(workerReady.node_status, "ready");
assert.strictEqual(workerReady.mode, "worker");
const firstNodeTaskCompletion = waitForNodeStatus(worker.child, "completed");
const { compileEvent, process: virtualProcess } = await launchFlagship(addr);
const workerCompletion = await firstNodeTaskCompletion;
assert.strictEqual(workerCompletion.node_status, "completed");
assert.strictEqual(
workerCompletion.task_assignment_response.task_spec.task_definition,
"snapshot_current_project"
);
assert.strictEqual(
workerCompletion.virtual_thread,
workerCompletion.task_assignment_response.task_spec.task_instance
);
assert.strictEqual(compileEvent.status_code, 0);
assert.match(
compileEvent.artifact_path,
/^\/vfs\/artifacts\/hello-clusterflux-[0-9a-f]{64}$/
);
const artifact = compileEvent.artifact_path.slice("/vfs/artifacts/".length);
await reportNode(addr, sourceNode, sourceIdentity, {
artifacts: [artifact],
});
const receiverIdentity = nodeIdentity("artifact-export-smoke", "node-export-receiver");
const attachedReceiver = await send(addr, {
type: "attach_node",
tenant: "tenant",
project: "project",
node: "node-export-receiver",
public_key: receiverIdentity.publicKey,
});
assert.strictEqual(attachedReceiver.type, "node_attached");
await reportNode(addr, "node-export-receiver", receiverIdentity);
const exportPlan = await send(addr, {
type: "export_artifact_to_node",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
receiver_node: "node-export-receiver",
direct_connectivity: true,
failure_reason: "",
});
assert.strictEqual(exportPlan.type, "artifact_export_plan");
assert.strictEqual(exportPlan.source_node, "node-export-source");
assert.strictEqual(exportPlan.receiver_node, "node-export-receiver");
assert.strictEqual(exportPlan.plan.transport, "NativeQuic");
assert.strictEqual(exportPlan.plan.scope.tenant, "tenant");
assert.strictEqual(exportPlan.plan.scope.project, "project");
assert.strictEqual(exportPlan.plan.scope.process, virtualProcess);
assert.deepStrictEqual(exportPlan.plan.scope.object, { Artifact: artifact });
assert.strictEqual(exportPlan.plan.source.node, "node-export-source");
assert.strictEqual(exportPlan.plan.destination.node, "node-export-receiver");
assert.strictEqual(exportPlan.plan.coordinator_assisted_rendezvous, true);
assert.strictEqual(exportPlan.plan.coordinator_bulk_relay_allowed, false);
assert.match(exportPlan.plan.authorization_digest, /^sha256:[0-9a-f]{64}$/);
assert.strictEqual(exportPlan.artifact_size_bytes, compileEvent.artifact_size_bytes);
const temp = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-artifact-export-"));
const exportPath = path.join(temp, "hello-clusterflux");
cp.execFileSync(
"cargo",
["build", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux"],
{ cwd: repo, stdio: "inherit" }
);
const cliBinary = path.join(
path.resolve(repo, process.env.CARGO_TARGET_DIR || "target"),
"debug",
process.platform === "win32" ? "clusterflux.exe" : "clusterflux"
);
await reportNode(addr, sourceNode, sourceIdentity, {
artifacts: [artifact],
});
const cliExport = await runJson(cliBinary, [
"artifact",
"export",
"--coordinator",
`${addr.host}:${addr.port}`,
"--tenant",
"tenant",
"--project-id",
"project",
"--user",
"user",
"--json",
artifact,
"--receiver-node",
"node-export-receiver",
"--to",
exportPath,
]);
assert.strictEqual(cliExport.command, "artifact export");
assert.strictEqual(cliExport.export_plan.local_bytes_written_by_cli, true);
assert.strictEqual(cliExport.export_plan.local_export_status, "local_bytes_written");
assert.strictEqual(
cliExport.export_plan.bytes_written,
compileEvent.artifact_size_bytes
);
assert.strictEqual(cliExport.local_export.stream.content_material_returned_in_report, false);
assert.strictEqual(
cliExport.local_export.verified_digest,
compileEvent.artifact_digest
);
fs.chmodSync(exportPath, 0o755);
assert.strictEqual(
cp.execFileSync(exportPath, { encoding: "utf8" }),
"hello from a real Clusterflux build\n"
);
const crossTenant = await send(addr, {
type: "export_artifact_to_node",
tenant: "other",
project: "project",
actor_user: "user",
artifact,
receiver_node: "node-export-receiver",
direct_connectivity: true,
failure_reason: "",
});
assert.strictEqual(crossTenant.type, "error");
assert.match(crossTenant.message, /artifact does not exist/);
await reportNode(addr, sourceNode, sourceIdentity, { artifacts: [artifact] });
const failedDirect = await send(addr, {
type: "export_artifact_to_node",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
receiver_node: "node-export-receiver",
direct_connectivity: false,
failure_reason: "nat traversal failed",
});
assert.strictEqual(failedDirect.type, "error");
assert.match(failedDirect.message, /nat traversal failed/);
assert.match(failedDirect.message, /coordinator bulk relay is disabled/);
await reportNode(addr, "node-export-receiver", receiverIdentity, { online: false });
await new Promise((resolve) => setTimeout(resolve, 2100));
await reportNode(addr, sourceNode, sourceIdentity, { artifacts: [artifact] });
const offlineReceiver = await send(addr, {
type: "export_artifact_to_node",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact,
receiver_node: "node-export-receiver",
direct_connectivity: true,
failure_reason: "",
});
assert.strictEqual(offlineReceiver.type, "error");
assert.match(offlineReceiver.message, /offline/);
} finally {
worker?.child.kill("SIGTERM");
coordinator.kill("SIGTERM");
}
console.log("Artifact export smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,27 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$repo_root"
maximum_lines=3000
failed=0
source_roots=(crates)
if [[ -d private/hosted-policy/src ]]; then
source_roots+=(private/hosted-policy/src)
fi
while IFS= read -r -d '' file; do
case "$file" in
*/tests.rs|*/tests/*) continue ;;
esac
lines="$(wc -l < "$file")"
if ((lines > maximum_lines)); then
printf '%s has %s lines; production file limit is %s\n' "$file" "$lines" "$maximum_lines" >&2
failed=1
fi
done < <(find "${source_roots[@]}" -type f -name '*.rs' -print0)
if ((failed)); then
exit 1
fi
printf 'production source file size guard passed (%s lines maximum)\n' "$maximum_lines"

View file

@ -1,113 +0,0 @@
#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");
const root = path.resolve(__dirname, "..");
const publicDocs = [
"README.md",
"SECURITY.md",
"docs/getting-started.md",
"docs/architecture.md",
"docs/nodes.md",
"docs/environments.md",
"docs/artifacts.md",
"docs/debugging.md",
"docs/task-abi.md",
"docs/self-hosting.md",
"docs/security.md",
];
const contributorDocs = ["docs/contributing/releases.md"];
const privateDocs = [
"private/docs/hosted-deployment.md",
"private/docs/authentik.md",
"private/docs/community-policy.md",
"private/docs/bandwidth-and-cost-controls.md",
"private/docs/publishing.md",
];
const internalDocs = ["internal/finish_mvp_2.md"];
const filteredPublicTree =
process.env.CLUSTERFLUX_FILTERED_PUBLIC_TREE === "1" ||
fs.existsSync(path.join(root, "CLUSTERFLUX_PUBLIC_TREE.json"));
const failures = [];
const expectExactMarkdownSet = (directory, expected) => {
const actual = fs
.readdirSync(path.join(root, directory), { withFileTypes: true })
.filter((entry) => entry.isFile() && entry.name.endsWith(".md"))
.map((entry) => path.posix.join(directory, entry.name))
.sort();
const wanted = [...expected].sort();
if (JSON.stringify(actual) !== JSON.stringify(wanted)) {
failures.push(`${directory} markdown set is ${actual.join(", ")}; expected ${wanted.join(", ")}`);
}
};
const requiredDocs = filteredPublicTree
? [...publicDocs, ...contributorDocs]
: [...publicDocs, ...contributorDocs, ...privateDocs, ...internalDocs];
for (const file of requiredDocs) {
if (!fs.existsSync(path.join(root, file))) failures.push(`missing canonical document: ${file}`);
}
expectExactMarkdownSet("docs", publicDocs.filter((file) => file.startsWith("docs/")));
expectExactMarkdownSet("docs/contributing", contributorDocs);
if (filteredPublicTree) {
for (const directory of ["private", "internal"]) {
if (fs.existsSync(path.join(root, directory))) {
failures.push(`${directory}/ must not exist in the filtered public tree`);
}
}
}
const forbidden = [
[/\bmvp\b/i, "internal milestone term"],
[/acceptance criteria/i, "internal gate language"],
[/release verification/i, "internal release language"],
[/public\/private source split/i, "source split narrative"],
[/founder|business decisions/i, "business planning narrative"],
[/hacker news|\bHN\b/, "launch-channel narrative"],
[/\busers can\b/i, "indirect reader wording"],
[/node\s+scripts\//i, "developer script instruction"],
[/scripts\/[^\s)]*smoke/i, "smoke script instruction"],
[/internal\/[^\s)]*/i, "internal tooling reference"],
[/private\/[^\s)]*/i, "private source reference"],
];
const topLevelCommands = new Set([
"doctor", "login", "logout", "auth", "agent", "key", "project", "inspect",
"build", "bundle", "run", "node", "process", "task", "logs", "artifact",
"dap", "debug", "quota", "admin",
]);
for (const file of publicDocs) {
const absolute = path.join(root, file);
const content = fs.readFileSync(absolute, "utf8");
for (const [pattern, description] of forbidden) {
if (pattern.test(content)) failures.push(`${file}: contains ${description}`);
}
for (const match of content.matchAll(/\]\(([^)#]+)(?:#[^)]+)?\)/g)) {
const target = match[1];
if (/^(?:https?:|mailto:)/.test(target)) continue;
const resolved = path.resolve(path.dirname(absolute), target);
if (!fs.existsSync(resolved)) failures.push(`${file}: broken link ${target}`);
}
for (const line of content.split(/\r?\n/)) {
const command = line.trim().match(/^clusterflux\s+([a-z][a-z-]*)\b/);
if (command && !topLevelCommands.has(command[1])) {
failures.push(`${file}: unknown top-level CLI command ${command[1]}`);
}
}
}
const rootMarkdown = fs
.readdirSync(root, { withFileTypes: true })
.filter((entry) => entry.isFile() && entry.name.endsWith(".md"))
.map((entry) => entry.name)
.sort();
if (JSON.stringify(rootMarkdown) !== JSON.stringify(["README.md", "SECURITY.md"])) {
failures.push(`top-level markdown set is ${rootMarkdown.join(", ")}; expected README.md, SECURITY.md`);
}
if (failures.length) {
for (const failure of failures) console.error(failure);
process.exit(1);
}
console.log("documentation checks passed");

View file

@ -1,39 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$repo_root"
legacy_lower="$(printf '%s%s' 'disa' 'smer')"
legacy_title="$(printf '%s%s' 'Disa' 'smer')"
legacy_upper="$(printf '%s%s' 'DISA' 'SMER')"
pattern="${legacy_lower}|${legacy_title}|${legacy_upper}"
allowed_content='^\./scripts/migrate-clusterflux-state\.sh:'
matches="$(
rg -n --hidden \
--glob '!**/.git/**' \
--glob '!**/target/**' \
--glob '!**/node_modules/**' \
--glob '!**/vendor/**' \
--glob '!**/.direnv/**' \
--glob '!**/.cache/**' \
--glob '!**/dist/**' \
--glob '!**/out/**' \
"$pattern" . 2>/dev/null | rg -v "$allowed_content" || true
)"
paths="$(
find . \
\( -type d \( -name .git -o -name target -o -name node_modules -o -name vendor -o -name .direnv -o -name .cache -o -name dist -o -name out \) -prune \) -o \
-iname "*${legacy_lower}*" -print | sort || true
)"
if [[ -n "$matches" || -n "$paths" ]]; then
[[ -z "$matches" ]] || printf '%s\n' "$matches" >&2
[[ -z "$paths" ]] || printf '%s\n' "$paths" >&2
printf 'unexpected legacy product name remains\n' >&2
exit 1
fi
printf 'old-name guard passed\n'

View file

@ -1,222 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const net = require("net");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const tmp = path.join(repo, "target", "acceptance", "tmp", "cli-browser-login-flow");
const project = path.join(tmp, "project");
fs.rmSync(tmp, { recursive: true, force: true });
fs.mkdirSync(project, { recursive: true });
function writeOpener() {
const opener = path.join(tmp, "browser-opener.js");
const trace = path.join(tmp, "browser-opener.log");
fs.writeFileSync(
opener,
`#!/usr/bin/env node
const fs = require("fs");
const trace = ${JSON.stringify(trace)};
const loginUrl = new URL(process.argv[2]);
const state = loginUrl.searchParams.get("state");
const nonce = loginUrl.searchParams.get("nonce");
const challenge = loginUrl.searchParams.get("code_challenge");
if (loginUrl.protocol !== "https:" || !state || !nonce || !challenge) {
fs.appendFileSync(trace, "missing server-owned OIDC parameters\\n");
process.exit(1);
}
fs.appendFileSync(trace, "server-owned browser transaction\\n");
// Model a real browser/opener that remains alive after the CLI transaction.
// Its descriptors must not keep the invoking CLI process open.
setTimeout(() => process.exit(0), 5000);
`
);
fs.chmodSync(opener, 0o755);
return opener;
}
function startCoordinator() {
return new Promise((resolve, reject) => {
const requests = [];
const server = net.createServer((socket) => {
let buffered = "";
socket.on("data", (chunk) => {
buffered += chunk.toString("utf8");
while (buffered.includes("\n")) {
const newline = buffered.indexOf("\n");
const line = buffered.slice(0, newline);
buffered = buffered.slice(newline + 1);
const envelope = JSON.parse(line);
requests.push(envelope);
assert.strictEqual(envelope.type, "coordinator_request");
assert.strictEqual(envelope.protocol_version, 1);
assert.strictEqual(envelope.authentication.kind, "none");
const request = envelope.payload;
if (requests.length === 1) {
assert.strictEqual(envelope.request_id, "cli-1");
assert.strictEqual(envelope.operation, "begin_oidc_browser_login");
assert.deepStrictEqual(request, {
type: "begin_oidc_browser_login",
});
socket.write(
`${JSON.stringify({
type: "oidc_browser_login_started",
transaction_id: "login-transaction",
polling_secret: "opaque-polling-secret",
authorization_url:
"https://auth.michelpaulissen.com/application/o/authorize/?state=server-state&nonce=server-nonce&code_challenge=server-pkce&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fclusterflux.michelpaulissen.com%2Fauth%2Fcallback",
expires_at_epoch_seconds: 1800000000,
})}\n`
);
continue;
}
assert.strictEqual(envelope.request_id, "cli-2");
assert.strictEqual(envelope.operation, "poll_oidc_browser_login");
assert.deepStrictEqual(request, {
type: "poll_oidc_browser_login",
transaction_id: "login-transaction",
polling_secret: "opaque-polling-secret",
});
socket.end(
`${JSON.stringify({
type: "oidc_browser_session",
session: {
tenant: "tenant-smoke",
project: "project-smoke",
user: "user-smoke",
cli_session_credential_kind: "CliDeviceSession",
cli_session_secret: "scoped-cli-session-secret",
expires_at_epoch_seconds: 1800000000,
provider_tokens_sent_to_nodes: false,
},
})}\n`
);
server.close();
}
});
});
server.once("error", reject);
server.listen(0, "127.0.0.1", () => {
const address = server.address();
resolve({
url: `${address.address}:${address.port}`,
requests,
close: () =>
new Promise((closeResolve) => {
if (!server.listening) closeResolve();
else server.close(() => closeResolve());
}),
});
});
});
}
function runClusterflux(args, env) {
return new Promise((resolve, reject) => {
const child = cp.spawn(
"cargo",
[
"run",
"-q",
"--manifest-path",
path.join(repo, "Cargo.toml"),
"-p",
"clusterflux-cli",
"--bin",
"clusterflux",
"--",
...args,
],
{ cwd: project, env, stdio: ["ignore", "pipe", "pipe"] }
);
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => (stdout += chunk.toString("utf8")));
child.stderr.on("data", (chunk) => (stderr += chunk.toString("utf8")));
child.once("error", reject);
child.once("close", (code) => {
if (code === 0) resolve(stdout);
else reject(new Error(`clusterflux exited ${code}\n${stderr}\n${stdout}`));
});
});
}
(async () => {
const opener = writeOpener();
const coordinator = await startCoordinator();
try {
const loginStarted = Date.now();
const report = JSON.parse(
await runClusterflux(
[
"login",
"--browser",
"--json",
"--coordinator",
coordinator.url,
"--project-id",
"project-smoke",
],
{
...process.env,
CLUSTERFLUX_BROWSER_OPEN_COMMAND: opener,
CLUSTERFLUX_BROWSER_LOGIN_TIMEOUT_SECONDS: "5",
}
)
);
assert(
Date.now() - loginStarted < 3000,
"a long-lived browser opener must not keep CLI output pipes or login completion open"
);
assert.strictEqual(report.plan.coordinator, coordinator.url);
assert.strictEqual(report.boundary.cli_contacted_coordinator, true);
assert.strictEqual(report.boundary.scoped_cli_session_received, true);
assert.strictEqual(report.boundary.local_cli_session_file_written, true);
assert.strictEqual(report.boundary.provider_tokens_persisted_locally, false);
assert.strictEqual(report.boundary.provider_tokens_exposed_to_cli, false);
assert.strictEqual(report.boundary.provider_tokens_sent_to_nodes, false);
assert.strictEqual(report.boundary.coordinator_session_requests, 2);
assert.strictEqual(coordinator.requests.length, 2);
const sessionFile = path.join(project, ".clusterflux", "session.json");
const sessionText = fs.readFileSync(sessionFile, "utf8");
const session = JSON.parse(sessionText);
assert.strictEqual(session.kind, "human");
assert.strictEqual(session.coordinator, coordinator.url);
assert.strictEqual(session.tenant, "tenant-smoke");
assert.strictEqual(session.project, "project-smoke");
assert.strictEqual(session.user, "user-smoke");
assert.strictEqual(session.cli_session_credential_kind, "CliDeviceSession");
assert.strictEqual(session.token_expiry_posture, "expires_at");
assert.strictEqual(session.expires_at, "1800000000");
assert.strictEqual(session.provider_tokens_exposed_to_cli, false);
assert.strictEqual(session.provider_tokens_sent_to_nodes, false);
assert.doesNotMatch(
sessionText,
/access_token|refresh_token|id_token|provider-secret|authorization_code|Bearer/
);
const authStatus = JSON.parse(
await runClusterflux(["auth", "status", "--json"], process.env)
);
assert.strictEqual(authStatus.active_coordinator, coordinator.url);
assert.strictEqual(authStatus.principal, "user-smoke");
assert.strictEqual(authStatus.tenant, "tenant-smoke");
assert.strictEqual(authStatus.project, "project-smoke");
assert.strictEqual(authStatus.session.kind, "human");
assert.strictEqual(authStatus.session.source, "session_file");
assert.strictEqual(authStatus.session.provider_tokens_exposed_to_cli, false);
assert.strictEqual(authStatus.session.provider_tokens_exposed_to_nodes, false);
} finally {
await coordinator.close();
}
console.log("CLI browser login flow smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,365 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const http = require("http");
const os = require("os");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "tests/fixtures/runtime-conformance");
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-cli-error-"));
function runClusterflux(args) {
return new Promise((resolve) => {
const child = cp.spawn(
"cargo",
["run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--", ...args],
{
cwd: repo,
stdio: ["ignore", "pipe", "pipe"],
}
);
let stdout = "";
let stderr = "";
child.stdout.setEncoding("utf8");
child.stderr.setEncoding("utf8");
child.stdout.on("data", (chunk) => {
stdout += chunk;
});
child.stderr.on("data", (chunk) => {
stderr += chunk;
});
child.on("close", (code, signal) => {
resolve({ code, signal, stdout, stderr });
});
});
}
async function runWithOneCoordinatorResponse(buildArgs, response) {
let request = "";
const server = http.createServer((incoming, outgoing) => {
incoming.setEncoding("utf8");
incoming.on("data", (chunk) => {
request += chunk;
});
incoming.on("end", () => {
outgoing.writeHead(200, { "content-type": "application/json" });
outgoing.end(JSON.stringify(response));
server.close();
});
});
const address = await new Promise((resolve) => {
server.listen(0, "127.0.0.1", () => resolve(server.address()));
});
const coordinator = `http://${address.address}:${address.port}`;
const result = await runClusterflux(buildArgs(coordinator));
return { request, result };
}
async function main() {
const environmentProject = path.join(tempRoot, "missing-env-project");
fs.mkdirSync(path.join(environmentProject, "src"), { recursive: true });
fs.writeFileSync(
path.join(environmentProject, "Cargo.toml"),
"[package]\nname = \"missing-env-project\"\nversion = \"0.1.0\"\nedition = \"2021\"\n"
);
fs.writeFileSync(
path.join(environmentProject, "src", "main.rs"),
"fn main() { let _target = env!(\"linux\"); }\n"
);
const environmentFailure = await runClusterflux([
"build",
"--project",
environmentProject,
"--json",
]);
assert.strictEqual(environmentFailure.signal, null, environmentFailure.stderr);
assert.strictEqual(environmentFailure.code, 26, environmentFailure.stderr);
const environmentReport = JSON.parse(environmentFailure.stdout);
assert.strictEqual(environmentReport.status, "blocked_before_schedule");
assert.strictEqual(environmentReport.scheduled_work, false);
assert.strictEqual(environmentReport.machine_error.category, "environment");
assert.strictEqual(
environmentReport.machine_error.process_exit_code_applied,
true
);
assert(
environmentReport.machine_error.next_actions.includes("clusterflux inspect")
);
assert.strictEqual(environmentReport.diagnostics[0].code, "missing_environment");
const nonInteractive = await runClusterflux([
"run",
"build",
"--project",
project,
"--non-interactive",
"--json",
]);
assert.strictEqual(nonInteractive.signal, null, nonInteractive.stderr);
assert.strictEqual(nonInteractive.code, 20, nonInteractive.stderr);
assert.doesNotMatch(nonInteractive.stderr, /Opening Clusterflux browser login/);
const nonInteractiveReport = JSON.parse(nonInteractive.stdout);
assert.strictEqual(nonInteractiveReport.status, "authentication_required");
assert.strictEqual(nonInteractiveReport.non_interactive, true);
assert.strictEqual(nonInteractiveReport.browser_opened, false);
assert.strictEqual(nonInteractiveReport.machine_error.category, "authentication");
assert.strictEqual(nonInteractiveReport.machine_error.stable_exit_code, 20);
assert.strictEqual(
nonInteractiveReport.machine_error.process_exit_code_applied,
true
);
assert(
nonInteractiveReport.machine_error.next_actions.includes(
"pass --local to run against local services"
)
);
let request = "";
const server = http.createServer((incoming, outgoing) => {
incoming.setEncoding("utf8");
incoming.on("data", (chunk) => {
request += chunk;
});
incoming.on("end", () => {
outgoing.writeHead(200, { "content-type": "application/json" });
outgoing.end(
JSON.stringify({
type: "error",
message: "quota unavailable: resource limit exceeded for api_calls",
})
);
server.close();
});
});
const address = await new Promise((resolve) => {
server.listen(0, "127.0.0.1", () => resolve(server.address()));
});
const coordinator = `http://${address.address}:${address.port}`;
const result = await runClusterflux([
"run",
"build",
"--project",
project,
"--coordinator",
coordinator,
"--json",
]);
assert.strictEqual(result.signal, null, result.stderr);
assert.strictEqual(result.code, 22, result.stderr);
assert.match(request, /"type":"start_process"/);
const report = JSON.parse(result.stdout);
assert.strictEqual(report.status, "coordinator_rejected");
assert.strictEqual(report.run_start.machine_error.category, "quota");
assert.strictEqual(report.run_start.machine_error.resource_category, "api_calls");
assert.strictEqual(report.run_start.machine_error.community_tier_language, true);
assert.strictEqual(
report.run_start.machine_error.community_tier_label,
"community tier"
);
assert.doesNotMatch(result.stdout, new RegExp(["free", "tier"].join(" "), "i"));
assert.strictEqual(
report.run_start.machine_error.private_abuse_heuristics_exposed,
false
);
assert.strictEqual(report.run_start.machine_error.stable_exit_code, 22);
assert.strictEqual(
report.run_start.machine_error.process_exit_code_applied,
true
);
assert(
report.run_start.machine_error.next_actions.includes("clusterflux quota status")
);
const capabilityFailure = await runWithOneCoordinatorResponse(
(coordinator) => [
"run",
"build",
"--project",
project,
"--coordinator",
coordinator,
"--json",
],
{
type: "error",
message:
"scheduler placement failed: no capable node for placement: missing capability Command",
}
);
assert.strictEqual(capabilityFailure.result.signal, null, capabilityFailure.result.stderr);
assert.strictEqual(capabilityFailure.result.code, 24, capabilityFailure.result.stderr);
assert.match(capabilityFailure.request, /"type":"start_process"/);
const capabilityReport = JSON.parse(capabilityFailure.result.stdout);
assert.strictEqual(
capabilityReport.run_start.machine_error.category,
"capability"
);
assert.strictEqual(
capabilityReport.run_start.machine_error.process_exit_code_applied,
true
);
assert(
capabilityReport.run_start.machine_error.next_actions.includes(
"attach a node with the required capabilities"
)
);
const nodePolicyFailure = await runWithOneCoordinatorResponse(
(coordinator) => [
"run",
"build",
"--project",
project,
"--coordinator",
coordinator,
"--json",
],
{
type: "error",
message: "node policy denied native command execution",
}
);
assert.strictEqual(nodePolicyFailure.result.signal, null, nodePolicyFailure.result.stderr);
assert.strictEqual(nodePolicyFailure.result.code, 23, nodePolicyFailure.result.stderr);
assert.match(nodePolicyFailure.request, /"type":"start_process"/);
const nodePolicyReport = JSON.parse(nodePolicyFailure.result.stdout);
assert.strictEqual(
nodePolicyReport.run_start.machine_error.category,
"policy"
);
assert.strictEqual(
nodePolicyReport.run_start.machine_error.process_exit_code_applied,
true
);
assert(
nodePolicyReport.run_start.machine_error.next_actions.includes(
"check coordinator policy for this action"
)
);
const programFailure = await runWithOneCoordinatorResponse(
(coordinator) => [
"task",
"list",
"--coordinator",
coordinator,
"--json",
],
{
type: "task_events",
events: [
{
process: "vp-current",
task: "compile",
terminal_state: "failed",
environment: "linux",
node: "node-linux",
status_code: 1,
stderr_tail: "task exited with status 1",
},
],
}
);
assert.strictEqual(programFailure.result.signal, null, programFailure.result.stderr);
assert.strictEqual(programFailure.result.code, 0, programFailure.result.stderr);
assert.match(programFailure.request, /"type":"list_task_events"/);
const programReport = JSON.parse(programFailure.result.stdout);
assert.strictEqual(programReport.tasks[0].machine_error.category, "program");
assert.strictEqual(programReport.tasks[0].machine_error.stable_exit_code, 27);
assert(
programReport.tasks[0].machine_error.next_actions.includes("clusterflux logs")
);
const artifactDownload = await runWithOneCoordinatorResponse(
(coordinator) => [
"artifact",
"download",
"app.txt",
"--coordinator",
coordinator,
"--json",
],
{
type: "artifact_download_denied",
message: "artifact download unauthorized for project",
}
);
assert.strictEqual(artifactDownload.result.signal, null, artifactDownload.result.stderr);
assert.strictEqual(artifactDownload.result.code, 21, artifactDownload.result.stderr);
assert.match(artifactDownload.request, /"type":"create_artifact_download_link"/);
const artifactDownloadReport = JSON.parse(artifactDownload.result.stdout);
assert.strictEqual(
artifactDownloadReport.download_session.machine_error.category,
"authorization"
);
assert.strictEqual(
artifactDownloadReport.download_session.machine_error.process_exit_code_applied,
true
);
const artifactExport = await runWithOneCoordinatorResponse(
(coordinator) => [
"artifact",
"export",
"app.txt",
"--to",
path.join(project, "target", "blocked-artifact.txt"),
"--coordinator",
coordinator,
"--json",
],
{
type: "artifact_export_unavailable",
message: "direct connectivity unavailable for artifact export",
}
);
assert.strictEqual(artifactExport.result.signal, null, artifactExport.result.stderr);
assert.strictEqual(artifactExport.result.code, 25, artifactExport.result.stderr);
assert.match(artifactExport.request, /"type":"export_artifact_to_node"/);
const artifactExportReport = JSON.parse(artifactExport.result.stdout);
assert.strictEqual(
artifactExportReport.export_plan.machine_error.category,
"connectivity"
);
assert.strictEqual(
artifactExportReport.export_plan.machine_error.process_exit_code_applied,
true
);
const confirmation = await runClusterflux([
"process",
"cancel",
"--coordinator",
"127.0.0.1:9",
"--json",
]);
assert.strictEqual(confirmation.signal, null, confirmation.stderr);
assert.strictEqual(confirmation.code, 23, confirmation.stderr);
const confirmationReport = JSON.parse(confirmation.stdout);
assert.strictEqual(confirmationReport.status, "confirmation_required");
assert.strictEqual(confirmationReport.coordinator_request_sent, false);
assert.strictEqual(confirmationReport.machine_error.category, "policy");
assert.strictEqual(
confirmationReport.machine_error.process_exit_code_applied,
true
);
assert(
confirmationReport.next_actions.some((action) => action.includes("--yes"))
);
}
main()
.then(() => {
console.log("CLI error exit smoke passed");
})
.catch((error) => {
console.error(error);
process.exit(1);
});

File diff suppressed because it is too large Load diff

View file

@ -1,61 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const temp = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-cli-install-"));
const installRoot = path.join(temp, "install");
const targetDir =
process.env.CLUSTERFLUX_CLI_INSTALL_CARGO_TARGET_DIR ||
process.env.CARGO_TARGET_DIR ||
path.join(repo, "target");
const project = path.join(repo, "tests/fixtures/runtime-conformance");
const binName = process.platform === "win32" ? "clusterflux.exe" : "clusterflux";
const installedBin = path.join(installRoot, "bin", binName);
try {
cp.execFileSync(
"cargo",
[
"install",
"--path",
"crates/clusterflux-cli",
"--bin",
"clusterflux",
"--root",
installRoot,
"--debug"
],
{
cwd: repo,
env: {
...process.env,
CARGO_TARGET_DIR: targetDir
},
stdio: "inherit"
}
);
assert(fs.existsSync(installedBin), "installed clusterflux binary must exist");
const inspection = JSON.parse(
cp.execFileSync(
installedBin,
["bundle", "inspect", "--project", project, "--json"],
{ cwd: repo, encoding: "utf8" }
)
);
assert.strictEqual(inspection.project, project);
assert.strictEqual(inspection.metadata.embeds_full_container_images, false);
assert(inspection.metadata.environments.some((env) => env.name === "linux"));
assert(inspection.metadata.selected_inputs.some((input) => input.path === "src/lib.rs"));
} finally {
fs.rmSync(temp, { recursive: true, force: true });
}
console.log("CLI install smoke passed");

View file

@ -1,269 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const { configurePodmanTestEnvironment } = require("./podman-test-env");
const repo = path.resolve(__dirname, "..");
configurePodmanTestEnvironment(repo);
if (
!process.env.CLUSTERFLUX_PODMAN_NIX_SHELL &&
cp.spawnSync("podman", ["--version"], { stdio: "ignore" }).status !== 0 &&
cp.spawnSync("nix", ["--version"], { stdio: "ignore" }).status === 0
) {
cp.execFileSync(
"nix",
["shell", "nixpkgs#podman", "--command", "node", __filename],
{
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_PODMAN_NIX_SHELL: "1",
},
stdio: "inherit",
}
);
process.exit(0);
}
const project = path.join(repo, "tests/fixtures/runtime-conformance");
cp.execFileSync(
"cargo",
["build", "-q", "-p", "clusterflux-node", "--bin", "clusterflux-node"],
{ cwd: repo, stdio: "inherit" }
);
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function runCli(args, env = {}) {
return new Promise((resolve, reject) => {
const child = cp.spawn(
"cargo",
["run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--", ...args],
{
cwd: repo,
env: {
...process.env,
...env
}
}
);
const cliPid = child.pid;
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString();
});
child.on("exit", (code) => {
if (code !== 0) {
reject(new Error(`CLI run failed with code ${code}\n${stderr}`));
return;
}
try {
resolve({ pid: cliPid, report: JSON.parse(stdout) });
} catch (error) {
reject(new Error(`CLI output was not JSON: ${stdout}\n${error.stack || error.message}`));
}
});
});
}
(async () => {
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback"
],
{ cwd: repo }
);
assert(Number.isInteger(coordinator.pid));
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const { pid: cliPid, report } = await runCli([
"run",
"--coordinator",
`${addr.host}:${addr.port}`,
"--project",
project,
"--json",
]);
assert(Number.isInteger(cliPid));
assert.notStrictEqual(cliPid, coordinator.pid);
assert.strictEqual(report.plan.entry, "build");
assert.deepStrictEqual(report.plan.session, "Anonymous");
assert.strictEqual(report.boundary.cli_process_started_node_process, true);
assert.strictEqual(report.boundary.cli_process_started_coordinator_process, false);
assert(Number.isInteger(report.boundary.spawned_node_process_id));
assert.notStrictEqual(report.boundary.spawned_node_process_id, cliPid);
assert.notStrictEqual(report.boundary.spawned_node_process_id, coordinator.pid);
assert.strictEqual(report.boundary.node_session_requests, 0);
assert.strictEqual(report.node_report.node_status, "completed");
assert.strictEqual(report.node_report.execution_substrate, "wasm");
assert.strictEqual(report.node_report.task_spawn_host_import, true);
assert.strictEqual(
report.node_report.pre_node_process_status.processes.length,
1
);
assert.deepStrictEqual(
report.node_report.pre_node_process_status.processes[0].connected_nodes,
[]
);
assert.strictEqual(
report.node_report.pre_node_process_status.processes[0].main_state,
"running"
);
assert.strictEqual(
report.node_report.pre_node_process_status.processes[0].main_wait_state,
"waiting_for_node",
"the coordinator must expose that the capless main is parked on placement before a node exists"
);
assert.strictEqual(
report.node_report.pre_node_process_status.processes[0].main_task_instance,
report.node_report.run.task_instance
);
assert.strictEqual(report.node_report.run.status, "main_launched");
assert.strictEqual(report.node_report.join.type, "task_joined");
const process = report.node_report.run.process;
assert.strictEqual(process, "vp-current");
const events = await send(addr, {
type: "list_task_events",
tenant: "tenant",
project: "project",
actor_user: "user",
process
});
assert.strictEqual(events.type, "task_events");
assert(events.events.length >= 4);
assert(
events.events
.filter((event) => event.executor === "node")
.every((event) => event.node === "node-cli-local")
);
assert(
events.events.some(
(event) =>
event.executor === "coordinator_main" &&
event.node === "coordinator-main"
)
);
assert(events.events.every((event) => event.process === process));
assert.deepStrictEqual(
new Set(events.events.map((event) => event.task_definition)),
new Set([
report.node_report.run.task_definition,
"prepare_source",
"compile_linux",
"package_release",
])
);
assert.strictEqual(
new Set(events.events.map((event) => event.task)).size,
events.events.length,
"every live task event must retain its unique instance identity"
);
assert(
events.events.some(
(event) => event.task === report.node_report.run.task_instance
)
);
assert(events.events.some((event) => event.task.endsWith(":child:1")));
assert(events.events.some((event) => event.task.endsWith(":child:2")));
assert(events.events.some((event) => event.task.endsWith(":child:3")));
assert(events.events.some((event) => event.artifact_path));
} finally {
coordinator.kill("SIGTERM");
}
const { pid: autoCliPid, report: autoReport } = await runCli([
"run",
"--local",
"--project",
project,
"--json",
]);
assert(Number.isInteger(autoCliPid));
assert.strictEqual(autoReport.plan.entry, "build");
assert.deepStrictEqual(autoReport.plan.coordinator, "LocalOnly");
assert.deepStrictEqual(autoReport.plan.session, "Anonymous");
assert.strictEqual(autoReport.boundary.cli_process_started_node_process, true);
assert.strictEqual(autoReport.boundary.cli_process_started_coordinator_process, true);
assert.match(autoReport.boundary.coordinator_address, /^127\.0\.0\.1:\d+$/);
assert(Number.isInteger(autoReport.boundary.coordinator_process_id));
assert(Number.isInteger(autoReport.boundary.spawned_node_process_id));
assert.notStrictEqual(autoReport.boundary.coordinator_process_id, autoCliPid);
assert.notStrictEqual(autoReport.boundary.spawned_node_process_id, autoCliPid);
assert.notStrictEqual(
autoReport.boundary.spawned_node_process_id,
autoReport.boundary.coordinator_process_id
);
assert.strictEqual(autoReport.boundary.node_session_requests, 0);
assert.strictEqual(autoReport.node_report.node_status, "completed");
assert.strictEqual(autoReport.node_report.execution_substrate, "wasm");
assert.strictEqual(autoReport.node_report.task_spawn_host_import, true);
assert.strictEqual(autoReport.node_report.run.status, "main_launched");
assert.strictEqual(autoReport.node_report.join.type, "task_joined");
console.log("CLI local run smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,72 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const coordinator = "https://coord.example.test";
const defaultHostedCoordinatorEndpoint = "https://clusterflux.michelpaulissen.com";
function clusterflux(args) {
return JSON.parse(
cp.execFileSync(
"cargo",
["run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--", ...args],
{ cwd: repo, encoding: "utf8" }
)
);
}
function clusterfluxRaw(args, env = {}) {
return cp.spawnSync(
"cargo",
["run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--", ...args],
{
cwd: repo,
encoding: "utf8",
env: {
...process.env,
...env,
},
}
);
}
const browser = clusterflux(["login", "--plan", "--coordinator", coordinator, "--json"]);
assert.strictEqual(browser.coordinator, coordinator);
assert(browser.human_flow.Browser, "browser login should be available for human users");
assert.strictEqual(browser.human_flow.Browser.authorization_url, null);
assert.strictEqual(browser.human_flow.Browser.server_owns_state, true);
assert.strictEqual(browser.human_flow.Browser.server_owns_nonce, true);
assert.strictEqual(browser.human_flow.Browser.pkce_required, true);
assert.strictEqual(browser.human_flow.Browser.hosted_callback, true);
assert.strictEqual(browser.human_flow.Browser.cli_receives_provider_authorization_code, false);
assert.strictEqual(browser.human_flow.Browser.cli_submits_identity_claims, false);
const defaultBrowser = clusterflux(["login", "--plan", "--json"]);
assert.strictEqual(defaultBrowser.coordinator, defaultHostedCoordinatorEndpoint);
assert(defaultBrowser.human_flow.Browser);
const nonInteractiveBrowser = clusterfluxRaw(
["login", "--browser", "--non-interactive", "--coordinator", coordinator, "--json"],
{
CLUSTERFLUX_BROWSER_OPEN_COMMAND:
"node -e 'require(\"fs\").writeFileSync(\"/tmp/clusterflux-browser-should-not-open\", \"opened\")'",
}
);
assert.strictEqual(nonInteractiveBrowser.status, 20, nonInteractiveBrowser.stderr);
assert.doesNotMatch(nonInteractiveBrowser.stderr, /Opening Clusterflux browser login/);
const nonInteractiveReport = JSON.parse(nonInteractiveBrowser.stdout);
assert.strictEqual(nonInteractiveReport.status, "authentication_required");
assert.strictEqual(nonInteractiveReport.non_interactive, true);
assert.strictEqual(nonInteractiveReport.browser_opened, false);
assert.strictEqual(nonInteractiveReport.machine_error.category, "authentication");
assert.strictEqual(nonInteractiveReport.machine_error.stable_exit_code, 20);
assert(
nonInteractiveReport.machine_error.next_actions.includes(
"rerun without --non-interactive to open the browser"
)
);
console.log("CLI login smoke passed");

View file

@ -1,191 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "tests/fixtures/runtime-conformance");
const isolatedCwd = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-cli-output-"));
const isolatedHome = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-cli-home-"));
function clusterflux(args, env = {}, cwd = isolatedCwd) {
return cp.execFileSync(
"cargo",
[
"run",
"-q",
"--manifest-path",
path.join(repo, "Cargo.toml"),
"-p",
"clusterflux-cli",
"--bin",
"clusterflux",
"--",
...args,
],
{
cwd,
encoding: "utf8",
env: {
...process.env,
HOME: isolatedHome,
USERPROFILE: isolatedHome,
XDG_CONFIG_HOME: path.join(isolatedHome, ".config"),
XDG_DATA_HOME: path.join(isolatedHome, ".local", "share"),
XDG_STATE_HOME: path.join(isolatedHome, ".local", "state"),
...env,
},
}
);
}
function json(args, env, cwd) {
return JSON.parse(clusterflux(args, env, cwd));
}
function assertHuman(name, output, requiredPatterns) {
assert(
!output.trimStart().startsWith("{"),
`${name} default output should be human-readable text, not JSON`
);
for (const pattern of requiredPatterns) {
assert.match(output, pattern, `${name} human output missing ${pattern}`);
}
}
const helpHuman = clusterflux(["help"]);
assertHuman("help", helpHuman, [
/Primary workflow:/,
/clusterflux login --browser/,
/clusterflux project init/,
/clusterflux node attach; clusterflux-node --worker/,
/Clusterflux: Launch Virtual Process/,
/Hosted account creation happens in the browser login flow/,
/--json/,
]);
const loginHuman = clusterflux([
"login",
"--plan",
"--coordinator",
"https://coord.example.test",
]);
assertHuman("login", loginHuman, [
/Clusterflux login/,
/flow: browser/,
]);
const loginJson = json([
"login",
"--plan",
"--coordinator",
"https://coord.example.test",
"--json",
]);
assert.strictEqual(loginJson.coordinator, "https://coord.example.test");
assert(loginJson.human_flow.Browser);
assert.strictEqual(loginJson.human_flow.Browser.hosted_callback, true);
assert.strictEqual(loginJson.human_flow.Browser.cli_submits_identity_claims, false);
const doctorHuman = clusterflux(["doctor"]);
assertHuman("doctor", doctorHuman, [
/Clusterflux doctor/,
/coordinator reachability: not_configured/,
/dependencies:/,
/auth:/,
/node capabilities:/,
/node readiness: (ready_to_attach|local_dependencies_missing|limited_capabilities)/,
/node next:/,
]);
const doctorJson = json(["doctor", "--json"]);
assert.strictEqual(doctorJson.coordinator_reachability.checked, false);
assert.strictEqual(doctorJson.coordinator_reachability.status, "not_configured");
assert(
["ready_to_attach", "local_dependencies_missing", "limited_capabilities"].includes(
doctorJson.node_readiness_summary.status
)
);
assert.strictEqual(doctorJson.node_readiness_summary.explicit_attach_required, true);
assert.strictEqual(
doctorJson.node_readiness_summary.command_execution_capability,
true
);
assert(Array.isArray(doctorJson.node_readiness_summary.missing_local_dependencies));
assert(doctorJson.node_readiness_summary.next_actions.length >= 2);
const authJson = json(["auth", "status", "--json"], {
CLUSTERFLUX_TOKEN: "token",
CLUSTERFLUX_TOKEN_EXPIRES_AT: "2026-07-04T00:00:00Z",
}, isolatedCwd);
assert.strictEqual(authJson.session.kind, "human");
assert.strictEqual(authJson.session.token_expiry_posture, "expires_at");
assert.strictEqual(authJson.session.expires_at, "2026-07-04T00:00:00Z");
assert.strictEqual(authJson.coordinator_account_status.checked, false);
assert.strictEqual(authJson.coordinator_account_status.account_status, "unknown");
assert.strictEqual(
authJson.coordinator_account_status.private_moderation_details_exposed,
false
);
const inspectHuman = clusterflux(["bundle", "inspect", "--project", project]);
assertHuman("bundle inspect", inspectHuman, [
/Clusterflux bundle inspect/,
/bundle: sha256:/,
/environments:/,
]);
const inspectJson = json(["bundle", "inspect", "--project", project, "--json"]);
assert.strictEqual(inspectJson.project, project);
assert.match(inspectJson.metadata.identity, /^sha256:/);
assert.match(inspectJson.metadata.wasm_code, /^sha256:/);
assert.strictEqual(inspectJson.metadata.task_metadata.default_entrypoint, "build");
assert.deepStrictEqual(inspectJson.metadata.task_metadata.entrypoints, [
"build",
"fail",
"identity",
"long-join",
"park-wake",
"restart",
]);
assert.strictEqual(
inspectJson.metadata.source_metadata.transfer_policy.coordinator_receives_source_bytes_by_default,
false
);
assert.strictEqual(
inspectJson.metadata.source_metadata.transfer_policy.default_full_repo_tarball,
false
);
assert.strictEqual(inspectJson.metadata.debug_metadata.dap_virtual_process, true);
assert.strictEqual(
inspectJson.metadata.large_input_policy.selected_inputs_are_content_digests,
true
);
assert.strictEqual(inspectJson.metadata.large_input_policy.selected_input_bytes_included, false);
assert.strictEqual(inspectJson.metadata.large_input_policy.full_repository_bytes_included, false);
assert.strictEqual(
inspectJson.metadata.large_input_policy.silent_task_argument_serialization,
false
);
assert(inspectJson.metadata.large_input_policy.supported_handle_types.includes("SourceSnapshot"));
assert.strictEqual(
inspectJson.metadata.restart_compatibility.source_edits_can_restart_from_clean_task_boundary,
true
);
assert.strictEqual(
inspectJson.metadata.restart_compatibility.requires_clean_checkpoint_boundary,
true
);
assert.strictEqual(
inspectJson.metadata.restart_compatibility.compares_task_abi,
inspectJson.metadata.task_metadata.task_abi
);
assert.strictEqual(
inspectJson.metadata.restart_compatibility.incompatible_changes_require_whole_process_restart,
true
);
console.log("CLI output mode smoke passed");

View file

@ -1,43 +0,0 @@
let requestId = 0;
function coordinatorWireRequest(payload, prefix = "acceptance") {
if (payload && payload.type === "coordinator_request") return payload;
if (!payload || typeof payload.type !== "string" || !payload.type.trim()) {
throw new Error("coordinator payload must have a non-empty type");
}
requestId += 1;
return {
type: "coordinator_request",
protocol_version: 1,
request_id: `${prefix}-${process.pid}-${requestId}`,
operation: payload.type,
authentication: authenticationMetadata(payload),
payload,
};
}
function authenticationMetadata(payload) {
if (payload.type === "authenticated") {
return {
kind: "cli_session",
session: true,
request_operation: payload.request?.type || "unknown",
};
}
if (payload.type === "signed_node" || payload.node_signature) {
return { kind: "node_signature", node: payload.node || null };
}
if (payload.agent_signature) {
return {
kind: "agent_signature",
agent: payload.actor_agent || null,
fingerprint: payload.agent_public_key_fingerprint || null,
};
}
if (payload.admin_token) {
return { kind: "admin_credential" };
}
return { kind: "none" };
}
module.exports = { coordinatorWireRequest };

View file

@ -1,135 +0,0 @@
const cp = require("child_process");
class DapClient {
constructor({
cwd = process.cwd(),
env = process.env,
command = "cargo",
args = [
"run",
"-q",
"-p",
"clusterflux-dap",
"--bin",
"clusterflux-debug-dap",
],
} = {}) {
this.child = cp.spawn(
command,
args,
{ cwd, env }
);
this.seq = 1;
this.buffer = Buffer.alloc(0);
this.messages = [];
this.waiters = [];
this.stderr = "";
this.child.stdout.on("data", (chunk) => {
this.buffer = Buffer.concat([this.buffer, chunk]);
this.parse();
});
this.child.stderr.on("data", (chunk) => {
this.stderr += chunk.toString();
});
this.child.on("exit", () => this.flushWaiters());
}
send(command, args = {}) {
const seq = this.seq++;
const message = { seq, type: "request", command, arguments: args };
const payload = Buffer.from(JSON.stringify(message));
this.child.stdin.write(`Content-Length: ${payload.length}\r\n\r\n`);
this.child.stdin.write(payload);
return seq;
}
async response(seq, command) {
const message = await this.waitFor(
(item) =>
item.type === "response" &&
item.request_seq === seq &&
item.command === command
);
if (!message.success) {
throw new Error(
`DAP ${command} failed: ${message.message || JSON.stringify(message)}\nAdapter stderr:\n${this.stderr}`
);
}
return message;
}
async failure(seq, command) {
const message = await this.waitFor(
(item) =>
item.type === "response" &&
item.request_seq === seq &&
item.command === command
);
if (message.success) {
throw new Error(`DAP ${command} unexpectedly succeeded`);
}
return message;
}
waitFor(
predicate,
timeoutMs = Number(process.env.CLUSTERFLUX_DAP_TIMEOUT_MS || 120000)
) {
const existing = this.messages.find(predicate);
if (existing) return Promise.resolve(existing);
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
this.child.kill("SIGKILL");
const recent = this.messages
.slice(-10)
.map((message) => JSON.stringify(message))
.join("\n");
reject(
new Error(
`timed out waiting for DAP message\nRecent DAP messages:\n${recent}\nAdapter stderr:\n${this.stderr}`
)
);
}, timeoutMs);
this.waiters.push({ predicate, resolve, timer });
});
}
parse() {
while (true) {
const headerEnd = this.buffer.indexOf("\r\n\r\n");
if (headerEnd < 0) return;
const header = this.buffer.slice(0, headerEnd).toString();
const match = header.match(/Content-Length: (\d+)/i);
if (!match) throw new Error(`bad DAP header: ${header}`);
const length = Number(match[1]);
const start = headerEnd + 4;
const end = start + length;
if (this.buffer.length < end) return;
const payload = this.buffer.slice(start, end).toString();
this.buffer = this.buffer.slice(end);
this.messages.push(JSON.parse(payload));
this.flushWaiters();
}
}
flushWaiters() {
for (const waiter of [...this.waiters]) {
const message = this.messages.find(waiter.predicate);
if (!message) continue;
clearTimeout(waiter.timer);
this.waiters.splice(this.waiters.indexOf(waiter), 1);
waiter.resolve(message);
}
}
async close() {
if (this.child.exitCode !== null) return;
const seq = this.send("disconnect");
await this.response(seq, "disconnect");
this.child.stdin.end();
}
}
module.exports = { DapClient };

View file

@ -1,510 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const { DapClient } = require("./dap-client");
(async () => {
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "tests/fixtures/runtime-conformance");
const sourcePath = fs.realpathSync(path.join(project, "src/lib.rs"));
const sourceLines = fs.readFileSync(sourcePath, "utf8").split(/\r?\n/);
const buildMainLine =
sourceLines.findIndex((line) => line.includes("pub async fn build_main()")) + 1;
assert(buildMainLine > 0, "flagship source must contain build_main");
const hostileDapClient = new DapClient();
try {
const initialize = hostileDapClient.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true,
});
await hostileDapClient.response(initialize, "initialize");
for (const processId of [
"",
" ",
"bad\u0000process",
"bad process!",
"x".repeat(256),
]) {
const malformedLaunch = hostileDapClient.send("launch", {
entry: "build",
project,
runtimeBackend: "local-services",
processId,
});
const rejection = await hostileDapClient.failure(
malformedLaunch,
"launch"
);
assert.match(
rejection.message,
/invalid DAP processId: ProcessId is invalid/,
`unexpected malformed DAP identifier response: ${JSON.stringify(rejection)}`
);
}
const validLaunch = hostileDapClient.send("launch", {
entry: "build",
project,
runtimeBackend: "local-services",
processId: "vp-valid-after-malformed",
});
await hostileDapClient.response(validLaunch, "launch");
await hostileDapClient.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
await hostileDapClient.close();
} catch (error) {
if (hostileDapClient.child.exitCode === null) {
hostileDapClient.child.kill("SIGKILL");
}
throw error;
}
const asynchronousClient = new DapClient();
try {
const initialize = asynchronousClient.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true,
});
await asynchronousClient.response(initialize, "initialize");
const launch = asynchronousClient.send("launch", {
entry: "long-join",
project,
runtimeBackend: "local-services",
});
await asynchronousClient.response(launch, "launch");
await asynchronousClient.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
const configuredAt = Date.now();
const configurationDone = asynchronousClient.send("configurationDone");
await asynchronousClient.response(configurationDone, "configurationDone");
assert(
Date.now() - configuredAt < 2_000,
"configurationDone must not wait for bundle build or runtime completion"
);
const threadDeadline = Date.now() + 120_000;
let runningThreads = [];
while (Date.now() < threadDeadline) {
const threadsRequest = asynchronousClient.send("threads");
runningThreads = (
await asynchronousClient.response(threadsRequest, "threads")
).body.threads;
if (runningThreads.length > 0) break;
await new Promise((resolve) => setTimeout(resolve, 100));
}
assert(runningThreads.length > 0, "asynchronous launch never reported a live thread");
const pauseAt = Date.now();
const pause = asynchronousClient.send("pause", {
threadId: runningThreads[0].id,
});
await asynchronousClient.response(pause, "pause");
assert(Date.now() - pauseAt < 2_000, "pause response was blocked by runtime work");
const paused = await asynchronousClient.waitFor(
(message) =>
message.type === "event" &&
message.event === "stopped" &&
message.body.reason === "pause"
);
const continueAt = Date.now();
const continued = asynchronousClient.send("continue", {
threadId: paused.body.threadId,
});
await asynchronousClient.response(continued, "continue");
assert(
Date.now() - continueAt < 2_000,
"continue response was blocked by runtime observation"
);
const disconnectAt = Date.now();
await asynchronousClient.close();
assert(
Date.now() - disconnectAt < 2_000,
"disconnect response was blocked by runtime observation"
);
} catch (error) {
if (asynchronousClient.child.exitCode === null) {
asynchronousClient.child.kill("SIGKILL");
}
throw error;
}
const client = new DapClient();
try {
const initialize = client.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true,
});
await client.response(initialize, "initialize");
const launch = client.send("launch", {
entry: "build",
project,
runtimeBackend: "local-services",
});
await client.response(launch, "launch");
await client.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
const breakpoints = client.send("setBreakpoints", {
source: { path: sourcePath },
breakpoints: [{ line: buildMainLine }],
});
const breakpointResponse = await client.response(
breakpoints,
"setBreakpoints"
);
assert.strictEqual(breakpointResponse.body.breakpoints.length, 1);
assert.strictEqual(breakpointResponse.body.breakpoints[0].verified, false);
const configurationDone = client.send("configurationDone");
await client.response(configurationDone, "configurationDone");
const installedBreakpoint = await client.waitFor(
(message) =>
message.type === "event" &&
message.event === "breakpoint" &&
message.body?.breakpoint?.verified === true
);
assert.strictEqual(installedBreakpoint.body.breakpoint.line, buildMainLine);
const stopped = await client.waitFor(
(message) =>
message.type === "event" &&
message.event === "stopped" &&
message.body.reason === "breakpoint"
);
assert.strictEqual(stopped.body.allThreadsStopped, true);
assert.match(stopped.body.description, /confirmed by every active participant/i);
const threadsRequest = client.send("threads");
const threads = (await client.response(threadsRequest, "threads")).body
.threads;
const mainThread = threads.find((thread) =>
thread.name.includes("build coordinator main")
);
assert(mainThread, "the running Wasm entrypoint must be the DAP coordinator-main thread");
assert.strictEqual(stopped.body.threadId, mainThread.id);
const stackRequest = client.send("stackTrace", {
threadId: mainThread.id,
startFrame: 0,
levels: 1,
});
const stack = (await client.response(stackRequest, "stackTrace")).body
.stackFrames;
assert.strictEqual(stack.length, 1);
assert.strictEqual(stack[0].line, buildMainLine);
assert.strictEqual(stack[0].source.path, sourcePath);
assert.match(stack[0].name, /build_main::wasm/);
assert.doesNotMatch(stack[0].name, /podman|cmd\.exe|powershell|pid|native child/i);
const sourceRequest = client.send("source", { source: stack[0].source });
const source = (await client.response(sourceRequest, "source")).body;
assert.match(source.content, /build_main/);
assert.match(source.mimeType, /rust/);
const scopesRequest = client.send("scopes", { frameId: stack[0].id });
const scopes = (await client.response(scopesRequest, "scopes")).body.scopes;
const localsScope = scopes.find((scope) => scope.name === "Source Locals");
const wasmScope = scopes.find((scope) => scope.name === "Wasm Frame Locals");
const argsScope = scopes.find(
(scope) => scope.name === "Task Args and Handles"
);
const runtimeScope = scopes.find(
(scope) => scope.name === "Clusterflux Runtime"
);
assert(localsScope && wasmScope && argsScope && runtimeScope);
const localsRequest = client.send("variables", {
variablesReference: localsScope.variablesReference,
});
const locals = (await client.response(localsRequest, "variables")).body
.variables;
assert(
locals.some(
(variable) =>
variable.name === "unavailable-local-diagnostic" &&
String(variable.value).includes("cannot be inspected")
)
);
const wasmRequest = client.send("variables", {
variablesReference: wasmScope.variablesReference,
});
const wasmLocals = (await client.response(wasmRequest, "variables")).body
.variables;
assert.deepStrictEqual(
wasmLocals.map((variable) => variable.name),
["wasm-local-diagnostic"]
);
assert.match(wasmLocals[0].value, /did not report inspectable Wasm frame locals/);
const argsRequest = client.send("variables", {
variablesReference: argsScope.variablesReference,
});
const args = (await client.response(argsRequest, "variables")).body.variables;
assert.deepStrictEqual(
args.map((variable) => variable.name),
["runtime-boundary-diagnostic"]
);
assert.match(args[0].value, /reported no task arguments or handles/);
const runtimeRequest = client.send("variables", {
variablesReference: runtimeScope.variablesReference,
});
const runtime = (await client.response(runtimeRequest, "variables")).body
.variables;
const value = (name) => runtime.find((variable) => variable.name === name)?.value;
assert.strictEqual(value("runtime_backend"), "LocalServices");
assert.strictEqual(value("state"), "Frozen");
assert.strictEqual(value("debug_epoch"), 1);
assert.strictEqual(value("coordinator_task_events"), 0);
assert.match(
String(value("command_status")),
/frozen through local services at executing Wasm probe/
);
const step = client.send("next", { threadId: mainThread.id });
const stepFailure = await client.failure(step, "next");
assert.match(stepFailure.message, /source stepping is not yet available/i);
assert.match(stepFailure.message, /synthetic step/i);
const restart = client.send("restartFrame", { frameId: stack[0].id });
const restartFailure = await client.failure(restart, "restartFrame");
assert.match(restartFailure.message, /checkpoint boundary|still active/i);
const incompatibleRestart = client.send("restartFrame", {
frameId: stack[0].id,
sourceCompatibility: "incompatible",
});
const incompatibleFailure = await client.failure(
incompatibleRestart,
"restartFrame"
);
assert.match(incompatibleFailure.message, /incompatible source edit/i);
assert.match(incompatibleFailure.message, /whole virtual-process restart/i);
await client.close();
} catch (error) {
if (client.child.exitCode === null) client.child.kill("SIGKILL");
throw error;
}
const failMainLine =
sourceLines.findIndex((line) => line.includes("pub async fn fail_main()")) + 1;
assert(failMainLine > 0, "flagship source must contain fail_main");
const taskTrapLine =
sourceLines.findIndex((line) => line.includes("fn task_trap(")) + 1;
assert(taskTrapLine > 0, "flagship source must contain task_trap");
const restartClient = new DapClient();
try {
const initialize = restartClient.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true,
});
await restartClient.response(initialize, "initialize");
const launch = restartClient.send("launch", {
entry: "fail",
project,
runtimeBackend: "local-services",
});
await restartClient.response(launch, "launch");
await restartClient.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
const breakpoints = restartClient.send("setBreakpoints", {
source: { path: sourcePath },
breakpoints: [{ line: failMainLine }, { line: taskTrapLine }],
});
const breakpointResponse = await restartClient.response(
breakpoints,
"setBreakpoints"
);
assert.deepStrictEqual(
breakpointResponse.body.breakpoints.map((breakpoint) => breakpoint.verified),
[false, false]
);
const configurationDone = restartClient.send("configurationDone");
await restartClient.response(configurationDone, "configurationDone");
const installedLines = [];
while (installedLines.length < 2) {
const installed = await restartClient.waitFor(
(message) =>
message.type === "event" &&
message.event === "breakpoint" &&
message.body?.breakpoint?.verified === true &&
!installedLines.includes(message.body.breakpoint.line)
);
installedLines.push(installed.body.breakpoint.line);
}
assert.deepStrictEqual(installedLines.sort((a, b) => a - b), [
failMainLine,
taskTrapLine,
].sort((a, b) => a - b));
const initialStop = await restartClient.waitFor(
(message) =>
message.type === "event" &&
message.event === "stopped" &&
message.body.reason === "breakpoint"
);
assert.strictEqual(initialStop.body.allThreadsStopped, true);
const threadsRequest = restartClient.send("threads");
const threads = (
await restartClient.response(threadsRequest, "threads")
).body.threads;
const failThread = threads.find(
(thread) => thread.id === initialStop.body.threadId
);
assert(failThread, "failed entrypoint must remain a virtual task thread");
const stackRequest = restartClient.send("stackTrace", {
threadId: failThread.id,
startFrame: 0,
levels: 1,
});
const failedStack = (
await restartClient.response(stackRequest, "stackTrace")
).body.stackFrames;
assert.strictEqual(failedStack[0].line, failMainLine);
const continueRequest = restartClient.send("continue", {
threadId: failThread.id,
});
await restartClient.response(continueRequest, "continue");
const childStop = await restartClient.waitFor(
(message) =>
message.seq > initialStop.seq &&
message.type === "event" &&
message.event === "stopped" &&
message.body.reason === "breakpoint",
70000
);
assert.strictEqual(childStop.body.allThreadsStopped, true);
const childThreadsRequest = restartClient.send("threads");
const childThreads = (
await restartClient.response(childThreadsRequest, "threads")
).body.threads;
const childThread = childThreads.find(
(thread) => thread.id === childStop.body.threadId
);
assert(childThread, "executing child task must become a DAP virtual thread");
assert.notStrictEqual(childThread.id, failThread.id);
assert.match(childThread.name, /task trap/i);
const childStackRequest = restartClient.send("stackTrace", {
threadId: childThread.id,
startFrame: 0,
levels: 1,
});
const childStack = (
await restartClient.response(childStackRequest, "stackTrace")
).body.stackFrames;
assert.strictEqual(childStack[0].line, taskTrapLine);
assert.match(childStack[0].name, /task_trap::wasm/);
const childScopesRequest = restartClient.send("scopes", {
frameId: childStack[0].id,
});
const childScopes = (
await restartClient.response(childScopesRequest, "scopes")
).body.scopes;
const childArgsScope = childScopes.find(
(scope) => scope.name === "Task Args and Handles"
);
assert(childArgsScope, "child task argument scope must be present");
const childArgsRequest = restartClient.send("variables", {
variablesReference: childArgsScope.variablesReference,
});
const childArgs = (
await restartClient.response(childArgsRequest, "variables")
).body.variables;
assert(
childArgs.some(
(variable) =>
variable.name === "arg_0" &&
/SmallJson\(Number\(0\)\)/.test(String(variable.value))
),
"child task argument must come from the frozen node participant"
);
const parentScopesRequest = restartClient.send("scopes", {
frameId: failedStack[0].id,
});
const parentScopes = (
await restartClient.response(parentScopesRequest, "scopes")
).body.scopes;
const parentArgsScope = parentScopes.find(
(scope) => scope.name === "Task Args and Handles"
);
const parentArgsRequest = restartClient.send("variables", {
variablesReference: parentArgsScope.variablesReference,
});
const parentArgs = (
await restartClient.response(parentArgsRequest, "variables")
).body.variables;
assert(
parentArgs.some(
(variable) =>
/^task_handle_\d+$/.test(variable.name) &&
/definition=task_trap instance=ti:.*:child:\d+ state=active/.test(
variable.value
) &&
variable.type === "runtime-handle"
),
"parent task handle must come from its live Wasm host registry"
);
const continueChildRequest = restartClient.send("continue", {
threadId: childThread.id,
});
await restartClient.response(continueChildRequest, "continue");
await restartClient.waitFor(
(message) =>
message.seq > childStop.seq &&
message.type === "event" &&
message.event === "terminated"
);
const terminalThreadsRequest = restartClient.send("threads");
const terminalThreads = (
await restartClient.response(terminalThreadsRequest, "threads")
).body.threads;
assert.deepStrictEqual(
terminalThreads,
[],
"terminated processes must not retain stale virtual threads"
);
const restartRequest = restartClient.send("restartFrame", {
frameId: failedStack[0].id,
});
const restartFailure = await restartClient.failure(
restartRequest,
"restartFrame"
);
assert.match(
restartFailure.message,
/does not map to a virtual task/i,
"a frame from a terminated process must not restart a stale task"
);
await restartClient.close();
} catch (error) {
if (restartClient.child.exitCode === null) restartClient.child.kill("SIGKILL");
throw error;
}
console.log("DAP smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,83 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
manifest=${1:?usage: deploy-release-candidate.sh MANIFEST}
: "${CLUSTERFLUX_DEPLOY_COMMAND:?set the documented exact-candidate deployment command}"
: "${CLUSTERFLUX_STRICT_SSH_TARGET:?set the production SSH target}"
service_unit=${CLUSTERFLUX_STRICT_SERVICE_UNIT:-clusterflux-hosted.service}
proxy_unit=${CLUSTERFLUX_STRICT_PROXY_UNIT:-nginx.service}
evidence_path=${CLUSTERFLUX_DEPLOYMENT_EVIDENCE_PATH:-target/acceptance/deployment.json}
staging=$(mktemp -d)
trap 'rm -rf "$staging"' EXIT
IFS=$'\t' read -r archive expected_archive_sha < <(
node - "$manifest" <<'NODE'
const fs = require("fs");
const path = require("path");
const manifestPath = path.resolve(process.argv[2]);
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
const asset = (manifest.assets || []).find((entry) => entry.name.startsWith("clusterflux-hosted-"));
if (!asset) throw new Error("candidate manifest has no hosted archive");
const file = path.isAbsolute(asset.file)
? asset.file
: path.resolve(path.dirname(manifestPath), asset.file);
process.stdout.write(`${file}\t${asset.sha256}\n`);
NODE
)
actual_archive_sha=$(sha256sum "$archive" | awk '{print $1}')
test "$actual_archive_sha" = "${expected_archive_sha#sha256:}"
tar -xzf "$archive" -C "$staging"
candidate_coordinator=$(find "$staging" -type f -name clusterflux-hosted-service -perm -u+x -print -quit)
test -n "$candidate_coordinator"
candidate_sha=$(sha256sum "$candidate_coordinator" | awk '{print $1}')
export CLUSTERFLUX_CANDIDATE_ARCHIVE="$archive"
export CLUSTERFLUX_CANDIDATE_ARCHIVE_SHA256="sha256:$actual_archive_sha"
export CLUSTERFLUX_CANDIDATE_COORDINATOR="$candidate_coordinator"
export CLUSTERFLUX_CANDIDATE_COORDINATOR_SHA256="sha256:$candidate_sha"
bash -euo pipefail -c "$CLUSTERFLUX_DEPLOY_COMMAND"
main_pid=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" systemctl show --property=MainPID --value "$service_unit")
test "$main_pid" != 0
remote_executable=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" readlink -f "/proc/$main_pid/exe")
remote_sha=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" sha256sum "$remote_executable" | awk '{print $1}')
test "$remote_sha" = "$candidate_sha"
service_fragment=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" systemctl show --property=FragmentPath --value "$service_unit")
service_fragment_sha=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" sha256sum "$service_fragment" | awk '{print $1}')
service_configuration_sha=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" systemctl cat "$service_unit" | sha256sum | awk '{print $1}')
proxy_fragment=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" systemctl show --property=FragmentPath --value "$proxy_unit")
proxy_fragment_sha=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" sha256sum "$proxy_fragment" | awk '{print $1}')
proxy_exec_start=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" systemctl show --property=ExecStart --value "$proxy_unit")
proxy_executable=$(sed -n 's/.*path=\([^ ;]*\).*/\1/p' <<<"$proxy_exec_start")
proxy_configuration=$(sed -n 's/.* argv\[\]=.* -c \([^ ;]*\).*/\1/p' <<<"$proxy_exec_start")
test -n "$proxy_executable"
test -n "$proxy_configuration"
proxy_configuration_sha=$(ssh "$CLUSTERFLUX_STRICT_SSH_TARGET" "$proxy_executable" -T -c "$proxy_configuration" 2>/dev/null | sha256sum | awk '{print $1}')
mkdir -p "$(dirname "$evidence_path")"
EVIDENCE_PATH="$evidence_path" SERVICE_UNIT="$service_unit" \
SERVICE_FRAGMENT="$service_fragment" SERVICE_FRAGMENT_SHA="$service_fragment_sha" \
SERVICE_CONFIGURATION_SHA="$service_configuration_sha" \
REMOTE_EXECUTABLE="$remote_executable" REMOTE_SHA="$remote_sha" \
PROXY_UNIT="$proxy_unit" PROXY_FRAGMENT="$proxy_fragment" \
PROXY_FRAGMENT_SHA="$proxy_fragment_sha" PROXY_EXECUTABLE="$proxy_executable" \
PROXY_CONFIGURATION="$proxy_configuration" PROXY_CONFIGURATION_SHA="$proxy_configuration_sha" node <<'NODE'
const fs = require("fs");
fs.writeFileSync(process.env.EVIDENCE_PATH, JSON.stringify({
kind: "clusterflux-exact-candidate-deployment",
service_unit: process.env.SERVICE_UNIT,
service_unit_fragment: process.env.SERVICE_FRAGMENT,
service_unit_sha256: `sha256:${process.env.SERVICE_FRAGMENT_SHA}`,
service_configuration_sha256: `sha256:${process.env.SERVICE_CONFIGURATION_SHA}`,
hosted_service_executable: process.env.REMOTE_EXECUTABLE,
hosted_service_sha256: `sha256:${process.env.REMOTE_SHA}`,
proxy_unit: process.env.PROXY_UNIT,
proxy_unit_fragment: process.env.PROXY_FRAGMENT,
proxy_unit_sha256: `sha256:${process.env.PROXY_FRAGMENT_SHA}`,
proxy_executable: process.env.PROXY_EXECUTABLE,
proxy_configuration: process.env.PROXY_CONFIGURATION,
proxy_configuration_sha256: `sha256:${process.env.PROXY_CONFIGURATION_SHA}`,
}, null, 2) + "\n");
NODE

View file

@ -1,80 +0,0 @@
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const hello = path.join(repo, "examples/hello-build");
const recovery = path.join(repo, "examples/recovery-build");
const conformance = path.join(repo, "tests/fixtures/runtime-conformance");
const source = fs.readFileSync(path.join(hello, "src/lib.rs"), "utf8");
const nonblank = source.split(/\r?\n/).filter((line) => line.trim()).length;
assert(nonblank <= 80, "hello-build source must stay below 80 nonblank lines");
for (const forbidden of [
"#[cfg",
"unsafe",
"extern \"C\"",
"no_mangle",
"sha256:",
".task_id(",
"#[test]",
"unwrap()",
"expect(",
]) {
assert(!source.includes(forbidden), "hello-build leaked implementation detail: " + forbidden);
}
assert.strictEqual((source.match(/#\[clusterflux::task/g) || []).length, 1);
assert.strictEqual((source.match(/#\[clusterflux::main/g) || []).length, 1);
assert(source.includes("source::current_project().snapshot().await?"));
assert(source.includes("clusterflux::spawn!(compile(source))"));
assert(source.includes(".on(clusterflux::env!(\"linux\"))"));
assert(source.includes(".run()"));
assert(source.includes("fs::publish"));
assert(fs.existsSync(path.join(hello, "fixture/hello-clusterflux.c")));
assert(fs.existsSync(path.join(hello, "envs/linux/Containerfile")));
const recoverySource = fs.readFileSync(path.join(recovery, "src/lib.rs"), "utf8");
assert.strictEqual((recoverySource.match(/spawn!\(build_lane/g) || []).length, 2);
assert(recoverySource.includes("TaskFailurePolicy::AwaitOperator"));
assert(recoverySource.includes("\"exit 23\""));
for (const forbidden of ["#[cfg", "unsafe", "extern \"C\"", "no_mangle", ".task_id("]) {
assert(!recoverySource.includes(forbidden), "recovery-build leaked " + forbidden);
}
const fixtureSource = fs.readFileSync(path.join(conformance, "src/lib.rs"), "utf8");
assert(fixtureSource.includes("task_trap"));
assert(fixtureSource.includes("cooperative_cancellation_probe"));
assert(!fs.existsSync(path.join(repo, "examples", "launch-" + "build-demo")));
assert(!fs.existsSync(path.join(hello, "src/bin/sdk-product-runtime.rs")));
const args = [
"run",
"-q",
"-p",
"clusterflux-cli",
"--bin",
"clusterflux",
"--",
"build",
"--project",
hello,
"--json",
];
const report = JSON.parse(cp.execFileSync("cargo", args, {
cwd: repo,
env: process.env,
encoding: "utf8",
}));
assert(report.bundle_artifact);
assert(report.bundle.metadata.selected_inputs.some((input) => input.path === "src/lib.rs"));
assert(report.bundle.metadata.task_metadata.entrypoints.includes("build"));
const tasks = JSON.parse(
fs.readFileSync(
path.resolve(repo, report.bundle_artifact.directory, "task-descriptors.json"),
"utf8"
)
);
assert(tasks.some((task) => task.name === "compile"));
assert(tasks.some((task) => task.name === "snapshot_current_project"));
console.log("primary and recovery example smoke passed");

View file

@ -1,235 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const {
agentIdentity,
signedAgentWorkflowRequest,
} = require("./agent-signing");
const {
nodeIdentity,
signedNodeHeartbeat,
} = require("./node-signing");
const repo = path.resolve(__dirname, "..");
const signingInstrumentAgent = agentIdentity(
"hostile-input-contract-agent",
"agent-hostile-input-contract"
);
const explicitlyEmptyAgentNonce = signedAgentWorkflowRequest(
signingInstrumentAgent,
{
type: "start_process",
tenant: "tenant",
project: "project",
actor_agent: "agent-hostile-input-contract",
process: "process",
launch_attempt: "attempt",
restart: false,
},
{ nonce: "" }
);
assert.strictEqual(
explicitlyEmptyAgentNonce.agent_signature.nonce,
"",
"Agent signing instrument replaced an explicitly empty hostile nonce"
);
const signingInstrumentNode = nodeIdentity(
"hostile-input-contract-node",
"node-hostile-input-contract"
);
assert.strictEqual(
signedNodeHeartbeat(
"tenant",
"project",
"node-hostile-input-contract",
signingInstrumentNode,
{ nonce: "" }
).nonce,
"",
"Node signing instrument replaced an explicitly empty hostile nonce"
);
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 hostile-input evidence: ${name}`);
}
const coreSource = read("crates/clusterflux-core/src/source.rs");
const coreCapabilities = read("crates/clusterflux-core/src/capability.rs");
const coordinatorService = [
read("crates/clusterflux-coordinator/src/service.rs"),
read("crates/clusterflux-coordinator/src/service/routing.rs"),
read("crates/clusterflux-coordinator/src/service/signed_nodes.rs"),
read("crates/clusterflux-coordinator/src/service/logs.rs"),
read("crates/clusterflux-coordinator/src/service/tests.rs"),
].join("\n");
const artifactDownloadSmoke = read("scripts/artifact-download-smoke.js");
const operatorPanelSmoke = read("scripts/operator-panel-smoke.js");
const schedulerSmoke = read("scripts/scheduler-placement-smoke.js");
const sourcePreparationSmoke = read("scripts/source-preparation-smoke.js");
for (const [name, pattern] of [
["source manifests validate shape", /pub fn validate_public_mvp\(&self\)[\s\S]*self\.validate_shape\(\)\?/],
["source manifests reject invalid digests", /SourceManifestError::InvalidDigest/],
["source manifests reject invalid custom providers", /SourceManifestError::InvalidProviderId/],
["source manifests reject control characters", /DescriptionControlCharacter/],
["source manifests reject coordinator checkout access", /CoordinatorCheckoutAccess/],
["source manifests reject default source-byte upload", /CoordinatorReceivesSourceBytes/],
]) {
expect(coreSource, name, pattern);
}
for (const [name, pattern] of [
["capability reports validate public shape", /pub fn validate_public_report\(&self\)/],
["capability reports validate architecture labels", /InvalidArchitecture/],
["capability reports validate OS labels", /InvalidOsLabel/],
["capability reports validate source providers", /InvalidSourceProvider/],
["source provider ids reject path traversal", /valid_source_provider_id/],
]) {
expect(coreCapabilities, name, pattern);
}
for (const [name, pattern] of [
["coordinator task log tails are bounded", /MAX_TASK_LOG_TAIL_BYTES: usize = 256 \* 1024/],
["coordinator validates reported stdout tails", /ReportTaskLog[\s\S]*validate_task_log_tail\("stdout_tail", &stdout_tail\)\?/],
["coordinator validates completed task stdout tails", /TaskCompleted[\s\S]*validate_task_log_tail\("stdout_tail", &stdout_tail\)\?/],
["coordinator rejects oversized log tail in unit coverage", /"x"\.repeat\(MAX_TASK_LOG_TAIL_BYTES \+ 1\)/],
]) {
expect(coordinatorService, name, pattern);
}
for (const [name, pattern] of [
["service rejects malformed node capability report", /fn service_rejects_malformed_node_capability_report\(\)/],
["capability report rejection leaves descriptors empty", /assert!\(service\.node_descriptors\.is_empty\(\)\)/],
["node capability report rejects cross-scope writes", /fn service_rejects_node_capability_report_outside_enrollment_scope\(\)/],
["task completion rejects cross-scope writes", /task completion outside node scope|outside/],
]) {
expect(coordinatorService, name, pattern);
}
for (const [name, source, patterns] of [
[
"artifact download smoke",
artifactDownloadSmoke,
[
/const crossTenant = await send/,
/const crossProject = await send/,
/const guessed = await send/,
/const crossActorOpen = await send/,
/token is invalid/,
/artifact does not exist/,
],
],
[
"operator panel smoke",
operatorPanelSmoke,
[
/render_operator_panel/,
/submit_panel_event/,
/assert\(!JSON\.stringify\(panel\)\.includes\("<script"\)\)/,
/assert\(!JSON\.stringify\(panel\)\.toLowerCase\(\)\.includes\("oauth"\)\)/,
/rate limit/i,
/exceeds download limit/,
],
],
[
"scheduler smoke",
schedulerSmoke,
[/const crossTenantReport = await send/, /report_node_capabilities/, /tenant\\\/project scope/],
],
[
"source preparation smoke",
sourcePreparationSmoke,
[/const crossTenantCompletion = await send/, /complete_source_preparation/, /tenant\\\/project scope/i],
],
]) {
for (const pattern of patterns) {
expect(source, name, pattern);
}
}
const hostedServiceMain = maybeRead([
"private",
"hosted-policy",
"src",
"bin",
"clusterflux-hosted-service.rs",
]);
const hostedValidation = maybeRead([
"private",
"hosted-policy",
"src",
"bin",
"clusterflux-hosted-service",
"validation.rs",
]);
const hostedWire = maybeRead([
"private",
"hosted-policy",
"src",
"bin",
"clusterflux-hosted-service",
"wire.rs",
]);
const hostedProtocol = maybeRead([
"private",
"hosted-policy",
"src",
"bin",
"clusterflux-hosted-service",
"hosted_service_protocol.rs",
]);
const hostedService =
hostedServiceMain && hostedValidation && hostedWire && hostedProtocol
? [
hostedServiceMain,
hostedValidation,
hostedWire,
hostedProtocol,
maybeRead(["crates", "clusterflux-core", "src", "ids.rs"]),
].join("\n")
: null;
const hostedTests = [
maybeRead(["private", "hosted-policy", "src", "bin", "clusterflux-hosted-service", "tests.rs"]),
maybeRead(["private", "hosted-policy", "scripts", "hosted-deployment-smoke.js"]),
maybeRead(["private", "hosted-policy", "scripts", "hosted-client-compat-smoke.js"]),
].filter(Boolean).join("\n");
if (hostedService && hostedTests) {
for (const [name, pattern] of [
["hosted service turns malformed JSON into error responses", /decode_incoming_request[\s\S]*HostedServiceResponse::Error/],
["tenant ids are validated", /fn tenant_id\(value: String\)[\s\S]*TenantId::try_new\(value\)/],
["node ids are validated", /fn node_id\(value: String\)[\s\S]*NodeId::try_new\(value\)/],
["process ids are validated", /fn process_id\(value: String\)[\s\S]*ProcessId::try_new\(value\)/],
["identifiers reject empty, oversized, control, and invalid format values", /MAX_EXTERNAL_ID_BYTES[\s\S]*trim\(\)\.is_empty\(\)[\s\S]*char::is_control[\s\S]*is_ascii_alphanumeric\(\)/],
["OIDC text fields are bounded", /fn validate_text[\s\S]*value\.len\(\) > max_bytes[\s\S]*contains unsupported characters/],
["tokens are bounded", /fn validate_token[\s\S]*value\.len\(\) > max_bytes[\s\S]*contains unsupported characters/],
["control request bodies are bounded", /MAX_CONTROL_FRAME_BYTES[\s\S]*control request too large/],
["identity protocol rejects unknown authority fields", /deny_unknown_fields/],
]) {
expect(hostedService, name, pattern);
}
for (const [name, pattern] of [
["old client identity protocol is rejected", /hosted_login_protocol_rejects_client_identity_and_provider_configuration/],
["raw operator action is rejected", /rawOperatorDenied[\s\S]*hosted_operator_request envelope/],
["unsigned client identity is rejected", /const forged = await sendHostedControl[\s\S]*authenticated CLI session/],
["cross-tenant process inspection is rejected", /crossTenantTaskEventsDenied[\s\S]*scope\|denied\|unauthorized/],
]) {
expect(hostedTests, name, pattern);
}
}
console.log("Hostile input contract smoke passed");

View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
migrate_path() {
local source="$1"
local destination="$2"
if [[ ! -e "$source" ]]; then
return
fi
if [[ -e "$destination" ]]; then
printf 'refusing to overwrite existing destination: %s\n' "$destination" >&2
exit 1
fi
mv -- "$source" "$destination"
printf 'migrated %s -> %s\n' "$source" "$destination"
}
migrate_path "${HOME}/.disasmer" "${HOME}/.clusterflux"
migrate_path "${XDG_CONFIG_HOME:-${HOME}/.config}/disasmer" \
"${XDG_CONFIG_HOME:-${HOME}/.config}/clusterflux"
migrate_path "${PWD}/.disasmer" "${PWD}/.clusterflux"
migrate_path "${PWD}/disasmer.toml" "${PWD}/clusterflux.toml"

View file

@ -1,307 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const repo = path.resolve(__dirname, "..");
const identities = new Map();
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function nodeIdentity(node) {
const existing = identities.get(node);
if (existing) return existing;
const { privateKey: privateKeyObject, publicKey } =
crypto.generateKeyPairSync("ed25519");
const privateDer = privateKeyObject.export({ format: "der", type: "pkcs8" });
const publicDer = publicKey.export({
format: "der",
type: "spki",
});
const privateSeed = Buffer.from(privateDer).subarray(-32);
const identity = {
privateKey: `ed25519:${privateSeed.toString("base64")}`,
publicKey: `ed25519:${Buffer.from(publicDer).subarray(-32).toString("base64")}`,
privateKeyObject,
};
identities.set(node, identity);
return identity;
}
function nodeSignatureMessage(
node,
requestKind,
payloadDigest,
nonce,
issuedAtEpochSeconds
) {
const parts = [
"clusterflux-node-request-signature:v2",
node,
requestKind,
payloadDigest,
nonce,
String(issuedAtEpochSeconds),
];
return Buffer.concat(
parts.flatMap((part) => [
Buffer.from(`${Buffer.byteLength(part)}:`),
Buffer.from(part),
Buffer.from("\n"),
])
);
}
function signedNodeHeartbeat(tenant, project, node, identity) {
const nonce = `node-attach-heartbeat-${process.pid}-${Date.now()}`;
const issuedAt = Math.floor(Date.now() / 1000);
const payloadDigest = `sha256:${crypto
.createHash("sha256")
.update(JSON.stringify({ node, project, tenant, type: "node_heartbeat" }))
.digest("hex")}`;
const signature = crypto.sign(
null,
nodeSignatureMessage(node, "node_heartbeat", payloadDigest, nonce, issuedAt),
identity.privateKeyObject
);
return {
nonce,
issued_at_epoch_seconds: issuedAt,
signature: `ed25519:${signature.toString("base64")}`,
};
}
function runAttach(addr, grant) {
const identity = nodeIdentity("node-attach");
return new Promise((resolve, reject) => {
const child = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-cli",
"--bin",
"clusterflux",
"--",
"node",
"attach",
"--coordinator",
`${addr.host}:${addr.port}`,
"--tenant",
"tenant",
"--project-id",
"project",
"--node",
"node-attach",
"--public-key",
identity.publicKey,
"--enrollment-grant",
grant,
"--cap",
"quic-direct",
"--json",
],
{
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_NODE_PRIVATE_KEY: identity.privateKey,
},
}
);
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString();
});
child.on("exit", (code) => {
if (code !== 0) {
reject(new Error(`node attach failed with code ${code}\n${stderr}`));
return;
}
try {
resolve(JSON.parse(stdout));
} catch (error) {
reject(
new Error(`node attach output was not JSON: ${stdout}\n${error.stack || error.message}`)
);
}
});
});
}
(async () => {
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback",
],
{ cwd: repo }
);
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const grant = await send(addr, {
type: "create_node_enrollment_grant",
tenant: "tenant",
project: "project",
actor_user: "operator",
ttl_seconds: 900
});
assert.strictEqual(grant.type, "node_enrollment_grant_created");
assert.strictEqual(grant.tenant, "tenant");
assert.strictEqual(grant.project, "project");
assert.match(grant.grant, /^node_grant_[A-Za-z0-9_-]+$/);
assert.strictEqual(grant.scope, "node:attach");
assert(grant.expires_at_epoch_seconds > Math.floor(Date.now() / 1000));
assert(grant.expires_at_epoch_seconds <= Math.floor(Date.now() / 1000) + 900);
const report = await runAttach(addr, grant.grant);
assert.strictEqual(report.plan.node, "node-attach");
assert.strictEqual(report.plan.coordinator, `${addr.host}:${addr.port}`);
assert.strictEqual(report.plan.enrollment.grant, grant.grant);
assert.match(report.plan.enrollment.public_key_fingerprint, /^sha256:[0-9a-f]{64}$/);
assert.strictEqual(
report.plan.enrollment.exchanges_short_lived_grant_for_long_lived_node_identity,
true
);
assert.ok(report.plan.capabilities.arch.length > 0);
assert.ok(report.plan.capabilities.source_providers.includes("filesystem"));
assert.ok(report.plan.capabilities.capabilities.includes("QuicDirect"));
assert.strictEqual(report.plan.detection.auto_detected, true);
assert.strictEqual(report.plan.detection.arch, report.plan.capabilities.arch);
assert.deepStrictEqual(report.plan.detection.manual_capability_overrides, ["quic-direct"]);
assert(
report.plan.detection.recognized_capability_overrides.includes("QuicDirect")
);
assert.strictEqual(
report.plan.detection.os_arch_capabilities_require_manual_flags,
false
);
assert.strictEqual(report.plan.detection.command_backend, "native-command");
assert.strictEqual(report.plan.detection.command_backend_available, true);
assert(
report.plan.detection.source_provider_backends.some(
(provider) => provider.provider === "filesystem" && provider.detected
)
);
assert(
report.grant_disclosures.length > 0,
"node attach should disclose capability grants before reporting capabilities"
);
assert(
report.grant_disclosures.every(
(disclosure) => disclosure.coordinator_policy_limited === true
),
"node attach should mark all capability grants as coordinator-policy-limited"
);
assert(
report.grant_disclosures.some(
(disclosure) => disclosure.grant === "native_command_execution"
),
"node attach should disclose native command execution when detected"
);
assert(
report.grant_disclosures.some(
(disclosure) => disclosure.grant === "source_access"
),
"node attach should disclose source access when detected"
);
assert.strictEqual(report.boundary.cli_contacted_coordinator, true);
assert.strictEqual(report.boundary.used_enrollment_exchange, true);
assert.strictEqual(report.boundary.coordinator_session_requests, 3);
assert.strictEqual(report.coordinator_response.type, "node_enrollment_exchanged");
assert.strictEqual(report.coordinator_response.node, "node-attach");
assert.strictEqual(report.coordinator_response.credential.node, "node-attach");
assert.strictEqual(report.coordinator_response.credential.scope, "node:attach");
assert.strictEqual(report.coordinator_response.credential.credential_kind, "NodeCredential");
assert.match(
report.coordinator_response.credential.capability_policy_digest,
/^sha256:[0-9a-f]{64}$/
);
assert.strictEqual(report.heartbeat_response.type, "node_heartbeat");
assert.strictEqual(report.capability_response.type, "node_capabilities_recorded");
const heartbeat = await send(addr, {
type: "node_heartbeat",
tenant: "tenant",
project: "project",
node: "node-attach",
node_signature: signedNodeHeartbeat(
"tenant",
"project",
"node-attach",
nodeIdentity("node-attach")
),
});
assert.strictEqual(heartbeat.type, "node_heartbeat");
assert.strictEqual(heartbeat.node, "node-attach");
} finally {
coordinator.kill("SIGTERM");
}
console.log("Node attach smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,151 +0,0 @@
#!/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 expect(source, name, pattern) {
assert.match(source, pattern, `missing node lifecycle evidence: ${name}`);
}
const nodeMain = read("crates/clusterflux-node/src/daemon.rs");
const nodeIdentity = read("crates/clusterflux-node/src/node_identity.rs");
const cliNode = read("crates/clusterflux-cli/src/node.rs");
const nodeTaskReports = read("crates/clusterflux-node/src/task_reports.rs");
const nodeDebugAgent = read("crates/clusterflux-node/src/debug_agent.rs");
const nodeLib = read("crates/clusterflux-node/src/lib.rs");
const sharedWasmtimeRuntime = `${read("crates/clusterflux-wasm-runtime/src/lib.rs")}\n${read("crates/clusterflux-wasm-runtime/src/task_host_linker.rs")}`;
const nodeRuntimeSurface = `${nodeLib}\n${sharedWasmtimeRuntime}`;
const nodeLifecycleSurface = `${nodeMain}\n${nodeIdentity}\n${nodeTaskReports}\n${nodeDebugAgent}`;
const nodeAssignmentRunner = `${read("crates/clusterflux-node/src/assignment_runner.rs")}\n${read("crates/clusterflux-node/src/assignment_runner/control_watcher.rs")}\n${read("crates/clusterflux-node/src/assignment_runner/process_runner.rs")}\n${read("crates/clusterflux-node/src/assignment_runner/validation.rs")}`;
const coordinatorCore = read("crates/clusterflux-coordinator/src/lib.rs");
const coordinatorService = `${read("crates/clusterflux-coordinator/src/service.rs")}\n${read("crates/clusterflux-coordinator/src/service/routing.rs")}`;
const coordinatorServiceTests = read("crates/clusterflux-coordinator/src/service/tests.rs");
const coordinatorServiceSurface = `${coordinatorService}\n${coordinatorServiceTests}`;
const cliLocalRunSmoke = read("scripts/cli-local-run-smoke.js");
const liveSmoke = read("scripts/cli-happy-path-live-smoke.js");
const wasmtimeSmoke = read("scripts/wasmtime-node-smoke.js");
const debugCore = read("crates/clusterflux-core/src/debug.rs");
assert.strictEqual(
(nodeMain.match(/CoordinatorSession::connect/g) || []).length,
1,
"node runtime should open one coordinator session in the local process-boundary runtime"
);
for (const [name, pattern] of [
["enrollment exchange over session", /"type": "exchange_node_enrollment_grant"/],
["persisted node identity is reused locally", /"type": "node_identity_reused"/],
["heartbeat over session", /"type": "node_heartbeat"/],
["node-originated requests use signed envelope", /"type": "signed_node"/],
["capability report over session", /"type": "report_node_capabilities"/],
["task assignment polling over session", /"type": "poll_task_assignment"/],
["process start over session", /"type": "start_process"/],
["reconnect over session", /"type": "reconnect_node"/],
["debug command polling over session", /"type": "poll_debug_command"/],
["log event over session", /"type": "report_task_log"/],
["VFS metadata over session", /"type": "report_vfs_metadata"/],
["task control polling over session", /"type": "poll_task_control"/],
["completion over session", /"type": "task_completed"/],
["cancellation uses same session", /poll_task_cancellation\(session, args, &task, node_private_key\)/],
["request count is reported", /session\.requests\(\)/],
]) {
expect(nodeLifecycleSurface, name, pattern);
}
expect(cliNode, "user-authorized node attach over Client session", /"type": "attach_node"/);
assert.doesNotMatch(
nodeIdentity,
/"type": "attach_node"/,
"a persisted node must authenticate with its signed identity instead of replaying Client attach"
);
const runtimeAcceptanceSurface = `${cliLocalRunSmoke}\n${liveSmoke}\n${coordinatorServiceTests}\n${nodeLib}\n${nodeAssignmentRunner}`;
for (const [name, pattern] of [
["real CLI launches a coordinator main", /node_report\.run\.status, "main_launched"/],
["real CLI observes coordinator-main task spawning", /task_spawn_host_import, true/],
["real CLI keeps child task instances distinct", /every live task event must retain its unique instance identity/],
["signed active Wasm parent spawns and joins child", /fn signed_active_wasm_task_can_spawn_and_join_child_in_its_process_only\(\)/],
["controlled native process abort is exercised", /fn abort_requested[\s\S]*poll_task_control/],
["native lifecycle freeze and resume are exercised", /linux_task_lifecycle_supports_cancel_and_all_stop_freeze_resume/],
["strict live run requires a usable partial freeze", /partial_freeze\.partially_frozen/],
["strict live run requires hosted restart evidence", /serviceRestart\.executed === true/],
]) {
expect(runtimeAcceptanceSurface, name, pattern);
}
for (const [name, pattern] of [
["cooperative cancellation and abort are distinct", /cancel_requested: false,[\s\S]*abort_requested: true/],
["controlled runner polls abort while command runs", /fn abort_requested[\s\S]*poll_task_control/],
["controlled runner creates a process group", /process\.process_group\(0\)/],
["controlled runner freezes the native process group", /libc::kill\(process_group, libc::SIGSTOP\)/],
["controlled runner resumes the native process group", /libc::kill\(process_group, libc::SIGCONT\)/],
["controlled runner kills the process group", /libc::kill\(process_group, libc::SIGKILL\)/],
["Wasm code can poll cooperative cancellation", /task_control_v1/],
["matched Wasm probes remain at a quiescent boundary", /TaskHostOperation::DebugProbe[\s\S]*enter_quiescent_host_boundary[\s\S]*leave_quiescent_host_boundary/],
["debug snapshots use the live Wasm task handle registry", /debug_handle_snapshot[\s\S]*task_handle_\{handle_id\}[\s\S]*state=active/],
["native command status comes from the controlled runner", /set_command_status[\s\S]*frozen command pid[\s\S]*native command exited with status/],
]) {
expect(`${coordinatorServiceSurface}\n${nodeLifecycleSurface}\n${sharedWasmtimeRuntime}\n${nodeAssignmentRunner}`, name, pattern);
}
for (const [name, pattern] of [
["coordinator rejects stale process ownership", /fn node_reconnect_rejects_stale_process_epoch_after_restart\(\)/],
["reconnect preserves scoped enrolled node identity", /reconnect_node\([\s\S]*&TenantId::from\("tenant"\),[\s\S]*&ProjectId::from\("project"\),[\s\S]*&NodeId::from\("node"\),[\s\S]*None/],
["stale process epoch is rejected", /CoordinatorError::StaleProcessEpoch/],
]) {
expect(coordinatorCore, name, pattern);
}
for (const [name, pattern] of [
["coordinator delivers cancellation to connected node", /fn service_delivers_cancellation_to_connected_node_and_records_terminal_state\(\)/],
["node polls task control", /CoordinatorRequest::PollTaskControl/],
["cancelled terminal state is recorded", /TaskTerminalState::Cancelled/],
]) {
expect(coordinatorServiceSurface, name, pattern);
}
for (const [name, pattern] of [
["native lifecycle test exists", /fn linux_task_lifecycle_supports_cancel_and_all_stop_freeze_resume\(\)/],
["native freeze succeeds when supported", /lifecycle\.freeze_for_debug_epoch\(\)\.unwrap\(\)/],
["native resume succeeds", /lifecycle\.resume_after_debug_epoch\(\)/],
["native cancel reaches lifecycle", /lifecycle\.cancel\(\)/],
["unsupported freeze errors", /BackendError::DebugFreezeUnsupported/],
["wasmtime runtime exposes freeze resume probe", /pub fn freeze_resume_i32_export_probe/],
["wasmtime runtime captures Wasm frame locals", /debug_i32_export_snapshot[\s\S]*local_values/],
["wasmtime runtime creates Wasm debug participant", /kind: DebugParticipantKind::WasmTask/],
["wasmtime debug participant carries local values", /local_values: snapshot\.local_values\.clone\(\)/],
["wasmtime runtime resumes after freeze", /epoch\.continue_all\(\)/],
]) {
expect(nodeRuntimeSurface, name, pattern);
}
for (const [name, pattern] of [
["wasmtime smoke runs debug freeze resume mode", /--debug-freeze-resume/],
["wasmtime smoke verifies frozen state", /debugReport\.frozen_state, "Frozen"/],
["wasmtime smoke verifies resumed state", /debugReport\.resumed_state, "Running"/],
["wasmtime smoke verifies frame local values", /debugReport\.local_values[\s\S]*wasm_local_0/],
["wasmtime smoke proves node runtime reached wasm task", /node_runtime_reached_wasm_task/],
["wasmtime smoke proves node captured locals", /node_runtime_captured_wasm_locals/],
]) {
expect(wasmtimeSmoke, name, pattern);
}
for (const [name, pattern] of [
["debug model freezes wasm and command participants", /fn breakpoint_creates_all_stop_debug_epoch_for_wasm_and_command_tasks\(\)/],
["debug model rejects unsupported freeze", /fn debug_epoch_reports_failure_when_no_participant_can_freeze\(\)/],
["debug model resumes frozen participants", /fn continue_resumes_every_frozen_participant\(\)/],
["debug model includes captured locals", /local_values/],
["wasm participants are modeled", /DebugParticipantKind::WasmTask/],
["controlled native command participants are modeled", /DebugParticipantKind::ControlledNativeCommand/],
]) {
expect(debugCore, name, pattern);
}
console.log("Node lifecycle contract smoke passed");

View file

@ -1,181 +0,0 @@
const crypto = require("crypto");
const identities = new Map();
function nodeIdentity(identityPurpose, node) {
const identityKey = `${identityPurpose}:${node}`;
const existing = identities.get(identityKey);
if (existing) return existing;
const { privateKey: privateKeyObject, publicKey } =
crypto.generateKeyPairSync("ed25519");
const privateDer = privateKeyObject.export({ format: "der", type: "pkcs8" });
const publicDer = publicKey.export({
format: "der",
type: "spki",
});
const privateSeed = Buffer.from(privateDer).subarray(-32);
const identity = {
privateKey: `ed25519:${privateSeed.toString("base64")}`,
publicKey: `ed25519:${Buffer.from(publicDer).subarray(-32).toString("base64")}`,
privateKeyObject,
};
identities.set(identityKey, identity);
return identity;
}
function nodeIdentityFromPrivateKey(privateKey) {
if (typeof privateKey !== "string" || !privateKey.startsWith("ed25519:")) {
throw new Error("node private key must use ed25519:<base64> encoding");
}
const seed = Buffer.from(privateKey.slice("ed25519:".length), "base64");
if (seed.length !== 32) throw new Error("node private key must contain 32 bytes");
const privateKeyObject = crypto.createPrivateKey({
key: Buffer.concat([
Buffer.from("302e020100300506032b657004220420", "hex"),
seed,
]),
format: "der",
type: "pkcs8",
});
const publicKeyObject = crypto.createPublicKey(privateKeyObject);
const publicDer = publicKeyObject.export({ format: "der", type: "spki" });
return {
privateKey,
publicKey: `ed25519:${Buffer.from(publicDer).subarray(-32).toString("base64")}`,
privateKeyObject,
};
}
function canonicalSignedRequest(value, topLevel = true) {
if (Array.isArray(value)) {
return value.map((entry) => canonicalSignedRequest(entry, false));
}
if (value && typeof value === "object") {
return Object.fromEntries(
Object.entries(value)
.filter(
([key, entry]) =>
entry !== null &&
(!topLevel || !["agent_signature", "node_signature"].includes(key))
)
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
.map(([key, entry]) => [key, canonicalSignedRequest(entry, false)])
);
}
return value;
}
function withWireDefaults(request) {
const value = { ...request };
if (value.type === "report_node_capabilities") {
value.dependency_cache_digests ??= [];
} else if (value.type === "launch_task" || value.type === "launch_child_task") {
value.wait_for_node ??= false;
if (value.task_spec && typeof value.task_spec === "object") {
value.task_spec = { ...value.task_spec };
value.task_spec.failure_policy ??= "fail_fast";
}
} else if (value.type === "start_process") {
value.restart ??= false;
} else if (value.type === "report_debug_state") {
value.stack_frames ??= [];
value.local_values ??= [];
value.task_args ??= [];
value.handles ??= [];
value.recent_output ??= [];
} else if (value.type === "report_task_log") {
value.stdout_tail ??= "";
value.stderr_tail ??= "";
} else if (value.type === "task_completed") {
value.stdout_tail ??= "";
value.stderr_tail ??= "";
value.stdout_truncated ??= false;
value.stderr_truncated ??= false;
}
return value;
}
function signedRequestPayloadDigest(request) {
return `sha256:${crypto
.createHash("sha256")
.update(JSON.stringify(canonicalSignedRequest(withWireDefaults(request))))
.digest("hex")}`;
}
function nodeSignatureMessage(
node,
requestKind,
payloadDigest,
nonce,
issuedAtEpochSeconds
) {
const parts = [
"clusterflux-node-request-signature:v2",
node,
requestKind,
payloadDigest,
nonce,
String(issuedAtEpochSeconds),
];
return Buffer.concat(
parts.flatMap((part) => [
Buffer.from(`${Buffer.byteLength(part)}:`),
Buffer.from(part),
Buffer.from("\n"),
])
);
}
function signedNodeProof(node, identity, requestKind, request, options = {}) {
const nonce =
options.nonce ??
`${requestKind}-${process.pid}-${Date.now()}-${crypto
.randomBytes(8)
.toString("hex")}`;
const issuedAt =
options.issuedAtEpochSeconds ?? Math.floor(Date.now() / 1000);
const signature = crypto.sign(
null,
nodeSignatureMessage(
node,
requestKind,
signedRequestPayloadDigest(request),
nonce,
issuedAt
),
identity.privateKeyObject
);
return {
nonce,
issued_at_epoch_seconds: issuedAt,
signature: `ed25519:${signature.toString("base64")}`,
};
}
function signedNodeHeartbeat(tenant, project, node, identity, options = {}) {
const request = { type: "node_heartbeat", tenant, project, node };
return signedNodeProof(node, identity, "node_heartbeat", request, options);
}
function signedNodeRequest(node, identity, requestKind, request, options = {}) {
return {
type: "signed_node",
node,
node_signature: signedNodeProof(
node,
identity,
requestKind,
request,
options
),
request,
};
}
module.exports = {
nodeIdentity,
nodeIdentityFromPrivateKey,
signedNodeProof,
signedRequestPayloadDigest,
signedNodeHeartbeat,
signedNodeRequest,
};

View file

@ -1,385 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const path = require("path");
const { nodeIdentity } = require("./node-signing");
const {
ensureRootlessPodman,
repo,
runFlagshipWorker,
send,
startFlagship,
waitForTaskEvent,
waitForJsonLine,
waitForNodeStatus,
} = require("./real-flagship-harness");
const panelNode = "panel-node";
const panelNodeIdentity = nodeIdentity("operator-panel-smoke", panelNode);
const panelProject = path.join(repo, "tests/fixtures/runtime-conformance");
function widget(panel, id) {
const item = panel.widgets[id];
assert(item, `missing panel widget ${id}`);
return item;
}
const delay = (milliseconds) =>
new Promise((resolve) => setTimeout(resolve, milliseconds));
async function waitForBreakpointHit(addr, process) {
for (let attempt = 0; attempt < 2400; attempt += 1) {
const status = await send(addr, {
type: "inspect_debug_breakpoints",
tenant: "tenant",
project: "project",
actor_user: "user",
process,
});
if (status.type !== "debug_breakpoints") {
const events = await send(addr, {
type: "list_task_events",
tenant: "tenant",
project: "project",
actor_user: "user",
process,
});
throw new Error(
`breakpoint state disappeared: ${JSON.stringify({ status, events })}`
);
}
if (status.hit_epoch != null) return status;
await delay(25);
}
throw new Error(`timed out waiting for package breakpoint in ${process}`);
}
async function waitForDebugEpochFrozen(addr, process, epoch) {
for (let attempt = 0; attempt < 2400; attempt += 1) {
const status = await send(addr, {
type: "inspect_debug_epoch",
tenant: "tenant",
project: "project",
actor_user: "user",
process,
epoch,
});
assert.strictEqual(status.type, "debug_epoch_status", JSON.stringify(status));
if (status.failed) {
throw new Error(status.failure_messages.join("; "));
}
if (status.fully_frozen) return status;
await delay(25);
}
throw new Error(`timed out waiting for debug epoch ${epoch} to freeze`);
}
(async () => {
ensureRootlessPodman();
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback"
],
{ cwd: repo }
);
let coordinatorStderr = "";
let worker;
coordinator.stderr.on("data", (chunk) => {
coordinatorStderr += chunk.toString();
});
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const projectCreated = await send(addr, {
type: "create_project",
tenant: "tenant",
actor_user: "user",
project: "project",
name: "Operator panel smoke",
});
assert.strictEqual(projectCreated.type, "project_created");
worker = await runFlagshipWorker(
addr,
panelNode,
panelNodeIdentity,
panelProject
);
const workerReady = await worker.ready;
assert.strictEqual(workerReady.node_status, "ready");
const workerCompletion = waitForNodeStatus(worker.child, "completed");
const flagship = startFlagship(addr, panelProject);
const configuredBreakpoints = await send(addr, {
type: "set_debug_breakpoints",
tenant: "tenant",
project: "project",
actor_user: "user",
process: flagship.process,
probe_symbols: ["clusterflux.probe.package_release"],
});
assert.strictEqual(configuredBreakpoints.type, "debug_breakpoints");
await waitForTaskEvent(
addr,
flagship.process,
(event) => event.task_definition === "prepare_source",
"prepare_source after breakpoint configuration"
);
const breakpointHit = await waitForBreakpointHit(addr, flagship.process);
assert.strictEqual(
breakpointHit.hit_probe_symbol,
"clusterflux.probe.package_release"
);
const frozenEpoch = await waitForDebugEpochFrozen(
addr,
flagship.process,
breakpointHit.hit_epoch
);
assert(frozenEpoch.acknowledgements.length >= 2);
const compileEvent = await waitForTaskEvent(
addr,
flagship.process,
(event) => event.task_definition === "compile_linux",
"compile before the package breakpoint"
);
const report = await workerCompletion;
assert.strictEqual(report.node_status, "completed");
assert.strictEqual(report.coordinator_response.type, "task_recorded");
const process = flagship.process;
const rendered = await send(addr, {
type: "render_operator_panel",
tenant: "tenant",
project: "project",
process,
actor_user: "user",
max_download_bytes: 1024 * 1024,
stopped: false
});
assert.strictEqual(rendered.type, "operator_panel");
const panel = rendered.panel;
assert.strictEqual(panel.tenant, "tenant");
assert.strictEqual(panel.project, "project");
assert.strictEqual(panel.process, process);
assert.strictEqual(panel.program_ui_events_enabled, true);
assert.deepStrictEqual(widget(panel, "process-status").kind, {
Text: { value: "running" }
});
const taskProgress = widget(panel, "task-progress").kind.Progress;
assert(taskProgress.current >= 2);
assert.strictEqual(taskProgress.current, taskProgress.total);
const taskSummary = widget(panel, "task-summary").kind.Text.value;
assert.match(
taskSummary,
new RegExp(`compile_linux \\[${compileEvent.task}\\]:Some\\(0\\):panel-node`)
);
assert.match(widget(panel, "recent-logs").kind.Text.value, /stdout=\d+ stderr=\d+/);
const downloadWidget = widget(panel, "download-artifact").kind;
const artifact = downloadWidget.ArtifactDownload.artifact;
assert(
artifact === compileEvent.artifact_path.slice("/vfs/artifacts/".length),
"panel download must point at a real flagship artifact"
);
assert(!JSON.stringify(downloadWidget).includes("url_path"));
assert(!JSON.stringify(downloadWidget).includes("scoped_token_digest"));
assert.deepStrictEqual(widget(panel, "debug-process").kind, {
Button: { action: "debug-process" }
});
assert.deepStrictEqual(widget(panel, "cancel-process").kind, {
Button: { action: "cancel-process" }
});
assert.deepStrictEqual(widget(panel, "restart-selected-task").kind, {
Button: { action: "restart-task" }
});
assert(panel.control_plane_actions.includes("DebugProcess"));
assert(panel.control_plane_actions.includes("CancelProcess"));
const restartTarget = panel.control_plane_actions.find(
(action) => action.RestartTask
)?.RestartTask;
assert(
restartTarget && taskSummary.includes(`[${restartTarget}]`),
"panel restart must target the real flagship task instance"
);
assert(
panel.control_plane_actions.some(
(action) => action.DownloadArtifact === artifact
)
);
assert(!JSON.stringify(panel).includes("<script"));
assert(!JSON.stringify(panel).toLowerCase().includes("oauth"));
const panelLink = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact: downloadWidget.ArtifactDownload.artifact,
max_bytes: 1024 * 1024,
ttl_seconds: 60
});
assert.strictEqual(panelLink.type, "artifact_download_link");
assert.strictEqual(panelLink.link.artifact, downloadWidget.ArtifactDownload.artifact);
assert.match(panelLink.link.policy_context_digest, /^sha256:[0-9a-f]{64}$/);
assert.deepStrictEqual(panelLink.link.source, { RetainedNode: "panel-node" });
assert(panelLink.link.url_path.endsWith(`/artifacts/tenant/project/${process}/${artifact}`));
const apiTooLarge = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact: downloadWidget.ArtifactDownload.artifact,
max_bytes: 1,
ttl_seconds: 60
});
assert.strictEqual(apiTooLarge.type, "error");
assert.match(apiTooLarge.message, /exceeds download limit/);
const panelTooLarge = await send(addr, {
type: "render_operator_panel",
tenant: "tenant",
project: "project",
process,
actor_user: "user",
max_download_bytes: 1,
stopped: false
});
assert.strictEqual(panelTooLarge.type, "error");
assert.match(panelTooLarge.message, /exceeds download limit/);
const accepted = await send(addr, {
type: "submit_panel_event",
tenant: "tenant",
project: "project",
process,
widget_id: "debug-process",
kind: "ButtonClicked",
max_events: 1
});
assert.strictEqual(accepted.type, "panel_event_accepted");
assert.strictEqual(accepted.used_events, 1);
assert.strictEqual(accepted.max_events, 1);
const rateLimited = await send(addr, {
type: "submit_panel_event",
tenant: "tenant",
project: "project",
process,
widget_id: "debug-process",
kind: "ButtonClicked",
max_events: 1
});
assert.strictEqual(rateLimited.type, "error");
assert.match(rateLimited.message, /rate limit/i);
const stopped = await send(addr, {
type: "render_operator_panel",
tenant: "tenant",
project: "project",
process,
actor_user: "user",
max_download_bytes: 1024 * 1024,
stopped: true
});
assert.strictEqual(stopped.type, "operator_panel");
assert.strictEqual(stopped.panel.program_ui_events_enabled, false);
assert.deepStrictEqual(widget(stopped.panel, "process-status").kind, {
Text: { value: "stopped" }
});
assert.deepStrictEqual(
widget(stopped.panel, "task-progress").kind,
widget(panel, "task-progress").kind
);
assert.deepStrictEqual(
widget(stopped.panel, "task-summary").kind,
widget(panel, "task-summary").kind
);
assert.deepStrictEqual(
widget(stopped.panel, "recent-logs").kind,
widget(panel, "recent-logs").kind
);
assert.deepStrictEqual(
widget(stopped.panel, "download-artifact").kind,
widget(panel, "download-artifact").kind
);
assert(stopped.panel.control_plane_actions.includes("DebugProcess"));
assert(
stopped.panel.control_plane_actions.some(
(action) => action.DownloadArtifact === artifact
)
);
const frozenEvent = await send(addr, {
type: "submit_panel_event",
tenant: "tenant",
project: "project",
process,
widget_id: "debug-process",
kind: "ButtonClicked",
max_events: 10
});
assert.strictEqual(frozenEvent.type, "error");
assert.match(frozenEvent.message, /program UI events are disabled/i);
const crossTenant = await send(addr, {
type: "render_operator_panel",
tenant: "other",
project: "project",
process,
actor_user: "user",
max_download_bytes: 1024 * 1024,
stopped: false
});
assert.strictEqual(crossTenant.type, "error");
assert.match(
crossTenant.message,
/scope|tenant|project|requires an active virtual process/i
);
assert(!crossTenant.message.includes(process));
const resumed = await send(addr, {
type: "resume_debug_epoch",
tenant: "tenant",
project: "project",
actor_user: "user",
process,
epoch: breakpointHit.hit_epoch,
});
assert.strictEqual(resumed.type, "debug_epoch");
const cleanup = await send(addr, {
type: "abort_process",
tenant: "tenant",
project: "project",
actor_user: "user",
process,
});
assert.strictEqual(cleanup.type, "process_aborted");
} catch (error) {
if (coordinatorStderr) {
error.message = `${error.message}\ncoordinator stderr:\n${coordinatorStderr}`;
}
throw error;
} finally {
worker?.child.kill("SIGTERM");
coordinator.kill("SIGTERM");
}
console.log("Operator panel smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,86 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const path = require("path");
const { configurePodmanTestEnvironment } = require("./podman-test-env");
const repo = path.resolve(__dirname, "..");
const baseImage = "docker.io/library/alpine:3.20";
// Nix's standalone Podman package may not install the distribution-level
// containers/image policy normally found under /etc. Use an isolated test HOME
// without replacing a policy supplied by the host.
configurePodmanTestEnvironment(repo);
function run(command, args, options = {}) {
return cp.execFileSync(command, args, {
cwd: repo,
encoding: "utf8",
stdio: options.stdio || ["ignore", "pipe", "pipe"],
});
}
function incomplete(reason) {
const error = new Error(`Linux Podman backend incomplete: ${reason}`);
error.code = "CLUSTERFLUX_PODMAN_INCOMPLETE";
throw error;
}
function ensurePodmanBaseImage() {
try {
run("podman", ["--version"]);
} catch (error) {
incomplete(`podman command is unavailable (${error.message})`);
}
let rootless;
try {
rootless = run("podman", ["info", "--format", "{{.Host.Security.Rootless}}"]).trim();
} catch (error) {
incomplete(`podman info did not report rootless status (${error.message})`);
}
if (rootless !== "true") {
incomplete(`podman is not running in rootless mode (reported ${JSON.stringify(rootless)})`);
}
try {
run("podman", ["image", "exists", baseImage]);
} catch (_) {
try {
run("podman", ["pull", baseImage], { stdio: "inherit" });
} catch (error) {
incomplete(`unable to make ${baseImage} available (${error.message})`);
}
}
}
try {
ensurePodmanBaseImage();
const stdout = run("cargo", [
"run",
"-q",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-podman-smoke"
]);
const report = JSON.parse(stdout.trim().split("\n").at(-1));
assert.strictEqual(report.podman_status, "completed");
assert.strictEqual(report.status_code, 0);
assert.strictEqual(report.stdout, "podman-ok:node-local source\n");
assert.strictEqual(report.large_bytes_uploaded, false);
assert.strictEqual(report.uses_full_repo_tarball, false);
assert.strictEqual(report.coordinator_routed_file_reads, false);
assert.strictEqual(report.staged_artifact.path, "/vfs/artifacts/podman-smoke.txt");
console.log("Podman backend smoke passed");
} catch (error) {
if (error.code === "CLUSTERFLUX_PODMAN_INCOMPLETE") {
console.error(error.message);
process.exit(2);
}
throw error;
}

View file

@ -1,41 +0,0 @@
const fs = require("fs");
const os = require("os");
const path = require("path");
function configurePodmanTestEnvironment(repo) {
const originalHome = os.homedir();
if (
fs.existsSync(path.join(originalHome, ".config/containers/policy.json")) ||
fs.existsSync("/etc/containers/policy.json")
) {
return;
}
const isolatedHome = path.join(repo, "scripts/containers-home");
const policy = path.join(isolatedHome, ".config/containers/policy.json");
fs.mkdirSync(path.dirname(policy), { recursive: true });
if (!fs.existsSync(policy)) {
fs.writeFileSync(
policy,
`${JSON.stringify(
{ default: [{ type: "insecureAcceptAnything" }] },
null,
2
)}\n`
);
}
process.env.CARGO_HOME ||= path.join(originalHome, ".cargo");
process.env.RUSTUP_HOME ||= path.join(originalHome, ".rustup");
process.env.HOME = isolatedHome;
process.env.XDG_DATA_HOME = path.join(
os.tmpdir(),
`clusterflux-containers-data-${process.getuid?.() ?? "user"}`
);
process.env.XDG_CACHE_HOME = path.join(
os.tmpdir(),
`clusterflux-containers-cache-${process.getuid?.() ?? "user"}`
);
}
module.exports = { configurePodmanTestEnvironment };

File diff suppressed because it is too large Load diff

View file

@ -1,14 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
cd "$repo"
scripts/check-old-name.sh
node scripts/check-docs.js
scripts/check-code-size.sh
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo test --locked --manifest-path private/hosted-policy/Cargo.toml
node scripts/vscode-extension-smoke.js

View file

@ -1,69 +0,0 @@
#!/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 expect(source, name, pattern) {
assert.match(source, pattern, `missing public local demo evidence: ${name}`);
}
const publicAcceptance = read("scripts/acceptance-public.sh");
const publicSplit = read("scripts/verify-public-split.sh");
const cliInstall = read("scripts/cli-install-smoke.js");
const flagship = read("scripts/flagship-demo-smoke.js");
const cliLocalRun = read("scripts/cli-local-run-smoke.js");
const nodeAttach = read("scripts/node-attach-smoke.js");
const vscodeExtension = read("scripts/vscode-extension-smoke.js");
const vscodeF5 = read("scripts/vscode-f5-smoke.js");
const artifactDownload = read("scripts/artifact-download-smoke.js");
const artifactExport = read("scripts/artifact-export-smoke.js");
for (const script of [publicAcceptance, publicSplit]) {
for (const smoke of [
"scripts/cli-install-smoke.js",
"scripts/flagship-demo-smoke.js",
"scripts/cli-local-run-smoke.js",
"scripts/node-attach-smoke.js",
"scripts/vscode-extension-smoke.js",
"scripts/vscode-f5-smoke.js",
"scripts/artifact-download-smoke.js",
"scripts/artifact-export-smoke.js",
]) {
assert(script.includes(`node ${smoke}`), `public demo gate must run ${smoke}`);
}
}
expect(cliInstall, "CLI install from project path", /cargo[\s\S]*install[\s\S]*crates\/clusterflux-cli/);
expect(cliInstall, "CLI install smoke targets runtime fixture", /const project = path\.join\(repo, "tests\/fixtures\/runtime-conformance"\)/);
expect(cliInstall, "installed CLI inspects flagship project", /installedBin[\s\S]*\["bundle", "inspect", "--project", project, "--json"\]/);
expect(flagship, "flagship project source is conventional Rust workflow", /examples\/hello-build[\s\S]*src\/lib\.rs/);
expect(flagship, "flagship source avoids implementation details", /const forbidden/);
expect(flagship, "flagship builds a real bundle", /clusterflux-cli[\s\S]*build[\s\S]*hello/);
expect(cliLocalRun, "local run starts node process", /cli_process_started_node_process[\s\S]*true/);
expect(cliLocalRun, "local run records real task events", /events\.events\.length >= 4[\s\S]*prepare_source[\s\S]*compile_linux[\s\S]*package_release/);
expect(cliLocalRun, "local run records artifact metadata", /events\.events\.some\(\(event\) => event\.artifact_path\)/);
expect(nodeAttach, "Linux node attach creates enrollment grant", /create_node_enrollment_grant/);
expect(nodeAttach, "Linux node attach uses enrollment exchange", /used_enrollment_exchange[\s\S]*true/);
expect(nodeAttach, "attached Linux node proves signed enrollment", /used_enrollment_exchange[\s\S]*signedNodeHeartbeat/);
expect(vscodeExtension, "extension contributes debugger", /contributes\.debuggers[\s\S]*type === "clusterflux"/);
expect(vscodeF5, "F5 uses local-services backend", /runtimeBackend[\s\S]*local-services/);
expect(vscodeF5, "F5 exposes real coordinator main thread", /threads\.find\(\(thread\) => thread\.name\.includes\("build coordinator main"\)\)[\s\S]*real coordinator-main entrypoint thread/);
expect(vscodeF5, "F5 does not fabricate a terminal event at the entry probe", /coordinator_task_events[\s\S]*value === 0[\s\S]*must not fabricate a terminal task event/);
expect(artifactDownload, "artifact download creates scoped link", /create_artifact_download_link/);
expect(artifactDownload, "artifact download opens stream", /open_artifact_download_stream/);
expect(artifactExport, "artifact export targets receiver node", /export_artifact_to_node[\s\S]*node-export-receiver/);
expect(artifactExport, "artifact export rejects coordinator bulk relay", /coordinator_bulk_relay_allowed[\s\S]*false/);
console.log("Public local demo matrix smoke passed");

View file

@ -1,451 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const releaseRoot = path.resolve(
process.env.CLUSTERFLUX_PUBLIC_RELEASE_DIR ||
path.join(repo, "target/public-release")
);
const acceptanceRoot = path.join(repo, "target/acceptance");
const manifestPath =
process.env.CLUSTERFLUX_PUBLIC_RELEASE_MANIFEST ||
path.join(releaseRoot, "public-release-manifest.json");
const reportPath =
process.env.CLUSTERFLUX_PUBLIC_RELEASE_PREFLIGHT_REPORT ||
path.join(acceptanceRoot, "public-release-preflight.json");
function commandOutput(command, args, options = {}) {
try {
return cp
.execFileSync(command, args, {
cwd: repo,
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
...options,
})
.trim();
} catch (_) {
return null;
}
}
function nonInteractiveEnv(extra = {}) {
return {
...process.env,
GIT_TERMINAL_PROMPT: "0",
GIT_ASKPASS: process.env.GIT_ASKPASS || "/bin/false",
SSH_ASKPASS: process.env.SSH_ASKPASS || "/bin/false",
GIT_SSH_COMMAND:
process.env.GIT_SSH_COMMAND ||
"ssh -o BatchMode=yes -o NumberOfPasswordPrompts=0",
...extra,
};
}
function expectedSourceCommit() {
const head = commandOutput("git", ["rev-parse", "HEAD"]);
assert(head && /^[0-9a-f]{40}$/u.test(head), "preflight requires an exact Git HEAD");
const asserted = process.env.CLUSTERFLUX_ACCEPTANCE_COMMIT;
if (asserted) {
assert.strictEqual(asserted, head, "acceptance commit must match Git HEAD");
}
return head;
}
function readJson(file) {
return JSON.parse(fs.readFileSync(file, "utf8"));
}
function sha256File(file) {
return crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
}
function sha256Buffer(buffer) {
return crypto.createHash("sha256").update(buffer).digest("hex");
}
function readArchiveMember(archive, member) {
return cp.execFileSync("tar", ["-xOzf", archive, `./${member}`], {
cwd: repo,
encoding: null,
maxBuffer: 128 * 1024 * 1024,
stdio: ["ignore", "pipe", "pipe"],
});
}
function parseSha256Sums(file) {
const sums = new Map();
for (const line of fs.readFileSync(file, "utf8").split(/\r?\n/)) {
if (!line.trim()) continue;
const match = /^([0-9a-f]{64})\s+(.+)$/.exec(line.trim());
assert(match, `malformed SHA256SUMS line: ${line}`);
sums.set(path.basename(match[2]), match[1]);
}
return sums;
}
function remoteHead(remote) {
const output = commandOutput("git", ["ls-remote", remote, "HEAD", "refs/heads/main"], {
env: nonInteractiveEnv(),
timeout: Number(process.env.CLUSTERFLUX_PUBLIC_REPO_REMOTE_TIMEOUT_MS || 30000),
});
if (!output) return null;
const lines = output.split(/\r?\n/).filter(Boolean);
const head = lines.find((line) => line.endsWith("\tHEAD")) || lines[0];
return head && head.split(/\s+/)[0];
}
function publicTreeAlreadyPushed(manifest) {
return (
(manifest.public_tree_publish && manifest.public_tree_publish.pushed === true) ||
process.env.CLUSTERFLUX_PUBLIC_TREE_ALREADY_PUSHED === "1"
);
}
function publicTreePushSource(manifest) {
return manifest.public_tree_publish && manifest.public_tree_publish.pushed === true
? "manifest"
: "external-env";
}
function publicRepoRemoteForManifest(manifest) {
return (
manifest.public_repo_url ||
manifest.public_repo_remote ||
process.env.CLUSTERFLUX_PUBLIC_REPO_REMOTE ||
process.env.CLUSTERFLUX_PUBLIC_REPO_URL ||
null
);
}
function publicTreeCommitForManifest(manifest) {
return (
(manifest.public_tree_publish && manifest.public_tree_publish.commit) ||
process.env.CLUSTERFLUX_PUBLIC_TREE_COMMIT ||
process.env.CLUSTERFLUX_PUBLIC_RELEASE_TARGET ||
null
);
}
function envState(name) {
return process.env[name] ? "set" : "unset";
}
function staleEvidence(file, currentSourceCommit) {
if (!fs.existsSync(file)) {
return { file, status: "missing", source_commit: null, release_name: null };
}
const evidence = readJson(file);
if (!evidence.source_commit) {
return {
file,
status: "unversioned",
source_commit: null,
release_name: evidence.release_name || null,
};
}
return {
file,
status: evidence.source_commit === currentSourceCommit ? "current" : "stale",
source_commit: evidence.source_commit,
release_name: evidence.release_name || null,
};
}
assert(fs.existsSync(manifestPath), `missing public release manifest: ${manifestPath}`);
const manifest = readJson(manifestPath);
for (const asset of manifest.assets ?? []) {
asset.file = path.isAbsolute(asset.file)
? asset.file
: path.resolve(path.dirname(manifestPath), asset.file);
}
const currentSourceCommit = expectedSourceCommit();
const currentTreeStatus = commandOutput("git", ["status", "--short"]) || "";
assert.strictEqual(
currentTreeStatus,
"",
"public release preflight requires a clean source tree"
);
assert.strictEqual(manifest.kind, "clusterflux-public-release");
assert.strictEqual(
manifest.source_commit,
currentSourceCommit,
"public release manifest must be regenerated for the current acceptance commit"
);
assert.strictEqual(manifest.source_tree_clean, true, "public release prep must start clean");
assert.strictEqual(
publicTreeAlreadyPushed(manifest),
true,
"filtered public tree must be pushed to Forgejo before release publication"
);
const publicRepoRemote = publicRepoRemoteForManifest(manifest);
assert(publicRepoRemote, "manifest must record public repository URL or remote");
const publicTreeCommit = publicTreeCommitForManifest(manifest);
const remoteMain = remoteHead(publicRepoRemote);
assert(remoteMain, "Forgejo public repository main branch must be readable");
if (publicTreeCommit) {
assert.strictEqual(
remoteMain,
publicTreeCommit,
"Forgejo public repository main branch must match the prepared public tree commit"
);
}
assert(Array.isArray(manifest.assets) && manifest.assets.length > 0, "manifest assets missing");
const checksumAsset = manifest.assets.find((asset) => asset.name === "SHA256SUMS");
assert(checksumAsset, "manifest must include SHA256SUMS");
assert(fs.existsSync(checksumAsset.file), `missing checksum asset: ${checksumAsset.file}`);
const checksums = parseSha256Sums(checksumAsset.file);
const assets = manifest.assets.map((asset) => {
assert(fs.existsSync(asset.file), `missing release asset: ${asset.file}`);
const actual = sha256File(asset.file);
const expected = checksums.get(asset.name);
if (asset.name !== "SHA256SUMS") {
assert.strictEqual(actual, expected, `checksum mismatch for ${asset.name}`);
}
return {
name: asset.name,
file: asset.file,
bytes: fs.statSync(asset.file).size,
sha256: actual,
};
});
const binaryAsset = manifest.assets.find((asset) =>
asset.name.startsWith("clusterflux-public-binaries-")
);
const hostedBinaryAsset = manifest.assets.find((asset) =>
asset.name.startsWith("clusterflux-hosted-")
);
assert(binaryAsset, "manifest must include the exact candidate binary archive");
assert(hostedBinaryAsset, "manifest must include the exact hosted binary archive");
for (const [name, digest] of Object.entries(manifest.binary_digests)) {
const archive = name === "clusterflux-hosted-service" ? hostedBinaryAsset : binaryAsset;
const binary = readArchiveMember(archive.file, `bin/${name}`);
assert.strictEqual(
`sha256:${sha256Buffer(binary)}`,
digest,
`candidate archive binary ${name} does not match the manifest`
);
}
assert(
manifest.final_evidence && manifest.final_evidence.complete === true,
"release publication requires complete final result and transcript evidence"
);
const evidenceAsset = manifest.assets.find((asset) =>
asset.name.startsWith("clusterflux-public-evidence-")
);
assert(evidenceAsset, "manifest must include the final evidence archive");
const binding = JSON.parse(
readArchiveMember(evidenceAsset.file, "EVIDENCE_BINDING.json").toString("utf8")
);
assert.strictEqual(binding.source_commit, currentSourceCommit);
assert.strictEqual(binding.source_tree_digest, manifest.source_tree_digest);
assert.strictEqual(binding.public_tree_identity, manifest.public_tree_identity);
assert.deepStrictEqual(binding.binary_digests, manifest.binary_digests);
assert(binding.final_evidence && binding.final_evidence.complete === true);
assert(Array.isArray(binding.included_evidence));
const includedEvidence = new Map(
binding.included_evidence.map((entry) => [entry.name, entry.sha256])
);
for (const required of ["FINAL_RELEASE_RESULT.json", "FINAL_RELEASE_TRANSCRIPT.txt"]) {
assert(includedEvidence.has(required), `final evidence archive is missing ${required}`);
const contents = readArchiveMember(evidenceAsset.file, required);
assert.strictEqual(
sha256Buffer(contents),
includedEvidence.get(required),
`final evidence digest mismatch for ${required}`
);
}
const finalResult = JSON.parse(
readArchiveMember(evidenceAsset.file, "FINAL_RELEASE_RESULT.json").toString("utf8")
);
assert.strictEqual(finalResult.source_commit, currentSourceCommit);
assert.strictEqual(finalResult.source_tree_digest, manifest.source_tree_digest);
assert.strictEqual(finalResult.public_tree_identity, manifest.public_tree_identity);
assert.deepStrictEqual(finalResult.binary_digests, manifest.binary_digests);
assert.strictEqual(
manifest.release_candidate?.mode,
"finalized-exact",
"publication requires exact candidate finalization"
);
assert.strictEqual(finalResult.release_binding?.source_commit, currentSourceCommit);
assert.strictEqual(
finalResult.release_binding?.source_tree_digest,
manifest.source_tree_digest
);
assert.strictEqual(
finalResult.release_binding?.public_tree_identity,
manifest.public_tree_identity
);
assert.deepStrictEqual(
finalResult.release_binding?.binary_digests,
manifest.binary_digests
);
assert.deepStrictEqual(
finalResult.release_candidate,
manifest.release_candidate
);
assert.strictEqual(finalResult.acceptance_result, "passed");
assert.deepStrictEqual(finalResult.scenario_skips, []);
assert(
finalResult.release_binding?.deployment &&
finalResult.release_binding?.configuration &&
finalResult.release_binding?.proxy_configuration,
"final evidence must bind deployment, runtime configuration, and proxy configuration identities"
);
if (manifest.candidate_configuration_identity) {
assert.strictEqual(
finalResult.release_binding.configuration.evidence_identity,
manifest.candidate_configuration_identity,
"live configuration identity differs from the candidate binding"
);
}
if (manifest.candidate_proxy_configuration_identity) {
assert.strictEqual(
finalResult.release_binding.proxy_configuration.evidence_identity,
manifest.candidate_proxy_configuration_identity,
"live proxy configuration identity differs from the candidate binding"
);
}
assert(
Array.isArray(finalResult.named_scenarios) &&
finalResult.named_scenarios.length >= 29 &&
finalResult.named_scenarios.length ===
finalResult.strict_requirement_ledger.length &&
finalResult.named_scenarios.every(
(scenario) =>
scenario.status === "passed" &&
Number.isFinite(scenario.duration_ms) &&
scenario.duration_ms > 0
),
"all named final checks must be present, measured, and passed"
);
assert(
Array.isArray(finalResult.strict_requirement_ledger) &&
finalResult.strict_requirement_ledger.length > 0 &&
finalResult.strict_requirement_ledger.every(
(requirement) =>
requirement.passed === true &&
Number.isFinite(requirement.duration_ms) &&
requirement.duration_ms > 0 &&
requirement.evidence
),
"the strict final requirement ledger must be present and passed"
);
const finalTranscript = readArchiveMember(
evidenceAsset.file,
"FINAL_RELEASE_TRANSCRIPT.txt"
).toString("utf8");
for (const identity of [
currentSourceCommit,
manifest.source_tree_digest,
manifest.public_tree_identity,
...Object.values(manifest.binary_digests),
]) {
assert(finalTranscript.includes(identity), `final transcript is missing identity ${identity}`);
}
const evidence = [
staleEvidence(
path.join(acceptanceRoot, "public-release-forgejo-release.json"),
currentSourceCommit
),
staleEvidence(
path.join(acceptanceRoot, "public-release-service.json"),
currentSourceCommit
),
staleEvidence(
path.join(acceptanceRoot, "hosted-client-compat.json"),
currentSourceCommit
),
staleEvidence(
path.join(acceptanceRoot, "core-coordinator-compat.json"),
currentSourceCommit
),
staleEvidence(
path.join(acceptanceRoot, "public-release-e2e.json"),
currentSourceCommit
),
staleEvidence(
path.join(acceptanceRoot, "public-release-final.json"),
currentSourceCommit
),
];
const report = {
kind: "clusterflux-public-release-preflight",
source_commit: currentSourceCommit,
release_name: manifest.release_name,
public_tree_commit: publicTreeCommit || remoteMain,
public_tree_push_source: publicTreePushSource(manifest),
public_repo_url: publicRepoRemote,
public_repo_remote_head: remoteMain,
source_tree_clean: currentTreeStatus === "",
local_assets_ready: true,
assets,
final_evidence: {
complete: true,
binding,
},
evidence,
external_gates: {
forgejo_release_publication: {
status: envState("CLUSTERFLUX_FORGEJO_TOKEN") === "set" ? "ready" : "pending",
env: {
CLUSTERFLUX_FORGEJO_TOKEN: envState("CLUSTERFLUX_FORGEJO_TOKEN"),
},
},
live_service_smoke: {
status:
envState("CLUSTERFLUX_PUBLIC_RELEASE_SERVICE_ADDR") === "set" &&
envState("CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND") === "set"
? "ready"
: "pending",
env: {
CLUSTERFLUX_PUBLIC_RELEASE_SERVICE_ADDR: envState(
"CLUSTERFLUX_PUBLIC_RELEASE_SERVICE_ADDR"
),
CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND: envState(
"CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND"
),
},
},
public_release_e2e: {
status:
envState("CLUSTERFLUX_PUBLIC_RELEASE_E2E") === "set" &&
process.env.CLUSTERFLUX_PUBLIC_RELEASE_E2E === "1" &&
envState("CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND") === "set"
? "ready"
: "pending",
env: {
CLUSTERFLUX_PUBLIC_RELEASE_E2E:
process.env.CLUSTERFLUX_PUBLIC_RELEASE_E2E || "unset",
CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND: envState(
"CLUSTERFLUX_PUBLIC_RELEASE_BROWSER_OPEN_COMMAND"
),
},
},
final_evidence: {
status:
envState("CLUSTERFLUX_PUBLIC_RELEASE_FINAL") === "set" &&
process.env.CLUSTERFLUX_PUBLIC_RELEASE_FINAL === "1"
? "ready"
: "pending",
env: {
CLUSTERFLUX_PUBLIC_RELEASE_FINAL:
process.env.CLUSTERFLUX_PUBLIC_RELEASE_FINAL || "unset",
},
},
},
};
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
console.log(JSON.stringify({ report: reportPath, release_name: report.release_name }, null, 2));

View file

@ -1,7 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
cd "$repo"
scripts/verify-public-split.sh

View file

@ -1,354 +0,0 @@
#!/usr/bin/env node
const fs = require("fs");
const https = require("https");
const path = require("path");
const cp = require("child_process");
const repo = path.resolve(__dirname, "..");
const releaseRoot = path.resolve(
process.env.CLUSTERFLUX_PUBLIC_RELEASE_DIR ||
path.join(repo, "target/public-release")
);
const manifestPath = path.join(releaseRoot, "public-release-manifest.json");
const reportPath = path.join(
repo,
"target/acceptance/public-release-forgejo-release.json"
);
const forgejoUrl = (
process.env.CLUSTERFLUX_FORGEJO_URL || "https://git.michelpaulissen.com"
).replace(/\/+$/, "");
const token = process.env.CLUSTERFLUX_FORGEJO_TOKEN;
let owner = process.env.CLUSTERFLUX_PUBLIC_REPO_OWNER;
let repoName = process.env.CLUSTERFLUX_PUBLIC_REPO_NAME;
function requireEnv(name, value) {
if (!value) {
throw new Error(`${name} is required`);
}
}
function commandOutput(command, args) {
try {
return cp
.execFileSync(command, args, {
cwd: repo,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
})
.trim();
} catch (_) {
return null;
}
}
function expectedSourceCommit() {
return (
process.env.CLUSTERFLUX_ACCEPTANCE_COMMIT ||
commandOutput("git", ["rev-parse", "HEAD"]) ||
"unknown"
);
}
function parseForgejoRepoIdentity(remote) {
if (!remote) {
return null;
}
let pathname = remote;
try {
pathname = new URL(remote).pathname;
} catch (_) {
const scpLike = /^[^@/]+@[^:]+:(.+)$/.exec(remote);
if (scpLike) {
pathname = scpLike[1];
}
}
const parts = pathname
.replace(/^\/+/, "")
.replace(/\.git$/, "")
.split("/")
.filter(Boolean);
if (parts.length < 2) {
return null;
}
return {
owner: parts[parts.length - 2],
repoName: parts[parts.length - 1],
};
}
function resolveRepoIdentity(manifest) {
if (owner && repoName) {
return;
}
const inferred = parseForgejoRepoIdentity(
manifest.public_repo_url ||
manifest.public_repo_remote ||
process.env.CLUSTERFLUX_PUBLIC_REPO_REMOTE
);
owner = owner || (inferred && inferred.owner);
repoName = repoName || (inferred && inferred.repoName);
if (!owner || !repoName) {
throw new Error(
"CLUSTERFLUX_PUBLIC_REPO_OWNER and CLUSTERFLUX_PUBLIC_REPO_NAME are required when the manifest does not contain a parseable Forgejo repository URL"
);
}
}
function publicTreeAlreadyPushed(manifest) {
return (
(manifest.public_tree_publish && manifest.public_tree_publish.pushed === true) ||
process.env.CLUSTERFLUX_PUBLIC_TREE_ALREADY_PUSHED === "1"
);
}
function publicTreeCommit(manifest) {
return (
(manifest.public_tree_publish && manifest.public_tree_publish.commit) ||
process.env.CLUSTERFLUX_PUBLIC_TREE_COMMIT ||
process.env.CLUSTERFLUX_PUBLIC_RELEASE_TARGET ||
null
);
}
function apiPath(pathname) {
return `/api/v1${pathname}`;
}
function request(method, pathname, { body, headers = {} } = {}) {
const url = new URL(apiPath(pathname), forgejoUrl);
const payload =
body === undefined
? null
: Buffer.isBuffer(body)
? body
: Buffer.from(JSON.stringify(body));
const requestHeaders = {
Accept: "application/json",
Authorization: `token ${token}`,
...headers,
};
if (payload) {
requestHeaders["Content-Length"] = payload.length;
if (!requestHeaders["Content-Type"]) {
requestHeaders["Content-Type"] = "application/json";
}
}
return new Promise((resolve, reject) => {
const req = https.request(
url,
{
method,
headers: requestHeaders,
},
(res) => {
const chunks = [];
res.on("data", (chunk) => chunks.push(chunk));
res.on("end", () => {
const text = Buffer.concat(chunks).toString("utf8");
let parsed = null;
if (text.trim()) {
try {
parsed = JSON.parse(text);
} catch (_) {
parsed = text;
}
}
if (res.statusCode < 200 || res.statusCode >= 300) {
reject(
new Error(
`${method} ${url.pathname} failed with ${res.statusCode}: ${text}`
)
);
return;
}
resolve({ status: res.statusCode, body: parsed });
});
}
);
req.on("error", reject);
if (payload) req.write(payload);
req.end();
});
}
function multipartFile(fieldName, file) {
const boundary = `clusterflux-${Date.now()}-${Math.random().toString(16).slice(2)}`;
const name = path.basename(file);
const header = Buffer.from(
`--${boundary}\r\n` +
`Content-Disposition: form-data; name="${fieldName}"; filename="${name}"\r\n` +
"Content-Type: application/octet-stream\r\n\r\n"
);
const footer = Buffer.from(`\r\n--${boundary}--\r\n`);
return {
body: Buffer.concat([header, fs.readFileSync(file), footer]),
contentType: `multipart/form-data; boundary=${boundary}`,
};
}
async function existingRelease(tagName) {
const releases = await request(
"GET",
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repoName)}/releases?limit=100`
);
return (releases.body || []).find((release) => release.tag_name === tagName) || null;
}
async function createOrReuseRelease(manifest) {
const tagName = manifest.release_name;
const found = await existingRelease(tagName);
if (found) {
return { release: found, created: false };
}
const targetCommitish =
publicTreeCommit(manifest) ||
"main";
const body = [
"Clusterflux public release.",
"",
`Default hosted coordinator endpoint: ${manifest.default_hosted_coordinator_endpoint}`,
`DNS publication state: ${manifest.dns_publication_state}`,
`Resolver override: ${manifest.resolver_override}`,
`Public tree identity: ${manifest.public_tree_identity}`,
`Source commit: ${manifest.source_commit}`,
].join("\n");
const created = await request(
"POST",
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repoName)}/releases`,
{
body: {
tag_name: tagName,
target_commitish: targetCommitish,
name: tagName,
body,
draft: false,
prerelease: false,
},
}
);
return { release: created.body, created: true };
}
async function loadRelease(releaseId) {
const response = await request(
"GET",
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repoName)}/releases/${releaseId}`
);
return response.body;
}
async function uploadAsset(release, asset) {
const { body, contentType } = multipartFile("attachment", asset.file);
const response = await request(
"POST",
`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repoName)}/releases/${release.id}/assets?name=${encodeURIComponent(asset.name)}`,
{
body,
headers: {
"Content-Type": contentType,
},
}
);
return response.body;
}
function existingAssetByName(release, name) {
return Array.isArray(release.assets)
? release.assets.find((asset) => asset.name === name) || null
: null;
}
async function main() {
requireEnv("CLUSTERFLUX_FORGEJO_TOKEN", token);
if (!fs.existsSync(manifestPath)) {
throw new Error(`missing public release manifest: ${manifestPath}`);
}
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
for (const asset of manifest.assets ?? []) {
asset.file = path.isAbsolute(asset.file)
? asset.file
: path.resolve(path.dirname(manifestPath), asset.file);
}
resolveRepoIdentity(manifest);
if (manifest.kind !== "clusterflux-public-release") {
throw new Error(`unexpected public release manifest kind: ${manifest.kind}`);
}
if (manifest.source_commit !== expectedSourceCommit()) {
throw new Error(
"public release manifest is stale; regenerate it for the current acceptance commit before publishing the Forgejo Release"
);
}
if (
!publicTreeAlreadyPushed(manifest)
) {
throw new Error(
"public tree must be pushed before publishing the Forgejo Release; run prepare-public-release.js with CLUSTERFLUX_PUBLISH_PUBLIC_TREE=1"
);
}
if (!Array.isArray(manifest.assets) || manifest.assets.length === 0) {
throw new Error("public release manifest has no assets");
}
const { release: releaseResult, created } = await createOrReuseRelease(manifest);
const release = await loadRelease(releaseResult.id);
const uploaded = [];
const reused = [];
for (const asset of manifest.assets) {
if (!fs.existsSync(asset.file)) {
throw new Error(`missing release asset: ${asset.file}`);
}
const existing = existingAssetByName(release, asset.name);
if (existing) {
reused.push(existing);
continue;
}
uploaded.push(await uploadAsset(release, asset));
}
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
const report = {
kind: "clusterflux-public-release-forgejo-release",
forgejo_url: forgejoUrl,
owner,
repo: repoName,
release_id: release.id,
release_name: release.name || manifest.release_name,
tag_name: release.tag_name || manifest.release_name,
release_created: created,
default_hosted_coordinator_endpoint: manifest.default_hosted_coordinator_endpoint,
public_tree_identity: manifest.public_tree_identity,
public_tree_commit: publicTreeCommit(manifest),
source_commit: manifest.source_commit,
uploaded_assets: uploaded.map((asset) => ({
id: asset.id,
name: asset.name,
size: asset.size,
browser_download_url: asset.browser_download_url,
})),
reused_assets: reused.map((asset) => ({
id: asset.id,
name: asset.name,
size: asset.size,
browser_download_url: asset.browser_download_url,
})),
};
fs.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}\n`);
console.log(
JSON.stringify(
{ report: reportPath, uploaded: uploaded.length, reused: reused.length },
null,
2
)
);
}
main().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,154 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const repo = path.resolve(__dirname, "..");
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function rendezvousRequest(overrides = {}) {
return {
type: "request_rendezvous",
scope: {
tenant: "tenant",
project: "project",
process: "vp-quic",
object: { Artifact: "quic-artifact" },
authorization_subject: "node-a-to-node-b",
},
source: {
node: "node-a",
advertised_addr: "node-a.mesh.invalid:4433",
public_key_fingerprint: "sha256:node-a-public-key",
},
destination: {
node: "node-b",
advertised_addr: "node-b.mesh.invalid:4433",
public_key_fingerprint: "sha256:node-b-public-key",
},
direct_connectivity: true,
failure_reason: "",
...overrides,
};
}
(async () => {
const output = cp.execFileSync(
"cargo",
["run", "-q", "-p", "clusterflux-node", "--bin", "clusterflux-quic-smoke"],
{ cwd: repo, encoding: "utf8" }
);
const report = JSON.parse(output.trim().split("\n").at(-1));
assert.strictEqual(report.kind, "clusterflux_quic_smoke");
assert.strictEqual(report.transport, "NativeQuic");
assert.strictEqual(report.rust_native_quic, true);
assert.strictEqual(report.authenticated_direct_connection, true);
assert.strictEqual(report.coordinator_assisted_rendezvous, true);
assert.strictEqual(report.coordinator_bulk_relay_allowed, false);
assert.strictEqual(report.source_node, "node-a");
assert.strictEqual(report.destination_node, "node-b");
assert.strictEqual(report.scope.tenant, "tenant");
assert.strictEqual(report.scope.project, "project");
assert.strictEqual(report.scope.process, "vp-quic");
assert.deepStrictEqual(report.scope.object, { Artifact: "quic-artifact" });
assert.ok(report.authorization_digest.startsWith("sha256:"));
assert.ok(report.request_bytes > 0);
assert.strictEqual(report.server_received_request_bytes, report.request_bytes);
assert.ok(report.payload_bytes > 0);
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback",
],
{ cwd: repo }
);
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
const plan = await send(addr, rendezvousRequest());
assert.strictEqual(plan.type, "rendezvous_plan");
assert.strictEqual(plan.charged_rendezvous_attempts, 1);
assert.strictEqual(plan.plan.transport, "NativeQuic");
assert.strictEqual(plan.plan.scope.tenant, "tenant");
assert.strictEqual(plan.plan.scope.project, "project");
assert.strictEqual(plan.plan.source.node, "node-a");
assert.strictEqual(plan.plan.destination.node, "node-b");
assert.strictEqual(plan.plan.coordinator_assisted_rendezvous, true);
assert.strictEqual(plan.plan.coordinator_bulk_relay_allowed, false);
assert.ok(plan.plan.authorization_digest.startsWith("sha256:"));
const failed = await send(
addr,
rendezvousRequest({
direct_connectivity: false,
failure_reason: "nat traversal failed",
})
);
assert.strictEqual(failed.type, "error");
assert.match(failed.message, /nat traversal failed/);
assert.match(failed.message, /coordinator bulk relay is disabled/);
} finally {
coordinator.kill("SIGTERM");
}
console.log("QUIC smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,285 +0,0 @@
const assert = require("assert");
const cp = require("child_process");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const { configurePodmanTestEnvironment } = require("./podman-test-env");
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "examples/hello-build");
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.stderr?.on("data", (chunk) => {
stderr += chunk.toString();
if (stderr.length > 4096) stderr = stderr.slice(-4096);
});
child.once("exit", (code) => {
const detail = stderr.trim();
reject(new Error(
`process exited before JSON line with code ${code}${detail ? `: ${detail}` : ""}`
));
});
});
}
function waitForNodeStatus(child, expectedStatus) {
return new Promise((resolve, reject) => {
let buffer = "";
let stderr = "";
const cleanup = () => {
child.stdout.off("data", onData);
child.stderr?.off("data", onStderr);
child.off("exit", onExit);
};
const onData = (chunk) => {
buffer += chunk.toString();
while (buffer.includes("\n")) {
const newline = buffer.indexOf("\n");
const line = buffer.slice(0, newline).trim();
buffer = buffer.slice(newline + 1);
if (!line) continue;
let event;
try {
event = JSON.parse(line);
} catch (error) {
cleanup();
reject(error);
return;
}
if (event.node_status === expectedStatus) {
cleanup();
resolve(event);
return;
}
}
};
const onStderr = (chunk) => {
stderr += chunk.toString();
if (stderr.length > 4096) stderr = stderr.slice(-4096);
};
const onExit = (code) => {
cleanup();
const detail = stderr.trim();
reject(
new Error(
`worker exited before node status ${expectedStatus} with code ${code}${
detail ? `: ${detail}` : ""
}`
)
);
};
child.stdout.on("data", onData);
child.stderr?.on("data", onStderr);
child.once("exit", onExit);
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function configureContainerPolicyHome() {
configurePodmanTestEnvironment(repo);
}
function commandWithPodman(program, args) {
if (cp.spawnSync("podman", ["--version"], { stdio: "ignore" }).status === 0) {
return { program, args };
}
if (cp.spawnSync("nix", ["--version"], { stdio: "ignore" }).status === 0) {
return {
program: "nix",
args: ["shell", "nixpkgs#podman", "--command", program, ...args],
};
}
throw new Error(
"real flagship smoke requires rootless Podman (or Nix to provide it)"
);
}
function ensureRootlessPodman() {
configureContainerPolicyHome();
const invocation = commandWithPodman("podman", [
"info",
"--format",
"{{.Host.Security.Rootless}}",
]);
const rootless = cp.execFileSync(invocation.program, invocation.args, {
cwd: repo,
env: process.env,
encoding: "utf8",
}).trim();
assert.strictEqual(rootless, "true", "flagship worker must use rootless Podman");
}
async function runFlagshipWorker(addr, node, identity, projectRoot = project) {
const enrollment = await send(addr, {
type: "create_node_enrollment_grant",
tenant: "tenant",
project: "project",
actor_user: "user",
ttl_seconds: 60,
});
assert.strictEqual(enrollment.type, "node_enrollment_grant_created");
const cargoArgs = [
"run", "-q", "-p", "clusterflux-node", "--bin", "clusterflux-node", "--",
"--coordinator", `${addr.host}:${addr.port}`,
"--tenant", "tenant",
"--project-id", "project",
"--node", node,
"--enrollment-grant", enrollment.grant,
"--worker",
"--emit-ready",
"--project-root", projectRoot,
"--assignment-poll-ms", "25",
];
const invocation = commandWithPodman("cargo", cargoArgs);
const child = cp.spawn(invocation.program, invocation.args, {
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_NODE_PRIVATE_KEY: identity.privateKey,
},
});
return { child, ready: waitForJsonLine(child) };
}
const delay = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));
async function waitForTaskEvent(addr, process, predicate, description) {
for (let attempt = 0; attempt < 2400; attempt += 1) {
const response = await send(addr, {
type: "list_task_events",
tenant: "tenant",
project: "project",
actor_user: "user",
process,
});
assert.strictEqual(response.type, "task_events", JSON.stringify(response));
const event = response.events.find(predicate);
if (event) return event;
await delay(25);
}
throw new Error(`timed out waiting for real Wasm task ${description}`);
}
function startFlagship(addr, projectRoot = project) {
const report = JSON.parse(
cp.execFileSync(
"cargo",
[
"run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--",
"run", "build",
"--coordinator", `clusterflux+tcp://${addr.host}:${addr.port}`,
"--project", projectRoot,
"--json",
],
{ cwd: repo, env: process.env, encoding: "utf8" }
)
);
assert.strictEqual(report.command, "run");
assert.strictEqual(report.status, "main_launched", JSON.stringify(report));
assert.strictEqual(report.entry, "build");
assert.strictEqual(report.task_launch.type, "main_launched");
assert.strictEqual(report.task_launch.task_instance, report.task_instance);
assert.strictEqual(report.task_launch.task_definition, report.task_definition);
assert.strictEqual(report.worker_placement_requested, true);
assert.match(report.bundle_digest, /^sha256:[0-9a-f]{64}$/);
assert.match(report.entry_export, /^clusterflux_entry_v1_/);
const virtualProcess = report.process;
return { report, process: virtualProcess };
}
async function launchFlagship(addr) {
const { report, process: virtualProcess } = startFlagship(addr);
const compileEvent = await waitForTaskEvent(
addr,
virtualProcess,
(event) => event.task_definition === "compile",
"compile"
);
const sourceEvent = await waitForTaskEvent(
addr,
virtualProcess,
(event) => event.task_definition === "snapshot_current_project",
"snapshot_current_project"
);
const packageEvent = compileEvent;
const buildEvent = await waitForTaskEvent(
addr,
virtualProcess,
(event) => event.task === report.task_instance && event.executor === "coordinator_main",
"coordinator build main"
);
for (const event of [sourceEvent, compileEvent, buildEvent]) {
assert.strictEqual(event.terminal_state, "completed", JSON.stringify(event));
}
return {
report,
process: virtualProcess,
compileEvent,
sourceEvent,
packageEvent,
buildEvent,
};
}
function flagshipNodeCapabilities() {
return {
os: "Linux",
arch: process.arch,
capabilities: [
"Command",
"Containers",
"RootlessPodman",
"SourceFilesystem",
"VfsArtifacts",
],
environment_backends: ["Container"],
source_providers: ["filesystem"],
};
}
module.exports = {
ensureRootlessPodman,
flagshipNodeCapabilities,
launchFlagship,
project,
repo,
runFlagshipWorker,
send,
startFlagship,
waitForTaskEvent,
waitForJsonLine,
waitForNodeStatus,
};

View file

@ -1,139 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const { DapClient } = require("./dap-client");
const { configurePodmanTestEnvironment } = require("./podman-test-env");
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "examples/recovery-build");
const sourcePath = fs.realpathSync(path.join(project, "src/lib.rs"));
const original = fs.readFileSync(sourcePath, "utf8");
const failing = "\"exit 23\".to_owned()";
const replacement =
"\"printf 'recovered\\n' > /clusterflux/output/recovering.txt\".to_owned()";
assert(original.includes(failing), "recovery source must contain the real failing command");
configurePodmanTestEnvironment(repo);
(async () => {
const client = new DapClient({
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_DAP_TIMEOUT_MS:
process.env.CLUSTERFLUX_DAP_TIMEOUT_MS || "120000",
},
});
let restored = false;
try {
const initialize = client.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true,
});
await client.response(initialize, "initialize");
const launch = client.send("launch", {
entry: "build",
project,
runtimeBackend: "local-services",
});
await client.response(launch, "launch");
await client.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
const configured = client.send("configurationDone");
await client.response(configured, "configurationDone");
const failed = await client.waitFor(
(message) =>
message.type === "event" &&
message.event === "stopped" &&
message.body.reason === "exception"
);
assert.strictEqual(failed.body.allThreadsStopped, false);
const threadRequest = client.send("threads");
const threads = (await client.response(threadRequest, "threads")).body.threads;
const laneThreads = threads
.filter((thread) => /build[_ ]lane/.test(thread.name))
.sort((left, right) => left.id - right.id);
assert.strictEqual(
laneThreads.length,
1,
"only the failed recovering lane should remain a live DAP thread"
);
const recoveringThread = laneThreads[0];
const views = JSON.parse(
fs.readFileSync(path.join(project, ".clusterflux/views.json"), "utf8")
);
const nodeReport = JSON.parse(
views.inspector.find((item) => item.label === "Node report").value
);
const laneSnapshots = nodeReport.task_snapshots.snapshots.filter(
(snapshot) => snapshot.task_definition === "build_lane"
);
assert.strictEqual(laneSnapshots.length, 2);
assert.notStrictEqual(laneSnapshots[0].task, laneSnapshots[1].task);
assert(laneSnapshots.some((snapshot) => snapshot.state === "completed"));
assert(
laneSnapshots.some(
(snapshot) => snapshot.state === "failed_awaiting_action"
)
);
const startedIds = new Set(
client.messages
.filter(
(message) =>
message.type === "event" &&
message.event === "thread" &&
message.body.reason === "started"
)
.map((message) => message.body.threadId)
);
const laneStartedIds = [...startedIds]
.filter((id) => id !== 1)
.sort((left, right) => left - right)
.slice(-2);
assert.strictEqual(laneStartedIds.length, 2);
assert.notStrictEqual(laneStartedIds[0], laneStartedIds[1]);
assert(startedIds.has(recoveringThread.id));
fs.writeFileSync(sourcePath, original.replace(failing, replacement));
const restart = client.send("restartFrame", {
threadId: recoveringThread.id,
});
await client.response(restart, "restartFrame");
const terminated = await client.waitFor(
(message) =>
message.type === "event" &&
message.event === "terminated"
);
assert(terminated);
const exitedIds = new Set(
client.messages
.filter(
(message) =>
message.type === "event" &&
message.event === "thread" &&
message.body.reason === "exited"
)
.map((message) => message.body.threadId)
);
assert(exitedIds.has(laneStartedIds[0]));
assert(exitedIds.has(recoveringThread.id));
fs.writeFileSync(sourcePath, original);
restored = true;
await client.close();
console.log("Recovery build DAP restart smoke passed");
} finally {
if (!restored) fs.writeFileSync(sourcePath, original);
if (client.child.exitCode === null) client.child.kill("SIGKILL");
}
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,322 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const os = require("os");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const manifestPath = path.resolve(
process.env.CLUSTERFLUX_PUBLIC_RELEASE_MANIFEST ||
path.join(
process.env.CLUSTERFLUX_PUBLIC_RELEASE_DIR ||
path.join(repo, "target/release-candidate"),
"public-release-manifest.json"
)
);
const evidencePath = path.resolve(
process.env.CLUSTERFLUX_QUALITY_GATE_EVIDENCE_PATH ||
path.join(repo, "target/acceptance/quality-gates.json")
);
const transcriptPath = path.resolve(
process.env.CLUSTERFLUX_QUALITY_GATE_TRANSCRIPT_PATH ||
path.join(repo, "target/acceptance/quality-gates-transcript.txt")
);
function readJson(file) {
return JSON.parse(fs.readFileSync(file, "utf8"));
}
function sha256(file) {
return crypto
.createHash("sha256")
.update(fs.readFileSync(file))
.digest("hex");
}
function commandText(command, args) {
return [command, ...args]
.map((value) =>
/^[A-Za-z0-9_./:=+-]+$/.test(value)
? value
: JSON.stringify(value)
)
.join(" ");
}
function main() {
assert(fs.existsSync(manifestPath), `missing release manifest ${manifestPath}`);
const manifest = readJson(manifestPath);
fs.mkdirSync(path.dirname(evidencePath), { recursive: true });
fs.mkdirSync(path.dirname(transcriptPath), { recursive: true });
const transcript = fs.openSync(transcriptPath, "w");
const evidence = {
kind: "clusterflux-release-quality-gates",
source_commit: manifest.source_commit,
source_tree_digest: manifest.source_tree_digest,
public_tree_identity: manifest.public_tree_identity,
checks: {},
};
const runGroup = (id, commands, extra = {}) => {
const startedAt = Date.now();
const commandEvidence = [];
let status = "passed";
for (const command of commands) {
const args = command.args || [];
const cwd = command.cwd || repo;
const text = commandText(command.command, args);
fs.writeSync(transcript, `\n[${id}] ${text}\n`);
const commandStartedAt = Date.now();
const result = cp.spawnSync(command.command, args, {
cwd,
env: { ...process.env, ...(command.env || {}) },
stdio: ["ignore", transcript, transcript],
});
const durationMs = Math.max(1, Date.now() - commandStartedAt);
commandEvidence.push({
command: text,
cwd,
exit_status: result.status,
duration_ms: durationMs,
});
if (result.error || result.status !== 0) {
status = "failed";
evidence.checks[id] = {
status,
duration_ms: Math.max(1, Date.now() - startedAt),
commands: commandEvidence,
error: result.error?.message || `command exited ${result.status}`,
...extra,
};
fs.writeFileSync(evidencePath, `${JSON.stringify(evidence, null, 2)}\n`);
throw new Error(`${id} failed: ${text}`);
}
}
evidence.checks[id] = {
status,
duration_ms: Math.max(1, Date.now() - startedAt),
commands: commandEvidence,
...extra,
};
};
try {
runGroup("repository_structure", [
{ command: path.join(repo, "scripts/check-old-name.sh") },
{ command: "node", args: [path.join(repo, "scripts/check-docs.js")] },
{ command: path.join(repo, "scripts/check-code-size.sh") },
]);
runGroup("formatting", [
{ command: "cargo", args: ["fmt", "--all", "--check"] },
{
command: "cargo",
args: [
"fmt",
"--all",
"--manifest-path",
"private/hosted-policy/Cargo.toml",
"--check",
],
},
]);
runGroup("clippy_warnings_denied", [
{
command: "cargo",
args: ["clippy", "--workspace", "--all-targets", "--", "-D", "warnings"],
},
{
command: "cargo",
args: [
"clippy",
"--manifest-path",
"private/hosted-policy/Cargo.toml",
"--all-targets",
"--",
"-D",
"warnings",
],
},
]);
runGroup("public_workspace_tests", [
{
command: "cargo",
args: ["test", "--workspace", "--all-targets"],
},
{
command: "cargo",
args: ["build", "--workspace", "--all-targets"],
},
]);
runGroup("private_hosted_policy_locked_tests", [
{
command: "cargo",
args: [
"test",
"--locked",
"--manifest-path",
"private/hosted-policy/Cargo.toml",
"--all-targets",
],
},
]);
runGroup("process_lifecycle_regressions", [
{
command: "cargo",
args: [
"test",
"-p",
"clusterflux-coordinator",
"completed_main_",
],
},
{
command: "cargo",
args: [
"test",
"-p",
"clusterflux-coordinator",
"failed_main_aborts_unfinished_children_and_clears_process_debug_state",
],
},
{
command: "cargo",
args: [
"test",
"-p",
"clusterflux-coordinator",
"service_cancels_whole_process_and_blocks_new_task_launches",
],
},
]);
runGroup("wasm_example_builds", [
{
command: "cargo",
args: [
"build",
"-p",
"hello-build",
"--target",
"wasm32-unknown-unknown",
],
},
{
command: "cargo",
args: [
"build",
"-p",
"recovery-build",
"--target",
"wasm32-unknown-unknown",
],
},
{
command: "cargo",
args: [
"build",
"-p",
"runtime-conformance",
"--target",
"wasm32-unknown-unknown",
],
},
]);
runGroup("filtered_public_tree_build_and_tests", [
{ command: path.join(repo, "scripts/verify-public-split.sh") },
]);
const extensionAsset = manifest.assets.find((asset) =>
asset.name.endsWith(".vsix")
);
assert(extensionAsset, "candidate manifest omitted its VSIX");
const extensionFile = path.resolve(
path.dirname(manifestPath),
extensionAsset.file
);
assert(fs.existsSync(extensionFile), `missing candidate VSIX ${extensionFile}`);
const extensionDigest = sha256(extensionFile);
assert.strictEqual(extensionDigest, extensionAsset.sha256);
assert.strictEqual(
extensionDigest,
manifest.release_candidate.extension_sha256
);
const extractedVsix = fs.mkdtempSync(
path.join(os.tmpdir(), "clusterflux-tested-vsix-")
);
try {
runGroup(
"vscode_extension_candidate",
[
{
command: "npm",
args: ["ci", "--ignore-scripts"],
cwd: path.join(repo, "vscode-extension"),
},
{
command: "unzip",
args: ["-q", extensionFile, "-d", extractedVsix],
},
{
command: "node",
args: [path.join(repo, "scripts/vscode-extension-smoke.js")],
env: {
CLUSTERFLUX_VSCODE_EXTENSION_ROOT: path.join(
extractedVsix,
"extension"
),
},
},
],
{
candidate_vsix: {
file: extensionFile,
sha256: extensionDigest,
},
}
);
} finally {
fs.rmSync(extractedVsix, { recursive: true, force: true });
}
const publicCheckIds = [
"repository_structure",
"formatting",
"clippy_warnings_denied",
"public_workspace_tests",
"process_lifecycle_regressions",
"wasm_example_builds",
"filtered_public_tree_build_and_tests",
"vscode_extension_candidate",
];
evidence.public = {
status: "passed",
duration_ms: publicCheckIds.reduce(
(total, id) => total + evidence.checks[id].duration_ms,
0
),
independent_filtered_tree: true,
};
evidence.private = {
status: "passed",
duration_ms:
evidence.checks.formatting.duration_ms +
evidence.checks.clippy_warnings_denied.duration_ms +
evidence.checks.private_hosted_policy_locked_tests.duration_ms,
};
evidence.status = "passed";
evidence.transcript = transcriptPath;
fs.writeFileSync(evidencePath, `${JSON.stringify(evidence, null, 2)}\n`);
} finally {
fs.closeSync(transcript);
}
console.log(`Release quality gates passed: ${evidencePath}`);
}
try {
main();
} catch (error) {
console.error(error.stack || error.message);
process.exit(1);
}

View file

@ -1,73 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$repo"
release_paths=(
Cargo.toml
Cargo.lock
README.md
crates
examples
private
scripts
vscode-extension
)
existing_release_paths=()
for path in "${release_paths[@]}"; do
if [[ -e "$path" ]]; then
existing_release_paths+=("$path")
fi
done
prose_scan_paths=(
README.md
crates
examples
private
scripts
vscode-extension
)
existing_prose_scan_paths=()
for path in "${prose_scan_paths[@]}"; do
if [[ -e "$path" ]]; then
existing_prose_scan_paths+=("$path")
fi
done
scan_globs=(
--glob '!**/target/**'
--glob '!**/node_modules/**'
--glob '!scripts/release-source-scan.sh'
--glob '!scripts/rename-to-clusterflux.sh'
--glob '!scripts/check-docs.js'
)
placeholder_pattern='debugger-gate|experiments/debugger-gate|CLUSTERFLUX-DEMO|device-code-placeholder|artifact://demo|vp-local-demo'
if rg -n "${scan_globs[@]}" "$placeholder_pattern" "${existing_release_paths[@]}"; then
echo "release source scan failed: stale experiment/demo placeholder reference found" >&2
exit 1
fi
demo_setup_pattern='undocumented manual state|hidden setup|demo-only credentials?|hard-coded local paths?'
if rg -n "${scan_globs[@]}" "$demo_setup_pattern" "${existing_prose_scan_paths[@]}"; then
echo "release source scan failed: demo requires hidden setup or demo-only state" >&2
exit 1
fi
hidden_local_pattern='file://|/home/[[:alnum:]_.-]+/|/Users/[[:alnum:]_.-]+/|C:\\Users\\|https?://(localhost|127\.0\.0\.1)[^[:space:]]*/artifacts/'
if rg -n "${scan_globs[@]}" "$hidden_local_pattern" "${existing_release_paths[@]}"; then
echo "release source scan failed: hidden local path or local artifact URL found" >&2
exit 1
fi
public_wording_pattern='reddit|hacker news|lobsters|launch forum|traffic source|free tier'
if rg -n "${scan_globs[@]}" "$public_wording_pattern" "${existing_prose_scan_paths[@]}"; then
echo "release source scan failed: public-facing launch-forum/free-tier wording found" >&2
exit 1
fi
echo "Release source scan passed"

View file

@ -1,230 +0,0 @@
#!/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");

View file

@ -1,400 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const { nodeIdentity, signedNodeRequest } = require("./node-signing");
const repo = path.resolve(__dirname, "..");
const digest = (value) =>
`sha256:${crypto.createHash("sha256").update(value).digest("hex")}`;
const environmentDigest = digest("scheduler-linux-container");
const dependencyDigest = digest("scheduler-toolchain-dependencies");
const sourceDigest = digest("scheduler-source-tree");
function buildFlagshipBundle() {
const output = cp.execFileSync(
"cargo",
[
"run", "-q", "-p", "clusterflux-cli", "--bin", "clusterflux", "--",
"build", "--project", "tests/fixtures/runtime-conformance", "--json",
],
{ cwd: repo, encoding: "utf8" }
);
const report = JSON.parse(output);
const directory = path.resolve(repo, report.bundle_artifact.directory);
const manifest = JSON.parse(fs.readFileSync(path.join(directory, "manifest.json"), "utf8"));
const entrypoints = JSON.parse(
fs.readFileSync(path.join(directory, manifest.entrypoints), "utf8")
);
const entrypoint = entrypoints.find((candidate) => candidate.name === "build");
assert(entrypoint, "flagship bundle omitted build entrypoint");
const taskDescriptors = JSON.parse(
fs.readFileSync(path.join(directory, manifest.task_descriptors), "utf8")
);
const prepareSource = taskDescriptors.find(
(candidate) => candidate.name === "prepare_source"
);
assert(prepareSource, "flagship bundle omitted prepare_source task");
return {
digest: manifest.bundle_digest,
taskExport: prepareSource.export,
wasmModuleBase64: fs.readFileSync(path.join(directory, "module.wasm")).toString("base64"),
};
}
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function linuxCapabilities() {
return {
os: "Linux",
arch: "x86_64",
capabilities: [
"Command",
"Containers",
"RootlessPodman",
"SourceFilesystem",
"VfsArtifacts"
],
environment_backends: ["Container"],
source_providers: ["filesystem"]
};
}
function gitCapabilities() {
const capabilities = linuxCapabilities();
capabilities.capabilities = [...capabilities.capabilities, "SourceGit"].sort();
capabilities.source_providers = [...capabilities.source_providers, "git"].sort();
return capabilities;
}
async function attachNode(addr, node) {
const identity = nodeIdentity("scheduler-placement-smoke", node);
const attached = await send(addr, {
type: "attach_node",
tenant: "tenant",
project: "project",
node,
public_key: identity.publicKey
});
assert.strictEqual(attached.type, "node_attached");
assert.strictEqual(attached.node, node);
return identity;
}
async function reportNode(addr, node, identity, locality) {
const recorded = await send(addr, signedNodeRequest(node, identity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node,
capabilities: locality.capabilities || linuxCapabilities(),
cached_environment_digests: locality.cached_environment_digests,
dependency_cache_digests: locality.dependency_cache_digests,
source_snapshots: locality.source_snapshots,
artifact_locations: locality.artifact_locations,
direct_connectivity: locality.direct_connectivity !== false,
online: true
}));
assert.strictEqual(
recorded.type,
"node_capabilities_recorded",
JSON.stringify(recorded)
);
assert.strictEqual(recorded.node, node);
return recorded;
}
(async () => {
const bundle = buildFlagshipBundle();
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback"
],
{ cwd: repo }
);
let coordinatorStderr = "";
coordinator.stderr.on("data", (chunk) => {
coordinatorStderr += chunk.toString();
});
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const coldNode = await attachNode(addr, "cold-node");
const warmNode = await attachNode(addr, "warm-node");
const cold = await reportNode(addr, "cold-node", coldNode, {
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: false
});
assert.strictEqual(cold.node_descriptors, 1);
const warm = await reportNode(addr, "warm-node", warmNode, {
cached_environment_digests: [environmentDigest],
dependency_cache_digests: [dependencyDigest],
source_snapshots: [sourceDigest],
artifact_locations: ["toolchain-cache"]
});
assert.strictEqual(warm.node_descriptors, 2);
const reportedNodes = new Set([cold.node, warm.node]);
assert.strictEqual(reportedNodes.size, 2);
assert(reportedNodes.has("cold-node"));
assert(reportedNodes.has("warm-node"));
const inspected = await send(addr, {
type: "list_node_descriptors",
tenant: "tenant",
project: "project",
actor_user: "operator"
});
assert.strictEqual(inspected.type, "node_descriptors");
assert.strictEqual(inspected.actor, "operator");
assert.strictEqual(inspected.descriptors.length, 2);
const warmDescriptor = inspected.descriptors.find(
(descriptor) => descriptor.id === "warm-node"
);
assert(warmDescriptor, "warm node descriptor must be visible to inspector state");
assert(warmDescriptor.capabilities.capabilities.includes("Command"));
assert(warmDescriptor.capabilities.capabilities.includes("RootlessPodman"));
assert(warmDescriptor.cached_environments.includes(environmentDigest));
assert(warmDescriptor.dependency_caches.includes(dependencyDigest));
assert(warmDescriptor.source_snapshots.includes(sourceDigest));
assert(warmDescriptor.artifact_locations.includes("toolchain-cache"));
const crossScopeInspection = await send(addr, {
type: "list_node_descriptors",
tenant: "other-tenant",
project: "project",
actor_user: "operator"
});
assert.strictEqual(crossScopeInspection.type, "node_descriptors");
assert.strictEqual(crossScopeInspection.descriptors.length, 0);
const crossTenantReport = await send(addr, signedNodeRequest("warm-node", warmNode, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "other-tenant",
project: "project",
node: "warm-node",
capabilities: linuxCapabilities(),
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: true,
online: true
}));
assert.strictEqual(crossTenantReport.type, "error");
assert.match(
crossTenantReport.message,
/tenant\/project scope|node identity is not enrolled/
);
const placement = await send(addr, {
type: "schedule_task",
tenant: "tenant",
project: "project",
environment: {
os: "Linux",
arch: null,
capabilities: ["Containers", "RootlessPodman"]
},
environment_digest: environmentDigest,
required_capabilities: ["Command"],
dependency_cache: dependencyDigest,
source_snapshot: sourceDigest,
required_artifacts: ["toolchain-cache"],
prefer_node: null
});
assert.strictEqual(placement.type, "task_placement");
assert.strictEqual(placement.placement.node, "warm-node");
assert.ok(placement.placement.score > 0);
assert.ok(placement.placement.reasons.includes("warm environment cache"));
assert.ok(placement.placement.reasons.includes("warm dependency cache"));
assert.ok(placement.placement.reasons.includes("source snapshot already local"));
assert.ok(
placement.placement.reasons.includes("1 required artifact(s) already local")
);
const impossible = await send(addr, {
type: "schedule_task",
tenant: "tenant",
project: "project",
environment: null,
environment_digest: null,
required_capabilities: ["WindowsCommandDev"],
dependency_cache: null,
source_snapshot: null,
required_artifacts: [],
prefer_node: null
});
assert.strictEqual(impossible.type, "error");
assert.match(impossible.message, /WindowsCommandDev/);
const started = await send(addr, {
type: "start_process",
tenant: "tenant",
project: "project",
actor_user: "operator",
process: "vp-wait-for-git"
});
assert.strictEqual(started.type, "process_started");
const queued = await send(addr, {
type: "launch_task",
tenant: "tenant",
project: "project",
actor_user: "operator",
task_spec: {
tenant: "tenant",
project: "project",
process: "vp-wait-for-git",
task_definition: "prepare_source",
task_instance: "prepare_source-1",
dispatch: {
kind: "coordinator_node_wasm",
export: bundle.taskExport,
abi: "task_v1",
},
environment_id: null,
environment: null,
environment_digest: null,
required_capabilities: ["SourceFilesystem", "SourceGit"],
dependency_cache: null,
source_snapshot: null,
required_artifacts: [],
args: [],
vfs_epoch: started.epoch,
bundle_digest: bundle.digest,
},
wait_for_node: true,
artifact_path: "/vfs/artifacts/git-status.txt",
wasm_module_base64: bundle.wasmModuleBase64,
});
assert.strictEqual(queued.type, "error");
assert.match(queued.message, /external callers may launch only EntrypointV1/);
const gitNode = await attachNode(addr, "git-node");
const gitRecorded = await reportNode(addr, "git-node", gitNode, {
capabilities: gitCapabilities(),
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: false
});
assert.strictEqual(gitRecorded.type, "node_capabilities_recorded");
const pendingAssignment = await send(addr, signedNodeRequest("git-node", gitNode, "poll_task_assignment", {
type: "poll_task_assignment",
tenant: "tenant",
project: "project",
node: "git-node"
}));
assert.strictEqual(pendingAssignment.type, "task_assignment");
assert.strictEqual(pendingAssignment.assignment, null);
const emptyAssignment = await send(addr, signedNodeRequest("git-node", gitNode, "poll_task_assignment", {
type: "poll_task_assignment",
tenant: "tenant",
project: "project",
node: "git-node"
}));
assert.strictEqual(emptyAssignment.type, "task_assignment");
assert.strictEqual(emptyAssignment.assignment, null);
await reportNode(addr, "warm-node", warmNode, {
cached_environment_digests: [],
dependency_cache_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: false
});
const disconnectedTransfer = await send(addr, {
type: "schedule_task",
tenant: "tenant",
project: "project",
environment: null,
environment_digest: null,
required_capabilities: ["Command"],
dependency_cache: null,
source_snapshot: sourceDigest,
required_artifacts: ["toolchain-cache"],
prefer_node: null
});
assert.strictEqual(disconnectedTransfer.type, "error");
assert.match(disconnectedTransfer.message, /source snapshot unavailable/);
assert.match(disconnectedTransfer.message, /required artifact\(s\) unavailable/);
assert.match(disconnectedTransfer.message, /direct connectivity unavailable/);
} catch (error) {
if (coordinatorStderr) {
error.message = `${error.message}\ncoordinator stderr:\n${coordinatorStderr}`;
}
throw error;
} finally {
coordinator.kill("SIGTERM");
}
console.log("Scheduler placement smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,48 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const sdk = fs.readFileSync(path.join(repo, "crates/clusterflux-sdk/src/lib.rs"), "utf8");
const productRuntime = fs.readFileSync(
path.join(repo, "crates/clusterflux-sdk/src/sdk_runtime.rs"),
"utf8"
);
assert.match(sdk, /pub struct RuntimeSpawnEvent/);
assert.match(sdk, /pub debugger_visible: bool/);
assert.match(sdk, /fn register_runtime_thread/);
assert.match(sdk, /register_runtime_thread\(id, self\.name, self\.env\)/);
assert.match(sdk, /pub fn debugger_visible\(&self\) -> bool/);
assert.match(sdk, /ProductRuntimeConfig::from_env\(\)/);
assert.match(sdk, /start_remote_task\(\s*config,\s*task_id/);
assert.match(sdk, /start_guest_host_task/);
assert.match(sdk, /join_remote_task\(remote\)/);
assert.doesNotMatch(productRuntime, /"type": "launch_task"/);
assert.match(productRuntime, /native SDK task spawning requires coordinator EntrypointV1 execution/);
assert.match(productRuntime, /task_start_v1/);
assert.match(productRuntime, /task_join_v1/);
assert.match(productRuntime, /command_run_v1/);
assert.match(productRuntime, /remote_completion_observed/);
assert.match(productRuntime, /TaskJoinState::Pending/);
assert.doesNotMatch(
productRuntime,
/entry\s*\(/,
"product runtime must not invoke the submitted local Rust closure"
);
cp.execFileSync(
"cargo",
[
"test",
"-p",
"clusterflux-sdk",
"spawn_task_start_registers_debugger_visible_runtime_thread",
],
{ cwd: repo, stdio: "inherit" }
);
console.log("SDK spawn runtime smoke passed");

View file

@ -1,666 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const repo = path.resolve(__dirname, "..");
const teamArtifactDigest = `sha256:${"a".repeat(64)}`;
const teamEnvironmentDigest = `sha256:${crypto
.createHash("sha256")
.update("env-team-linux")
.digest("hex")}`;
const teamDependencyCacheDigest = `sha256:${crypto
.createHash("sha256")
.update("cargo-cache")
.digest("hex")}`;
const teamSourceDigest = `sha256:${crypto
.createHash("sha256")
.update("source-team")
.digest("hex")}`;
const coordinatorTaskModule = Buffer.from([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
const coordinatorTaskBundleDigest = `sha256:${crypto
.createHash("sha256")
.update(coordinatorTaskModule)
.digest("hex")}`;
const adminToken = "self-hosted-smoke-admin-token";
const clientSessionSecret = "self-hosted-smoke-client-session-secret";
const releaseManifestPath =
process.env.CLUSTERFLUX_PUBLIC_RELEASE_MANIFEST ||
path.join(repo, "target/public-release/public-release-manifest.json");
function sha256(value) {
return `sha256:${crypto.createHash("sha256").update(value).digest("hex")}`;
}
function digestFromParts(parts) {
const hash = crypto.createHash("sha256");
for (const value of parts) {
const bytes = Buffer.from(String(value));
const length = Buffer.alloc(8);
length.writeBigUInt64BE(BigInt(bytes.length));
hash.update(length);
hash.update(bytes);
}
return `sha256:${hash.digest("hex")}`;
}
function adminRequest(token, operation, tenant, actorUser, targetTenant, nonce) {
const issuedAtEpochSeconds = Math.floor(Date.now() / 1000);
return {
type: operation,
tenant,
actor_user: actorUser,
...(operation === "suspend_tenant" ? { target_tenant: targetTenant } : {}),
admin_proof: digestFromParts([
"clusterflux-admin-request-proof:v1",
sha256(token),
operation,
tenant,
actorUser,
targetTenant,
nonce,
issuedAtEpochSeconds,
]),
admin_nonce: nonce,
issued_at_epoch_seconds: issuedAtEpochSeconds,
};
}
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function authenticated(request, sessionSecret = clientSessionSecret) {
return {
type: "authenticated",
session_secret: sessionSecret,
request,
};
}
function linuxNodeCapabilities() {
return {
os: "Linux",
arch: "x86_64",
capabilities: ["Command", "RootlessPodman", "VfsArtifacts", "QuicDirect"],
environment_backends: ["Container"],
source_providers: ["filesystem", "git"]
};
}
function nodeIdentity(node) {
void node;
const { privateKey: privateKeyObject, publicKey } =
crypto.generateKeyPairSync("ed25519");
const publicDer = publicKey.export({
format: "der",
type: "spki",
});
return {
publicKey: `ed25519:${Buffer.from(publicDer).subarray(-32).toString("base64")}`,
privateKeyObject,
};
}
function signedRequestPayloadDigest(request) {
const canonicalize = (value, topLevel = true) => {
if (Array.isArray(value)) return value.map((entry) => canonicalize(entry, false));
if (value && typeof value === "object") {
return Object.fromEntries(
Object.entries(value)
.filter(
([key, entry]) =>
entry !== null &&
(!topLevel || !["agent_signature", "node_signature"].includes(key))
)
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
.map(([key, entry]) => [key, canonicalize(entry, false)])
);
}
return value;
};
return `sha256:${crypto
.createHash("sha256")
.update(JSON.stringify(canonicalize(request)))
.digest("hex")}`;
}
function nodeSignatureMessage(
node,
requestKind,
payloadDigest,
nonce,
issuedAtEpochSeconds
) {
const parts = [
"clusterflux-node-request-signature:v2",
node,
requestKind,
payloadDigest,
nonce,
String(issuedAtEpochSeconds),
];
return Buffer.concat(
parts.flatMap((part) => [
Buffer.from(`${Buffer.byteLength(part)}:`),
Buffer.from(part),
Buffer.from("\n"),
])
);
}
function signedNodeHeartbeat(tenant, project, node, identity) {
const request = { type: "node_heartbeat", tenant, project, node };
const nonce = `self-hosted-heartbeat-${process.pid}-${Date.now()}`;
const issuedAt = Math.floor(Date.now() / 1000);
const signature = crypto.sign(
null,
nodeSignatureMessage(
node,
"node_heartbeat",
signedRequestPayloadDigest(request),
nonce,
issuedAt
),
identity.privateKeyObject
);
return {
nonce,
issued_at_epoch_seconds: issuedAt,
signature: `ed25519:${signature.toString("base64")}`,
};
}
function signedNodeRequest(node, identity, requestKind, request) {
return {
type: "signed_node",
node,
node_signature: signedNodeHeartbeatForKind(node, identity, requestKind, request),
request,
};
}
function signedNodeHeartbeatForKind(node, identity, requestKind, request) {
const nonce = `${requestKind}-${process.pid}-${Date.now()}`;
const issuedAt = Math.floor(Date.now() / 1000);
const signature = crypto.sign(
null,
nodeSignatureMessage(
node,
requestKind,
signedRequestPayloadDigest(request),
nonce,
issuedAt
),
identity.privateKeyObject
);
return {
nonce,
issued_at_epoch_seconds: issuedAt,
signature: `ed25519:${signature.toString("base64")}`,
};
}
function commandOutput(command, args) {
try {
return cp
.execFileSync(command, args, {
cwd: repo,
encoding: "utf8",
stdio: ["ignore", "pipe", "ignore"],
})
.trim();
} catch (_) {
return null;
}
}
function runJson(command, args, options = {}) {
return JSON.parse(
cp.execFileSync(command, args, {
cwd: options.cwd || repo,
encoding: "utf8",
input: options.input,
})
);
}
function expectedSourceCommit() {
return (
process.env.CLUSTERFLUX_ACCEPTANCE_COMMIT ||
commandOutput("git", ["rev-parse", "HEAD"])
);
}
function readReleaseManifest() {
if (!fs.existsSync(releaseManifestPath)) return null;
const manifest = JSON.parse(fs.readFileSync(releaseManifestPath, "utf8"));
if (manifest.kind !== "clusterflux-public-release") return null;
const expectedCommit = expectedSourceCommit();
if (expectedCommit && manifest.source_commit !== expectedCommit) return null;
return manifest;
}
function releaseIdentity() {
const manifest = readReleaseManifest();
return {
sourceCommit: manifest ? manifest.source_commit : expectedSourceCommit(),
releaseName:
(manifest && manifest.release_name) ||
process.env.CLUSTERFLUX_PUBLIC_RELEASE_NAME ||
null,
};
}
async function attachTrustedNode(addr, node, capabilities = linuxNodeCapabilities()) {
const identity = nodeIdentity(node);
const grant = await send(addr, authenticated({
type: "create_node_enrollment_grant",
ttl_seconds: 900,
}));
assert.strictEqual(grant.type, "node_enrollment_grant_created");
const attached = await send(addr, {
type: "exchange_node_enrollment_grant",
tenant: "team",
project: "self-hosted",
node,
public_key: identity.publicKey,
enrollment_grant: grant.grant,
});
assert.strictEqual(attached.type, "node_enrollment_exchanged");
const heartbeat = await send(addr, {
type: "node_heartbeat",
tenant: "team",
project: "self-hosted",
node,
node_signature: signedNodeHeartbeat("team", "self-hosted", node, identity)
});
assert.strictEqual(heartbeat.type, "node_heartbeat");
const reported = await send(addr, signedNodeRequest(node, identity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "team",
project: "self-hosted",
node,
capabilities,
cached_environment_digests: [teamEnvironmentDigest],
dependency_cache_digests: [teamDependencyCacheDigest],
source_snapshots: [teamSourceDigest],
artifact_locations: [],
direct_connectivity: true,
online: true
}));
assert.strictEqual(reported.type, "node_capabilities_recorded");
return identity;
}
(async () => {
const release = releaseIdentity();
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0"
],
{
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_ADMIN_TOKEN: adminToken,
CLUSTERFLUX_SELF_HOSTED_SESSION_SECRET: clientSessionSecret,
CLUSTERFLUX_SELF_HOSTED_TENANT: "team",
CLUSTERFLUX_SELF_HOSTED_PROJECT: "self-hosted",
CLUSTERFLUX_SELF_HOSTED_USER: "developer",
},
}
);
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual(ready.client_authority, "strict");
assert.strictEqual(ready.self_hosted_session_bootstrapped, true);
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const forgedBodyAuthority = await send(addr, {
type: "start_process",
tenant: "victim-tenant",
project: "victim-project",
actor_user: "forged-user",
process: "vp-forged",
});
assert.strictEqual(forgedBodyAuthority.type, "error");
assert.match(forgedBodyAuthority.message, /body.*identity.*not authority/i);
const wrongSession = await send(
addr,
authenticated({ type: "auth_status" }, "wrong-session-secret")
);
assert.strictEqual(wrongSession.type, "error");
assert.match(wrongSession.message, /session.*not recognized|not recognized.*session/i);
const authStatus = await send(addr, authenticated({ type: "auth_status" }));
assert.strictEqual(authStatus.type, "auth_status");
assert.strictEqual(authStatus.tenant, "team");
assert.strictEqual(authStatus.project, "self-hosted");
assert.strictEqual(authStatus.actor, "developer");
const missingAdminCredential = await send(
addr,
adminRequest("", "admin_status", "team", "forged-admin", "team", "admin-empty")
);
assert.strictEqual(missingAdminCredential.type, "error");
assert.match(missingAdminCredential.message, /admin.*proof.*invalid/i);
const wrongAdminCredential = await send(
addr,
adminRequest(
"wrong-token",
"admin_status",
"team",
"forged-admin",
"team",
"admin-wrong"
)
);
assert.strictEqual(wrongAdminCredential.type, "error");
assert.match(wrongAdminCredential.message, /admin.*proof.*invalid/i);
const replayableAdminRequest = adminRequest(
adminToken,
"admin_status",
"team",
"self-hosted-admin",
"team",
"admin-replay"
);
const directAdminStatus = await send(addr, replayableAdminRequest);
assert.strictEqual(directAdminStatus.type, "admin_status");
const replayedAdminStatus = await send(addr, replayableAdminRequest);
assert.strictEqual(replayedAdminStatus.type, "error");
assert.match(replayedAdminStatus.message, /nonce was already used/i);
const cargoTargetDir = path.resolve(
process.env.CARGO_TARGET_DIR || path.join(repo, "target")
);
const cliBin = path.join(
cargoTargetDir,
"debug",
process.platform === "win32" ? "clusterflux.exe" : "clusterflux"
);
const selfHostedCliProject = path.join(
repo,
"target/acceptance/self-hosted-cli-project"
);
fs.rmSync(selfHostedCliProject, { recursive: true, force: true });
fs.mkdirSync(selfHostedCliProject, { recursive: true });
const cliConnect = runJson(
cliBin,
[
"auth",
"connect-self-hosted",
"--coordinator",
ready.listen,
"--tenant",
"team",
"--project-id",
"self-hosted",
"--user",
"developer",
"--session-secret-stdin",
"--json",
],
{ cwd: selfHostedCliProject, input: `${clientSessionSecret}\n` }
);
assert.strictEqual(cliConnect.status, "connected");
assert.strictEqual(cliConnect.session_secret_read_from_stdin, true);
assert.strictEqual(cliConnect.session_secret_exposed_in_report, false);
assert.strictEqual(cliConnect.coordinator_response.type, "auth_status");
const sessionPath = path.join(
selfHostedCliProject,
".clusterflux/session.json"
);
const storedSession = JSON.parse(fs.readFileSync(sessionPath, "utf8"));
assert.strictEqual(storedSession.kind, "self_hosted");
assert.strictEqual(storedSession.session_secret, clientSessionSecret);
assert.strictEqual(storedSession.provider_tokens_exposed_to_cli, false);
assert.strictEqual(storedSession.provider_tokens_sent_to_nodes, false);
if (process.platform !== "win32") {
assert.strictEqual(fs.statSync(sessionPath).mode & 0o777, 0o600);
}
const cliAuthStatus = runJson(
cliBin,
["auth", "status", "--json"],
{ cwd: selfHostedCliProject }
);
assert.strictEqual(cliAuthStatus.active_coordinator, ready.listen);
assert.strictEqual(
cliAuthStatus.coordinator_account_status.used_cli_session_credential,
true
);
assert.strictEqual(
cliAuthStatus.coordinator_account_status.coordinator_response_type,
"auth_status"
);
const cliAdminStatus = runJson(cliBin, [
"admin",
"status",
"--coordinator",
ready.listen,
"--tenant",
"team",
"--user",
"self-hosted-admin",
"--admin-token",
adminToken,
"--json",
]);
assert.strictEqual(cliAdminStatus.response.type, "admin_status");
assert.strictEqual(cliAdminStatus.suspended, false);
const cliAdminSuspend = runJson(cliBin, [
"admin",
"suspend-tenant",
"--coordinator",
ready.listen,
"--tenant",
"team",
"--user",
"self-hosted-admin",
"--target-tenant",
"admin-probe-tenant",
"--admin-token",
adminToken,
"--yes",
"--json",
]);
assert.strictEqual(cliAdminSuspend.response.type, "tenant_suspended");
assert.strictEqual(cliAdminSuspend.suspended, true);
const cliAdminProbeStatus = runJson(cliBin, [
"admin",
"status",
"--coordinator",
ready.listen,
"--tenant",
"admin-probe-tenant",
"--user",
"self-hosted-admin",
"--admin-token",
adminToken,
"--json",
]);
assert.strictEqual(cliAdminProbeStatus.suspended, true);
const teamLinuxA = await attachTrustedNode(addr, "team-linux-a");
const teamLinuxBCapabilities = linuxNodeCapabilities();
teamLinuxBCapabilities.capabilities = teamLinuxBCapabilities.capabilities.filter(
(capability) => capability !== "VfsArtifacts"
);
await attachTrustedNode(addr, "team-linux-b", teamLinuxBCapabilities);
const placement = await send(addr, authenticated({
type: "schedule_task",
environment: {
os: "Linux",
arch: "x86_64",
capabilities: ["Command", "QuicDirect"]
},
environment_digest: teamEnvironmentDigest,
required_capabilities: ["VfsArtifacts"],
source_snapshot: teamSourceDigest,
required_artifacts: [],
prefer_node: "team-linux-a"
}));
assert.strictEqual(placement.type, "task_placement");
assert.strictEqual(placement.placement.node, "team-linux-a");
assert(placement.placement.reasons.includes("preferred node"));
assert(placement.placement.reasons.includes("warm environment cache"));
assert(placement.placement.reasons.includes("source snapshot already local"));
const started = await send(addr, authenticated({
type: "start_process",
process: "vp-team-build",
restart: false,
}));
assert.strictEqual(started.type, "process_started");
const reconnected = await send(addr, signedNodeRequest("team-linux-a", teamLinuxA, "reconnect_node", {
type: "reconnect_node",
tenant: "team",
project: "self-hosted",
node: "team-linux-a",
process: "vp-team-build",
epoch: started.epoch
}));
assert.strictEqual(reconnected.type, "node_reconnected");
const launched = await send(addr, authenticated({
type: "launch_task",
task_spec: {
tenant: "team",
project: "self-hosted",
process: "vp-team-build",
task_definition: "compile-linux",
task_instance: "compile-linux",
dispatch: {
kind: "coordinator_node_wasm",
export: "compile_linux",
abi: "task_v1",
},
environment_id: null,
environment: null,
environment_digest: null,
required_capabilities: ["VfsArtifacts"],
dependency_cache: null,
source_snapshot: null,
required_artifacts: [],
args: [],
vfs_epoch: started.epoch,
bundle_digest: coordinatorTaskBundleDigest,
},
wait_for_node: false,
artifact_path: "/vfs/artifacts/team-output.txt",
wasm_module_base64: coordinatorTaskModule.toString("base64"),
}));
assert.strictEqual(launched.type, "error", JSON.stringify(launched));
assert.match(launched.message, /external callers may launch only EntrypointV1/);
const reportPath = path.join(repo, "target/acceptance/core-coordinator-compat.json");
fs.mkdirSync(path.dirname(reportPath), { recursive: true });
fs.writeFileSync(
reportPath,
`${JSON.stringify(
{
kind: "clusterflux-core-coordinator-compatibility",
source_commit: release.sourceCommit,
release_name: release.releaseName,
coordinator_implementation: "standalone-core-coordinator",
coordinator_addr: ready.listen,
client_authority: ready.client_authority,
authenticated_session: authStatus.authenticated,
forged_body_authority_denied: forgedBodyAuthority.type,
wrong_session_denied: wrongSession.type,
ping: "pong",
nodes: ["team-linux-a", "team-linux-b"],
task_placement: placement.type,
process_started: started.type,
external_task_v1_denied: launched.type,
self_hosted_admin: {
missing_credential_denied: missingAdminCredential.type,
wrong_credential_denied: wrongAdminCredential.type,
nonce_bound_proof_succeeded: directAdminStatus.type,
replay_denied: replayedAdminStatus.type,
cli_status: cliAdminStatus.response.type,
cli_suspend: cliAdminSuspend.response.type,
suspended_state_observed: cliAdminProbeStatus.suspended,
},
self_hosted_cli: {
connected: cliConnect.status,
secret_read_from_stdin: cliConnect.session_secret_read_from_stdin,
secret_exposed_in_report: cliConnect.session_secret_exposed_in_report,
session_file_mode:
process.platform === "win32"
? "windows-best-effort"
: (fs.statSync(sessionPath).mode & 0o777).toString(8),
authenticated_status:
cliAuthStatus.coordinator_account_status.coordinator_response_type,
},
},
null,
2
)}\n`
);
} finally {
coordinator.kill("SIGTERM");
}
console.log("Self-hosted coordinator smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,221 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const { nodeIdentity, signedNodeRequest } = require("./node-signing");
const repo = path.resolve(__dirname, "..");
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function sourceCapableNode(sourceProviders = ["git"]) {
return {
os: "Linux",
arch: "x86_64",
capabilities: ["Command", "SourceFilesystem", "SourceGit"],
environment_backends: [],
source_providers: sourceProviders
};
}
(async () => {
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback"
],
{ cwd: repo }
);
let coordinatorStderr = "";
coordinator.stderr.on("data", (chunk) => {
coordinatorStderr += chunk.toString();
});
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const pending = await send(addr, {
type: "request_source_preparation",
tenant: "tenant",
project: "project",
provider: "Git"
});
assert.strictEqual(pending.type, "source_preparation");
assert.strictEqual(pending.status.preparation.tenant, "tenant");
assert.strictEqual(pending.status.preparation.project, "project");
assert.strictEqual(pending.status.preparation.provider, "Git");
assert.strictEqual(
pending.status.preparation.coordinator_requires_checkout_access,
false
);
assert.deepStrictEqual(pending.status.preparation.required_capabilities, [
"SourceGit"
]);
assert.match(pending.status.disposition.Pending.reason, /waiting|node/i);
const nodeIdentities = new Map();
for (const node of ["source-cold", "source-ready"]) {
const identity = nodeIdentity("source-preparation-smoke", node);
nodeIdentities.set(node, identity);
const attached = await send(addr, {
type: "attach_node",
tenant: "tenant",
project: "project",
node,
public_key: identity.publicKey
});
assert.strictEqual(attached.type, "node_attached");
}
const cold = await send(addr, signedNodeRequest("source-cold", nodeIdentities.get("source-cold"), "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: "source-cold",
capabilities: sourceCapableNode(),
cached_environment_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: true,
online: true
}));
assert.strictEqual(cold.type, "node_capabilities_recorded");
const readyReport = await send(addr, signedNodeRequest("source-ready", nodeIdentities.get("source-ready"), "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: "source-ready",
capabilities: sourceCapableNode(),
cached_environment_digests: [],
source_snapshots: [],
artifact_locations: [],
direct_connectivity: true,
online: true
}));
assert.strictEqual(readyReport.type, "node_capabilities_recorded");
const assigned = await send(addr, {
type: "request_source_preparation",
tenant: "tenant",
project: "project",
provider: "Git"
});
assert.strictEqual(assigned.type, "source_preparation");
assert(["source-cold", "source-ready"].includes(assigned.status.disposition.Assigned.node));
assert.strictEqual(
assigned.status.preparation.coordinator_requires_checkout_access,
false
);
const crossTenantCompletion = await send(addr, signedNodeRequest("source-ready", nodeIdentities.get("source-ready"), "complete_source_preparation", {
type: "complete_source_preparation",
tenant: "other",
project: "project",
node: "source-ready",
provider: "Git",
source_snapshot: "sha256:source-prepared"
}));
assert.strictEqual(crossTenantCompletion.type, "error");
assert.match(
crossTenantCompletion.message,
/tenant\/project scope|node identity is not enrolled/i
);
const completed = await send(addr, signedNodeRequest("source-ready", nodeIdentities.get("source-ready"), "complete_source_preparation", {
type: "complete_source_preparation",
tenant: "tenant",
project: "project",
node: "source-ready",
provider: "Git",
source_snapshot: "sha256:source-prepared"
}));
assert.strictEqual(completed.type, "source_preparation_completed");
assert.strictEqual(completed.node, "source-ready");
assert.strictEqual(completed.provider, "Git");
assert.strictEqual(completed.source_snapshot, "sha256:source-prepared");
const placement = await send(addr, {
type: "schedule_task",
tenant: "tenant",
project: "project",
environment: null,
environment_digest: null,
required_capabilities: ["SourceGit"],
source_snapshot: "sha256:source-prepared",
required_artifacts: [],
prefer_node: null
});
assert.strictEqual(placement.type, "task_placement");
assert.strictEqual(placement.placement.node, "source-ready");
assert(
placement.placement.reasons.includes("source snapshot already local"),
"completed source preparation must update node source locality"
);
} catch (error) {
if (coordinatorStderr) {
error.message = `${error.message}\ncoordinator stderr:\n${coordinatorStderr}`;
}
throw error;
} finally {
coordinator.kill("SIGTERM");
}
console.log("Source preparation smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,197 +0,0 @@
#!/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 tenant-isolation evidence: ${name}`);
}
const auth = read("crates/clusterflux-core/src/auth.rs");
const artifact = read("crates/clusterflux-core/src/artifact.rs");
const operatorPanel = read("crates/clusterflux-core/src/operator_panel.rs");
const source = read("crates/clusterflux-core/src/source.rs");
const coordinatorService = [
read("crates/clusterflux-coordinator/src/service.rs"),
read("crates/clusterflux-coordinator/src/service/routing.rs"),
read("crates/clusterflux-coordinator/src/service/nodes.rs"),
read("crates/clusterflux-coordinator/src/service/keys.rs"),
read("crates/clusterflux-coordinator/src/service/artifacts.rs"),
read("crates/clusterflux-coordinator/src/service/processes.rs"),
read("crates/clusterflux-coordinator/src/service/process_launch.rs"),
read("crates/clusterflux-coordinator/src/service/tests.rs"),
].join("\n");
const artifactDownloadSmoke = read("scripts/artifact-download-smoke.js");
const operatorPanelSmoke = read("scripts/operator-panel-smoke.js");
const schedulerSmoke = read("scripts/scheduler-placement-smoke.js");
const sourcePreparationSmoke = read("scripts/source-preparation-smoke.js");
const liveSmoke = read("scripts/cli-happy-path-live-smoke.js");
for (const [name, pattern] of [
["auth contexts carry tenant and project", /pub struct AuthContext[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId/],
["enrollment grants carry tenant and project", /pub struct EnrollmentGrant[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId/],
["node credentials carry tenant and project", /pub struct NodeCredential[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId/],
["same tenant/project denies tenant mismatch", /pub fn same_tenant_project[\s\S]*tenant mismatch/],
["same tenant/project denies project mismatch", /pub fn same_tenant_project[\s\S]*project mismatch/],
["auth unit denies cross-tenant access", /fn tenant_project_scope_denies_cross_tenant_access\(\)/],
]) {
expect(auth, name, pattern);
}
for (const [name, pattern] of [
["artifact metadata carries tenant and project", /pub struct ArtifactMetadata[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId/],
["download links carry tenant project process and actor", /pub struct DownloadLink[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId[\s\S]*pub process: ProcessId[\s\S]*pub actor: Actor/],
["downloads authorize against scoped metadata", /let authz = same_tenant_project\(context, &scope\)/],
["artifact test denies cross-tenant download", /fn cross_tenant_download_is_denied_even_with_known_artifact_id\(\)/],
["artifact test denies cross-project download", /fn cross_project_download_is_denied_even_with_known_artifact_id\(\)/],
]) {
expect(artifact, name, pattern);
}
for (const [name, pattern] of [
["panel state carries tenant project and process", /pub struct PanelState[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId[\s\S]*pub process: ProcessId/],
["panel events carry tenant project and process", /pub struct PanelEvent[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId[\s\S]*pub process: ProcessId/],
["panel events reject scope mismatch", /PanelError::ScopeMismatch/],
["panel scope validation compares tenant project process", /self\.tenant != event\.tenant[\s\S]*self\.project != event\.project[\s\S]*self\.process != event\.process/],
]) {
expect(operatorPanel, name, pattern);
}
expect(
source,
"source preparation carries tenant and project",
/pub struct SourcePreparation[\s\S]*pub tenant: TenantId[\s\S]*pub project: ProjectId/
);
for (const [name, pattern] of [
["project creation rejects foreign tenant reuse", /project id is outside the signed-in tenant scope/],
["project selection rejects foreign tenant", /project is outside the signed-in tenant scope/],
["project listing uses tenant-scoped context", /CoordinatorRequest::ListProjects[\s\S]*list_projects\(&context\)/],
[
"node capability reports resolve the full enrolled scope",
/NodeScopeKey::from_refs\(&tenant, &project, &node\)[\s\S]*node_identity\(&tenant, &project, &node\)/,
],
["operator panel stop state is tenant/project/process keyed", /type PanelStopKey = \(TenantId, ProjectId, ProcessId\)/],
["download service hides cross-tenant artifact existence", /cross_tenant\.to_string\(\)\.contains\("does not exist"\)/],
["download service hides cross-project artifact existence", /cross_project\.to_string\(\)\.contains\("does not exist"\)/],
["node capability test rejects cross-scope report", /fn service_rejects_node_capability_report_outside_enrollment_scope\(\)/],
["source preparation test rejects cross-scope completion", /fn service_rejects_source_preparation_completion_outside_node_scope\(\)/],
]) {
expect(coordinatorService, name, pattern);
}
for (const [name, sourceText, patterns] of [
[
"artifact download smoke",
artifactDownloadSmoke,
[
/const crossTenant = await send/,
/const crossProject = await send/,
/const crossTenantOpen = await send/,
/const crossProjectOpen = await send/,
/artifact does not exist/,
/token is invalid/,
],
],
[
"operator panel smoke",
operatorPanelSmoke,
[/const crossTenant = await send/, /render_operator_panel/, /scope\|tenant\|project/],
],
[
"scheduler and capability smoke",
schedulerSmoke,
[
/const crossScopeInspection = await send/,
/assert\.strictEqual\(crossScopeInspection\.descriptors\.length, 0\)/,
/const crossTenantReport = await send/,
/tenant\\\/project scope/,
],
],
[
"source preparation smoke",
sourcePreparationSmoke,
[/const crossTenantCompletion = await send/, /complete_source_preparation/, /tenant\\\/project scope/i],
],
]) {
for (const pattern of patterns) {
expect(sourceText, name, pattern);
}
}
for (const [name, pattern] of [
[
"live same-ID collision refreshes first-tenant metadata before the second build",
/const firstCollisionHelloBuild = await runHostedHelloBuild[\s\S]*secondHelloBuild = await runHostedHelloBuild/,
],
[
"live same-ID collision re-reads the fresh first-tenant process",
/"--process",[\s\S]*firstCollisionHelloBuild\.process[\s\S]*candidate\.artifact === firstCollisionHelloBuild\.artifact/,
],
]) {
expect(liveSmoke, name, pattern);
}
const hostedLibRoot = maybeRead(["private", "hosted-policy", "src", "lib.rs"]);
const hostedServiceSource = maybeRead([
"private",
"hosted-policy",
"src",
"bin",
"clusterflux-hosted-service.rs",
]);
const hostedLib = hostedLibRoot;
const hostedSmoke = maybeRead([
"private",
"hosted-policy",
"scripts",
"hosted-client-compat-smoke.js",
]);
if (hostedLib && hostedServiceSource && hostedSmoke) {
for (const [name, pattern] of [
["hosted private layer is a compact identity broker", /pub struct HostedIdentityBroker[\s\S]*cli_session_ttl_seconds/],
["hosted private layer has no parallel coordinator", /Runtime, persistence, nodes, processes,[\s\S]*remain owned by public CoordinatorService/],
["hosted service delegates Client state to Core", /core_coordinator: CoordinatorService/],
["hosted login creates project through Core", /issue_cli_session[\s\S]*AuthenticatedCoordinatorRequest::CreateProject/],
]) {
expect(`${hostedLib}\n${hostedServiceSource}`, name, pattern);
}
for (const forbidden of [
"HostedCommunityControlPlane",
"HostedObservabilitySnapshot",
"agent_public_keys: BTreeMap",
"node_statuses: BTreeMap",
"process_statuses: BTreeMap",
"debug_sessions: BTreeMap",
]) {
assert(
!hostedLib.includes(forbidden),
`private hosted policy must not reimplement Core state: ${forbidden}`
);
}
for (const [name, pattern] of [
["client-supplied identity is denied", /const forged = await sendHostedControl[\s\S]*authenticated CLI session/],
["second OIDC subject receives a different tenant", /assert\.notStrictEqual\(victimLogin\.session\.tenant, session\.tenant\)/],
["cross-tenant process events are denied", /const crossTenantTaskEventsDenied = await sendHostedControl[\s\S]*vp-victim[\s\S]*scope\|denied\|unauthorized/],
]) {
expect(hostedSmoke, name, pattern);
}
}
console.log("Tenant isolation contract smoke passed");

View file

@ -1,120 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const repo = path.resolve(__dirname, "..");
function read(file) {
return fs.readFileSync(path.join(repo, file), "utf8");
}
function extractBalancedBlock(source, marker) {
const start = source.indexOf(marker);
assert(start >= 0, `missing marker ${marker}`);
const open = source.indexOf("{", start);
assert(open >= 0, `missing opening brace for ${marker}`);
let depth = 0;
for (let index = open; index < source.length; index += 1) {
const char = source[index];
if (char === "{") depth += 1;
if (char === "}") {
depth -= 1;
if (depth === 0) return source.slice(start, index + 1);
}
}
throw new Error(`missing closing brace for ${marker}`);
}
function extractEnumVariant(source, variant) {
const marker = ` ${variant} {`;
return extractBalancedBlock(source, marker);
}
const forbiddenUserSessionCredentials =
/\b(BrowserSession|CliDeviceSession|BrowserLoginFlow|CliLoginFlow|authorization_url|verification_url|device_code|access_token|refresh_token|provider_token|provider_tokens|session_token|user_token|oauth_token)\b/i;
function assertNoUserSessionCredential(surface, text) {
assert.doesNotMatch(
text,
forbiddenUserSessionCredentials,
`${surface} must not carry user OAuth/browser/session credentials`
);
}
const coordinatorService = `${read("crates/clusterflux-coordinator/src/service/protocol.rs")}\n${read("crates/clusterflux-coordinator/src/service/protocol/responses.rs")}`;
for (const variant of [
"AdminStatus",
"SuspendTenant",
"AttachNode",
"RegisterAgentPublicKey",
"ListAgentPublicKeys",
"RotateAgentPublicKey",
"RevokeAgentPublicKey",
"NodeHeartbeat",
"ReportNodeCapabilities",
"RevokeNodeCredential",
"RequestRendezvous",
"RequestSourcePreparation",
"CompleteSourcePreparation",
"StartProcess",
"ReconnectNode",
"CancelTask",
"CancelProcess",
"PollTaskControl",
"RestartTask",
"DebugAttach",
"TaskCompleted",
]) {
assertNoUserSessionCredential(
`CoordinatorRequest::${variant}`,
extractEnumVariant(coordinatorService, variant)
);
}
const nodeRuntime = [
read("crates/clusterflux-node/src/lib.rs"),
read("crates/clusterflux-node/src/command_runner.rs"),
].join("\n");
for (const marker of [
"pub struct LinuxCommandRunPlan",
"pub struct LinuxCommandTaskOutput",
"pub struct CapturedCommandLogs",
"pub struct VirtualThreadCommand",
"pub struct CommandOutput",
]) {
assertNoUserSessionCredential(marker, extractBalancedBlock(nodeRuntime, marker));
}
const coreExecution = read("crates/clusterflux-core/src/execution.rs");
assertNoUserSessionCredential(
"CommandInvocation",
extractBalancedBlock(coreExecution, "pub struct CommandInvocation")
);
const dapAdapter = read("crates/clusterflux-dap/src/variables.rs");
assertNoUserSessionCredential(
"DAP variables response",
extractBalancedBlock(dapAdapter, "fn variables_response")
);
const panel = read("crates/clusterflux-core/src/operator_panel.rs");
assertNoUserSessionCredential(
"PanelEvent",
extractBalancedBlock(panel, "pub struct PanelEvent")
);
const auth = read("crates/clusterflux-core/src/auth.rs");
assert.match(
auth,
/task_credentials_do_not_contain_user_session/,
"core auth must keep the task credential user-session guard"
);
assert.match(
auth,
/CredentialKind::BrowserSession \| CredentialKind::CliDeviceSession/,
"task credential guard must reject browser and CLI sessions"
);
console.log("User session token boundary smoke passed");

View file

@ -1,72 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
source_commit="$(git -C "$repo_root" rev-parse HEAD)"
export CLUSTERFLUX_ACCEPTANCE_COMMIT="$source_commit"
tmp_dir="$(mktemp -d)"
trap 'rm -rf "$tmp_dir"' EXIT
tar \
--exclude='./.git' \
--exclude='./target' \
--exclude='./private' \
--exclude='./internal' \
--exclude='./experiments' \
--exclude='./.clusterflux' \
--exclude='./vscode-extension/node_modules' \
--exclude='./scripts/containers-home' \
-C "$repo_root" \
-cf - . | tar -C "$tmp_dir" -xf -
if find "$tmp_dir" -path "$tmp_dir/private" -print -quit | grep -q .; then
echo "private directory leaked into public split" >&2
exit 1
fi
if find "$tmp_dir" -path "$tmp_dir/experiments" -print -quit | grep -q .; then
echo "experiments directory leaked into public split" >&2
exit 1
fi
if find "$tmp_dir" -path "$tmp_dir/internal" -print -quit | grep -q .; then
echo "internal directory leaked into public split" >&2
exit 1
fi
(cd "$tmp_dir" && scripts/check-old-name.sh)
(cd "$tmp_dir" && CLUSTERFLUX_FILTERED_PUBLIC_TREE=1 node scripts/check-docs.js)
(cd "$tmp_dir" && scripts/check-code-size.sh)
(cd "$tmp_dir" && node scripts/resource-metering-contract-smoke.js)
(cd "$tmp_dir" && node scripts/hostile-input-contract-smoke.js)
(cd "$tmp_dir" && node scripts/tenant-isolation-contract-smoke.js)
(cd "$tmp_dir" && cargo fmt --all --check)
CARGO_TARGET_DIR="$tmp_dir/target" cargo test \
--workspace \
--all-targets \
--manifest-path "$tmp_dir/Cargo.toml"
CARGO_TARGET_DIR="$tmp_dir/target" cargo build \
--workspace \
--all-targets \
--manifest-path "$tmp_dir/Cargo.toml"
(cd "$tmp_dir" && node scripts/cli-install-smoke.js)
(cd "$tmp_dir" && node scripts/flagship-demo-smoke.js)
(cd "$tmp_dir" && node scripts/cli-local-run-smoke.js)
(cd "$tmp_dir" && node scripts/node-attach-smoke.js)
(cd "$tmp_dir" && node scripts/vscode-extension-smoke.js)
(cd "$tmp_dir" && node scripts/vscode-f5-smoke.js)
(cd "$tmp_dir" && node scripts/artifact-download-smoke.js)
(cd "$tmp_dir" && node scripts/artifact-export-smoke.js)
public_digest="$(
find "$tmp_dir" \
-path "$tmp_dir/target" -prune -o \
-type f -print0 \
| LC_ALL=C sort -z \
| xargs -0 sha256sum \
| sha256sum \
| cut -d' ' -f1
)"
printf 'Filtered public tree passed: commit=%s digest=sha256:%s\n' \
"$source_commit" \
"$public_digest"

View file

@ -1,233 +0,0 @@
#!/usr/bin/env node
const fs = require("fs");
const os = require("os");
const path = require("path");
const assert = require("assert");
const extensionRoot = path.resolve(
process.env.CLUSTERFLUX_VSCODE_EXTENSION_ROOT ||
path.join(__dirname, "../vscode-extension")
);
const extension = require(path.join(extensionRoot, "extension.js"));
const packageJson = require(path.join(extensionRoot, "package.json"));
const extensionSource = fs.readFileSync(
path.join(extensionRoot, "extension.js"),
"utf8"
);
const repo = path.resolve(__dirname, "..");
assert.strictEqual(packageJson.main, "./extension.js");
assert(fs.existsSync(path.join(extensionRoot, packageJson.main)));
assert.deepStrictEqual(packageJson.dependencies || {}, {});
const root = fs.mkdtempSync(path.join(os.tmpdir(), "clusterflux-vscode-"));
fs.mkdirSync(path.join(root, "envs/linux"), { recursive: true });
fs.writeFileSync(path.join(root, "envs/linux/Containerfile"), "FROM alpine\n");
fs.mkdirSync(path.join(root, ".clusterflux"), { recursive: true });
fs.writeFileSync(
extension.clusterfluxViewStatePath(root),
JSON.stringify({
nodes: [{ id: "node-linux", status: "online", capabilities: "Command RootlessPodman" }],
processes: [{ id: "vp-build", status: "running", entry: "build" }],
logs: [{ task: "compile-linux", message: "stdout=12 stderr=0", bytes: 12 }],
artifacts: [{ path: "/vfs/artifacts/app.tar.zst", status: "retained", size: 12 }],
inspector: [{ label: "debug", value: "attached" }]
})
);
const envs = extension.discoverEnvironmentNames(root);
assert.deepStrictEqual(envs, ["linux"]);
const diagnostics = extension.diagnoseEnvReferences(
'let _ = env!("linux"); let _ = env!("windows");',
envs
);
assert.strictEqual(diagnostics.length, 1);
assert.strictEqual(diagnostics[0].name, "windows");
assert.match(diagnostics[0].message, /envs\/windows\/Containerfile/);
const inspectCommand = extension.bundleInspectCommand(root, "/repo");
assert.strictEqual(inspectCommand.command, "cargo");
assert.deepStrictEqual(inspectCommand.args.slice(0, 8), [
"run",
"-q",
"-p",
"clusterflux-cli",
"--bin",
"clusterflux",
"--",
"bundle"
]);
assert(inspectCommand.args.includes("inspect"));
assert(inspectCommand.args.includes("--project"));
assert(inspectCommand.args.includes(root));
assert(inspectCommand.args.includes("--json"));
const refreshed = extension.refreshBundleBeforeLaunch(root, "/repo", (command, args, options) => {
assert.strictEqual(command, "cargo");
assert(args.includes("bundle"));
assert.strictEqual(options.cwd, "/repo");
return {
status: 0,
stdout: JSON.stringify({ metadata: { identity: "sha256:abc" } }),
stderr: ""
};
});
assert.strictEqual(refreshed.metadata.identity, "sha256:abc");
const launch = extension.resolveClusterfluxDebugConfiguration(
{ uri: { fsPath: root } },
{}
);
assert.deepStrictEqual(launch, {
name: "Clusterflux: Launch Virtual Process",
type: "clusterflux",
request: "launch",
entry: "build",
project: root,
runtimeBackend: "local-services"
});
assert.strictEqual(
extension.clusterfluxProcessId("/workspace/app", "build"),
"vp-e4bd6ef50539"
);
assert.strictEqual(
extension.existingProcessRelationship(
{ process: "vp-e4bd6ef50539", state: "running" },
"vp-e4bd6ef50539"
),
"same_launch_target"
);
assert.strictEqual(
extension.existingProcessRelationship(
{ process: "vp-other", state: "running" },
"vp-e4bd6ef50539"
),
"different_launch_target"
);
const liveProcesses = extension.loadLiveProcesses(root, "/repo", (_command, args) => {
assert.deepStrictEqual(args.slice(-3), ["process", "list", "--json"]);
return {
status: 0,
stdout: JSON.stringify({
coordinator: "https://clusterflux.michelpaulissen.com",
tenant: "tenant-live",
project: "project-live",
user: "user-live",
processes: [{ process: "vp-live", state: "cancelling" }]
}),
stderr: ""
};
});
assert.deepStrictEqual(liveProcesses.processes, [
{ process: "vp-live", state: "cancelling" }
]);
assert.strictEqual(liveProcesses.project, "project-live");
const adapter = extension.debugAdapterExecutableSpec(root, repo);
assert.strictEqual(adapter.command, "cargo");
assert.deepStrictEqual(adapter.args, [
"run",
"-q",
"-p",
"clusterflux-dap",
"--bin",
"clusterflux-debug-dap"
]);
assert.deepStrictEqual(adapter.options, { cwd: repo });
const releasedAdapterPath = path.join(root, process.platform === "win32" ? "clusterflux-debug-dap.exe" : "clusterflux-debug-dap");
fs.writeFileSync(releasedAdapterPath, "");
const releasedAdapter = extension.debugAdapterExecutableSpec(root, repo);
assert.strictEqual(releasedAdapter.command, releasedAdapterPath);
assert.deepStrictEqual(releasedAdapter.args, []);
assert.deepStrictEqual(releasedAdapter.options, { cwd: root });
assert.throws(
() =>
extension.refreshBundleBeforeLaunch(root, "/repo", () => ({
status: 1,
stdout: "",
stderr: "missing environment linux"
})),
/missing environment linux/
);
assert(
packageJson.contributes.viewsContainers.activitybar.some(
(container) => container.id === "clusterflux" && container.title === "Clusterflux"
),
"package.json must contribute a Clusterflux activity-bar container"
);
assert(
fs.existsSync(path.join(extensionRoot, "resources/clusterflux.svg")),
"Clusterflux activity-bar icon must exist"
);
const packageViewIds = packageJson.contributes.views.clusterflux.map((view) => view.id).sort();
const descriptorViewIds = extension.clusterfluxViewDescriptors().map((view) => view.id).sort();
assert.deepStrictEqual(descriptorViewIds, [
"clusterflux.artifacts",
"clusterflux.inspector",
"clusterflux.logs",
"clusterflux.nodes",
"clusterflux.processes"
]);
assert.deepStrictEqual(packageViewIds, descriptorViewIds);
for (const viewId of descriptorViewIds) {
const items = extension.clusterfluxViewItems(
extension.loadClusterfluxViewState(root),
viewId
);
assert(
items.length > 0 && !items[0].label.startsWith("No "),
`${viewId} should render state-backed items`
);
}
assert.deepStrictEqual(
extension.clusterfluxViewItems(extension.loadClusterfluxViewState(root), "clusterflux.nodes")[0],
{
label: "node-linux",
description: "online Command RootlessPodman"
}
);
assert(
packageJson.contributes.debuggers.some((debuggerContribution) => debuggerContribution.type === "clusterflux"),
"package.json must contribute the clusterflux debugger type"
);
for (const viewId of descriptorViewIds) {
assert(
packageJson.activationEvents.includes(`onView:${viewId}`),
`${viewId} should activate the extension when opened`
);
}
const launchProperties =
packageJson.contributes.debuggers[0].configurationAttributes.launch.properties;
assert.strictEqual(launchProperties.runtimeBackend.default, "local-services");
assert(launchProperties.runtimeBackend.enum.includes("live-services"));
assert.strictEqual(launchProperties.coordinatorEndpoint.default, undefined);
assert.strictEqual(launchProperties.tenant, undefined);
assert.strictEqual(launchProperties.projectId, undefined);
assert.strictEqual(launchProperties.actorUser, undefined);
assert(
packageJson.contributes.debuggers[0].configurationAttributes.attach,
"package.json must contribute an attach configuration"
);
for (const command of [
"clusterflux.refreshProcesses",
"clusterflux.process.attach",
"clusterflux.process.cancel",
"clusterflux.process.abort"
]) {
assert(
packageJson.contributes.commands.some((entry) => entry.command === command),
`${command} must be contributed`
);
}
assert.match(extensionSource, /registerDebugAdapterDescriptorFactory\("clusterflux"/);
assert.match(extensionSource, /clusterflux-debug-dap/);
assert.match(extensionSource, /\.clusterflux\/views\.json/);
fs.rmSync(root, { recursive: true, force: true });
console.log("VS Code extension smoke passed");

View file

@ -1,321 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const path = require("path");
const extension = require("../vscode-extension/extension");
class DapClient {
constructor(spec) {
this.child = cp.spawn(spec.command, spec.args, {
cwd: spec.options && spec.options.cwd,
env: spec.options && spec.options.env,
detached: process.platform !== "win32"
});
this.seq = 1;
this.buffer = Buffer.alloc(0);
this.messages = [];
this.waiters = [];
this.stderr = "";
this.child.stdout.on("data", (chunk) => {
this.buffer = Buffer.concat([this.buffer, chunk]);
this.parse();
});
this.child.stderr.on("data", (chunk) => {
this.stderr += chunk.toString();
});
this.child.on("exit", () => this.flushWaiters());
}
send(command, args = {}) {
const seq = this.seq++;
const message = { seq, type: "request", command, arguments: args };
const payload = Buffer.from(JSON.stringify(message));
this.child.stdin.write(`Content-Length: ${payload.length}\r\n\r\n`);
this.child.stdin.write(payload);
return seq;
}
async response(seq, command) {
const message = await this.waitFor(
(item) =>
item.type === "response" &&
item.request_seq === seq &&
item.command === command
);
if (!message.success) {
throw new Error(
`DAP ${command} failed: ${message.message || JSON.stringify(message)}\n${this.stderr}`
);
}
return message;
}
terminate() {
if (this.child.exitCode !== null) return;
if (process.platform === "win32") {
this.child.kill("SIGKILL");
return;
}
try {
process.kill(-this.child.pid, "SIGKILL");
} catch (_) {
this.child.kill("SIGKILL");
}
}
waitFor(predicate, timeoutMs = 240000) {
const existing = this.messages.find(predicate);
if (existing) return Promise.resolve(existing);
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
this.terminate();
reject(new Error(`timed out waiting for DAP message\n${this.stderr}`));
}, timeoutMs);
this.waiters.push({ predicate, resolve, timer });
});
}
parse() {
while (true) {
const headerEnd = this.buffer.indexOf("\r\n\r\n");
if (headerEnd < 0) return;
const header = this.buffer.slice(0, headerEnd).toString();
const match = header.match(/Content-Length: (\d+)/i);
if (!match) throw new Error(`bad DAP header: ${header}`);
const length = Number(match[1]);
const start = headerEnd + 4;
const end = start + length;
if (this.buffer.length < end) return;
const payload = this.buffer.slice(start, end).toString();
this.buffer = this.buffer.slice(end);
this.messages.push(JSON.parse(payload));
this.flushWaiters();
}
}
flushWaiters() {
for (const waiter of [...this.waiters]) {
const message = this.messages.find(waiter.predicate);
if (!message) continue;
clearTimeout(waiter.timer);
this.waiters.splice(this.waiters.indexOf(waiter), 1);
waiter.resolve(message);
}
}
async close() {
if (this.child.exitCode !== null) return;
const seq = this.send("disconnect");
await this.response(seq, "disconnect");
this.child.stdin.end();
}
}
(async () => {
const repo = path.resolve(__dirname, "..");
const project = path.join(repo, "examples/hello-build");
const buildSourceLines = fs
.readFileSync(path.join(project, "src/lib.rs"), "utf8")
.split(/\r?\n/);
const sourceLine = (needle) => {
const index = buildSourceLines.findIndex((line) => line.includes(needle));
assert(index >= 0, `flagship source must contain ${needle}`);
return index + 1;
};
const buildMainLine = sourceLine("async fn build()");
const launchConfig = extension.resolveClusterfluxDebugConfiguration(
{ uri: { fsPath: project } },
{}
);
assert.strictEqual(launchConfig.type, "clusterflux");
assert.strictEqual(launchConfig.request, "launch");
assert.strictEqual(launchConfig.entry, "build");
assert.strictEqual(launchConfig.project, project);
assert.strictEqual(launchConfig.runtimeBackend, "local-services");
const inspection = extension.refreshBundleBeforeLaunch(project, repo);
assert.match(inspection.metadata.identity, /^sha256:/);
// Keep the timed attach focused on the runtime boundary. A completely fresh
// public checkout may otherwise spend most of that window compiling the
// coordinator or node after the adapter has already started waiting.
cp.execFileSync(
"cargo",
[
"build",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-node",
],
{ cwd: repo, stdio: "inherit" }
);
const executableSuffix = process.platform === "win32" ? ".exe" : "";
const adapterSpec = extension.debugAdapterExecutableSpec(repo);
adapterSpec.options = {
...(adapterSpec.options || {}),
env: {
...process.env,
CLUSTERFLUX_COORDINATOR_BIN: path.join(
repo,
"target",
"debug",
`clusterflux-coordinator${executableSuffix}`
),
CLUSTERFLUX_NODE_BIN: path.join(
repo,
"target",
"debug",
`clusterflux-node${executableSuffix}`
),
},
};
const client = new DapClient(adapterSpec);
try {
const initialize = client.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true
});
await client.response(initialize, "initialize");
const launch = client.send("launch", launchConfig);
await client.response(launch, "launch");
await client.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
const breakpoints = client.send("setBreakpoints", {
source: { path: path.join(project, "src/lib.rs") },
breakpoints: [{ line: buildMainLine }]
});
const breakpointResponse = await client.response(breakpoints, "setBreakpoints");
assert.strictEqual(breakpointResponse.body.breakpoints[0].verified, false);
assert.match(
breakpointResponse.body.breakpoints[0].message,
/Pending coordinator breakpoint installation/
);
const configurationDone = client.send("configurationDone");
await client.response(configurationDone, "configurationDone");
const installedBreakpoint = await client.waitFor(
(message) =>
message.type === "event" &&
message.event === "breakpoint" &&
message.body?.breakpoint?.verified === true
);
assert.strictEqual(installedBreakpoint.body.breakpoint.line, buildMainLine);
const stopped = await client.waitFor(
(message) => message.type === "event" && message.event === "stopped"
);
assert.strictEqual(stopped.body.allThreadsStopped, true);
assert.strictEqual(stopped.body.reason, "breakpoint");
const threadsRequest = client.send("threads");
const threads = (await client.response(threadsRequest, "threads")).body.threads;
const mainThread = threads.find((thread) => thread.name.includes("build coordinator main"));
assert(mainThread, "F5 launch must expose the real coordinator-main entrypoint thread");
const stackRequest = client.send("stackTrace", {
threadId: mainThread.id,
startFrame: 0,
levels: 1
});
const stack = (await client.response(stackRequest, "stackTrace")).body.stackFrames;
assert.strictEqual(stack[0].line, buildMainLine);
assert.strictEqual(stack[0].source.path, path.join(project, "src/lib.rs"));
assert.strictEqual(stack[0].source.sourceReference || 0, 0);
const sourceRequest = client.send("source", { source: stack[0].source });
const source = (await client.response(sourceRequest, "source")).body;
assert.match(source.content, /compile/);
const scopesRequest = client.send("scopes", { frameId: stack[0].id });
const scopes = (await client.response(scopesRequest, "scopes")).body.scopes;
const localsScope = scopes.find((scope) => scope.name === "Source Locals");
const argsScope = scopes.find((scope) => scope.name === "Task Args and Handles");
const runtimeScope = scopes.find((scope) => scope.name === "Clusterflux Runtime");
const outputScope = scopes.find((scope) => scope.name === "Recent Output");
assert(localsScope, "F5 launch must expose source locals scope");
assert(argsScope, "F5 launch must expose task args and handles");
assert(runtimeScope, "F5 launch must expose Clusterflux runtime state");
assert(outputScope, "F5 launch must expose recent output state");
const localsRequest = client.send("variables", {
variablesReference: localsScope.variablesReference
});
const locals = (await client.response(localsRequest, "variables")).body.variables;
assert(
locals.some(
(variable) =>
variable.name === "unavailable-local-diagnostic" &&
String(variable.value).includes("cannot be inspected")
),
"source locals scope must report unavailable real Rust locals explicitly"
);
const runtimeRequest = client.send("variables", {
variablesReference: runtimeScope.variablesReference
});
const runtime = (await client.response(runtimeRequest, "variables")).body.variables;
assert(
runtime.some(
(variable) => variable.name === "runtime_backend" && variable.value === "LocalServices"
),
"extension-resolved F5 launch must use the real local-services backend"
);
assert(
runtime.some(
(variable) => variable.name === "coordinator_task_events" && variable.value === 0
),
"a task frozen at its entry probe must not fabricate a terminal task event"
);
assert(
runtime.some(
(variable) =>
variable.name === "command_status" &&
String(variable.value).includes(
"frozen through local services at executing Wasm probe"
)
)
);
assert(
runtime.some(
(variable) => variable.name === "state" && variable.value === "Frozen"
),
"F5 must expose the node-acknowledged frozen participant state"
);
assert(runtime.some((variable) => variable.name === "command_spec"));
assert(runtime.some((variable) => variable.name === "stdout_tail"));
assert(runtime.some((variable) => variable.name === "stderr_tail"));
const outputRequest = client.send("variables", {
variablesReference: outputScope.variablesReference
});
const output = (await client.response(outputRequest, "variables")).body.variables;
assert(output.some((variable) => variable.name === "stdout_tail"));
assert(output.some((variable) => variable.name === "stderr_tail"));
await client.close();
} catch (error) {
client.terminate();
throw error;
}
console.log("VS Code F5 smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,44 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const sdkRuntime = fs.readFileSync(
path.join(repo, "crates/clusterflux-sdk/src/sdk_runtime.rs"),
"utf8"
);
assert.doesNotMatch(
sdkRuntime,
/"type": "launch_task"/,
"native SDK code must not submit external TaskV1 work"
);
assert.match(
sdkRuntime,
/native SDK task spawning requires coordinator EntrypointV1 execution/
);
cp.execFileSync("node", ["scripts/cli-local-run-smoke.js"], {
cwd: repo,
stdio: "inherit",
});
cp.execFileSync(
"cargo",
["test", "-p", "clusterflux-node", "wasmtime_runtime_runs_named_task_export"],
{ cwd: repo, stdio: "inherit" }
);
cp.execFileSync(
"cargo",
[
"test",
"-p",
"clusterflux-coordinator",
"signed_active_wasm_task_can_spawn_and_join_child_in_its_process_only",
],
{ cwd: repo, stdio: "inherit" }
);
console.log("Wasmtime assignment smoke passed");

View file

@ -1,172 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const fs = require("fs");
const path = require("path");
const repo = path.resolve(__dirname, "..");
const wasmTarget = path.join(
repo,
"target",
"wasm32-unknown-unknown",
"release",
"runtime_conformance.wasm"
);
cp.execFileSync(
"cargo",
[
"build",
"--release",
"-p",
"runtime-conformance",
"--target",
"wasm32-unknown-unknown",
],
{
cwd: repo,
stdio: "inherit",
env: {
...process.env,
CARGO_PROFILE_RELEASE_OPT_LEVEL: "z",
CARGO_PROFILE_RELEASE_LTO: "thin",
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: "1",
},
}
);
assert(fs.existsSync(wasmTarget), `missing compiled Wasm module at ${wasmTarget}`);
const output = cp.execFileSync(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-wasmtime-smoke",
"--",
wasmTarget,
"task_add_one",
"41",
"42",
],
{ cwd: repo, encoding: "utf8" }
);
const report = JSON.parse(output);
assert.strictEqual(report.type, "wasmtime_task_smoke");
assert.strictEqual(report.export, "task_add_one");
assert.strictEqual(report.arg, 41);
assert.strictEqual(report.result, 42);
const debugOutput = cp.execFileSync(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-wasmtime-smoke",
"--",
"--debug-freeze-resume",
wasmTarget,
"task_add_one",
"41",
"42",
],
{ cwd: repo, encoding: "utf8" }
);
const debugReport = JSON.parse(debugOutput);
assert.strictEqual(debugReport.type, "wasmtime_debug_freeze_resume_smoke");
assert.strictEqual(debugReport.export, "task_add_one");
assert.strictEqual(debugReport.task, "task_add_one");
assert.strictEqual(debugReport.frozen_state, "Frozen");
assert.strictEqual(debugReport.resumed_state, "Running");
assert(debugReport.stack_frames.some((frame) => String(frame).includes("task_add_one")));
assert(
debugReport.local_values.some(
([name, value]) => name === "wasm_local_0" && String(value).includes("41")
),
"Wasmtime debug snapshot must expose the real i32 argument as a frame local"
);
assert.strictEqual(debugReport.node_runtime_captured_wasm_locals, true);
assert.strictEqual(debugReport.result, 42);
assert.strictEqual(debugReport.node_runtime_reached_wasm_task, true);
const hostCommandOutput = cp.execFileSync(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-wasmtime-smoke",
"--",
"--host-command",
wasmTarget,
"compile_linux",
],
{ cwd: repo, encoding: "utf8" }
);
const hostCommandReport = JSON.parse(hostCommandOutput);
assert.strictEqual(hostCommandReport.type, "wasmtime_host_command_smoke");
assert.strictEqual(hostCommandReport.task, "compile_linux");
assert.match(hostCommandReport.export, /^clusterflux_task_v1_[0-9a-f]{64}$/);
assert.strictEqual(hostCommandReport.program, "cc");
assert.deepStrictEqual(hostCommandReport.args, [
"-Os",
"-static",
"-s",
"fixture/hello-clusterflux.c",
"-o",
"/clusterflux/output/hello-clusterflux",
]);
assert.strictEqual(hostCommandReport.working_directory, "/workspace");
assert.deepStrictEqual(hostCommandReport.environment_variables, {
SOURCE_DATE_EPOCH: "0",
});
assert.strictEqual(hostCommandReport.timeout_ms, 180000);
assert.strictEqual(hostCommandReport.network, "disabled");
assert.strictEqual(hostCommandReport.status_code, 0);
assert.strictEqual(hostCommandReport.stdout, "");
assert.strictEqual(hostCommandReport.artifact_name, "hello-clusterflux");
assert.strictEqual(hostCommandReport.artifact_size_bytes, "hello-clusterflux".length);
assert.match(hostCommandReport.artifact_digest, /^sha256:[0-9a-f]{64}$/);
assert.strictEqual(hostCommandReport.node_host_import, "clusterflux.command_run_v1");
assert.strictEqual(hostCommandReport.artifact_host_import, "clusterflux.vfs_operation_v1");
assert.strictEqual(hostCommandReport.flagship_linux_build_task, true);
assert.strictEqual(hostCommandReport.node_executed_host_command, true);
assert.strictEqual(hostCommandReport.hosted_control_plane_ran_command, false);
const artifactOutput = cp.execFileSync(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-wasmtime-smoke",
"--",
"--task-artifact",
wasmTarget,
"package_release",
],
{ cwd: repo, encoding: "utf8" }
);
const artifactReport = JSON.parse(artifactOutput);
assert.strictEqual(artifactReport.type, "wasmtime_task_artifact_smoke");
assert.strictEqual(artifactReport.task, "package_release");
assert.strictEqual(artifactReport.artifact_name, "release.tar");
assert.strictEqual(artifactReport.artifact_size_bytes, "release.tar".length);
assert.match(artifactReport.artifact_digest, /^sha256:[0-9a-f]{64}$/);
assert.strictEqual(artifactReport.host_import, "clusterflux.vfs_operation_v1");
assert.strictEqual(artifactReport.host_issued_handle_returned, true);
assert.ok(artifactReport.artifact.id.endsWith(artifactReport.artifact_digest.slice("sha256:".length)));
console.log("Wasmtime node smoke passed");

View file

@ -1,301 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const { nodeIdentity, signedNodeRequest } = require("./node-signing");
const repo = path.resolve(__dirname, "..");
const digest = (value) =>
`sha256:${crypto.createHash("sha256").update(value).digest("hex")}`;
const environmentDigest = digest("windows-command-dev-environment");
const sourceDigest = digest("windows-best-effort-source");
const windowsArtifactBytes = Buffer.from("windows-output-data");
const windowsArtifactDigest = digest(windowsArtifactBytes);
const emptyWasm = Buffer.from([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
const emptyWasmDigest = digest(emptyWasm);
const nodeDaemon = fs.readFileSync(path.join(repo, "crates/clusterflux-node/src/daemon.rs"), "utf8");
const taskReports = fs.readFileSync(
path.join(repo, "crates/clusterflux-node/src/task_reports.rs"),
"utf8"
);
const nodeLib = fs.readFileSync(path.join(repo, "crates/clusterflux-node/src/lib.rs"), "utf8");
const windowsDev = fs.readFileSync(
path.join(repo, "crates/clusterflux-node/src/windows_dev.rs"),
"utf8"
);
const executionCore = fs.readFileSync(
path.join(repo, "crates/clusterflux-core/src/execution.rs"),
"utf8"
);
const dapSource = [
fs.readFileSync(path.join(repo, "crates/clusterflux-dap/src/demo_backend.rs"), "utf8"),
fs.readFileSync(path.join(repo, "crates/clusterflux-dap/src/tests.rs"), "utf8"),
].join("\n");
const windowsNode = "windows-node";
const windowsIdentity = nodeIdentity("windows-best-effort-smoke", windowsNode);
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function windowsCapabilities() {
return {
os: "Windows",
arch: "x86_64",
capabilities: ["Command", "VfsArtifacts", "WindowsCommandDev"],
environment_backends: ["WindowsCommandDev"],
source_providers: ["filesystem"]
};
}
function assertWindowsBackendBoundary() {
assert.match(nodeDaemon, /CoordinatorSession::connect\(&args\.coordinator\)/);
assert.match(nodeDaemon, /record_completed_task\(/);
assert.match(taskReports, /"type": "task_completed"/);
assert.doesNotMatch(nodeDaemon, /WindowsCommandDev|windows-command-dev|cfg\(windows\)/);
assert.match(nodeLib, /impl CommandBackend for LinuxRootlessPodmanBackend/);
assert.match(nodeLib, /mod windows_dev/);
assert.match(nodeLib, /pub use windows_dev::\{WindowsCommandDevBackend, WindowsSandboxStubBackend\}/);
assert.match(windowsDev, /impl CommandBackend for WindowsCommandDevBackend/);
assert.match(windowsDev, /impl CommandBackend for WindowsSandboxStubBackend/);
assert.doesNotMatch(windowsDev, /LinuxRootlessPodmanBackend/);
assert.match(executionCore, /\bLinuxRootlessPodman\b/);
assert.match(executionCore, /\bWindowsCommandDev\b/);
assert.match(executionCore, /\bStubbedWindowsSandbox\b/);
assert.match(dapSource, /thread\(WINDOWS_THREAD, "compile-windows", "compile windows"/);
assert.match(dapSource, /fn launch_threads_include_windows_task_in_same_virtual_process\(\)/);
assert.match(dapSource, /fn windows_thread_runtime_variables_share_virtual_process\(\)/);
}
(async () => {
assertWindowsBackendBoundary();
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback"
],
{ cwd: repo }
);
let coordinatorStderr = "";
coordinator.stderr.on("data", (chunk) => {
coordinatorStderr += chunk.toString();
});
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const attached = await send(addr, {
type: "attach_node",
tenant: "tenant",
project: "project",
node: windowsNode,
public_key: windowsIdentity.publicKey
});
assert.strictEqual(attached.type, "node_attached");
assert.strictEqual(attached.node, windowsNode);
const recorded = await send(addr, signedNodeRequest(windowsNode, windowsIdentity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: windowsNode,
capabilities: windowsCapabilities(),
cached_environment_digests: [environmentDigest],
dependency_cache_digests: [],
source_snapshots: [sourceDigest],
artifact_locations: [],
direct_connectivity: true,
online: true
}));
assert.strictEqual(recorded.type, "node_capabilities_recorded");
assert.strictEqual(recorded.node, windowsNode);
const placement = await send(addr, {
type: "schedule_task",
tenant: "tenant",
project: "project",
environment: {
os: "Windows",
arch: null,
capabilities: ["WindowsCommandDev"]
},
environment_digest: environmentDigest,
required_capabilities: ["Command"],
dependency_cache: null,
source_snapshot: sourceDigest,
required_artifacts: [],
prefer_node: null
});
assert.strictEqual(placement.type, "task_placement");
assert.strictEqual(placement.placement.node, windowsNode);
assert.ok(placement.placement.reasons.includes("warm environment cache"));
assert.ok(placement.placement.reasons.includes("source snapshot already local"));
const started = await send(addr, {
type: "start_process",
tenant: "tenant",
project: "project",
process: "vp-windows"
});
assert.strictEqual(started.type, "process_started");
assert.strictEqual(started.process, "vp-windows");
const reconnected = await send(addr, signedNodeRequest(windowsNode, windowsIdentity, "reconnect_node", {
type: "reconnect_node",
tenant: "tenant",
project: "project",
node: windowsNode,
process: "vp-windows",
epoch: started.epoch
}));
assert.strictEqual(reconnected.type, "node_reconnected");
const launched = await send(addr, {
type: "launch_task",
tenant: "tenant",
project: "project",
actor_user: "operator",
task_spec: {
tenant: "tenant",
project: "project",
process: "vp-windows",
task_definition: "windows-command-dev",
task_instance: "windows-command-dev",
dispatch: {
kind: "coordinator_node_wasm",
export: "windows_command_dev",
abi: "task_v1",
},
environment_id: "windows",
environment: {
os: "Windows",
arch: null,
capabilities: ["WindowsCommandDev"],
},
environment_digest: environmentDigest,
required_capabilities: ["Command", "WindowsCommandDev"],
dependency_cache: null,
source_snapshot: sourceDigest,
required_artifacts: [],
args: [{ SourceSnapshot: sourceDigest }],
vfs_epoch: started.epoch,
bundle_digest: emptyWasmDigest,
},
wait_for_node: false,
artifact_path: "/vfs/artifacts/windows-output.txt",
wasm_module_base64: emptyWasm.toString("base64"),
});
assert.strictEqual(launched.type, "error", JSON.stringify(launched));
assert.match(launched.message, /external callers may launch only EntrypointV1/);
const recordedTask = await send(addr, signedNodeRequest(windowsNode, windowsIdentity, "task_completed", {
type: "task_completed",
tenant: "tenant",
project: "project",
process: "vp-windows",
node: windowsNode,
task: "windows-command-dev",
status_code: 0,
stdout_bytes: 18,
stderr_bytes: 0,
stdout_tail: "",
stderr_tail: "",
stdout_truncated: false,
stderr_truncated: false,
artifact_path: "/vfs/artifacts/windows-output.txt",
artifact_digest: windowsArtifactDigest,
artifact_size_bytes: windowsArtifactBytes.length
}));
assert.strictEqual(recordedTask.type, "error");
assert.match(recordedTask.message, /coordinator-issued task instance|issued active task|active task/);
const events = await send(addr, {
type: "list_task_events",
tenant: "tenant",
project: "project",
actor_user: "user",
process: "vp-windows"
});
assert.strictEqual(events.type, "task_events");
assert.strictEqual(events.events.length, 0);
const link = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact: "windows-output.txt",
max_bytes: 1024
});
assert.strictEqual(link.type, "error");
assert.match(link.message, /does not exist|not found|unavailable/);
} catch (error) {
if (coordinatorStderr) {
error.message = `${error.message}\ncoordinator stderr:\n${coordinatorStderr}`;
}
throw error;
} finally {
coordinator.kill("SIGTERM");
}
console.log("Windows best-effort smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,479 +0,0 @@
#!/usr/bin/env node
const assert = require("assert");
const cp = require("child_process");
const crypto = require("crypto");
const fs = require("fs");
const net = require("net");
const path = require("path");
const { coordinatorWireRequest } = require("./coordinator-wire");
const { nodeIdentity, signedNodeRequest } = require("./node-signing");
const repo = path.resolve(__dirname, "..");
const forgejoWindowsNode = "forgejo-windows-node";
const forgejoWindowsIdentity = nodeIdentity("windows-runner-smoke", forgejoWindowsNode);
const windowsEnvironmentDigest = `sha256:${crypto
.createHash("sha256")
.update("clusterflux/windows-command-dev/v1")
.digest("hex")}`;
const sourceSnapshot = `sha256:${crypto
.createHash("sha256")
.update("clusterflux/windows-runner/source/v1")
.digest("hex")}`;
class DapClient {
constructor() {
this.child = cp.spawn(
"cargo",
["run", "-q", "-p", "clusterflux-dap", "--bin", "clusterflux-debug-dap"],
{ cwd: repo }
);
this.seq = 1;
this.buffer = Buffer.alloc(0);
this.messages = [];
this.waiters = [];
this.stderr = "";
this.child.stdout.on("data", (chunk) => {
this.buffer = Buffer.concat([this.buffer, chunk]);
this.parse();
});
this.child.stderr.on("data", (chunk) => {
this.stderr += chunk.toString();
});
this.child.on("exit", () => this.flushWaiters());
}
send(command, args = {}) {
const seq = this.seq++;
const message = { seq, type: "request", command, arguments: args };
const payload = Buffer.from(JSON.stringify(coordinatorWireRequest(message)));
this.child.stdin.write(`Content-Length: ${payload.length}\r\n\r\n`);
this.child.stdin.write(payload);
return seq;
}
async response(seq, command) {
const message = await this.waitFor(
(item) =>
item.type === "response" &&
item.request_seq === seq &&
item.command === command
);
if (!message.success) {
throw new Error(`DAP ${command} failed: ${message.message || JSON.stringify(coordinatorWireRequest(message))}`);
}
return message;
}
waitFor(predicate, timeoutMs = 120000) {
const existing = this.messages.find(predicate);
if (existing) return Promise.resolve(existing);
return new Promise((resolve, reject) => {
const timer = setTimeout(() => {
this.child.kill("SIGKILL");
reject(new Error(`timed out waiting for DAP message\n${this.stderr}`));
}, timeoutMs);
this.waiters.push({ predicate, resolve, timer });
});
}
parse() {
while (true) {
const headerEnd = this.buffer.indexOf("\r\n\r\n");
if (headerEnd < 0) return;
const header = this.buffer.slice(0, headerEnd).toString();
const match = header.match(/Content-Length: (\d+)/i);
if (!match) throw new Error(`bad DAP header: ${header}`);
const length = Number(match[1]);
const start = headerEnd + 4;
const end = start + length;
if (this.buffer.length < end) return;
const payload = this.buffer.slice(start, end).toString();
this.buffer = this.buffer.slice(end);
this.messages.push(JSON.parse(payload));
this.flushWaiters();
}
}
flushWaiters() {
for (const waiter of [...this.waiters]) {
const message = this.messages.find(waiter.predicate);
if (!message) continue;
clearTimeout(waiter.timer);
this.waiters.splice(this.waiters.indexOf(waiter), 1);
waiter.resolve(message);
}
}
async close() {
if (this.child.exitCode !== null) return;
const seq = this.send("disconnect");
await this.response(seq, "disconnect");
this.child.stdin.end();
}
}
function waitForJsonLine(child) {
return new Promise((resolve, reject) => {
let buffer = "";
child.stdout.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
try {
resolve(JSON.parse(buffer.slice(0, newline).trim()));
} catch (error) {
reject(error);
}
});
child.once("exit", (code) => {
reject(new Error(`process exited before JSON line with code ${code}`));
});
});
}
function send(addr, message) {
return new Promise((resolve, reject) => {
const socket = net.connect(addr.port, addr.host, () => {
socket.write(`${JSON.stringify(coordinatorWireRequest(message))}\n`);
});
let buffer = "";
socket.on("data", (chunk) => {
buffer += chunk.toString();
const newline = buffer.indexOf("\n");
if (newline < 0) return;
socket.end();
try {
resolve(JSON.parse(buffer.slice(0, newline)));
} catch (error) {
reject(error);
}
});
socket.on("error", reject);
});
}
function runWindowsAttach(addr, grant) {
return new Promise((resolve, reject) => {
const child = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-cli",
"--bin",
"clusterflux",
"--",
"node",
"attach",
"--coordinator",
`${addr.host}:${addr.port}`,
"--tenant",
"tenant",
"--project-id",
"project",
"--node",
forgejoWindowsNode,
"--public-key",
forgejoWindowsIdentity.publicKey,
"--enrollment-grant",
grant,
"--cap",
"windows-command-dev",
"--json"
],
{
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_NODE_PRIVATE_KEY: forgejoWindowsIdentity.privateKey,
},
}
);
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString();
});
child.on("exit", (code) => {
if (code !== 0) {
reject(new Error(`Windows node attach failed with code ${code}\n${stderr}`));
return;
}
try {
resolve(JSON.parse(stdout));
} catch (error) {
reject(
new Error(`Windows node attach output was not JSON: ${stdout}\n${error.stack || error.message}`)
);
}
});
});
}
function runWindowsNode(addr, grant) {
return new Promise((resolve, reject) => {
const child = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-node",
"--bin",
"clusterflux-node",
"--",
"--coordinator",
`${addr.host}:${addr.port}`,
"--tenant",
"tenant",
"--project-id",
"project",
"--node",
forgejoWindowsNode,
"--public-key",
forgejoWindowsIdentity.publicKey,
"--enrollment-grant",
grant,
"--process",
"vp-forgejo-windows",
"--task",
"windows-command-dev",
"--command",
"cmd",
"--arg",
"/C",
"--arg",
"echo clusterflux-windows-runner",
"--artifact",
"/vfs/artifacts/windows-runner-output.txt"
],
{
cwd: repo,
env: {
...process.env,
CLUSTERFLUX_NODE_PRIVATE_KEY: forgejoWindowsIdentity.privateKey,
},
}
);
let stdout = "";
let stderr = "";
child.stdout.on("data", (chunk) => {
stdout += chunk.toString();
});
child.stderr.on("data", (chunk) => {
stderr += chunk.toString();
});
child.on("exit", (code) => {
if (code !== 0) {
reject(new Error(`Windows node smoke failed with code ${code}\n${stderr}`));
return;
}
try {
resolve(JSON.parse(stdout.trim().split(/\r?\n/).at(-1)));
} catch (error) {
reject(new Error(`node output was not JSON: ${stdout}\n${error.stack || error.message}`));
}
});
});
}
async function assertDebuggerShowsWindowsThread() {
const client = new DapClient();
try {
const initialize = client.send("initialize", {
adapterID: "clusterflux",
linesStartAt1: true,
columnsStartAt1: true
});
await client.response(initialize, "initialize");
const launch = client.send("launch", {
entry: "build",
project: path.join(repo, "tests/fixtures/runtime-conformance"),
runtimeBackend: "simulated"
});
await client.response(launch, "launch");
await client.waitFor(
(message) => message.type === "event" && message.event === "initialized"
);
const configurationDone = client.send("configurationDone");
await client.response(configurationDone, "configurationDone");
const threadsRequest = client.send("threads");
const threads = (await client.response(threadsRequest, "threads")).body.threads;
assert(
threads.some((thread) => thread.name.includes("compile windows")),
"debugger must represent the Windows task as a virtual thread"
);
await client.close();
} catch (error) {
client.child.kill("SIGKILL");
throw error;
}
}
(async () => {
if (process.platform !== "win32") {
throw new Error(
`Windows runner validation requires win32; current platform is ${process.platform}`
);
}
const coordinator = cp.spawn(
"cargo",
[
"run",
"-q",
"-p",
"clusterflux-coordinator",
"--bin",
"clusterflux-coordinator",
"--",
"--listen",
"127.0.0.1:0",
"--allow-local-trusted-loopback"
],
{ cwd: repo }
);
let coordinatorStderr = "";
coordinator.stderr.on("data", (chunk) => {
coordinatorStderr += chunk.toString();
});
try {
const ready = await waitForJsonLine(coordinator);
const [host, portText] = ready.listen.split(":");
const addr = { host, port: Number(portText) };
assert.strictEqual((await send(addr, { type: "ping" })).type, "pong");
const attachGrant = await send(addr, {
type: "create_node_enrollment_grant",
tenant: "tenant",
project: "project",
actor_user: "operator",
ttl_seconds: 900
});
assert.strictEqual(attachGrant.type, "node_enrollment_grant_created");
assert.strictEqual(attachGrant.scope, "node:attach");
const attach = await runWindowsAttach(addr, attachGrant.grant);
assert.strictEqual(attach.plan.node, forgejoWindowsNode);
assert.strictEqual(attach.boundary.cli_contacted_coordinator, true);
assert.strictEqual(attach.boundary.used_enrollment_exchange, true);
assert.strictEqual(attach.coordinator_response.type, "node_enrollment_exchanged");
assert.strictEqual(attach.coordinator_response.credential.scope, "node:attach");
assert(attach.plan.capabilities.capabilities.includes("WindowsCommandDev"));
const runtimeGrant = await send(addr, {
type: "create_node_enrollment_grant",
tenant: "tenant",
project: "project",
actor_user: "operator",
ttl_seconds: 900
});
assert.strictEqual(runtimeGrant.type, "node_enrollment_grant_created");
const report = await runWindowsNode(addr, runtimeGrant.grant);
assert.strictEqual(report.node_status, "completed");
assert.strictEqual(report.virtual_thread, "windows-command-dev");
assert.strictEqual(report.status_code, 0);
assert.strictEqual(report.large_bytes_uploaded, false);
assert.strictEqual(
report.staged_artifact.path,
"/vfs/artifacts/windows-runner-output.txt"
);
assert.strictEqual(report.registration_response.type, "node_enrollment_exchanged");
assert.strictEqual(report.registration_response.credential.scope, "node:attach");
assert.strictEqual(report.coordinator_response.type, "task_recorded");
const recorded = await send(addr, signedNodeRequest(forgejoWindowsNode, forgejoWindowsIdentity, "report_node_capabilities", {
type: "report_node_capabilities",
tenant: "tenant",
project: "project",
node: forgejoWindowsNode,
capabilities: {
os: "Windows",
arch: "x86_64",
capabilities: ["Command", "WindowsCommandDev", "VfsArtifacts"],
environment_backends: ["WindowsCommandDev"],
source_providers: ["filesystem"]
},
cached_environment_digests: [windowsEnvironmentDigest],
source_snapshots: [sourceSnapshot],
artifact_locations: ["windows-runner-output.txt"],
direct_connectivity: true,
online: true
}));
assert.strictEqual(recorded.type, "node_capabilities_recorded");
const placement = await send(addr, {
type: "schedule_task",
tenant: "tenant",
project: "project",
environment: {
os: "Windows",
arch: null,
capabilities: ["WindowsCommandDev"]
},
environment_digest: windowsEnvironmentDigest,
required_capabilities: ["Command"],
source_snapshot: sourceSnapshot,
required_artifacts: ["windows-runner-output.txt"],
prefer_node: null
});
assert.strictEqual(placement.type, "task_placement");
assert.strictEqual(placement.placement.node, "forgejo-windows-node");
const link = await send(addr, {
type: "create_artifact_download_link",
tenant: "tenant",
project: "project",
actor_user: "user",
artifact: "windows-runner-output.txt",
max_bytes: 1024
});
assert.strictEqual(link.type, "artifact_download_link");
assert.deepStrictEqual(link.link.source, {
RetainedNode: "forgejo-windows-node"
});
} catch (error) {
if (coordinatorStderr) {
error.message = `${error.message}\ncoordinator stderr:\n${coordinatorStderr}`;
}
throw error;
} finally {
coordinator.kill("SIGTERM");
}
await assertDebuggerShowsWindowsThread();
const outDir = path.join(repo, "target", "acceptance");
fs.mkdirSync(outDir, { recursive: true });
fs.writeFileSync(
path.join(outDir, "windows-runner.json"),
`${JSON.stringify(
{
kind: "clusterflux_windows_runner_validation",
platform: process.platform,
runner: process.env.FORGEJO_RUNNER_NAME || process.env.RUNNER_NAME || null,
validated: true
},
null,
2
)}\n`
);
console.log("Windows runner smoke passed");
})().catch((error) => {
console.error(error.stack || error.message);
process.exit(1);
});

View file

@ -1,16 +0,0 @@
[package]
name = "runtime-conformance"
version = "0.1.0"
edition.workspace = true
license.workspace = true
repository.workspace = true
publish = false
[lib]
crate-type = ["rlib", "cdylib"]
[dependencies]
clusterflux = { package = "clusterflux-sdk", path = "../../../crates/clusterflux-sdk" }
futures-executor.workspace = true
serde.workspace = true
serde_json.workspace = true

View file

@ -1,5 +0,0 @@
# Runtime conformance fixture
This is test-only coverage for raw task ABI, cancellation, long joins, placement,
debug probes, and failure injection. It is intentionally not a public SDK
example. Start with examples/hello-build.

View file

@ -1,3 +0,0 @@
FROM docker.io/library/alpine:3.20
RUN apk add --no-cache build-base tar zstd
WORKDIR /workspace

View file

@ -1,2 +0,0 @@
# User-attached Windows development execution contract.
# This is not a managed untrusted Windows sandbox.

View file

@ -1,6 +0,0 @@
#include <stdio.h>
int main(void) {
puts("hello from a real Clusterflux build");
return 0;
}

View file

@ -1,501 +0,0 @@
use clusterflux::{Artifact, EnvRef, SourceSnapshot};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, clusterflux::TaskArg)]
pub struct BuildReport {
pub linux_thread: u64,
pub linux_parallel_thread: u64,
pub package_thread: u64,
pub linux_artifact: Artifact,
pub package_artifact: Artifact,
pub source: SourceSnapshot,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, clusterflux::TaskArg)]
pub struct PackageInput {
pub release_name: String,
pub source: SourceSnapshot,
pub executable: Option<Artifact>,
pub inputs: Vec<Artifact>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, clusterflux::TaskArg)]
pub struct IdentityProbeInput {
pub source: SourceSnapshot,
pub label: String,
pub delay_seconds: u64,
}
pub fn linux_env() -> EnvRef {
clusterflux::env!("linux")
}
pub fn windows_env() -> EnvRef {
clusterflux::env!("windows")
}
#[clusterflux::task(capabilities = "source_filesystem")]
pub async fn prepare_source() -> SourceSnapshot {
#[cfg(target_arch = "wasm32")]
{
return clusterflux::source::snapshot()
.await
.expect("the source task should snapshot the node checkout it was placed on");
}
#[cfg(not(target_arch = "wasm32"))]
SourceSnapshot {
digest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
.to_owned(),
}
}
#[clusterflux::task(capabilities = "command")]
pub async fn compile_linux(source: SourceSnapshot) -> Artifact {
let _ = &source;
#[cfg(target_arch = "wasm32")]
{
let executable = clusterflux::fs::output_path("hello-clusterflux")
.expect("the executable output path should be task-local");
let output = clusterflux::command::Command::new("cc")
.args([
"-Os",
"-static",
"-s",
"fixture/hello-clusterflux.c",
"-o",
executable.as_str(),
])
.current_dir("/workspace")
.env("SOURCE_DATE_EPOCH", "0")
.timeout(std::time::Duration::from_secs(180))
.network_disabled()
.output()
.await
.expect("the declared Linux environment should provide a real C compiler");
assert_eq!(output.status_code, Some(0));
return clusterflux::fs::flush(&executable)
.await
.expect("the command-created executable should flush to node artifact storage");
}
#[cfg(not(target_arch = "wasm32"))]
Artifact {
id: "hello-clusterflux-native-test".to_owned(),
digest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
.to_owned(),
size_bytes: 0,
}
}
#[clusterflux::task]
#[unsafe(no_mangle)]
pub extern "C" fn task_add_one(input: i32) -> i32 {
input + 1
}
#[clusterflux::task]
#[unsafe(no_mangle)]
pub extern "C" fn task_trap(_input: i32) -> i32 {
#[cfg(target_arch = "wasm32")]
core::arch::wasm32::unreachable();
#[cfg(not(target_arch = "wasm32"))]
panic!("intentional task trap")
}
#[clusterflux::task(capabilities = "command")]
pub async fn package_release(input: PackageInput) -> Artifact {
#[cfg(target_arch = "wasm32")]
{
assert_eq!(input.release_name, "release.tar");
let executable = input
.executable
.as_ref()
.expect("the package input should contain the compiler artifact");
assert!(input.inputs.iter().any(|artifact| artifact == executable));
let executable = clusterflux::fs::materialize(&executable, "package/hello-clusterflux")
.await
.expect("the retaining node should materialize the compiler artifact locally");
let release = clusterflux::fs::output_path("release.tar")
.expect("the release output path should be task-local");
let output = clusterflux::command::Command::new("tar")
.args([
"--sort=name",
"--mtime=@0",
"--owner=0",
"--group=0",
"--numeric-owner",
"--mode=0755",
"-cf",
release.as_str(),
"-C",
"/clusterflux/output/package",
"hello-clusterflux",
])
.current_dir("/workspace")
.env("SOURCE_DATE_EPOCH", "0")
.timeout(std::time::Duration::from_secs(180))
.network_disabled()
.output()
.await
.expect("the declared Linux environment should package the materialized executable");
assert_eq!(output.status_code, Some(0));
assert_eq!(
executable.as_str(),
"/clusterflux/output/package/hello-clusterflux"
);
return clusterflux::fs::flush(&release)
.await
.expect("the command-created release archive should flush as the final artifact");
}
#[cfg(not(target_arch = "wasm32"))]
{
let _ = input;
Artifact {
id: "release-native-test".to_owned(),
digest: "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
.to_owned(),
size_bytes: 0,
}
}
}
#[clusterflux::task(capabilities = "command")]
pub async fn abort_probe(source: SourceSnapshot) -> i32 {
let _ = &source;
#[cfg(target_arch = "wasm32")]
{
let output = clusterflux::command::Command::new("sh")
.args(["-c", "sleep 90"])
.timeout(std::time::Duration::from_secs(120))
.network_disabled()
.output()
.await
.expect("abort probe command should either finish or be stopped by process abort");
return output.status_code.unwrap_or(-1);
}
#[cfg(not(target_arch = "wasm32"))]
0
}
#[clusterflux::task(capabilities = "command")]
pub async fn long_join_probe(source: SourceSnapshot) -> i32 {
let _ = &source;
#[cfg(target_arch = "wasm32")]
{
let output = clusterflux::command::Command::new("sh")
.args(["-c", "sleep 125"])
.timeout(std::time::Duration::from_secs(180))
.network_disabled()
.output()
.await
.expect("the controlled long-running command should complete normally");
return output.status_code.unwrap_or(-1);
}
#[cfg(not(target_arch = "wasm32"))]
0
}
#[clusterflux::task(capabilities = "command")]
pub async fn identity_probe(input: IdentityProbeInput) -> String {
let _ = &input.source;
#[cfg(target_arch = "wasm32")]
{
let script = format!(
"sleep {}; printf '%s' '{}'",
input.delay_seconds, input.label
);
let output = clusterflux::command::Command::new("sh")
.args(["-c", script.as_str()])
.timeout(std::time::Duration::from_secs(60))
.network_disabled()
.output()
.await
.expect("identity probe command should complete");
assert_eq!(output.status_code, Some(0));
return input.label;
}
#[cfg(not(target_arch = "wasm32"))]
input.label
}
#[clusterflux::task]
pub fn cooperative_cancellation_probe() -> i32 {
#[cfg(target_arch = "wasm32")]
loop {
if clusterflux::process::cancellation_requested()
.expect("task control should remain available while the Wasm task is running")
{
// Cancellation is a request observed and handled by task code. Returning
// normally is intentionally distinct from the runtime's forced abort path.
return 17;
}
}
#[cfg(not(target_arch = "wasm32"))]
17
}
#[clusterflux::task]
pub fn debug_child_probe() -> i32 {
#[cfg(target_arch = "wasm32")]
loop {
if clusterflux::process::cancellation_requested()
.expect("child debug participant should retain task control")
{
return 23;
}
}
#[cfg(not(target_arch = "wasm32"))]
23
}
#[clusterflux::task]
pub async fn debug_parent_probe() -> i32 {
#[cfg(target_arch = "wasm32")]
{
let child = clusterflux::spawn::task(debug_child_probe)
.name("debug child participant")
.start()
.await
.expect("parent debug participant should spawn its child");
return child
.join()
.await
.expect("parent debug participant should join its child");
}
#[cfg(not(target_arch = "wasm32"))]
23
}
#[clusterflux::main]
pub async fn build_main() -> BuildReport {
run_build_workflow().await
}
#[clusterflux::main(name = "fail")]
pub async fn fail_main() -> Result<i32, String> {
#[cfg(target_arch = "wasm32")]
{
let child = clusterflux::spawn::task_with_arg(0_i32, |value| task_trap(value))
.task_id("task_trap")
.name("intentional failing child")
.start()
.await
.map_err(|error| format!("failing entrypoint could not launch its child: {error}"))?;
return child
.join()
.await
.map_err(|error| format!("intentional child failure: {error}"));
}
#[cfg(not(target_arch = "wasm32"))]
Err("intentional child failure".to_owned())
}
#[clusterflux::main(name = "restart")]
pub async fn restart_main() -> i32 {
#[cfg(target_arch = "wasm32")]
{
return clusterflux::spawn::task_with_arg(0_i32, |value| task_trap(value))
.task_id("task_trap")
.name("edited restart probe")
.failure_policy(clusterflux::spawn::TaskFailurePolicy::AwaitOperator)
.start()
.await
.expect("restart probe should launch its child")
.join()
.await
.expect("restart probe child should complete");
}
#[cfg(not(target_arch = "wasm32"))]
task_add_one(41)
}
#[clusterflux::main(name = "park-wake")]
pub async fn park_wake_main() -> i32 {
#[cfg(target_arch = "wasm32")]
{
let mut value = 0_i32;
for _ in 0..16 {
let next = clusterflux::spawn::task_with_arg(value, |input| task_add_one(input))
.task_id("task_add_one")
.name("park/wake fuel refill probe")
.start()
.await
.expect("park/wake probe should launch")
.join()
.await
.expect("park/wake probe should complete");
value = i32::try_from(next).expect("park/wake result should remain in i32 range");
}
return value;
}
#[cfg(not(target_arch = "wasm32"))]
16
}
#[clusterflux::main(name = "long-join")]
pub async fn long_join_main() -> i32 {
#[cfg(target_arch = "wasm32")]
{
let source = clusterflux::spawn::async_task(prepare_source)
.name("prepare source for controlled long-running task")
.start()
.await
.expect("long join source preparation should launch")
.join()
.await
.expect("long join source preparation should complete");
return clusterflux::spawn::async_task_with_arg(source, long_join_probe)
.name("controlled task longer than two minutes")
.env(linux_env())
.start()
.await
.expect("long join probe should launch")
.join()
.await
.expect("long join probe should remain joinable beyond two minutes");
}
#[cfg(not(target_arch = "wasm32"))]
0
}
#[clusterflux::main(name = "identity")]
pub async fn identity_main() -> Vec<String> {
#[cfg(target_arch = "wasm32")]
{
let source = clusterflux::spawn::async_task(prepare_source)
.name("prepare source for identity probes")
.start()
.await
.expect("identity source preparation should launch")
.join()
.await
.expect("identity source preparation should complete");
let slow = clusterflux::spawn::async_task_with_arg(
IdentityProbeInput {
source: source.clone(),
label: "slow-first".to_owned(),
delay_seconds: 30,
},
identity_probe,
)
.name("identity probe slow")
.env(linux_env())
.start()
.await
.expect("slow identity probe should launch");
let fast = clusterflux::spawn::async_task_with_arg(
IdentityProbeInput {
source,
label: "fast-second".to_owned(),
delay_seconds: 20,
},
identity_probe,
)
.name("identity probe fast")
.env(linux_env())
.start()
.await
.expect("fast identity probe should launch");
let fast_result = fast
.join()
.await
.expect("fast identity probe should complete first");
let slow_result = slow
.join()
.await
.expect("slow identity probe should remain independently joinable");
return vec![fast_result, slow_result];
}
#[cfg(not(target_arch = "wasm32"))]
vec!["fast-second".to_owned(), "slow-first".to_owned()]
}
pub async fn run_build_workflow() -> BuildReport {
let source = clusterflux::spawn::async_task(prepare_source)
.name("prepare source snapshot")
.start()
.await
.unwrap()
.join()
.await
.unwrap();
let linux = clusterflux::spawn::async_task_with_arg(source.clone(), compile_linux)
.name("compile linux")
.env(linux_env())
.start()
.await
.unwrap();
let linux_parallel = clusterflux::spawn::async_task_with_arg(source.clone(), compile_linux)
.name("compile linux in parallel")
.env(linux_env())
.start()
.await
.unwrap();
let linux_thread = linux.virtual_thread_id();
let linux_parallel_thread = linux_parallel.virtual_thread_id();
let linux_artifact = linux.join().await.unwrap();
let linux_parallel_artifact = linux_parallel.join().await.unwrap();
assert_eq!(linux_artifact.digest, linux_parallel_artifact.digest);
let package = clusterflux::spawn::async_task_with_arg(
PackageInput {
release_name: "release.tar".to_owned(),
source: source.clone(),
executable: Some(linux_artifact.clone()),
inputs: vec![linux_artifact.clone()],
},
package_release,
)
.name("package artifacts")
.env(linux_env())
.start()
.await
.unwrap();
let package_thread = package.virtual_thread_id();
let package_artifact = package.join().await.unwrap();
BuildReport {
linux_thread,
linux_parallel_thread,
package_thread,
linux_artifact,
package_artifact,
source,
}
}
#[cfg(test)]
mod tests {
use futures_executor::block_on;
use super::*;
#[test]
fn flagship_workflow_is_rust_source_with_spawned_virtual_tasks() {
let main_report = block_on(build_main());
assert_eq!(
main_report.linux_artifact.id,
"hello-clusterflux-native-test"
);
assert_eq!(task_add_one(41), 42);
assert_eq!(block_on(restart_main()), 42);
assert_eq!(block_on(park_wake_main()), 16);
assert_eq!(block_on(long_join_main()), 0);
assert_eq!(
block_on(identity_main()),
vec!["fast-second".to_owned(), "slow-first".to_owned()]
);
assert_eq!(linux_env().name, "linux");
assert_eq!(windows_env().name, "windows");
let report = block_on(run_build_workflow());
assert_ne!(report.linux_thread, report.package_thread);
assert_ne!(report.linux_thread, report.linux_parallel_thread);
assert_eq!(report.linux_artifact.id, "hello-clusterflux-native-test");
assert_eq!(report.package_artifact.id, "release-native-test");
assert_eq!(
report.source.digest,
"sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
);
}
}