fix(team): surface runtime launch stages
This commit is contained in:
parent
9cfbb3898d
commit
6fb83676e7
4 changed files with 51 additions and 2 deletions
|
|
@ -54,6 +54,7 @@ const TRANSPORT_STAGE_LABELS: Record<string, string> = {
|
||||||
process_spawned: 'process spawned',
|
process_spawned: 'process spawned',
|
||||||
stdout_attached: 'stdout attached',
|
stdout_attached: 'stdout attached',
|
||||||
cli_started: 'CLI started',
|
cli_started: 'CLI started',
|
||||||
|
startup_checkpoint: 'startup checkpoint',
|
||||||
runtime_ready: 'runtime ready',
|
runtime_ready: 'runtime ready',
|
||||||
inbox_poller_ready: 'inbox poller ready',
|
inbox_poller_ready: 'inbox poller ready',
|
||||||
mailbox_bootstrap_written: 'bootstrap mailbox row written',
|
mailbox_bootstrap_written: 'bootstrap mailbox row written',
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,8 @@ const WORKSPACE_TRUST_FAILURE_PATTERN =
|
||||||
const BOOTSTRAP_TRANSPORT_EVIDENCE_PATTERN = new RegExp(
|
const BOOTSTRAP_TRANSPORT_EVIDENCE_PATTERN = new RegExp(
|
||||||
[
|
[
|
||||||
'mailbox_bootstrap_written',
|
'mailbox_bootstrap_written',
|
||||||
|
'startup_checkpoint',
|
||||||
|
'last runtime stage',
|
||||||
'bootstrap_prompt_observed',
|
'bootstrap_prompt_observed',
|
||||||
'bootstrap_submit_attempted',
|
'bootstrap_submit_attempted',
|
||||||
'bootstrap_submitted',
|
'bootstrap_submitted',
|
||||||
|
|
@ -341,13 +343,15 @@ export function extractLaunchBootstrapTransportBreadcrumb(
|
||||||
): LaunchBootstrapTransportBreadcrumb {
|
): LaunchBootstrapTransportBreadcrumb {
|
||||||
const parts = collectLaunchFailureSearchParts(input);
|
const parts = collectLaunchFailureSearchParts(input);
|
||||||
const combined = parts.join('\n');
|
const combined = parts.join('\n');
|
||||||
const lastStageMatches = [...combined.matchAll(/last transport stage:\s*([^;\n]+)/gi)];
|
const lastStageMatches = [
|
||||||
|
...combined.matchAll(/last (?:transport|runtime) stage:\s*([^;\n]+)/gi),
|
||||||
|
];
|
||||||
const retryableMatches = [
|
const retryableMatches = [
|
||||||
...combined.matchAll(/bootstrap_submit_rejected[^\n]*(?:retryable[=:]\s*(true|false))/gi),
|
...combined.matchAll(/bootstrap_submit_rejected[^\n]*(?:retryable[=:]\s*(true|false))/gi),
|
||||||
];
|
];
|
||||||
const evidence = firstEvidence(
|
const evidence = firstEvidence(
|
||||||
parts,
|
parts,
|
||||||
/bootstrap_submit_|mailbox_bootstrap_written|bootstrap_prompt_observed|bootstrap_submitted|last transport stage|no stdin data received|local prompt handler/i
|
/bootstrap_submit_|mailbox_bootstrap_written|startup_checkpoint|bootstrap_prompt_observed|bootstrap_submitted|last (?:transport|runtime) stage|no stdin data received|local prompt handler/i
|
||||||
).map(redactLaunchFailureArtifactText);
|
).map(redactLaunchFailureArtifactText);
|
||||||
const retryableRaw = retryableMatches.at(-1)?.[1]?.toLowerCase();
|
const retryableRaw = retryableMatches.at(-1)?.[1]?.toLowerCase();
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,30 @@ describe('ProcessBootstrapTransportEvidence', () => {
|
||||||
expect(summary?.lastStage).toBe('process spawned');
|
expect(summary?.lastStage).toBe('process spawned');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('surfaces headless startup checkpoints as transport progress', () => {
|
||||||
|
const summary = summarizeProcessBootstrapTransportEvents([
|
||||||
|
{
|
||||||
|
type: 'cli_started',
|
||||||
|
timestamp: '2026-05-07T10:00:00.000Z',
|
||||||
|
detail: 'teammateRuntime=headless',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'startup_checkpoint',
|
||||||
|
timestamp: '2026-05-07T10:00:01.000Z',
|
||||||
|
detail: 'commands_agents_loaded',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(summary).toMatchObject({
|
||||||
|
submitted: false,
|
||||||
|
hasProgress: true,
|
||||||
|
lastStage: 'startup checkpoint: commands_agents_loaded',
|
||||||
|
});
|
||||||
|
expect(buildProcessBootstrapTimeoutDiagnostic(summary!)).toBe(
|
||||||
|
'Bootstrap prompt was not submitted before timeout. Last transport stage: startup checkpoint: commands_agents_loaded'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('builds stable pending and timeout diagnostics from the last transport stage', () => {
|
it('builds stable pending and timeout diagnostics from the last transport stage', () => {
|
||||||
const summary = summarizeProcessBootstrapTransportEvents([
|
const summary = summarizeProcessBootstrapTransportEvents([
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,26 @@ describe('TeamLaunchFailureArtifactPack', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('extracts startup checkpoint runtime stages and keeps stdin warning secondary', () => {
|
||||||
|
const input = {
|
||||||
|
teamName: 'artifact-team',
|
||||||
|
runId: 'run-startup-checkpoint',
|
||||||
|
reason:
|
||||||
|
'alice: Teammate process alice@signal-ops did not become runtime_ready: timed out waiting for runtime_ready; last runtime stage: startup_checkpoint: commands_agents_loaded Last stderr: Warning: no stdin data received in 3s, proceeding without it.',
|
||||||
|
progressTraceLines: [
|
||||||
|
'startup_checkpoint detail=commands_agents_loaded',
|
||||||
|
'Warning: no stdin data received in 3s, proceeding without it.',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(classifyLaunchFailureArtifact(input).code).toBe('process_readiness_timeout');
|
||||||
|
expect(extractLaunchBootstrapTransportBreadcrumb(input)).toMatchObject({
|
||||||
|
lastTransportStage: 'startup_checkpoint: commands_agents_loaded',
|
||||||
|
noStdinWarning: true,
|
||||||
|
bootstrapSubmitted: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('keeps inbox poller bootstrap stalls out of stdin_missing classification', () => {
|
it('keeps inbox poller bootstrap stalls out of stdin_missing classification', () => {
|
||||||
const input = {
|
const input = {
|
||||||
teamName: 'artifact-team',
|
teamName: 'artifact-team',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue