generated-scene: add command-center automation semantics

This commit is contained in:
木炎
2026-05-06 15:22:49 +08:00
parent 6122b521a8
commit 1d586dbe27
7 changed files with 894 additions and 15 deletions

View File

@@ -3893,6 +3893,84 @@ fn generator_emits_scheduled_monitoring_action_skill_package() {
assert!(test_status.success());
}
#[test]
fn command_center_materializes_automation_semantics_into_workflow_ir() {
let output_root = temp_workspace("sgclaw-command-center-automation-workflow-ir");
let skill_root = generate_scheduled_monitoring_action_skill_package(
GenerateScheduledMonitoringActionSkillRequest {
scene_id: "command-center-fee-control-monitor".to_string(),
scene_name: "指挥中心费控异常监测".to_string(),
output_root: output_root.clone(),
source_evidence_json: PathBuf::from(
"tests/fixtures/generated_scene/monitoring_action_source_evidence_extraction_2026-04-21.json",
),
ir_contract_json: PathBuf::from(
"tests/fixtures/generated_scene/scheduled_monitoring_action_ir_contract_2026-04-22.json",
),
trigger_contract_json: PathBuf::from(
"tests/fixtures/generated_scene/scheduled_monitoring_action_trigger_runtime_contract_2026-04-22.json",
),
},
)
.unwrap();
let workflow_ir: serde_json::Value = serde_json::from_str(
&fs::read_to_string(skill_root.join("references/workflow-ir.json")).unwrap(),
)
.unwrap();
let action_contracts = workflow_ir["actionContracts"]
.as_array()
.expect("expected actionContracts array");
assert!(
action_contracts.iter().any(|item| {
item["targetEndpointOrHostCall"] == "repetCtrlSend"
|| item["actionId"] == "dispatch_exception_order"
}),
"expected action contract for repetCtrlSend dispatch"
);
assert_eq!(
workflow_ir["iterationContract"]["sourceCollection"],
"pendingList",
"expected iteration contract over pendingList"
);
assert_eq!(
workflow_ir["iterationContract"]["iterationMode"],
"sequential_per_item",
"expected sequential per-item iteration"
);
let queue_transition_rules = workflow_ir["queueTransitionRules"]
.as_array()
.expect("expected queueTransitionRules array");
assert!(
queue_transition_rules.iter().any(|item| {
item["triggerPoint"] == "on_empty_collection"
|| item["transitionId"] == "queue_continue_on_empty"
}),
"expected queue continue transition for empty collection"
);
assert!(
queue_transition_rules.iter().any(|item| {
item["triggerPoint"] == "on_all_items_done"
|| item["transitionId"] == "queue_continue_on_done"
}),
"expected queue continue transition for completed collection"
);
let log_write_contracts = workflow_ir["logWriteContracts"]
.as_array()
.expect("expected logWriteContracts array");
assert!(
log_write_contracts.iter().any(|item| {
item["targetEndpointOrHostCall"] == "setDisposeLog"
|| item["logId"] == "dispose_log_after_dispatch"
}),
"expected dispose-log contract"
);
}
#[test]
fn generator_preserves_localhost_dependency_as_host_runtime_evidence() {
let analysis = analyze_scene_source(Path::new(