From 6d809cb278b3b22eb8e9603543feb52a159a2658 Mon Sep 17 00:00:00 2001 From: bellman Date: Fri, 15 May 2026 09:37:17 +0900 Subject: [PATCH] omx(team): auto-checkpoint worker-1 [1] --- rust/crates/runtime/src/task_packet.rs | 97 ++++++++++++++++++++++++++ rust/crates/tools/src/lib.rs | 20 ++++++ 2 files changed, 117 insertions(+) diff --git a/rust/crates/runtime/src/task_packet.rs b/rust/crates/runtime/src/task_packet.rs index a97ffefb..9c061d69 100644 --- a/rust/crates/runtime/src/task_packet.rs +++ b/rust/crates/runtime/src/task_packet.rs @@ -357,4 +357,101 @@ mod tests { serde_json::from_str(&serialized).expect("packet should deserialize"); assert_eq!(deserialized, packet); } + + #[test] + fn legacy_packet_json_deserializes_with_defaults() { + let legacy = r#"{ + "objective": "Ship legacy task packet", + "scope": "module", + "scope_path": "runtime/task system", + "repo": "claw-code-parity", + "worktree": "/tmp/wt-legacy", + "branch_policy": "origin/main only", + "acceptance_tests": ["cargo test --workspace"], + "commit_policy": "single verified commit", + "reporting_contract": "print build result, test result, commit sha", + "escalation_policy": "manual escalation" + }"#; + + let packet: TaskPacket = serde_json::from_str(legacy).expect("legacy packet should parse"); + + assert_eq!(packet.acceptance_criteria, Vec::::new()); + assert_eq!( + packet.permission_profile, + TaskPermissionProfile::WorkspaceWrite + ); + assert_eq!(packet.model, None); + assert_eq!(packet.provider, None); + assert!(packet.recovery_policy.is_empty()); + assert_eq!(packet.commit_policy, "single verified commit"); + assert_eq!( + packet.reporting_contract, + "print build result, test result, commit sha" + ); + assert_eq!(packet.escalation_policy, "manual escalation"); + validate_packet(packet).expect("legacy packet should remain valid"); + } + + #[test] + fn new_schema_fields_validate_without_legacy_acceptance_tests() { + let mut packet = sample_packet(); + packet.acceptance_tests.clear(); + packet.commit_policy.clear(); + packet.reporting_contract.clear(); + packet.escalation_policy.clear(); + + validate_packet(packet).expect("new schema fields should be sufficient"); + } + + #[test] + fn scoped_packets_require_scope_path() { + for scope in [TaskScope::Module, TaskScope::SingleFile, TaskScope::Custom] { + let mut packet = sample_packet(); + packet.scope = scope; + packet.scope_path = Some(" ".to_string()); + + let error = validate_packet(packet).expect_err("scoped packet should require path"); + assert!(error + .errors() + .contains(&format!("scope_path is required for scope '{scope}'"))); + } + } + + #[test] + fn modern_required_groups_report_missing_fallbacks() { + let mut packet = sample_packet(); + packet.acceptance_criteria.clear(); + packet.acceptance_tests.clear(); + packet.recovery_policy.clear(); + packet.escalation_policy.clear(); + packet.reporting_targets.clear(); + packet.reporting_contract.clear(); + + let error = validate_packet(packet).expect_err("packet should require task policies"); + + for expected in [ + "acceptance_criteria or legacy acceptance_tests must contain at least one value", + "recovery_policy or legacy escalation_policy must not be empty", + "reporting_targets or legacy reporting_contract must not be empty", + ] { + assert!(error.errors().contains(&expected.to_string())); + } + } + + #[test] + fn permission_profile_variants_deserialize() { + for (raw, expected) in [ + ("read_only", TaskPermissionProfile::ReadOnly), + ("workspace_write", TaskPermissionProfile::WorkspaceWrite), + ( + "danger_full_access", + TaskPermissionProfile::DangerFullAccess, + ), + ] { + let value = format!(r#""{raw}""#); + let actual: TaskPermissionProfile = + serde_json::from_str(&value).expect("permission profile should parse"); + assert_eq!(actual, expected); + } + } } diff --git a/rust/crates/tools/src/lib.rs b/rust/crates/tools/src/lib.rs index e7016f71..2777bebf 100644 --- a/rust/crates/tools/src/lib.rs +++ b/rust/crates/tools/src/lib.rs @@ -10170,6 +10170,26 @@ printf 'pwsh:%s' "$1" assert_eq!(output["prompt"], "Ship packetized runtime task"); assert_eq!(output["description"], "runtime/task system"); assert_eq!(output["task_packet"]["repo"], "claw-code-parity"); + assert_eq!( + output["task_packet"]["files"][0], + "rust/crates/runtime/src/task_packet.rs" + ); + assert_eq!(output["task_packet"]["resources"][0], "ROADMAP.md#phase-4"); + assert_eq!( + output["task_packet"]["acceptance_criteria"][0], + "packet-backed task is created" + ); + assert_eq!(output["task_packet"]["model"], "gpt-5.5"); + assert_eq!(output["task_packet"]["provider"], "openai"); + assert_eq!( + output["task_packet"]["permission_profile"], + "workspace_write" + ); + assert_eq!( + output["task_packet"]["verification_plan"][0], + "cargo test -p tools run_task_packet" + ); + assert_eq!(output["task_packet"]["reporting_targets"][0], "stdout json"); assert_eq!( output["task_packet"]["acceptance_tests"][1], "cargo test --workspace"