use supercode_harness::{
ClaudeBackgroundState, ClaudeRuntimeManifest, Session, CLAUDE_RUNTIME_MANIFEST_VERSION,
};
fn assistant_call(id: &str, name: &str, input: serde_json::Value, timestamp: &str) -> String {
serde_json::json!({
"type": "assistant",
"timestamp": timestamp,
"entrypoint": "cli",
"userType": "external",
"version": "2.1.197",
"cwd": "/tmp/fleet",
"message": {
"role": "assistant",
"content": [{"type": "tool_use", "id": id, "name": name, "input": input}]
}
})
.to_string()
}
fn tool_result(
id: &str,
content: serde_json::Value,
timestamp: &str,
tool_use_result: Option<serde_json::Value>,
) -> String {
let mut value = serde_json::json!({
"type": "user",
"timestamp": timestamp,
"message": {
"role": "user",
"content": [{"type": "tool_result", "tool_use_id": id, "content": content}]
}
});
if let Some(result) = tool_use_result {
value["toolUseResult"] = result;
}
value.to_string()
}
fn load(lines: Vec<String>) -> Session {
Session::from_claude_code_str(&(lines.join("\n") + "\n")).unwrap()
}
#[test]
fn runtime_result_recorded_before_call_is_correlated_after_disk_reload() {
let result = tool_result(
"wake-forward-reference",
serde_json::json!("Next wakeup scheduled for 10:08:02 (in 300s). Nothing more to do this turn — the harness re-invokes you when the wakeup fires or a task-notification arrives."),
"2026-07-14T10:03:03Z",
None,
);
let call = assistant_call(
"wake-forward-reference",
"ScheduleWakeup",
serde_json::json!({
"delaySeconds": 300,
"reason": "later",
"prompt": "inspect after the delay"
}),
"2026-07-14T10:03:02Z",
);
let jsonl = format!("{result}\n{call}\n");
let path = std::env::temp_dir().join(format!(
"supercode-claude-runtime-forward-reference-{}.jsonl",
std::process::id()
));
std::fs::write(&path, jsonl.as_bytes()).unwrap();
let session = Session::from_claude_code(&path).unwrap();
std::fs::remove_file(&path).unwrap();
assert_eq!(session.raw, vec![result, call]);
let manifest = ClaudeRuntimeManifest::from_session(&session).unwrap();
assert_eq!(manifest.pending_wakeups.len(), 1);
let wakeup = &manifest.pending_wakeups[0];
assert_eq!(wakeup.tool_use_id, "wake-forward-reference");
assert_eq!(wakeup.delay_seconds, 300);
assert_eq!(wakeup.prompt.as_deref(), Some("inspect after the delay"));
assert_eq!(
manifest
.residue
.iter()
.map(|record| record.line)
.collect::<Vec<_>>(),
vec![1, 2],
"verbatim runtime residue must remain in source order"
);
let manifest_path = std::env::temp_dir().join(format!(
"supercode-claude-runtime-forward-reference-{}.json",
std::process::id()
));
std::fs::write(&manifest_path, manifest.to_pretty_json().unwrap()).unwrap();
let reloaded: ClaudeRuntimeManifest =
serde_json::from_slice(&std::fs::read(&manifest_path).unwrap()).unwrap();
std::fs::remove_file(manifest_path).unwrap();
assert_eq!(reloaded, manifest);
}
#[test]
fn recurring_result_overrides_omitted_request_flag_and_survives_first_fire() {
const HOUR: i64 = 1_700_002_800;
let lines = vec![
assistant_call(
"create-recurring-with-defaulted-input",
"CronCreate",
serde_json::json!({
"cron": "1 * * * *",
"durable": false,
"prompt": "keep watching"
}),
"2023-11-14T23:00:00.000Z",
),
tool_result(
"create-recurring-with-defaulted-input",
serde_json::json!(
"Scheduled recurring job recurring-default (1 * * * *). Session-only."
),
"2023-11-14T23:00:01.000Z",
None,
),
];
let mut manifest = ClaudeRuntimeManifest::from_session(&load(lines)).unwrap();
assert_eq!(manifest.active_crons.len(), 1);
assert!(
manifest.active_crons[0].recurring,
"the unambiguous success result describes the job Claude actually created"
);
manifest.activate_scheduler(HOUR).unwrap();
let due = manifest.claim_due(HOUR + 60).unwrap();
assert_eq!(due.len(), 1);
assert_eq!(due[0].id, "recurring-default");
manifest.complete_delivery(due[0].kind, &due[0].id).unwrap();
assert_eq!(manifest.active_crons.len(), 1);
assert_eq!(manifest.active_crons[0].id, "recurring-default");
assert!(manifest.next_due(HOUR + 60).unwrap().unwrap().due_unix > HOUR + 60);
}
#[test]
fn create_delete_create_fold_is_stable_and_persistable() {
let wake_prompt = "wake and inspect";
let notification = "<task-notification>\n<task-id>child-1</task-id>\n<tool-use-id>agent-call</tool-use-id>\n<status>completed</status>\n<summary>Agent finished</summary>\n</task-notification>";
let lines = vec![
assistant_call(
"create-old",
"CronCreate",
serde_json::json!({
"cron": "*/10 * * * *",
"recurring": true,
"durable": false,
"prompt": "old prompt"
}),
"2026-07-14T10:00:00Z",
),
tool_result(
"create-old",
serde_json::json!("Scheduled recurring job old123 (*/10 * * * *). Session-only (not written to disk, dies when Claude exits). Auto-expires after 7 days. Use CronDelete to cancel sooner."),
"2026-07-14T10:00:01Z",
None,
),
assistant_call(
"delete-old",
"CronDelete",
serde_json::json!({"id": "old123"}),
"2026-07-14T10:01:00Z",
),
tool_result(
"delete-old",
serde_json::json!("Cancelled job old123."),
"2026-07-14T10:01:01Z",
None,
),
assistant_call(
"create-new",
"CronCreate",
serde_json::json!({
"cron": "6,26,46 * * * *",
"recurring": true,
"durable": true,
"prompt": "pilot tick"
}),
"2026-07-14T10:02:00Z",
),
tool_result(
"create-new",
serde_json::json!("Scheduled recurring job new456 (6,26,46 * * * *). Session-only (not written to disk, dies when Claude exits). Auto-expires after 7 days. Use CronDelete to cancel sooner."),
"2026-07-14T10:02:01Z",
None,
),
assistant_call(
"wake-fired",
"ScheduleWakeup",
serde_json::json!({"delaySeconds": 30, "reason": "soon", "prompt": wake_prompt}),
"2026-07-14T10:03:00Z",
),
tool_result(
"wake-fired",
serde_json::json!("Next wakeup scheduled for 10:03:30 (in 30s). Nothing more to do this turn — the harness re-invokes you when the wakeup fires or a task-notification arrives."),
"2026-07-14T10:03:01Z",
None,
),
assistant_call(
"wake-pending",
"ScheduleWakeup",
serde_json::json!({"delaySeconds": 300, "reason": "later"}),
"2026-07-14T10:03:02Z",
),
tool_result(
"wake-pending",
serde_json::json!("Next wakeup scheduled for 10:08:02 (in 300s). Nothing more to do this turn — the harness re-invokes you when the wakeup fires or a task-notification arrives."),
"2026-07-14T10:03:03Z",
None,
),
assistant_call(
"agent-call",
"Agent",
serde_json::json!({
"description": "Pilot tick",
"subagent_type": "pilot-tick",
"model": "sonnet",
"prompt": "inspect fleet"
}),
"2026-07-14T10:04:00Z",
),
tool_result(
"agent-call",
serde_json::json!([{"type":"text", "text":"Async agent launched successfully."}]),
"2026-07-14T10:04:01Z",
Some(serde_json::json!({
"isAsync": true,
"status": "async_launched",
"agentId": "child-1",
"resolvedModel": "claude-sonnet-5",
"outputFile": "/tmp/child-1.output"
})),
),
serde_json::json!({
"type": "queue-operation",
"operation": "enqueue",
"content": wake_prompt,
"timestamp": "2026-07-14T10:04:02Z"
})
.to_string(),
serde_json::json!({
"type": "queue-operation",
"operation": "dequeue",
"timestamp": "2026-07-14T10:04:03Z"
})
.to_string(),
serde_json::json!({
"type": "queue-operation",
"operation": "enqueue",
"content": notification,
"timestamp": "2026-07-14T10:04:04Z"
})
.to_string(),
serde_json::json!({
"type": "queue-operation",
"operation": "dequeue",
"timestamp": "2026-07-14T10:04:05Z"
})
.to_string(),
serde_json::json!({
"type": "permission-mode",
"permissionMode": "bypassPermissions",
"sessionId": "session"
})
.to_string(),
serde_json::json!({
"type": "last-prompt",
"lastPrompt": "continue",
"leafUuid": "leaf-latest",
"sessionId": "session"
})
.to_string(),
serde_json::json!({
"type": "system",
"subtype": "turn_duration",
"pendingBackgroundAgentCount": 0,
"timestamp": "2026-07-14T10:05:00Z"
})
.to_string(),
];
let manifest = ClaudeRuntimeManifest::from_session(&load(lines)).unwrap();
assert_eq!(manifest.schema_version, CLAUDE_RUNTIME_MANIFEST_VERSION);
assert_eq!(
manifest.posture.permission_mode.as_deref(),
Some("bypassPermissions")
);
assert_eq!(
manifest.posture.last_prompt_leaf_uuid.as_deref(),
Some("leaf-latest")
);
assert_eq!(manifest.active_crons.len(), 1);
let cron = &manifest.active_crons[0];
assert_eq!(cron.id, "new456");
assert_eq!(cron.schedule, "6,26,46 * * * *");
assert!(cron.recurring);
assert!(cron.durable_requested);
assert_eq!(cron.expires_after_seconds, Some(604_800));
assert_eq!(manifest.pending_wakeups.len(), 1);
assert_eq!(manifest.pending_wakeups[0].tool_use_id, "wake-pending");
assert_eq!(manifest.queue.enqueued, 2);
assert_eq!(manifest.queue.dequeued, 2);
assert_eq!(manifest.queue.removed, 0);
assert!(manifest.queue.pending.is_empty());
assert_eq!(manifest.background_children.len(), 1);
let child = &manifest.background_children[0];
assert_eq!(child.agent_id.as_deref(), Some("child-1"));
assert!(child.origin_observed);
assert_eq!(child.resolved_model.as_deref(), Some("claude-sonnet-5"));
assert_eq!(child.state, ClaudeBackgroundState::Completed);
assert_eq!(manifest.reported_pending_background_children, Some(0));
assert!(manifest
.residue
.iter()
.any(|record| record.raw.contains("<task-notification>")));
let json = manifest.to_pretty_json().unwrap();
let path = std::env::temp_dir().join(format!(
"supercode-claude-runtime-state-{}.json",
std::process::id()
));
std::fs::write(&path, &json).unwrap();
let reloaded: ClaudeRuntimeManifest =
serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap();
std::fs::remove_file(path).unwrap();
assert_eq!(reloaded, manifest);
}
#[test]
fn unknown_successful_cron_delete_fails_loudly() {
let session = load(vec![
assistant_call(
"delete",
"CronDelete",
serde_json::json!({"id":"missing"}),
"2026-07-14T10:00:00Z",
),
tool_result(
"delete",
serde_json::json!("Cancelled job missing."),
"2026-07-14T10:00:01Z",
None,
),
]);
let error = ClaudeRuntimeManifest::from_session(&session).unwrap_err();
assert!(error.to_string().contains("unknown active job id missing"));
}
#[test]
fn invalid_cron_delete_with_error_result_is_preserved_without_mutation() {
let session = load(vec![
assistant_call(
"invalid-delete",
"CronDelete",
serde_json::json!({}),
"2026-07-14T10:00:00Z",
),
serde_json::json!({
"type": "user",
"timestamp": "2026-07-14T10:00:01Z",
"message": {
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": "invalid-delete",
"content": "InputValidationError: id is required",
"is_error": true
}]
},
"toolUseResult": "InputValidationError: id is required"
})
.to_string(),
]);
let manifest = ClaudeRuntimeManifest::from_session(&session).unwrap();
assert!(manifest.active_crons.is_empty());
assert!(manifest
.residue
.iter()
.any(|record| record.kind == "runtime-tool-call"));
assert!(manifest
.residue
.iter()
.any(|record| record.kind == "runtime-tool-result"));
}
#[test]
fn synthesized_plain_text_cron_list_reimports() {
let session = load(vec![
assistant_call(
"list",
"CronList",
serde_json::json!({}),
"2026-07-14T10:00:00Z",
),
tool_result(
"list",
serde_json::json!({
"execution_state": "paused",
"jobs": [{
"id": "imported-paused",
"cron": "*/20 * * * *",
"prompt": "preserve only",
"recurring": true,
"durable": true,
"state": "paused"
}]
})
.to_string()
.into(),
"2026-07-14T10:00:01Z",
None,
),
]);
let manifest = ClaudeRuntimeManifest::from_session(&session).unwrap();
assert_eq!(manifest.active_crons.len(), 1);
assert_eq!(manifest.active_crons[0].id, "imported-paused");
assert_eq!(manifest.active_crons[0].schedule, "*/20 * * * *");
}
#[test]
fn malformed_background_notification_reference_fails_loudly() {
let notification = "<task-notification>\n<status>completed</status>\n</task-notification>";
let session = load(vec![serde_json::json!({
"type": "queue-operation",
"operation": "enqueue",
"content": notification,
"timestamp": "2026-07-14T10:00:00Z"
})
.to_string()]);
let error = ClaudeRuntimeManifest::from_session(&session).unwrap_err();
assert!(error
.to_string()
.contains("missing tool-use-id and task-id"));
}
#[test]
fn queue_underflow_fails_loudly() {
let session = load(vec![serde_json::json!({
"type": "queue-operation",
"operation": "dequeue",
"timestamp": "2026-07-14T10:00:00Z"
})
.to_string()]);
let error = ClaudeRuntimeManifest::from_session(&session).unwrap_err();
assert!(error.to_string().contains("dequeue with an empty queue"));
}
#[test]
fn optional_real_claude_fixture_folds_without_provider() {
let Ok(path) = std::env::var("SUPERCODE_CLAUDE_RUNTIME_FIXTURE") else {
return;
};
let session = Session::from_claude_code(path).unwrap();
let manifest = ClaudeRuntimeManifest::from_session(&session).unwrap();
assert_eq!(manifest.schema_version, CLAUDE_RUNTIME_MANIFEST_VERSION);
assert!(!manifest.residue.is_empty());
}