story-kit: merge 141_story_improve_server_logging_with_timestamps_and_error_visibility

This commit is contained in:
Dave
2026-02-24 13:48:25 +00:00
parent b042c77fed
commit 73614fe5e8
4 changed files with 254 additions and 72 deletions

View File

@@ -1,5 +1,7 @@
use crate::agent_log::AgentLogWriter;
use crate::slog;
use crate::slog_error;
use crate::slog_warn;
use crate::config::ProjectConfig;
use crate::worktree::{self, WorktreeInfo};
use portable_pty::{CommandBuilder, PtySize, native_pty_system};
@@ -689,7 +691,7 @@ impl AgentPool {
let agents = match self.agents.lock() {
Ok(a) => a,
Err(e) => {
slog!("[pipeline] Failed to lock agents for '{story_id}:{agent_name}': {e}");
slog_error!("[pipeline] Failed to lock agents for '{story_id}:{agent_name}': {e}");
return;
}
};
@@ -707,14 +709,14 @@ impl AgentPool {
let completion = match completion {
Some(c) => c,
None => {
slog!("[pipeline] No completion report for '{story_id}:{agent_name}'");
slog_warn!("[pipeline] No completion report for '{story_id}:{agent_name}'");
return;
}
};
let project_root = match project_root {
Some(p) => p,
None => {
slog!("[pipeline] No project_root for '{story_id}:{agent_name}'");
slog_warn!("[pipeline] No project_root for '{story_id}:{agent_name}'");
return;
}
};
@@ -731,14 +733,14 @@ impl AgentPool {
"[pipeline] Coder '{agent_name}' passed gates for '{story_id}'. Moving to QA."
);
if let Err(e) = move_story_to_qa(&project_root, story_id) {
slog!("[pipeline] Failed to move '{story_id}' to 3_qa/: {e}");
slog_error!("[pipeline] Failed to move '{story_id}' to 3_qa/: {e}");
return;
}
if let Err(e) = self
.start_agent(&project_root, story_id, Some("qa"), None)
.await
{
slog!("[pipeline] Failed to start qa agent for '{story_id}': {e}");
slog_error!("[pipeline] Failed to start qa agent for '{story_id}': {e}");
}
// Coder slot is now free — pick up any other unassigned work in 2_current/.
self.auto_assign_available_work(&project_root).await;
@@ -756,7 +758,7 @@ impl AgentPool {
.start_agent(&project_root, story_id, Some(agent_name), Some(&context))
.await
{
slog!(
slog_error!(
"[pipeline] Failed to restart coder '{agent_name}' for '{story_id}': {e}"
);
}
@@ -771,7 +773,7 @@ impl AgentPool {
tokio::task::spawn_blocking(move || run_coverage_gate(&cp))
.await
.unwrap_or_else(|e| {
slog!("[pipeline] Coverage gate task panicked: {e}");
slog_warn!("[pipeline] Coverage gate task panicked: {e}");
Ok((false, format!("Coverage gate task panicked: {e}")))
});
let (coverage_passed, coverage_output) = match coverage_result {
@@ -784,14 +786,14 @@ impl AgentPool {
"[pipeline] QA passed gates and coverage for '{story_id}'. Moving to merge."
);
if let Err(e) = move_story_to_merge(&project_root, story_id) {
slog!("[pipeline] Failed to move '{story_id}' to 4_merge/: {e}");
slog_error!("[pipeline] Failed to move '{story_id}' to 4_merge/: {e}");
return;
}
if let Err(e) = self
.start_agent(&project_root, story_id, Some("mergemaster"), None)
.await
{
slog!("[pipeline] Failed to start mergemaster for '{story_id}': {e}");
slog_error!("[pipeline] Failed to start mergemaster for '{story_id}': {e}");
}
// QA slot is now free — pick up any other unassigned work in 3_qa/.
self.auto_assign_available_work(&project_root).await;
@@ -809,7 +811,7 @@ impl AgentPool {
.start_agent(&project_root, story_id, Some("qa"), Some(&context))
.await
{
slog!("[pipeline] Failed to restart qa for '{story_id}': {e}");
slog_error!("[pipeline] Failed to restart qa for '{story_id}': {e}");
}
}
} else {
@@ -826,7 +828,7 @@ impl AgentPool {
.start_agent(&project_root, story_id, Some("qa"), Some(&context))
.await
{
slog!("[pipeline] Failed to restart qa for '{story_id}': {e}");
slog_error!("[pipeline] Failed to restart qa for '{story_id}': {e}");
}
}
}
@@ -839,7 +841,7 @@ impl AgentPool {
let test_result = tokio::task::spawn_blocking(move || run_project_tests(&root))
.await
.unwrap_or_else(|e| {
slog!("[pipeline] Post-merge test task panicked: {e}");
slog_warn!("[pipeline] Post-merge test task panicked: {e}");
Ok((false, format!("Test task panicked: {e}")))
});
let (passed, output) = match test_result {
@@ -852,7 +854,7 @@ impl AgentPool {
"[pipeline] Post-merge tests passed for '{story_id}'. Archiving."
);
if let Err(e) = move_story_to_archived(&project_root, story_id) {
slog!("[pipeline] Failed to archive '{story_id}': {e}");
slog_error!("[pipeline] Failed to archive '{story_id}': {e}");
}
self.remove_agents_for_story(story_id);
// Mergemaster slot is now free — pick up any other items in 4_merge/.
@@ -886,7 +888,7 @@ impl AgentPool {
.start_agent(&project_root, story_id, Some("mergemaster"), Some(&context))
.await
{
slog!(
slog_error!(
"[pipeline] Failed to restart mergemaster for '{story_id}': {e}"
);
}
@@ -1211,7 +1213,7 @@ impl AgentPool {
let config = match ProjectConfig::load(project_root) {
Ok(c) => c,
Err(e) => {
slog!("[auto-assign] Failed to load project config: {e}");
slog_warn!("[auto-assign] Failed to load project config: {e}");
return;
}
};
@@ -1236,7 +1238,7 @@ impl AgentPool {
let agents = match self.agents.lock() {
Ok(a) => a,
Err(e) => {
slog!("[auto-assign] Failed to lock agents: {e}");
slog_error!("[auto-assign] Failed to lock agents: {e}");
break;
}
};
@@ -1612,7 +1614,7 @@ impl AgentPool {
let mut agents = match self.agents.lock() {
Ok(a) => a,
Err(e) => {
slog!("[agents] Failed to lock pool for cleanup of '{story_id}': {e}");
slog_error!("[agents] Failed to lock pool for cleanup of '{story_id}': {e}");
return 0;
}
};
@@ -1638,7 +1640,7 @@ impl AgentPool {
let mut agents = match self.agents.lock() {
Ok(a) => a,
Err(e) => {
slog!("[reaper] Failed to lock pool for TTL reaping: {e}");
slog_warn!("[reaper] Failed to lock pool for TTL reaping: {e}");
return 0;
}
};
@@ -2988,7 +2990,7 @@ fn run_agent_pty_blocking(
break;
}
Err(std::sync::mpsc::RecvTimeoutError::Timeout) => {
slog!(
slog_warn!(
"[agent:{story_id}:{agent_name}] Inactivity timeout after \
{inactivity_timeout_secs}s with no output. Killing process."
);