pi-crew 0.9.50 → 0.9.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +150 -0
- package/README.md +216 -20
- package/dist/build-meta.json +2222 -1761
- package/dist/index.mjs +18636 -17603
- package/docs/actions-reference.md +431 -1
- package/package.json +19 -9
- package/schema.json +41 -0
- package/scripts/check-bundle-size.mjs +38 -0
- package/scripts/test-runner.mjs +11 -1
- package/skills/distill-software/SKILL.md +24 -1
- package/dist/index.mjs.map +0 -7
- package/docs/FEATURE_INTAKE.md +0 -126
- package/docs/HARNESS.md +0 -87
- package/docs/HARNESS_BACKLOG.md +0 -89
- package/docs/PROJECT_REVIEW.md +0 -270
- package/docs/PROJECT_REVIEW_FIXES.md +0 -342
- package/docs/PROJECT_REVIEW_ROUND4.md +0 -156
- package/docs/PROJECT_REVIEW_ROUND5.md +0 -86
- package/docs/REVIEW-FINDINGS-2026-06 +0 -357
- package/docs/REVIEW-FINDINGS-2026-07-CORE.md +0 -139
- package/docs/REVIEW-FINDINGS-2026-07.md +0 -125
- package/docs/TEST_MATRIX.md +0 -51
- package/docs/archive/README.md +0 -91
- package/docs/archive/followup-review-round3-2026-05-12.md +0 -342
- package/docs/archive/followup-review-round4-2026-05-13.md +0 -107
- package/docs/archive/pi-crew-bugs.md +0 -961
- package/docs/archive/pi-crew-test-final.md +0 -120
- package/docs/archive/pi-crew-test-results.md +0 -260
- package/docs/archive/pi-crew-test-round2.md +0 -136
- package/docs/archive/pi-crew-test-round4.md +0 -100
- package/docs/archive/pi-crew-test-round5.md +0 -70
- package/docs/archive/pi-crew-test-round6.md +0 -110
- package/docs/archive/pi-crew-v0.5.10-audit-fix-plan.md +0 -60
- package/docs/archive/pi-crew-v0.5.11-audit-fix-plan.md +0 -92
- package/docs/archive/pi-crew-v0.5.12-audit-fix-plan.md +0 -76
- package/docs/archive/pi-crew-v0.5.13-audit-fix-plan.md +0 -75
- package/docs/archive/pi-crew-v0.5.14-audit-fix-plan.md +0 -75
- package/docs/archive/pi-crew-v0.5.16-audit-fix-plan.md +0 -35
- package/docs/archive/pi-crew-v0.5.17-audit-fix-plan.md +0 -80
- package/docs/archive/pi-crew-v0.5.5-audit-fix-plan.md +0 -133
- package/docs/archive/pi-crew-v0.5.9-audit-fix-plan.md +0 -88
- package/docs/archive/pi-mono-opportunities.md +0 -969
- package/docs/archive/pi-mono-review.md +0 -291
- package/docs/archive/pi-subagent4-comparison.md +0 -261
- package/docs/archive/pi-subagents3-deep-analysis.md +0 -508
- package/docs/bugs/bug-021-notification-badge-counter-misleading.md +0 -293
- package/docs/bugs/bug-023-chain-windows-path-resolution.md +0 -106
- package/docs/bugs/bug-quota-display-truncation.md +0 -223
- package/docs/bugs/cross-session-notification-leakage.md +0 -82
- package/docs/code-review-2026-05-11.md +0 -592
- package/docs/coding-agent-optimization.md +0 -268
- package/docs/comparison-pi-subagents-vs-pi-crew.md +0 -303
- package/docs/decisions/0001-durable-state.md +0 -41
- package/docs/decisions/0002-child-process-for-async.md +0 -42
- package/docs/decisions/0003-depth-guard.md +0 -36
- package/docs/decisions/0004-execfile-over-exec.md +0 -34
- package/docs/decisions/0005-no-parameter-properties.md +0 -49
- package/docs/decisions/0006-publish-bundled-esm.md +0 -63
- package/docs/decisions/0007-active-run-binary-index.md +0 -54
- package/docs/decisions/0008-child-pi-warm-pool.md +0 -61
- package/docs/decisions/2026-07-21-broker-phase4-default-on.md +0 -77
- package/docs/decisions/2026-07-21-broker-windows-perms.md +0 -91
- package/docs/decisions/2026-07-22-broker-phase4-gated-on.md +0 -99
- package/docs/decisions/2026-07-24-oidc-trusted-publishing.md +0 -112
- package/docs/decisions/README.md +0 -26
- package/docs/deep-review-report.md +0 -384
- package/docs/distillation/cybersecurity-patterns.md +0 -294
- package/docs/feature-analysis-subagent4.md +0 -305
- package/docs/fix-plan-disabletools-exit-null.md +0 -219
- package/docs/fixes/BATCH_A_H1_H2.md +0 -86
- package/docs/fixes/bug-006-foreground-cancel-concurrent.md +0 -78
- package/docs/fixes/bug-007-async-notifier-stale-ctx.md +0 -112
- package/docs/fixes/bug-008-child-process-silent-timeout.md +0 -100
- package/docs/fixes/bug-009-executor-yield-limit-needs-attention.md +0 -75
- package/docs/fixes/bug-010-child-process-api-key-filtered.md +0 -109
- package/docs/fixes/bug-011-spawn-pi-enoent.md +0 -92
- package/docs/fixes/bug-012-essential-env-stripped.md +0 -89
- package/docs/fixes/bug-013-background-runner-death.md +0 -84
- package/docs/fixes/bug-014-infinite-retry-loop-needs-attention.md +0 -82
- package/docs/fixes/bug-015-background-runner-sigterm.md +0 -65
- package/docs/fixes/bug-017-background-runner-session-shutdown.md +0 -66
- package/docs/fixes/bug-017-background-runner-sigkill-double-fork.md +0 -28
- package/docs/fixes/bug-018-child-pi-worker-stdin-hang.md +0 -61
- package/docs/fixes/bug-019-phantom-runs-temp-workspace.md +0 -52
- package/docs/fixes/bug-020-infinite-retry-loop-needs-attention.md +0 -47
- package/docs/fixes/v0.9.10/locks-fix-verify.md +0 -3
- package/docs/fixes/v0.9.10/smoke-test.md +0 -12
- package/docs/followup-plan-2026-05-12.md +0 -463
- package/docs/followup-review-2026-05-12.md +0 -297
- package/docs/goals.md +0 -59
- package/docs/implementation-plan-top3.md +0 -333
- package/docs/issue-29-analysis.md +0 -189
- package/docs/live-mailbox-runtime.md +0 -36
- package/docs/migration/atomic-write-v2-migration.md +0 -299
- package/docs/next-upgrade-roadmap.md +0 -808
- package/docs/oh-my-pi-research.md +0 -509
- package/docs/optimization-plan-2026-07.md +0 -366
- package/docs/optimization-plan.md +0 -644
- package/docs/patterns/command-agent-skill.md +0 -71
- package/docs/perf/baseline-2026-05.md +0 -113
- package/docs/perf/final-report-2026-05.md +0 -206
- package/docs/perf/optimization-plan-2026-07-verified.md +0 -396
- package/docs/perf/performance-audit-report-2026-07.md +0 -948
- package/docs/perf/performance-review-2026-07.md +0 -287
- package/docs/perf/sprint-1-report.md +0 -71
- package/docs/perf/sprint-2-report.md +0 -81
- package/docs/perf/sprint-2.5-report.md +0 -53
- package/docs/perf/sprint-3-report.md +0 -36
- package/docs/perf/sprint-4-report.md +0 -47
- package/docs/perf/sprint-5-report.md +0 -51
- package/docs/perf/sprint-6-report.md +0 -94
- package/docs/perf/sprint-7-report.md +0 -74
- package/docs/perf/upgrade-plan-2026-05.md +0 -147
- package/docs/performance-optimization-execution-plan.md +0 -520
- package/docs/phase4-triage.md +0 -58
- package/docs/pi-crew-investigation-report.md +0 -411
- package/docs/product/README.md +0 -31
- package/docs/product/platform.md +0 -27
- package/docs/product/runtime-safety.md +0 -37
- package/docs/product/team-run.md +0 -39
- package/docs/product/team-tool.md +0 -37
- package/docs/runtime-analysis-child-vs-live.md +0 -171
- package/docs/runtime-migration-in-process-analysis.md +0 -250
- package/docs/skills/REFERENCE.md +0 -138
- package/docs/stories/README.md +0 -32
- package/docs/stories/US-DEPS-major-upgrade.md +0 -62
- package/docs/stories/backlog.md +0 -36
- package/docs/superpowers/plans/2026-06-09-fallow-patterns-adoption.md +0 -1270
- package/docs/templates/decision.md +0 -27
- package/docs/templates/story.md +0 -44
- package/docs/templates/validation-report.md +0 -32
- package/docs/ui-optimization-plan.md +0 -447
- package/src/adapters/claude-adapter.ts +0 -23
- package/src/adapters/codex-adapter.ts +0 -21
- package/src/adapters/cursor-adapter.ts +0 -17
- package/src/adapters/export-util.ts +0 -143
- package/src/adapters/index.ts +0 -15
- package/src/adapters/registry.ts +0 -18
- package/src/adapters/types.ts +0 -23
- package/src/agents/agent-config.ts +0 -194
- package/src/agents/agent-search.ts +0 -98
- package/src/agents/agent-serializer.ts +0 -38
- package/src/agents/discover-agents.ts +0 -623
- package/src/benchmark/benchmark-runner.ts +0 -313
- package/src/benchmark/feedback-loop.ts +0 -73
- package/src/config/config.ts +0 -1269
- package/src/config/defaults.ts +0 -193
- package/src/config/drift-detector.ts +0 -290
- package/src/config/markers.ts +0 -330
- package/src/config/resilient-parser.ts +0 -117
- package/src/config/role-tools.ts +0 -118
- package/src/config/suggestions.ts +0 -75
- package/src/config/types.ts +0 -278
- package/src/errors.ts +0 -194
- package/src/extension/action-suggestions.ts +0 -117
- package/src/extension/async-notifier.ts +0 -179
- package/src/extension/autonomous-policy.ts +0 -209
- package/src/extension/command-completions.ts +0 -120
- package/src/extension/context-status-injection.ts +0 -185
- package/src/extension/crew-autocomplete.ts +0 -131
- package/src/extension/crew-cleanup.ts +0 -168
- package/src/extension/crew-input-router.ts +0 -93
- package/src/extension/crew-shortcuts.ts +0 -87
- package/src/extension/crew-vibes/cat-frames.ts +0 -18
- package/src/extension/crew-vibes/config.ts +0 -195
- package/src/extension/crew-vibes/figures.ts +0 -101
- package/src/extension/crew-vibes/font-detect.ts +0 -71
- package/src/extension/crew-vibes/footer.ts +0 -292
- package/src/extension/crew-vibes/index.ts +0 -432
- package/src/extension/crew-vibes/provider-usage.ts +0 -396
- package/src/extension/crew-vibes/render.ts +0 -206
- package/src/extension/crew-vibes/speed.ts +0 -286
- package/src/extension/cross-extension-rpc.ts +0 -350
- package/src/extension/help.ts +0 -62
- package/src/extension/import-index.ts +0 -74
- package/src/extension/knowledge-injection.ts +0 -402
- package/src/extension/management.ts +0 -571
- package/src/extension/message-renderers.ts +0 -108
- package/src/extension/notification-router.ts +0 -152
- package/src/extension/notification-sink.ts +0 -54
- package/src/extension/pi-api.ts +0 -56
- package/src/extension/plan-orchestrate.ts +0 -302
- package/src/extension/project-init.ts +0 -170
- package/src/extension/register.ts +0 -113
- package/src/extension/registration/artifact-cleanup.ts +0 -20
- package/src/extension/registration/command-registration.ts +0 -58
- package/src/extension/registration/command-utils.ts +0 -58
- package/src/extension/registration/commands.ts +0 -1228
- package/src/extension/registration/compaction-guard.ts +0 -333
- package/src/extension/registration/context-builder.ts +0 -135
- package/src/extension/registration/crash-recovery-cache.ts +0 -54
- package/src/extension/registration/foreground-run-controller.ts +0 -238
- package/src/extension/registration/hook-registration.ts +0 -119
- package/src/extension/registration/lazy-configurers.ts +0 -124
- package/src/extension/registration/lifecycle-handlers.ts +0 -923
- package/src/extension/registration/lifecycle.ts +0 -259
- package/src/extension/registration/observability.ts +0 -322
- package/src/extension/registration/registration-types.ts +0 -158
- package/src/extension/registration/runtime-cleanup.ts +0 -230
- package/src/extension/registration/subagent-helpers.ts +0 -125
- package/src/extension/registration/subagent-manager-setup.ts +0 -330
- package/src/extension/registration/subagent-tools.ts +0 -456
- package/src/extension/registration/team-tool.ts +0 -220
- package/src/extension/registration/tool-registration.ts +0 -50
- package/src/extension/registration/ui.ts +0 -172
- package/src/extension/registration/viewers.ts +0 -121
- package/src/extension/registration/wire-cross-extension.ts +0 -37
- package/src/extension/result-watcher.ts +0 -139
- package/src/extension/rpc-hmac.ts +0 -256
- package/src/extension/run-bundle-schema.ts +0 -104
- package/src/extension/run-export.ts +0 -97
- package/src/extension/run-import.ts +0 -168
- package/src/extension/run-index.ts +0 -131
- package/src/extension/run-maintenance.ts +0 -190
- package/src/extension/session-summary.ts +0 -18
- package/src/extension/team-manager-command.ts +0 -153
- package/src/extension/team-onboard.ts +0 -177
- package/src/extension/team-recommendation.ts +0 -288
- package/src/extension/team-tool/anchor.ts +0 -172
- package/src/extension/team-tool/api.ts +0 -1244
- package/src/extension/team-tool/auto-summarize.ts +0 -142
- package/src/extension/team-tool/cache-control.ts +0 -19
- package/src/extension/team-tool/cancel.ts +0 -337
- package/src/extension/team-tool/chain-dispatch.ts +0 -95
- package/src/extension/team-tool/chain-executor.ts +0 -379
- package/src/extension/team-tool/config-patch.ts +0 -50
- package/src/extension/team-tool/context.ts +0 -149
- package/src/extension/team-tool/destructive-gate.ts +0 -52
- package/src/extension/team-tool/doctor.ts +0 -431
- package/src/extension/team-tool/explain.ts +0 -282
- package/src/extension/team-tool/failure-patterns.ts +0 -118
- package/src/extension/team-tool/goal-wrap.ts +0 -330
- package/src/extension/team-tool/goal.ts +0 -556
- package/src/extension/team-tool/handle-schedule.ts +0 -332
- package/src/extension/team-tool/handle-settings.ts +0 -520
- package/src/extension/team-tool/health-monitor.ts +0 -481
- package/src/extension/team-tool/inspect.ts +0 -88
- package/src/extension/team-tool/intent-policy.ts +0 -45
- package/src/extension/team-tool/lifecycle-actions.ts +0 -615
- package/src/extension/team-tool/orchestrate.ts +0 -98
- package/src/extension/team-tool/parallel-dispatch.ts +0 -183
- package/src/extension/team-tool/plan.ts +0 -50
- package/src/extension/team-tool/respond.ts +0 -150
- package/src/extension/team-tool/run-not-found.ts +0 -49
- package/src/extension/team-tool/run.ts +0 -1035
- package/src/extension/team-tool/status.ts +0 -260
- package/src/extension/team-tool/workflow-manage.ts +0 -261
- package/src/extension/team-tool-types.ts +0 -26
- package/src/extension/team-tool.ts +0 -1116
- package/src/extension/tool-result.ts +0 -16
- package/src/extension/validate-resources.ts +0 -108
- package/src/hooks/registry.ts +0 -200
- package/src/hooks/types.ts +0 -69
- package/src/i18n.ts +0 -212
- package/src/observability/correlation.ts +0 -50
- package/src/observability/event-bus.ts +0 -86
- package/src/observability/event-to-metric.ts +0 -170
- package/src/observability/exporters/adapter.ts +0 -27
- package/src/observability/exporters/otlp-exporter.ts +0 -356
- package/src/observability/exporters/prometheus-exporter.ts +0 -54
- package/src/observability/metric-registry.ts +0 -100
- package/src/observability/metric-retention.ts +0 -64
- package/src/observability/metric-sink.ts +0 -99
- package/src/observability/metrics-primitives.ts +0 -219
- package/src/plugins/plugin-define.ts +0 -6
- package/src/plugins/plugin-registry.ts +0 -32
- package/src/plugins/plugins/index.ts +0 -3
- package/src/plugins/plugins/nextjs.ts +0 -19
- package/src/plugins/plugins/vite.ts +0 -10
- package/src/plugins/plugins/vitest.ts +0 -9
- package/src/prompt/prompt-runtime.ts +0 -380
- package/src/runtime/adaptive-plan.ts +0 -563
- package/src/runtime/agent-control.ts +0 -215
- package/src/runtime/agent-memory.ts +0 -81
- package/src/runtime/agent-observability.ts +0 -122
- package/src/runtime/anchor-manager.ts +0 -475
- package/src/runtime/async-marker.ts +0 -32
- package/src/runtime/async-runner.ts +0 -381
- package/src/runtime/attention-events.ts +0 -28
- package/src/runtime/auto-summarize.ts +0 -344
- package/src/runtime/background-runner.ts +0 -837
- package/src/runtime/batch-barrier.ts +0 -147
- package/src/runtime/broker-issuer.ts +0 -37
- package/src/runtime/cancellation-token.ts +0 -99
- package/src/runtime/cancellation.ts +0 -99
- package/src/runtime/capability-inventory.ts +0 -137
- package/src/runtime/chain-parser.ts +0 -237
- package/src/runtime/chain-runner.ts +0 -606
- package/src/runtime/checkpoint.ts +0 -291
- package/src/runtime/child-pi-constants.ts +0 -42
- package/src/runtime/child-pi-kill.ts +0 -180
- package/src/runtime/child-pi-pool.ts +0 -68
- package/src/runtime/child-pi-spawn.ts +0 -287
- package/src/runtime/child-pi-steering.ts +0 -128
- package/src/runtime/child-pi-streams.ts +0 -296
- package/src/runtime/child-pi-transcript.ts +0 -169
- package/src/runtime/child-pi.ts +0 -1105
- package/src/runtime/coalesce-tasks.ts +0 -268
- package/src/runtime/code-summary.ts +0 -292
- package/src/runtime/command-trace.ts +0 -105
- package/src/runtime/compact-pipeline.ts +0 -56
- package/src/runtime/compact-stages/ansi-strip-stage.ts +0 -25
- package/src/runtime/compact-stages/blank-collapse-stage.ts +0 -31
- package/src/runtime/compact-stages/deduplicate-stage.ts +0 -34
- package/src/runtime/compact-stages/head-snap-stage.ts +0 -57
- package/src/runtime/compact-stages/index.ts +0 -23
- package/src/runtime/compact-stages/tail-capture-stage.ts +0 -77
- package/src/runtime/compact-stages/truncation-stage.ts +0 -74
- package/src/runtime/compaction-summary.ts +0 -278
- package/src/runtime/completion-guard.ts +0 -207
- package/src/runtime/concurrency.ts +0 -58
- package/src/runtime/crash-classification.ts +0 -229
- package/src/runtime/crash-recovery.ts +0 -577
- package/src/runtime/crew-agent-records.ts +0 -593
- package/src/runtime/crew-agent-runtime.ts +0 -62
- package/src/runtime/crew-broker-child.ts +0 -88
- package/src/runtime/crew-broker-client.ts +0 -673
- package/src/runtime/crew-broker-tokens.ts +0 -84
- package/src/runtime/crew-broker.ts +0 -1276
- package/src/runtime/crew-hooks.ts +0 -227
- package/src/runtime/cross-extension-rpc.ts +0 -143
- package/src/runtime/custom-tools/irc-tool.ts +0 -282
- package/src/runtime/custom-tools/submit-result-tool.ts +0 -102
- package/src/runtime/deadletter.ts +0 -47
- package/src/runtime/delivery-coordinator.ts +0 -211
- package/src/runtime/delta-conflict.ts +0 -348
- package/src/runtime/deterministic-ast.ts +0 -161
- package/src/runtime/diagnostic-export.ts +0 -171
- package/src/runtime/direct-run.ts +0 -45
- package/src/runtime/dwf-state-store.ts +0 -102
- package/src/runtime/dynamic-workflow-context.ts +0 -1016
- package/src/runtime/dynamic-workflow-runner.ts +0 -310
- package/src/runtime/effectiveness.ts +0 -90
- package/src/runtime/errors/crew-errors.ts +0 -162
- package/src/runtime/event-stream-bridge.ts +0 -98
- package/src/runtime/foreground-control.ts +0 -193
- package/src/runtime/foreground-watchdog.ts +0 -132
- package/src/runtime/global-worker-cap.ts +0 -96
- package/src/runtime/goal-achievement.ts +0 -148
- package/src/runtime/goal-evaluator.ts +0 -361
- package/src/runtime/goal-loop-runner.ts +0 -828
- package/src/runtime/goal-state-store.ts +0 -219
- package/src/runtime/green-contract.ts +0 -55
- package/src/runtime/group-join.ts +0 -267
- package/src/runtime/handoff-manager.ts +0 -598
- package/src/runtime/heartbeat-gradient.ts +0 -36
- package/src/runtime/heartbeat-watcher.ts +0 -239
- package/src/runtime/hidden-handoff.ts +0 -407
- package/src/runtime/important-line-classifier.ts +0 -140
- package/src/runtime/intercom-bridge.ts +0 -187
- package/src/runtime/iteration-hooks.ts +0 -305
- package/src/runtime/live-agent-control.ts +0 -136
- package/src/runtime/live-agent-manager.ts +0 -704
- package/src/runtime/live-control-realtime.ts +0 -56
- package/src/runtime/live-extension-bridge.ts +0 -148
- package/src/runtime/live-irc.ts +0 -97
- package/src/runtime/live-session-health.ts +0 -108
- package/src/runtime/live-session-runtime.ts +0 -1139
- package/src/runtime/loop-gates.ts +0 -128
- package/src/runtime/manifest-cache.ts +0 -375
- package/src/runtime/mcp-proxy.ts +0 -105
- package/src/runtime/metric-parser.ts +0 -36
- package/src/runtime/model-fallback.ts +0 -409
- package/src/runtime/model-resolver.ts +0 -126
- package/src/runtime/model-scope.ts +0 -158
- package/src/runtime/orphan-worker-registry.ts +0 -465
- package/src/runtime/output-validator.ts +0 -202
- package/src/runtime/overflow-recovery.ts +0 -206
- package/src/runtime/parallel-research.ts +0 -68
- package/src/runtime/parallel-utils.ts +0 -160
- package/src/runtime/parent-guard.ts +0 -134
- package/src/runtime/path-overlap.ts +0 -150
- package/src/runtime/peer-dep.ts +0 -292
- package/src/runtime/per-write-validator.ts +0 -181
- package/src/runtime/phase-progress.ts +0 -217
- package/src/runtime/phase-tracker.ts +0 -385
- package/src/runtime/pi-args.ts +0 -655
- package/src/runtime/pi-json-output.ts +0 -170
- package/src/runtime/pi-spawn.ts +0 -273
- package/src/runtime/pipeline-runner.ts +0 -523
- package/src/runtime/plan-templates.ts +0 -201
- package/src/runtime/policy-engine.ts +0 -115
- package/src/runtime/post-checks.ts +0 -142
- package/src/runtime/post-exit-stdio-guard.ts +0 -104
- package/src/runtime/process-lifecycle.ts +0 -491
- package/src/runtime/process-status.ts +0 -154
- package/src/runtime/progress-event-coalescer.ts +0 -44
- package/src/runtime/progress-tracker.ts +0 -124
- package/src/runtime/prose-compressor.ts +0 -162
- package/src/runtime/recovery-recipes.ts +0 -203
- package/src/runtime/replace.ts +0 -570
- package/src/runtime/resilient-edit.ts +0 -153
- package/src/runtime/result-extractor.ts +0 -213
- package/src/runtime/retry-executor.ts +0 -100
- package/src/runtime/retry-runner.ts +0 -336
- package/src/runtime/role-permission.ts +0 -59
- package/src/runtime/run-coalesced-task-group.ts +0 -308
- package/src/runtime/run-drift.ts +0 -219
- package/src/runtime/run-tracker.ts +0 -116
- package/src/runtime/runtime-policy.ts +0 -29
- package/src/runtime/runtime-resolver.ts +0 -172
- package/src/runtime/runtime-warmup.ts +0 -160
- package/src/runtime/scheduler.ts +0 -353
- package/src/runtime/semaphore.ts +0 -141
- package/src/runtime/sensitive-paths.ts +0 -93
- package/src/runtime/session-resources.ts +0 -25
- package/src/runtime/session-snapshot.ts +0 -59
- package/src/runtime/session-usage.ts +0 -79
- package/src/runtime/settings-store.ts +0 -155
- package/src/runtime/sidechain-output.ts +0 -35
- package/src/runtime/single-agent-compose.ts +0 -84
- package/src/runtime/skill-effectiveness.ts +0 -524
- package/src/runtime/skill-instructions.ts +0 -391
- package/src/runtime/stale-reconciler.ts +0 -680
- package/src/runtime/stream-preview.ts +0 -184
- package/src/runtime/streaming-output.ts +0 -50
- package/src/runtime/subagent-manager.ts +0 -561
- package/src/runtime/subprocess-tool-registry.ts +0 -70
- package/src/runtime/supervisor-contact.ts +0 -64
- package/src/runtime/task-display.ts +0 -52
- package/src/runtime/task-graph-scheduler.ts +0 -227
- package/src/runtime/task-graph.ts +0 -290
- package/src/runtime/task-health.ts +0 -83
- package/src/runtime/task-id.ts +0 -161
- package/src/runtime/task-output-context.ts +0 -602
- package/src/runtime/task-packet.ts +0 -268
- package/src/runtime/task-quality.ts +0 -199
- package/src/runtime/task-runner/capabilities.ts +0 -78
- package/src/runtime/task-runner/context-retrieval.ts +0 -163
- package/src/runtime/task-runner/live-executor.ts +0 -227
- package/src/runtime/task-runner/output-splitter.ts +0 -152
- package/src/runtime/task-runner/progress.ts +0 -157
- package/src/runtime/task-runner/prompt-builder.ts +0 -278
- package/src/runtime/task-runner/prompt-pipeline.ts +0 -88
- package/src/runtime/task-runner/result-utils.ts +0 -16
- package/src/runtime/task-runner/retrieval-orchestrator.ts +0 -310
- package/src/runtime/task-runner/run-projection.ts +0 -125
- package/src/runtime/task-runner/state-helpers.ts +0 -176
- package/src/runtime/task-runner/tail-read.ts +0 -34
- package/src/runtime/task-runner.ts +0 -1420
- package/src/runtime/team-runner-artifacts.ts +0 -13
- package/src/runtime/team-runner.ts +0 -1993
- package/src/runtime/tool-output-pruner.ts +0 -333
- package/src/runtime/tool-progress.ts +0 -278
- package/src/runtime/usage-tracker.ts +0 -73
- package/src/runtime/verification-gates.ts +0 -571
- package/src/runtime/verification-integrity.ts +0 -105
- package/src/runtime/verification-worktree.ts +0 -186
- package/src/runtime/worker-heartbeat.ts +0 -25
- package/src/runtime/worker-startup.ts +0 -83
- package/src/runtime/workflow-state.ts +0 -195
- package/src/runtime/workspace-lock.ts +0 -443
- package/src/runtime/workspace-tree.ts +0 -312
- package/src/runtime/yield-handler.ts +0 -224
- package/src/runtime/zombie-scanner.ts +0 -298
- package/src/schema/config-schema.ts +0 -327
- package/src/schema/team-tool-schema.ts +0 -415
- package/src/schema/validation-types.ts +0 -159
- package/src/skills/discover-skills.ts +0 -197
- package/src/skills/skill-templates.ts +0 -456
- package/src/skills/validate.ts +0 -285
- package/src/state/active-run-registry.ts +0 -439
- package/src/state/artifact-store.ts +0 -176
- package/src/state/atomic-write.ts +0 -903
- package/src/state/blob-store.ts +0 -308
- package/src/state/contracts.ts +0 -158
- package/src/state/crew-init.ts +0 -269
- package/src/state/decision-ledger.ts +0 -345
- package/src/state/event-log-rotation.ts +0 -342
- package/src/state/event-log.ts +0 -1311
- package/src/state/event-reconstructor.ts +0 -229
- package/src/state/gitignore-manager.ts +0 -46
- package/src/state/health-store.ts +0 -79
- package/src/state/hook-instinct-bridge.ts +0 -94
- package/src/state/hook-integrations.ts +0 -51
- package/src/state/instinct-store.ts +0 -275
- package/src/state/jsonl-writer.ts +0 -107
- package/src/state/locks.ts +0 -562
- package/src/state/mailbox.ts +0 -916
- package/src/state/observation-store.ts +0 -176
- package/src/state/run-cache.ts +0 -193
- package/src/state/run-graph.ts +0 -183
- package/src/state/run-metrics.ts +0 -165
- package/src/state/schedule.ts +0 -166
- package/src/state/session-state-map.ts +0 -51
- package/src/state/state-store.ts +0 -958
- package/src/state/task-claims.ts +0 -61
- package/src/state/tiered-eval.ts +0 -480
- package/src/state/types-eval.ts +0 -58
- package/src/state/types.ts +0 -440
- package/src/state/usage.ts +0 -138
- package/src/state/worker-atomic-writer.ts +0 -194
- package/src/subagents/async-entry.ts +0 -1
- package/src/subagents/index.ts +0 -3
- package/src/subagents/live/control.ts +0 -1
- package/src/subagents/live/manager.ts +0 -1
- package/src/subagents/live/realtime.ts +0 -1
- package/src/subagents/live/session-runtime.ts +0 -1
- package/src/subagents/manager.ts +0 -1
- package/src/subagents/spawn.ts +0 -1
- package/src/teams/discover-teams.ts +0 -187
- package/src/teams/team-config.ts +0 -27
- package/src/teams/team-serializer.ts +0 -38
- package/src/tools/safe-bash-extension.ts +0 -54
- package/src/tools/safe-bash.ts +0 -505
- package/src/types/diff.d.ts +0 -18
- package/src/types/new-api-types.ts +0 -35
- package/src/ui/agent-management-overlay.ts +0 -160
- package/src/ui/card-colors.ts +0 -139
- package/src/ui/crew-footer.ts +0 -102
- package/src/ui/crew-select-list.ts +0 -111
- package/src/ui/dashboard-panes/agents-pane.ts +0 -164
- package/src/ui/dashboard-panes/cancellation-pane.ts +0 -66
- package/src/ui/dashboard-panes/capability-pane.ts +0 -77
- package/src/ui/dashboard-panes/health-pane.ts +0 -31
- package/src/ui/dashboard-panes/mailbox-pane.ts +0 -35
- package/src/ui/dashboard-panes/metrics-pane.ts +0 -37
- package/src/ui/dashboard-panes/progress-pane.ts +0 -38
- package/src/ui/dashboard-panes/transcript-pane.ts +0 -10
- package/src/ui/deploy-bundled-themes.ts +0 -71
- package/src/ui/dwf-phase-display.ts +0 -151
- package/src/ui/dynamic-border.ts +0 -35
- package/src/ui/heartbeat-aggregator.ts +0 -74
- package/src/ui/key-utils.ts +0 -42
- package/src/ui/keybinding-map.ts +0 -248
- package/src/ui/layout-primitives.ts +0 -106
- package/src/ui/live-conversation-overlay.ts +0 -183
- package/src/ui/live-duration.ts +0 -55
- package/src/ui/live-run-sidebar.ts +0 -301
- package/src/ui/loaders.ts +0 -176
- package/src/ui/mascot.ts +0 -436
- package/src/ui/overlays/agent-picker-overlay.ts +0 -65
- package/src/ui/overlays/confirm-overlay.ts +0 -60
- package/src/ui/overlays/help-overlay.ts +0 -177
- package/src/ui/overlays/mailbox-compose-overlay.ts +0 -181
- package/src/ui/overlays/mailbox-compose-preview.ts +0 -78
- package/src/ui/overlays/mailbox-detail-overlay.ts +0 -154
- package/src/ui/pi-ui-compat.ts +0 -68
- package/src/ui/powerbar-publisher.ts +0 -459
- package/src/ui/render-coalescer.ts +0 -101
- package/src/ui/render-diff.ts +0 -160
- package/src/ui/render-scheduler.ts +0 -224
- package/src/ui/run-action-dispatcher.ts +0 -182
- package/src/ui/run-dashboard.ts +0 -913
- package/src/ui/run-event-bus.ts +0 -381
- package/src/ui/run-snapshot-cache.ts +0 -1057
- package/src/ui/settings-overlay.ts +0 -1067
- package/src/ui/snapshot-types.ts +0 -90
- package/src/ui/spinner.ts +0 -17
- package/src/ui/status-colors.ts +0 -143
- package/src/ui/syntax-highlight.ts +0 -136
- package/src/ui/terminal-status.ts +0 -269
- package/src/ui/theme-adapter.ts +0 -271
- package/src/ui/theme-discovery.ts +0 -199
- package/src/ui/tool-progress-formatter.ts +0 -93
- package/src/ui/tool-render.ts +0 -453
- package/src/ui/tool-renderers/brief-mode.ts +0 -225
- package/src/ui/tool-renderers/index.ts +0 -726
- package/src/ui/transcript-cache.ts +0 -128
- package/src/ui/transcript-entries.ts +0 -256
- package/src/ui/transcript-viewer.ts +0 -424
- package/src/ui/widget/index.ts +0 -357
- package/src/ui/widget/widget-formatters.ts +0 -182
- package/src/ui/widget/widget-model.ts +0 -110
- package/src/ui/widget/widget-renderer.ts +0 -182
- package/src/ui/widget/widget-types.ts +0 -36
- package/src/utils/bm25-search.ts +0 -235
- package/src/utils/completion-dedupe.ts +0 -63
- package/src/utils/conflict-detect.ts +0 -668
- package/src/utils/env-allowlist.ts +0 -30
- package/src/utils/env-filter.ts +0 -155
- package/src/utils/file-coalescer.ts +0 -98
- package/src/utils/fingerprint.ts +0 -180
- package/src/utils/frontmatter.ts +0 -70
- package/src/utils/fs-watch.ts +0 -37
- package/src/utils/gh-protocol.ts +0 -556
- package/src/utils/git.ts +0 -260
- package/src/utils/guards.ts +0 -107
- package/src/utils/ids.ts +0 -24
- package/src/utils/incremental-reader.ts +0 -220
- package/src/utils/internal-error.ts +0 -10
- package/src/utils/names.ts +0 -36
- package/src/utils/ndjson.ts +0 -115
- package/src/utils/paths.ts +0 -227
- package/src/utils/project-detector.ts +0 -160
- package/src/utils/redaction.ts +0 -347
- package/src/utils/resolve-shell.ts +0 -36
- package/src/utils/run-watcher-registry.ts +0 -152
- package/src/utils/safe-paths.ts +0 -383
- package/src/utils/scan-cache.ts +0 -144
- package/src/utils/session-utils.ts +0 -110
- package/src/utils/sleep.ts +0 -54
- package/src/utils/socket-path.ts +0 -127
- package/src/utils/sse-parser.ts +0 -129
- package/src/utils/task-name-generator.ts +0 -337
- package/src/utils/timings.ts +0 -33
- package/src/utils/token-counter.ts +0 -200
- package/src/utils/visual.ts +0 -207
- package/src/workflows/cost-estimator.ts +0 -34
- package/src/workflows/discover-workflows.ts +0 -290
- package/src/workflows/intermediate-store.ts +0 -166
- package/src/workflows/preflight-validator.ts +0 -168
- package/src/workflows/topology-analyzer.ts +0 -203
- package/src/workflows/validate-workflow.ts +0 -50
- package/src/workflows/workflow-config.ts +0 -70
- package/src/workflows/workflow-serializer.ts +0 -32
- package/src/worktree/branch-freshness.ts +0 -112
- package/src/worktree/cleanup.ts +0 -341
- package/src/worktree/worktree-manager.ts +0 -1200
|
@@ -1,961 +0,0 @@
|
|
|
1
|
-
# Historical Bug Reports (v0.2.x)
|
|
2
|
-
|
|
3
|
-
> **Current version: v0.9.0** — See [CHANGELOG.md](../CHANGELOG.md) for all bug fixes.
|
|
4
|
-
> This page tracks historical bugs from v0.2.x. All listed bugs are fixed.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# pi-crew v0.2.20 — Bug Report & Fixes
|
|
9
|
-
|
|
10
|
-
**Date:** 2026-05-19
|
|
11
|
-
**Session:** Comprehensive integration test + root cause analysis
|
|
12
|
-
**Environment:** linux/x64, Node v22.22.0, Pi CLI v0.75.3, pi-crew v0.2.20
|
|
13
|
-
**Status:** ✅ 14/14 bugs fixed (commits `de9e8b4` and `5dc794e`)
|
|
14
|
-
|
|
15
|
-
> **All bugs fixed ✅** — Source code verified. See [pi-crew-test-final.md](pi-crew-test-final.md) for end-to-end test results.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Bug #1: Background workers "heartbeat dead" — actually a MiniMax 429 Rate Limit
|
|
20
|
-
|
|
21
|
-
| Field | Value |
|
|
22
|
-
|---|---|
|
|
23
|
-
| **Severity** | 🔴 HIGH |
|
|
24
|
-
| **Status** | ✅ Fixed — 429 now retries with fallback models instead of blocking 300s |
|
|
25
|
-
| **Affected** | All background/async workers |
|
|
26
|
-
| **Symptom** | Workers time out after 300s with "heartbeat dead", zero output |
|
|
27
|
-
|
|
28
|
-
### Description
|
|
29
|
-
|
|
30
|
-
When running `team action='run'` with `async=true` or `Agent(run_in_background=true)`, workers spawn successfully (PID exists) but **time out after 300s** with a generic error:
|
|
31
|
-
```
|
|
32
|
-
worker.response_timeout: No output for 300000ms
|
|
33
|
-
crew.task.heartbeat_dead: Task 01_assess heartbeat dead.
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Root cause
|
|
37
|
-
|
|
38
|
-
**Fixed.** Previously the 429 rate limit was not retried because:
|
|
39
|
-
1. `RETRYABLE_MODEL_FAILURE_PATTERNS` had `/\b429\b/` but MiniMax returns `rate_limit_error: usage limit exceeded` (no clear "429" number)
|
|
40
|
-
2. 429 was fast-failed in `child-pi.ts onJsonEvent` instead of letting the task-runner handle retry with fallback
|
|
41
|
-
|
|
42
|
-
### Fix applied
|
|
43
|
-
|
|
44
|
-
1. **model-fallback.ts**: Added `/rate_limit_error/i` to `RETRYABLE_MODEL_FAILURE_PATTERNS` to correctly identify the MiniMax rate limit error
|
|
45
|
-
2. **model-fallback.ts**: Changed `/\b429\b/` → `/rate.?limit/i` to match more formats
|
|
46
|
-
3. **child-pi.ts**: Removed the 429 fast-fail — let the task-runner handle retry with the model fallback chain
|
|
47
|
-
|
|
48
|
-
### Model fallback chain
|
|
49
|
-
|
|
50
|
-
When the main model gets a 429:
|
|
51
|
-
1. Fall back to `fallbackModels` (if configured)
|
|
52
|
-
2. Fall back to other available models in the system
|
|
53
|
-
3. If there is no fallback and retries are exhausted → fail with the correct error message
|
|
54
|
-
|
|
55
|
-
**Recommended config:** Add `fallbackModels` to the agent config to have more options when the main model is rate-limited.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
|
|
59
|
-
## Bug #2: child-pi.ts does not detect 429 rate limit error — reports wrong "heartbeat dead"
|
|
60
|
-
|
|
61
|
-
| Field | Value |
|
|
62
|
-
|---|---|
|
|
63
|
-
| **Severity** | 🔴 HIGH |
|
|
64
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
65
|
-
| **Affected** | All child Pi workers |
|
|
66
|
-
| **Symptom** | Worker reports generic "No output for 300000ms" instead of "Provider rate limit: 429" |
|
|
67
|
-
|
|
68
|
-
### Description
|
|
69
|
-
|
|
70
|
-
The Pi CLI outputs JSON events for 429 errors very clearly:
|
|
71
|
-
```json
|
|
72
|
-
{"type":"turn_end","message":{"stopReason":"error","errorMessage":"429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\"...}}"}}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
But `child-pi.ts` **does not parse error events** — it only cares about:
|
|
76
|
-
- `isFinalAssistantEvent()` — to trigger the final drain
|
|
77
|
-
- `turn_end` — to count turns for turn limiting
|
|
78
|
-
|
|
79
|
-
Result: child-pi sees output (JSON events), **restarts the heartbeat timer**, but **does not recognize it as an error**. Pi blocks after 3 retries → heartbeat times out at 300s → generic error message.
|
|
80
|
-
|
|
81
|
-
### Code location
|
|
82
|
-
|
|
83
|
-
`/home/bom/source/my_pi/pi-crew/src/runtime/child-pi.ts`, line ~394:
|
|
84
|
-
```typescript
|
|
85
|
-
onJsonEvent: (event) => {
|
|
86
|
-
restartNoResponseTimer();
|
|
87
|
-
// Turn-count-based steering: only counts turns, does NOT check errors
|
|
88
|
-
if (event && typeof event === "object" && !Array.isArray(event)) {
|
|
89
|
-
const obj = event as Record<string, unknown>;
|
|
90
|
-
if (obj.type === "turn_end") {
|
|
91
|
-
turnCount += 1;
|
|
92
|
-
// ... turn limit logic only ...
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// MISSING: detect provider errors (429, auth, etc.)
|
|
96
|
-
}
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### Fix
|
|
100
|
-
|
|
101
|
-
Add provider error detection in `onJsonEvent`:
|
|
102
|
-
```typescript
|
|
103
|
-
let providerError: string | undefined;
|
|
104
|
-
|
|
105
|
-
// In onJsonEvent:
|
|
106
|
-
if (obj.type === "turn_end" && obj.message?.stopReason === "error") {
|
|
107
|
-
const errMsg = obj.message?.errorMessage || "";
|
|
108
|
-
if (errMsg && !providerError) providerError = errMsg;
|
|
109
|
-
// Fast-fail on rate limit — don't wait 300s
|
|
110
|
-
if (/429|rate.?limit/i.test(errMsg)) {
|
|
111
|
-
settle({ exitCode: 1, stdout, stderr: `Provider rate limit: ${errMsg.slice(0, 200)}` });
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### Impact
|
|
117
|
-
|
|
118
|
-
This fix changes the error message from:
|
|
119
|
-
```
|
|
120
|
-
❌ "Child Pi produced no new output for 300000ms; process was terminated as unresponsive."
|
|
121
|
-
```
|
|
122
|
-
to:
|
|
123
|
-
```
|
|
124
|
-
✅ "Provider rate limit: 429 rate_limit_error: usage limit exceeded, resets at 2026-05-19T05:00:00Z"
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
And it **fails fast** instead of waiting 300s.
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## Bug #3: background.log is useless — does not capture worker output
|
|
132
|
-
|
|
133
|
-
| Field | Value |
|
|
134
|
-
|---|---|
|
|
135
|
-
| **Severity** | 🟠 MEDIUM |
|
|
136
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
137
|
-
| **Affected** | Debugging experience for all background runs |
|
|
138
|
-
| **Symptom** | background.log contains only 1 line: `[pi-crew] background loader=jiti` |
|
|
139
|
-
|
|
140
|
-
### Description
|
|
141
|
-
|
|
142
|
-
When a background worker fails, the log file at `.crew/state/runs/<id>/background.log` contains only:
|
|
143
|
-
```
|
|
144
|
-
[pi-crew] background loader=jiti
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Missing:
|
|
148
|
-
- Worker stdout/stderr
|
|
149
|
-
- Error messages
|
|
150
|
-
- Provider responses
|
|
151
|
-
- Exit codes
|
|
152
|
-
|
|
153
|
-
### Cause
|
|
154
|
-
|
|
155
|
-
`async-runner.ts` line 130-145:
|
|
156
|
-
```typescript
|
|
157
|
-
const logFd = fs.openSync(logPath, "a");
|
|
158
|
-
// ...
|
|
159
|
-
const child = spawn(process.execPath, command.args, buildBackgroundSpawnOptions(manifest, logFd));
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
`buildBackgroundSpawnOptions` line 123-127:
|
|
163
|
-
```typescript
|
|
164
|
-
return {
|
|
165
|
-
cwd: manifest.cwd,
|
|
166
|
-
detached: true,
|
|
167
|
-
stdio: ["ignore", logFd, logFd], // stdout+stderr → background.log
|
|
168
|
-
// ...
|
|
169
|
-
};
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**The stdout/stderr of the background-runner** is written to background.log. But **child Pi workers** (spawned by the background-runner via child-pi.ts) **output to child-pi's pipe**, NOT to background.log.
|
|
173
|
-
|
|
174
|
-
Flow:
|
|
175
|
-
```
|
|
176
|
-
background-runner.ts (stdout→logFd, stderr→logFd)
|
|
177
|
-
→ loader=jiti → writes to log ✅
|
|
178
|
-
→ executeTeamRun()
|
|
179
|
-
→ child-pi.ts spawns child Pi (stdout→pipe, stderr→pipe)
|
|
180
|
-
→ Pi output → child-pi.ts captures → DOES NOT WRITE TO background.log ❌
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### Fix
|
|
184
|
-
|
|
185
|
-
1. **Option A:** In `child-pi.ts` or `team-runner.ts`, write worker output events to background.log
|
|
186
|
-
2. **Option B:** Add event log entries for provider errors (there is an event log, but not detailed enough)
|
|
187
|
-
3. **Option C:** Background-runner tees output to a log file
|
|
188
|
-
|
|
189
|
-
### Key file
|
|
190
|
-
|
|
191
|
-
```
|
|
192
|
-
pi-crew/src/runtime/async-runner.ts — buildBackgroundSpawnOptions(), spawnBackgroundTeamRun()
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
---
|
|
196
|
-
|
|
197
|
-
## Bug #4: worker-startup.ts missing "rate_limited" classification
|
|
198
|
-
|
|
199
|
-
| Field | Value |
|
|
200
|
-
|---|---|
|
|
201
|
-
| **Severity** | 🟡 LOW |
|
|
202
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
203
|
-
| **Affected** | Error classification and reporting |
|
|
204
|
-
| **Symptom** | 429 errors classified as "unknown" instead of "rate_limited" |
|
|
205
|
-
|
|
206
|
-
### Description
|
|
207
|
-
|
|
208
|
-
`worker-startup.ts` has the `StartupFailureClassification` type:
|
|
209
|
-
```typescript
|
|
210
|
-
export type StartupFailureClassification =
|
|
211
|
-
| "trust_required"
|
|
212
|
-
| "prompt_misdelivery"
|
|
213
|
-
| "prompt_acceptance_timeout"
|
|
214
|
-
| "transport_dead"
|
|
215
|
-
| "worker_crashed"
|
|
216
|
-
| "unknown";
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Missing `"rate_limited"` and `"provider_error"`. Result: 429 errors are classified as `"unknown"`.
|
|
220
|
-
|
|
221
|
-
### Fix
|
|
222
|
-
|
|
223
|
-
Add to the type and `classifyStartupFailure` function:
|
|
224
|
-
```typescript
|
|
225
|
-
export type StartupFailureClassification =
|
|
226
|
-
| "trust_required"
|
|
227
|
-
| "prompt_misdelivery"
|
|
228
|
-
| "prompt_acceptance_timeout"
|
|
229
|
-
| "transport_dead"
|
|
230
|
-
| "worker_crashed"
|
|
231
|
-
| "rate_limited" // NEW
|
|
232
|
-
| "provider_error" // NEW
|
|
233
|
-
| "unknown";
|
|
234
|
-
|
|
235
|
-
// In classifyStartupFailure:
|
|
236
|
-
if (evidence.stderrPreview && /429|rate.?limit/i.test(evidence.stderrPreview)) return "rate_limited";
|
|
237
|
-
if (evidence.stderrPreview && /5\d{2}|server.?error|internal.?error/i.test(evidence.stderrPreview)) return "provider_error";
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
### Key file
|
|
241
|
-
|
|
242
|
-
```
|
|
243
|
-
pi-crew/src/runtime/worker-startup.ts — StartupFailureClassification, classifyStartupFailure()
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
---
|
|
247
|
-
|
|
248
|
-
## Bug #5: Stale heartbeat notifications after prune
|
|
249
|
-
|
|
250
|
-
| Field | Value |
|
|
251
|
-
|---|---|
|
|
252
|
-
| **Severity** | 🟡 LOW (cosmetic) |
|
|
253
|
-
| **Status** | Confirmed |
|
|
254
|
-
| **Affected** | User experience |
|
|
255
|
-
| **Symptom** | "Task heartbeat dead" notifications for already-removed runs |
|
|
256
|
-
|
|
257
|
-
### Description
|
|
258
|
-
|
|
259
|
-
After running `team prune --keep=0 --confirm=true`, the background watcher still emits notifications for pruned runs:
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
→ team prune: Removed 9 runs
|
|
263
|
-
→ Notification: "agent_mpc423rq_1 heartbeat dead" (run not found)
|
|
264
|
-
→ Notification: "agent_mpc423rv_2 heartbeat dead" (run not found)
|
|
265
|
-
→ Notification: "agent_mpc423rw_3 heartbeat dead" (run not found)
|
|
266
|
-
→ Notification: "agent_mpc423rw_4 heartbeat dead" (run not found)
|
|
267
|
-
... (6+ stale notifications)
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
Each notification triggers `get_subagent_result` → returns "not found".
|
|
271
|
-
|
|
272
|
-
### Cause
|
|
273
|
-
|
|
274
|
-
The background watcher maintains a worker health-check queue. When runs are pruned:
|
|
275
|
-
1. The watcher does not deregister immediately
|
|
276
|
-
2. Notifications already in the queue still emit
|
|
277
|
-
3. The notifications arrive one by one, a few seconds apart
|
|
278
|
-
|
|
279
|
-
### Impact
|
|
280
|
-
|
|
281
|
-
- Confusing for the user: seeing "heartbeat dead" for runs that no longer exist
|
|
282
|
-
- Wasted context: each notification triggers 1 tool call to verify
|
|
283
|
-
|
|
284
|
-
### Fix
|
|
285
|
-
|
|
286
|
-
The background watcher should check run existence before emitting:
|
|
287
|
-
```typescript
|
|
288
|
-
// Before emitting heartbeat_dead:
|
|
289
|
-
if (!runExists(runId)) {
|
|
290
|
-
deregisterWorker(workerId); // Silent cleanup
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### Key files
|
|
296
|
-
|
|
297
|
-
```
|
|
298
|
-
pi-crew/src/runtime/worker-heartbeat.ts — isWorkerHeartbeatStale()
|
|
299
|
-
pi-crew/src/runtime/background-runner.ts — heartbeat monitoring loop
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
---
|
|
303
|
-
|
|
304
|
-
# pi-crew v0.2.20 — Bug Report
|
|
305
|
-
|
|
306
|
-
**Date:** 2026-05-19
|
|
307
|
-
**Session:** Comprehensive integration test + root cause analysis
|
|
308
|
-
**Environment:** linux/x64, Node v22.22.0, Pi CLI v0.75.3, pi-crew v0.2.20
|
|
309
|
-
|
|
310
|
-
---
|
|
311
|
-
|
|
312
|
-
## Bug #1: Background workers "heartbeat dead" — actually a MiniMax 429 Rate Limit
|
|
313
|
-
|
|
314
|
-
| Field | Value |
|
|
315
|
-
|---|---|
|
|
316
|
-
| **Severity** | 🔴 HIGH |
|
|
317
|
-
| **Status** | ✅ Fixed — 429 now retries with fallback models instead of blocking 300s |
|
|
318
|
-
| **Affected** | All background/async workers |
|
|
319
|
-
| **Symptom** | Workers time out after 300s with "heartbeat dead", zero output |
|
|
320
|
-
|
|
321
|
-
### Description
|
|
322
|
-
|
|
323
|
-
When running `team action='run'` with `async=true` or `Agent(run_in_background=true)`, workers spawn successfully (PID exists) but **time out after 300s** with a generic error:
|
|
324
|
-
```
|
|
325
|
-
worker.response_timeout: No output for 300000ms
|
|
326
|
-
crew.task.heartbeat_dead: Task 01_assess heartbeat dead.
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Root cause
|
|
330
|
-
|
|
331
|
-
**Fixed.** Previously the 429 rate limit was not retried because:
|
|
332
|
-
1. `RETRYABLE_MODEL_FAILURE_PATTERNS` had `/\b429\b/` but MiniMax returns `rate_limit_error: usage limit exceeded` (no clear "429" number)
|
|
333
|
-
2. 429 was fast-failed in `child-pi.ts onJsonEvent` instead of letting the task-runner handle retry with fallback
|
|
334
|
-
|
|
335
|
-
### Fix applied
|
|
336
|
-
|
|
337
|
-
1. **model-fallback.ts**: Added `/rate_limit_error/i` to `RETRYABLE_MODEL_FAILURE_PATTERNS` to correctly identify the MiniMax rate limit error
|
|
338
|
-
2. **model-fallback.ts**: Changed `/\b429\b/` → `/rate.?limit/i` to match more formats
|
|
339
|
-
3. **child-pi.ts**: Removed the 429 fast-fail — let the task-runner handle retry with the model fallback chain
|
|
340
|
-
|
|
341
|
-
### Model fallback chain
|
|
342
|
-
|
|
343
|
-
When the main model gets a 429:
|
|
344
|
-
1. Fall back to `fallbackModels` (if configured)
|
|
345
|
-
2. Fall back to other available models in the system
|
|
346
|
-
3. If there is no fallback and retries are exhausted → fail with the correct error message
|
|
347
|
-
|
|
348
|
-
**Recommended config:** Add `fallbackModels` to the agent config to have more options when the main model is rate-limited.
|
|
349
|
-
|
|
350
|
-
---
|
|
351
|
-
|
|
352
|
-
## Bug #2: child-pi.ts does not detect 429 rate limit error — reports wrong "heartbeat dead"
|
|
353
|
-
|
|
354
|
-
| Field | Value |
|
|
355
|
-
|---|---|
|
|
356
|
-
| **Severity** | 🔴 HIGH |
|
|
357
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
358
|
-
| **Affected** | All child Pi workers |
|
|
359
|
-
| **Symptom** | Worker reports generic "No output for 300000ms" instead of "Provider rate limit: 429" |
|
|
360
|
-
|
|
361
|
-
### Description
|
|
362
|
-
|
|
363
|
-
The Pi CLI outputs JSON events for 429 errors very clearly:
|
|
364
|
-
```json
|
|
365
|
-
{"type":"turn_end","message":{"stopReason":"error","errorMessage":"429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\"...}}"}}
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
But `child-pi.ts` **does not parse error events** — it only cares about:
|
|
369
|
-
- `isFinalAssistantEvent()` — to trigger the final drain
|
|
370
|
-
- `turn_end` — to count turns for turn limiting
|
|
371
|
-
|
|
372
|
-
Result: child-pi sees output (JSON events), **restarts the heartbeat timer**, but **does not recognize it as an error**. Pi blocks after 3 retries → heartbeat times out at 300s → generic error message.
|
|
373
|
-
|
|
374
|
-
### Code location
|
|
375
|
-
|
|
376
|
-
`/home/bom/source/my_pi/pi-crew/src/runtime/child-pi.ts`, line ~394:
|
|
377
|
-
```typescript
|
|
378
|
-
onJsonEvent: (event) => {
|
|
379
|
-
restartNoResponseTimer();
|
|
380
|
-
// Turn-count-based steering: only counts turns, does NOT check errors
|
|
381
|
-
if (event && typeof event === "object" && !Array.isArray(event)) {
|
|
382
|
-
const obj = event as Record<string, unknown>;
|
|
383
|
-
if (obj.type === "turn_end") {
|
|
384
|
-
turnCount += 1;
|
|
385
|
-
// ... turn limit logic only ...
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
// MISSING: detect provider errors (429, auth, etc.)
|
|
389
|
-
}
|
|
390
|
-
```
|
|
391
|
-
|
|
392
|
-
### Fix
|
|
393
|
-
|
|
394
|
-
Add provider error detection in `onJsonEvent`:
|
|
395
|
-
```typescript
|
|
396
|
-
let providerError: string | undefined;
|
|
397
|
-
|
|
398
|
-
// In onJsonEvent:
|
|
399
|
-
if (obj.type === "turn_end" && obj.message?.stopReason === "error") {
|
|
400
|
-
const errMsg = obj.message?.errorMessage || "";
|
|
401
|
-
if (errMsg && !providerError) providerError = errMsg;
|
|
402
|
-
// Fast-fail on rate limit — don't wait 300s
|
|
403
|
-
if (/429|rate.?limit/i.test(errMsg)) {
|
|
404
|
-
settle({ exitCode: 1, stdout, stderr: `Provider rate limit: ${errMsg.slice(0, 200)}` });
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
```
|
|
408
|
-
|
|
409
|
-
### Impact
|
|
410
|
-
|
|
411
|
-
This fix changes the error message from:
|
|
412
|
-
```
|
|
413
|
-
❌ "Child Pi produced no new output for 300000ms; process was terminated as unresponsive."
|
|
414
|
-
```
|
|
415
|
-
to:
|
|
416
|
-
```
|
|
417
|
-
✅ "Provider rate limit: 429 rate_limit_error: usage limit exceeded, resets at 2026-05-19T05:00:00Z"
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
And it **fails fast** instead of waiting 300s.
|
|
421
|
-
|
|
422
|
-
---
|
|
423
|
-
|
|
424
|
-
## Bug #3: background.log is useless — does not capture worker output
|
|
425
|
-
|
|
426
|
-
| Field | Value |
|
|
427
|
-
|---|---|
|
|
428
|
-
| **Severity** | 🟠 MEDIUM |
|
|
429
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
430
|
-
| **Affected** | Debugging experience for all background runs |
|
|
431
|
-
| **Symptom** | background.log contains only 1 line: `[pi-crew] background loader=jiti` |
|
|
432
|
-
|
|
433
|
-
### Description
|
|
434
|
-
|
|
435
|
-
When a background worker fails, the log file at `.crew/state/runs/<id>/background.log` contains only:
|
|
436
|
-
```
|
|
437
|
-
[pi-crew] background loader=jiti
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
Missing:
|
|
441
|
-
- Worker stdout/stderr
|
|
442
|
-
- Error messages
|
|
443
|
-
- Provider responses
|
|
444
|
-
- Exit codes
|
|
445
|
-
|
|
446
|
-
### Cause
|
|
447
|
-
|
|
448
|
-
`async-runner.ts` line 130-145:
|
|
449
|
-
```typescript
|
|
450
|
-
const logFd = fs.openSync(logPath, "a");
|
|
451
|
-
// ...
|
|
452
|
-
const child = spawn(process.execPath, command.args, buildBackgroundSpawnOptions(manifest, logFd));
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
`buildBackgroundSpawnOptions` line 123-127:
|
|
456
|
-
```typescript
|
|
457
|
-
return {
|
|
458
|
-
cwd: manifest.cwd,
|
|
459
|
-
detached: true,
|
|
460
|
-
stdio: ["ignore", logFd, logFd], // stdout+stderr → background.log
|
|
461
|
-
// ...
|
|
462
|
-
};
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
**The stdout/stderr of the background-runner** is written to background.log. But **child Pi workers** (spawned by the background-runner via child-pi.ts) **output to child-pi's pipe**, NOT to background.log.
|
|
466
|
-
|
|
467
|
-
Flow:
|
|
468
|
-
```
|
|
469
|
-
background-runner.ts (stdout→logFd, stderr→logFd)
|
|
470
|
-
→ loader=jiti → writes to log ✅
|
|
471
|
-
→ executeTeamRun()
|
|
472
|
-
→ child-pi.ts spawns child Pi (stdout→pipe, stderr→pipe)
|
|
473
|
-
→ Pi output → child-pi.ts captures → DOES NOT WRITE TO background.log ❌
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
### Fix
|
|
477
|
-
|
|
478
|
-
1. **Option A:** In `child-pi.ts` or `team-runner.ts`, write worker output events to background.log
|
|
479
|
-
2. **Option B:** Add event log entries for provider errors (there is an event log, but not detailed enough)
|
|
480
|
-
3. **Option C:** Background-runner tees output to a log file
|
|
481
|
-
|
|
482
|
-
### Key file
|
|
483
|
-
|
|
484
|
-
```
|
|
485
|
-
pi-crew/src/runtime/async-runner.ts — buildBackgroundSpawnOptions(), spawnBackgroundTeamRun()
|
|
486
|
-
```
|
|
487
|
-
|
|
488
|
-
---
|
|
489
|
-
|
|
490
|
-
## Bug #4: worker-startup.ts missing "rate_limited" classification
|
|
491
|
-
|
|
492
|
-
| Field | Value |
|
|
493
|
-
|---|---|
|
|
494
|
-
| **Severity** | 🟡 LOW |
|
|
495
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
496
|
-
| **Affected** | Error classification and reporting |
|
|
497
|
-
| **Symptom** | 429 errors classified as "unknown" instead of "rate_limited" |
|
|
498
|
-
|
|
499
|
-
### Description
|
|
500
|
-
|
|
501
|
-
`worker-startup.ts` has the `StartupFailureClassification` type:
|
|
502
|
-
```typescript
|
|
503
|
-
export type StartupFailureClassification =
|
|
504
|
-
| "trust_required"
|
|
505
|
-
| "prompt_misdelivery"
|
|
506
|
-
| "prompt_acceptance_timeout"
|
|
507
|
-
| "transport_dead"
|
|
508
|
-
| "worker_crashed"
|
|
509
|
-
| "unknown";
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
Missing `"rate_limited"` and `"provider_error"`. Result: 429 errors are classified as `"unknown"`.
|
|
513
|
-
|
|
514
|
-
### Fix
|
|
515
|
-
|
|
516
|
-
Add to the type and `classifyStartupFailure` function:
|
|
517
|
-
```typescript
|
|
518
|
-
export type StartupFailureClassification =
|
|
519
|
-
| "trust_required"
|
|
520
|
-
| "prompt_misdelivery"
|
|
521
|
-
| "prompt_acceptance_timeout"
|
|
522
|
-
| "transport_dead"
|
|
523
|
-
| "worker_crashed"
|
|
524
|
-
| "rate_limited" // NEW
|
|
525
|
-
| "provider_error" // NEW
|
|
526
|
-
| "unknown";
|
|
527
|
-
|
|
528
|
-
// In classifyStartupFailure:
|
|
529
|
-
if (evidence.stderrPreview && /429|rate.?limit/i.test(evidence.stderrPreview)) return "rate_limited";
|
|
530
|
-
if (evidence.stderrPreview && /5\d{2}|server.?error|internal.?error/i.test(evidence.stderrPreview)) return "provider_error";
|
|
531
|
-
```
|
|
532
|
-
|
|
533
|
-
### Key file
|
|
534
|
-
|
|
535
|
-
```
|
|
536
|
-
pi-crew/src/runtime/worker-startup.ts — StartupFailureClassification, classifyStartupFailure()
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
---
|
|
540
|
-
|
|
541
|
-
## Bug #5: Stale heartbeat notifications after prune
|
|
542
|
-
|
|
543
|
-
| Field | Value |
|
|
544
|
-
|---|---|
|
|
545
|
-
| **Severity** | 🟡 LOW (cosmetic) |
|
|
546
|
-
| **Status** | Confirmed |
|
|
547
|
-
| **Affected** | User experience |
|
|
548
|
-
| **Symptom** | "Task heartbeat dead" notifications for already-removed runs |
|
|
549
|
-
|
|
550
|
-
### Description
|
|
551
|
-
|
|
552
|
-
After running `team prune --keep=0 --confirm=true`, the background watcher still emits notifications for pruned runs:
|
|
553
|
-
|
|
554
|
-
```
|
|
555
|
-
→ team prune: Removed 9 runs
|
|
556
|
-
→ Notification: "agent_mpc423rq_1 heartbeat dead" (run not found)
|
|
557
|
-
→ Notification: "agent_mpc423rv_2 heartbeat dead" (run not found)
|
|
558
|
-
→ Notification: "agent_mpc423rw_3 heartbeat dead" (run not found)
|
|
559
|
-
→ Notification: "agent_mpc423rw_4 heartbeat dead" (run not found)
|
|
560
|
-
... (6+ stale notifications)
|
|
561
|
-
```
|
|
562
|
-
|
|
563
|
-
Each notification triggers `get_subagent_result` → returns "not found".
|
|
564
|
-
|
|
565
|
-
### Cause
|
|
566
|
-
|
|
567
|
-
The background watcher maintains a worker health-check queue. When runs are pruned:
|
|
568
|
-
1. The watcher does not deregister immediately
|
|
569
|
-
2. Notifications already in the queue still emit
|
|
570
|
-
3. The notifications arrive one by one, a few seconds apart
|
|
571
|
-
|
|
572
|
-
### Impact
|
|
573
|
-
|
|
574
|
-
- Confusing for the user: seeing "heartbeat dead" for runs that no longer exist
|
|
575
|
-
- Wasted context: each notification triggers 1 tool call to verify
|
|
576
|
-
|
|
577
|
-
### Fix
|
|
578
|
-
|
|
579
|
-
The background watcher should check run existence before emitting:
|
|
580
|
-
```typescript
|
|
581
|
-
// Before emitting heartbeat_dead:
|
|
582
|
-
if (!runExists(runId)) {
|
|
583
|
-
deregisterWorker(workerId); // Silent cleanup
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
### Key files
|
|
589
|
-
|
|
590
|
-
```
|
|
591
|
-
pi-crew/src/runtime/worker-heartbeat.ts — isWorkerHeartbeatStale()
|
|
592
|
-
pi-crew/src/runtime/background-runner.ts — heartbeat monitoring loop
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
---
|
|
596
|
-
|
|
597
|
-
# pi-crew v0.2.20 — Bug Report
|
|
598
|
-
|
|
599
|
-
**Date:** 2026-05-19
|
|
600
|
-
**Session:** Comprehensive integration test + root cause analysis
|
|
601
|
-
**Environment:** linux/x64, Node v22.22.0, Pi CLI v0.75.3, pi-crew v0.2.20
|
|
602
|
-
|
|
603
|
-
---
|
|
604
|
-
|
|
605
|
-
## Bug #1: Background workers "heartbeat dead" — actually a MiniMax 429 Rate Limit
|
|
606
|
-
|
|
607
|
-
| Field | Value |
|
|
608
|
-
|---|---|
|
|
609
|
-
| **Severity** | 🔴 HIGH |
|
|
610
|
-
| **Status** | ✅ Fixed — 429 now retries with fallback models instead of blocking 300s |
|
|
611
|
-
| **Affected** | All background/async workers |
|
|
612
|
-
| **Symptom** | Workers time out after 300s with "heartbeat dead", zero output |
|
|
613
|
-
|
|
614
|
-
### Description
|
|
615
|
-
|
|
616
|
-
When running `team action='run'` with `async=true` or `Agent(run_in_background=true)`, workers spawn successfully (PID exists) but **time out after 300s** with a generic error:
|
|
617
|
-
```
|
|
618
|
-
worker.response_timeout: No output for 300000ms
|
|
619
|
-
crew.task.heartbeat_dead: Task 01_assess heartbeat dead.
|
|
620
|
-
```
|
|
621
|
-
|
|
622
|
-
### Root cause
|
|
623
|
-
|
|
624
|
-
**Fixed.** Previously the 429 rate limit was not retried because:
|
|
625
|
-
1. `RETRYABLE_MODEL_FAILURE_PATTERNS` had `/\b429\b/` but MiniMax returns `rate_limit_error: usage limit exceeded` (no clear "429" number)
|
|
626
|
-
2. 429 was fast-failed in `child-pi.ts onJsonEvent` instead of letting the task-runner handle retry with fallback
|
|
627
|
-
|
|
628
|
-
### Fix applied
|
|
629
|
-
|
|
630
|
-
1. **model-fallback.ts**: Added `/rate_limit_error/i` to `RETRYABLE_MODEL_FAILURE_PATTERNS` to correctly identify the MiniMax rate limit error
|
|
631
|
-
2. **model-fallback.ts**: Changed `/\b429\b/` → `/rate.?limit/i` to match more formats
|
|
632
|
-
3. **child-pi.ts**: Removed the 429 fast-fail — let the task-runner handle retry with the model fallback chain
|
|
633
|
-
|
|
634
|
-
### Model fallback chain
|
|
635
|
-
|
|
636
|
-
When the main model gets a 429:
|
|
637
|
-
1. Fall back to `fallbackModels` (if configured)
|
|
638
|
-
2. Fall back to other available models in the system
|
|
639
|
-
3. If there is no fallback and retries are exhausted → fail with the correct error message
|
|
640
|
-
|
|
641
|
-
**Recommended config:** Add `fallbackModels` to the agent config to have more options when the main model is rate-limited.
|
|
642
|
-
|
|
643
|
-
---
|
|
644
|
-
|
|
645
|
-
## Bug #2: child-pi.ts does not detect 429 rate limit error — reports wrong "heartbeat dead"
|
|
646
|
-
|
|
647
|
-
| Field | Value |
|
|
648
|
-
|---|---|
|
|
649
|
-
| **Severity** | 🔴 HIGH |
|
|
650
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
651
|
-
| **Affected** | All child Pi workers |
|
|
652
|
-
| **Symptom** | Worker reports generic "No output for 300000ms" instead of "Provider rate limit: 429" |
|
|
653
|
-
|
|
654
|
-
### Description
|
|
655
|
-
|
|
656
|
-
The Pi CLI outputs JSON events for 429 errors very clearly:
|
|
657
|
-
```json
|
|
658
|
-
{"type":"turn_end","message":{"stopReason":"error","errorMessage":"429 {\"type\":\"error\",\"error\":{\"type\":\"rate_limit_error\"...}}"}}
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
But `child-pi.ts` **does not parse error events** — it only cares about:
|
|
662
|
-
- `isFinalAssistantEvent()` — to trigger the final drain
|
|
663
|
-
- `turn_end` — to count turns for turn limiting
|
|
664
|
-
|
|
665
|
-
Result: child-pi sees output (JSON events), **restarts the heartbeat timer**, but **does not recognize it as an error**. Pi blocks after 3 retries → heartbeat times out at 300s → generic error message.
|
|
666
|
-
|
|
667
|
-
### Code location
|
|
668
|
-
|
|
669
|
-
`/home/bom/source/my_pi/pi-crew/src/runtime/child-pi.ts`, line ~394:
|
|
670
|
-
```typescript
|
|
671
|
-
onJsonEvent: (event) => {
|
|
672
|
-
restartNoResponseTimer();
|
|
673
|
-
// Turn-count-based steering: only counts turns, does NOT check errors
|
|
674
|
-
if (event && typeof event === "object" && !Array.isArray(event)) {
|
|
675
|
-
const obj = event as Record<string, unknown>;
|
|
676
|
-
if (obj.type === "turn_end") {
|
|
677
|
-
turnCount += 1;
|
|
678
|
-
// ... turn limit logic only ...
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
// MISSING: detect provider errors (429, auth, etc.)
|
|
682
|
-
}
|
|
683
|
-
```
|
|
684
|
-
|
|
685
|
-
### Fix
|
|
686
|
-
|
|
687
|
-
Add provider error detection in `onJsonEvent`:
|
|
688
|
-
```typescript
|
|
689
|
-
let providerError: string | undefined;
|
|
690
|
-
|
|
691
|
-
// In onJsonEvent:
|
|
692
|
-
if (obj.type === "turn_end" && obj.message?.stopReason === "error") {
|
|
693
|
-
const errMsg = obj.message?.errorMessage || "";
|
|
694
|
-
if (errMsg && !providerError) providerError = errMsg;
|
|
695
|
-
// Fast-fail on rate limit — don't wait 300s
|
|
696
|
-
if (/429|rate.?limit/i.test(errMsg)) {
|
|
697
|
-
settle({ exitCode: 1, stdout, stderr: `Provider rate limit: ${errMsg.slice(0, 200)}` });
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### Impact
|
|
703
|
-
|
|
704
|
-
This fix changes the error message from:
|
|
705
|
-
```
|
|
706
|
-
❌ "Child Pi produced no new output for 300000ms; process was terminated as unresponsive."
|
|
707
|
-
```
|
|
708
|
-
to:
|
|
709
|
-
```
|
|
710
|
-
✅ "Provider rate limit: 429 rate_limit_error: usage limit exceeded, resets at 2026-05-19T05:00:00Z"
|
|
711
|
-
```
|
|
712
|
-
|
|
713
|
-
And it **fails fast** instead of waiting 300s.
|
|
714
|
-
|
|
715
|
-
---
|
|
716
|
-
|
|
717
|
-
## Bug #3: background.log is useless — does not capture worker output
|
|
718
|
-
|
|
719
|
-
| Field | Value |
|
|
720
|
-
|---|---|
|
|
721
|
-
| **Severity** | 🟠 MEDIUM |
|
|
722
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
723
|
-
| **Affected** | Debugging experience for all background runs |
|
|
724
|
-
| **Symptom** | background.log contains only 1 line: `[pi-crew] background loader=jiti` |
|
|
725
|
-
|
|
726
|
-
### Description
|
|
727
|
-
|
|
728
|
-
When a background worker fails, the log file at `.crew/state/runs/<id>/background.log` contains only:
|
|
729
|
-
```
|
|
730
|
-
[pi-crew] background loader=jiti
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
Missing:
|
|
734
|
-
- Worker stdout/stderr
|
|
735
|
-
- Error messages
|
|
736
|
-
- Provider responses
|
|
737
|
-
- Exit codes
|
|
738
|
-
|
|
739
|
-
### Cause
|
|
740
|
-
|
|
741
|
-
`async-runner.ts` line 130-145:
|
|
742
|
-
```typescript
|
|
743
|
-
const logFd = fs.openSync(logPath, "a");
|
|
744
|
-
// ...
|
|
745
|
-
const child = spawn(process.execPath, command.args, buildBackgroundSpawnOptions(manifest, logFd));
|
|
746
|
-
```
|
|
747
|
-
|
|
748
|
-
`buildBackgroundSpawnOptions` line 123-127:
|
|
749
|
-
```typescript
|
|
750
|
-
return {
|
|
751
|
-
cwd: manifest.cwd,
|
|
752
|
-
detached: true,
|
|
753
|
-
stdio: ["ignore", logFd, logFd], // stdout+stderr → background.log
|
|
754
|
-
// ...
|
|
755
|
-
};
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
**The stdout/stderr of the background-runner** is written to background.log. But **child Pi workers** (spawned by the background-runner via child-pi.ts) **output to child-pi's pipe**, NOT to background.log.
|
|
759
|
-
|
|
760
|
-
Flow:
|
|
761
|
-
```
|
|
762
|
-
background-runner.ts (stdout→logFd, stderr→logFd)
|
|
763
|
-
→ loader=jiti → writes to log ✅
|
|
764
|
-
→ executeTeamRun()
|
|
765
|
-
→ child-pi.ts spawns child Pi (stdout→pipe, stderr→pipe)
|
|
766
|
-
→ Pi output → child-pi.ts captures → DOES NOT WRITE TO background.log ❌
|
|
767
|
-
```
|
|
768
|
-
|
|
769
|
-
### Fix
|
|
770
|
-
|
|
771
|
-
1. **Option A:** In `child-pi.ts` or `team-runner.ts`, write worker output events to background.log
|
|
772
|
-
2. **Option B:** Add event log entries for provider errors (there is an event log, but not detailed enough)
|
|
773
|
-
3. **Option C:** Background-runner tees output to a log file
|
|
774
|
-
|
|
775
|
-
### Key file
|
|
776
|
-
|
|
777
|
-
```
|
|
778
|
-
pi-crew/src/runtime/async-runner.ts — buildBackgroundSpawnOptions(), spawnBackgroundTeamRun()
|
|
779
|
-
```
|
|
780
|
-
|
|
781
|
-
---
|
|
782
|
-
|
|
783
|
-
## Bug #4: worker-startup.ts missing "rate_limited" classification
|
|
784
|
-
|
|
785
|
-
| Field | Value |
|
|
786
|
-
|---|---|
|
|
787
|
-
| **Severity** | 🟡 LOW |
|
|
788
|
-
| **Status** | New — discovered while debugging Bug #1 |
|
|
789
|
-
| **Affected** | Error classification and reporting |
|
|
790
|
-
| **Symptom** | 429 errors classified as "unknown" instead of "rate_limited" |
|
|
791
|
-
|
|
792
|
-
### Description
|
|
793
|
-
|
|
794
|
-
`worker-startup.ts` has the `StartupFailureClassification` type:
|
|
795
|
-
```typescript
|
|
796
|
-
export type StartupFailureClassification =
|
|
797
|
-
| "trust_required"
|
|
798
|
-
| "prompt_misdelivery"
|
|
799
|
-
| "prompt_acceptance_timeout"
|
|
800
|
-
| "transport_dead"
|
|
801
|
-
| "worker_crashed"
|
|
802
|
-
| "unknown";
|
|
803
|
-
```
|
|
804
|
-
|
|
805
|
-
Missing `"rate_limited"` and `"provider_error"`. Result: 429 errors are classified as `"unknown"`.
|
|
806
|
-
|
|
807
|
-
### Fix
|
|
808
|
-
|
|
809
|
-
Add to the type and `classifyStartupFailure` function:
|
|
810
|
-
```typescript
|
|
811
|
-
export type StartupFailureClassification =
|
|
812
|
-
| "trust_required"
|
|
813
|
-
| "prompt_misdelivery"
|
|
814
|
-
| "prompt_acceptance_timeout"
|
|
815
|
-
| "transport_dead"
|
|
816
|
-
| "worker_crashed"
|
|
817
|
-
| "rate_limited" // NEW
|
|
818
|
-
| "provider_error" // NEW
|
|
819
|
-
| "unknown";
|
|
820
|
-
|
|
821
|
-
// In classifyStartupFailure:
|
|
822
|
-
if (evidence.stderrPreview && /429|rate.?limit/i.test(evidence.stderrPreview)) return "rate_limited";
|
|
823
|
-
if (evidence.stderrPreview && /5\d{2}|server.?error|internal.?error/i.test(evidence.stderrPreview)) return "provider_error";
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
### Key file
|
|
827
|
-
|
|
828
|
-
```
|
|
829
|
-
pi-crew/src/runtime/worker-startup.ts — StartupFailureClassification, classifyStartupFailure()
|
|
830
|
-
```
|
|
831
|
-
|
|
832
|
-
---
|
|
833
|
-
|
|
834
|
-
## Bug #5: Stale heartbeat notifications after prune
|
|
835
|
-
|
|
836
|
-
| Field | Value |
|
|
837
|
-
|---|---|
|
|
838
|
-
| **Severity** | 🟡 LOW (cosmetic) |
|
|
839
|
-
| **Status** | Confirmed |
|
|
840
|
-
| **Affected** | User experience |
|
|
841
|
-
| **Symptom** | "Task heartbeat dead" notifications for already-removed runs |
|
|
842
|
-
|
|
843
|
-
### Description
|
|
844
|
-
|
|
845
|
-
After running `team prune --keep=0 --confirm=true`, the background watcher still emits notifications for pruned runs:
|
|
846
|
-
|
|
847
|
-
```
|
|
848
|
-
→ team prune: Removed 9 runs
|
|
849
|
-
→ Notification: "agent_mpc423rq_1 heartbeat dead" (run not found)
|
|
850
|
-
→ Notification: "agent_mpc423rv_2 heartbeat dead" (run not found)
|
|
851
|
-
→ Notification: "agent_mpc423rw_3 heartbeat dead" (run not found)
|
|
852
|
-
→ Notification: "agent_mpc423rw_4 heartbeat dead" (run not found)
|
|
853
|
-
... (6+ stale notifications)
|
|
854
|
-
```
|
|
855
|
-
|
|
856
|
-
Each notification triggers `get_subagent_result` → returns "not found".
|
|
857
|
-
|
|
858
|
-
### Cause
|
|
859
|
-
|
|
860
|
-
The background watcher maintains a worker health-check queue. When runs are pruned:
|
|
861
|
-
1. The watcher does not deregister immediately
|
|
862
|
-
2. Notifications already in the queue still emit
|
|
863
|
-
3. The notifications arrive one by one, a few seconds apart
|
|
864
|
-
|
|
865
|
-
### Impact
|
|
866
|
-
|
|
867
|
-
- Confusing for the user: seeing "heartbeat dead" for runs that no longer exist
|
|
868
|
-
- Wasted context: each notification triggers 1 tool call to verify
|
|
869
|
-
|
|
870
|
-
### Fix
|
|
871
|
-
|
|
872
|
-
The background watcher should check run existence before emitting:
|
|
873
|
-
```typescript
|
|
874
|
-
// Before emitting heartbeat_dead:
|
|
875
|
-
if (!runExists(runId)) {
|
|
876
|
-
deregisterWorker(workerId); // Silent cleanup
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
```
|
|
880
|
-
|
|
881
|
-
### Key files
|
|
882
|
-
|
|
883
|
-
```
|
|
884
|
-
pi-crew/src/runtime/worker-heartbeat.ts — isWorkerHeartbeatStale()
|
|
885
|
-
pi-crew/src/runtime/background-runner.ts — heartbeat monitoring loop
|
|
886
|
-
```
|
|
887
|
-
|
|
888
|
-
---
|
|
889
|
-
|
|
890
|
-
## Bug #6: Live-session run cancelled mid-execution
|
|
891
|
-
|
|
892
|
-
| Field | Value |
|
|
893
|
-
|---|---|
|
|
894
|
-
| **Severity** | 🟠 MEDIUM |
|
|
895
|
-
| **Status** | ✅ Confirmed — no code fix needed; documented as a user workflow constraint |
|
|
896
|
-
| **Affected** | Foreground team runs |
|
|
897
|
-
| **Symptom** | Run cancelled after the explore phase completes, before the execute phase |
|
|
898
|
-
|
|
899
|
-
### Description
|
|
900
|
-
|
|
901
|
-
A fast-fix team ran in a live-session:
|
|
902
|
-
```
|
|
903
|
-
04:12:20 live-session.prompt_start 01_explore
|
|
904
|
-
04:12:51 live-session.prompt_done 01_explore (31s, completed)
|
|
905
|
-
04:12:51 live_agent.terminated 01_explore (status=cancelled)
|
|
906
|
-
04:12:51 task.completed 01_explore
|
|
907
|
-
04:12:51 run.cancelled: "This operation was aborted"
|
|
908
|
-
```
|
|
909
|
-
|
|
910
|
-
Task `01_explore` completed successfully, but the run was cancelled before `02_execute` started.
|
|
911
|
-
|
|
912
|
-
### Possible causes
|
|
913
|
-
|
|
914
|
-
1. **Session concurrency limit** — only 1 active live-session, conflicting with parallel test operations
|
|
915
|
-
2. **User-initiated cancellation** — accidentally triggered
|
|
916
|
-
3. **Workflow phase transition bug** — does not trigger the next phase after explore completes
|
|
917
|
-
|
|
918
|
-
### Needs further investigation
|
|
919
|
-
|
|
920
|
-
- Run the fast-fix team standalone (no concurrent operations)
|
|
921
|
-
- Check live-session-runtime.ts for phase-transition logic
|
|
922
|
-
|
|
923
|
-
---
|
|
924
|
-
|
|
925
|
-
## Summary
|
|
926
|
-
|
|
927
|
-
| # | Bug | Severity | Status | Category |
|
|
928
|
-
|---|---|---|---|---|
|
|
929
|
-
| 1 | Background workers timeout due to MiniMax 429 | 🔴 HIGH | ✅ Fixed — 429 now retries with fallback models via improved RETRYABLE_MODEL_FAILURE_PATTERNS | Code |
|
|
930
|
-
| 2 | child-pi.ts does not detect 429, reports wrong "heartbeat dead" | 🔴 HIGH | ✅ Fixed — removed 429 fast-fail; let task-runner handle retry+fallback | Code |
|
|
931
|
-
| 3 | background.log useless, does not capture worker output | 🟠 MEDIUM | ✅ Fixed — added PI_CREW_BACKGROUND_MODE flag + event logging to background.log | Observability |
|
|
932
|
-
| 4 | worker-startup.ts missing rate_limited classification | 🟡 LOW | ✅ Fixed — added rate_limited + provider_error to StartupFailureClassification | Code |
|
|
933
|
-
| 5 | Stale heartbeat notifications after prune | 🟡 LOW | ✅ Fixed — HeartbeatWatcher skips pruned runs via stateRoot existence check | UX |
|
|
934
|
-
| 6 | Live-session foreground run cancelled when there are concurrent tool calls | 🟠 MEDIUM | ✅ Confirmed — concurrent calls interrupt live-session → outputLength:0 → caller_cancelled. Avoid concurrent team actions during foreground runs. | Runtime |
|
|
935
|
-
| 7 | Async notifier "stale ctx" — dies, does not restart after Pi restart | 🔴 HIGH | ✅ Fixed — swallow stale error, isCurrent guard handles dormancy | Code |
|
|
936
|
-
| 8 | Background child-process 300s timeout — child Pi hangs, zero output | 🟠 MEDIUM | ✅ Fixed — Root cause found (Bug #10): MINIMAX_API_KEY stripped by sanitizeEnvSecrets(). Allow-list in child-pi.ts preserves model provider API keys. Restart Pi to verify fix. | Code |
|
|
937
|
-
| 9 | Executor hit yield limit — file write not completed | 🟡 LOW | 🔲 Open — executor hit 3 Yield Reminders and terminated before writing file. Task marked completed but artifact missing. | Runtime |
|
|
938
|
-
| 10 | Child-process silent timeout — MINIMAX_API_KEY filtered out of child env | 🔴 HIGH | ✅ Fixed — sanitizeEnvSecrets() strips *API_KEY* vars. Allow-list in buildChildPiSpawnOptions preserves model provider keys (MINIMAX_*, OPENAI_*, etc.). See docs/fixes/bug-010-child-process-api-key-filtered.md | Code |
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
| 11 | Background runner "spawn pi ENOENT" — pi binary not in PATH | 🔴 HIGH | ✅ Fixed — added resolvePiCliScript() call for non-Windows platforms in getPiSpawnCommand(). Restart Pi to verify. | Code |
|
|
942
|
-
| 12 | Essential env vars (PATH) stripped - child Pi crashes with npm root -g error | HIGH | ✅ Fixed — added essential env vars (PATH, HOME, USER, etc.) to allow-list alongside model API keys. Restart Pi to verify. | Code |
|
|
943
|
-
| 15 | Background runner receives SIGTERM ~3s after spawn from Pi infrastructure | 🟠 MEDIUM | ✅ Fixed — disabled async mode by default + ignore SIGTERM from Pi in background-runner | Runtime |
|
|
944
|
-
|
|
945
|
-
### Priority fix order
|
|
946
|
-
|
|
947
|
-
1. **Bug #1** — ✅ Fixed — 429 now retried with model fallback chain
|
|
948
|
-
2. **Bug #2** — ✅ Fixed — removed 429 fast-fail
|
|
949
|
-
3. **Bug #3** — ✅ Fixed — worker events now logged to background.log
|
|
950
|
-
4. **Bug #4** — ✅ Fixed — rate_limited + provider_error classification added
|
|
951
|
-
5. **Bug #5** — ✅ Fixed — HeartbeatWatcher skips pruned runs
|
|
952
|
-
6. **Bug #6** — ✅ Confirmed — concurrent tool calls cancel foreground runs; avoid concurrent team actions during runs
|
|
953
|
-
7. **Bug #7** — ✅ Fixed — async notifier handles stale ctx gracefully, isCurrent guard manages dormancy
|
|
954
|
-
8. **Bug #8/10** — ✅ Fixed — Bug #10 root cause: MINIMAX_API_KEY filtered out. Allow-list preserves model provider API keys for child processes.
|
|
955
|
-
9. **Bug #9** — ✅ Fixed — Added `needs_attention` task status. Workers that complete without calling `submit_result` now get `status: "needs_attention"` instead of `"completed"`, with ⚠ icon in UI.
|
|
956
|
-
10. **Bug #10** — ✅ Fixed — Added allow-list to sanitizeEnvSecrets in child-pi.ts to preserve model API keys (MINIMAX_*, OPENAI_*, etc.)
|
|
957
|
-
11. **Bug #11** — ✅ Fixed — resolvePiCliScript() added for non-Windows in getPiSpawnCommand() to fix ENOENT on spawn
|
|
958
|
-
12. **Bug #12** — ✅ Fixed — Essential env vars (PATH, HOME, USER, etc.) added to allow-list alongside model API keys
|
|
959
|
-
13. **Bug #13** — 🟠 MEDIUM — ✅ Fixed — Background runner dies after ~59s. 3-layer fix: (1) heartbeat mechanism prevents false repairs; (2) --max-old-space-size=512 limits V8 heap to prevent OOM; (3) SIGTERM/SIGINT handlers log async.failed event for diagnosis. Heartbeat includes memory stats (heapUsedMb, rssMb) for post-mortem.
|
|
960
|
-
14. **Bug #14** — 🔴 HIGH — ✅ Fixed — Infinite retry loop: needs_attention tasks had `queue: "blocked"` in task graph instead of `queue: "done"`, causing them to be re-scheduled indefinitely. Added `needs_attention` to the terminal status check in `withQueue()` in task-graph-scheduler.ts.
|
|
961
|
-
15. **Bug #15** — 🟠 MEDIUM — ✅ Fixed — Disabled async mode by default (runAsync=false). Background runners receive SIGTERM ~3s after spawn from Pi infrastructure because Node.js 22.22.0 setsid:true doesn't create a new session. Also added ignore-SIGTERM-from-Pi logic in background-runner.ts (A2 approach).
|