Skip to content

Fix startup reconciliation and container monitor never running in production - #852

Merged
jwbron merged 1 commit into
mainfrom
fix/wire-startup-reconciliation-to-cli
Feb 21, 2026
Merged

Fix startup reconciliation and container monitor never running in production#852
jwbron merged 1 commit into
mainfrom
fix/wire-startup-reconciliation-to-cli

Conversation

@jwbron

@jwbron jwbron commented Feb 21, 2026

Copy link
Copy Markdown
Owner

Summary

Root cause

entrypoint.sh runs python cli.py serve, which does from api import app then calls waitress.serve(app) directly. The reconciliation and monitor startup were added to api.main() (which is only reachable via python api.py) — meaning neither mechanism has ever executed in a real deployment.

This is why the issue-835 pipeline remained stuck through multiple orchestrator restarts despite #839 and #848 being merged.

Test plan

  • Restart the orchestrator and confirm "Configuration", "Recovered stale pipelines on startup" (if applicable), and "Container monitor started" log lines now appear on startup
  • Existing tests: cd orchestrator && python -m pytest tests/test_startup_reconciliation.py tests/test_container_monitor.py -v

🤖 Generated with Claude Code

…duction

api.main() and cli.cmd_serve were duplicate startup paths. The production
entrypoint always uses cli.py, so startup_reconciliation (#839) and
ContainerMonitor (#848) were dead code — never executed on any restart.

Move the startup logic into cmd_serve and delete api.main() along with
its now-unused argparse and waitress imports.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@egg-reviewer egg-reviewer Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

The diagnosis is correct — api.main() was dead code in production because entrypoint.sh runs python cli.py serve, which imports the Flask app directly and never calls main(). Moving startup reconciliation and the container monitor into cmd_serve is the right fix. The code is a clean lift-and-shift with no logic changes.

One issue worth addressing before merge:

threads=16 silently dropped

The deleted api.main() called:

serve(app, host=host, port=port, threads=16)

But the existing cmd_serve (line 137) calls:

serve(app, host=host, port=port)

Waitress defaults to 4 threads. This discrepancy existed before this PR — cmd_serve never had threads=16 — but this PR deletes the only place that documented the intended concurrency. The orchestrator handles webhook processing, container lifecycle, and SSE connections concurrently, so 4 threads may be insufficient under load.

Suggested fix — add threads=16 to the serve() call in cli.py:137:

serve(app, host=host, port=port, threads=16)

This is low-risk and ensures the intended production configuration isn't lost.

Minor: PR body includes "Claude Code" branding

The repo conventions (CLAUDE.md) say PR descriptions must never include "Claude Code" or claude.ai links. The PR body ends with 🤖 Generated with [Claude Code](https://claude.com/claude-code) — remove that line before merge.

What looks good

  • Correct root cause analysis — the entrypoint.shcli.py servefrom api import app path never touched api.main().
  • Both try/except Exception blocks around reconciliation and monitor startup are preserved, so failures in either won't prevent the server from starting.
  • if repo_path != "not set" guard is preserved, correctly skipping startup logic when EGG_REPO_PATH isn't configured.
  • Existing unit tests (test_startup_reconciliation.py, test_container_monitor.py) test the functions directly and are unaffected by the move.
  • No other callers of api.main() or python api.py exist — the deletion is safe.
  • Import cleanup in api.py (removing argparse, os, waitress) is correct — none are used outside the deleted main().

— Authored by egg

@james-in-a-box

This comment has been minimized.

@james-in-a-box

Copy link
Copy Markdown
Contributor
egg is addressing review feedback...

@james-in-a-box

Copy link
Copy Markdown
Contributor

Review feedback addressed

threads=16 silently dropped

Agreed. Added threads=16 to the serve() call in cli.py:137. The gateway blocked pushing to the fix/wire-startup-reconciliation-to-cli branch (not egg-prefixed and not bot-owned), so the fix is in PR #853 (egg/fix-startup-threads). That PR contains the single-line fix and can be merged independently or squashed into this one.

PR body includes "Claude Code" branding

Agreed. Attempted to remove it via gh pr edit but the gateway blocked the edit (PR authored by jwbron, not by the bot). The line 🤖 Generated with [Claude Code](https://claude.com/claude-code) should be removed from the PR body before merge.

— Authored by egg

@james-in-a-box

Copy link
Copy Markdown
Contributor

egg feedback addressed. View run logs

1 previous review(s) hidden.

@jwbron
jwbron merged commit 5910fc5 into main Feb 21, 2026
11 checks passed
james-in-a-box Bot pushed a commit that referenced this pull request Feb 21, 2026
Comprehensive architecture analysis for a two-tier pipeline failure
detection framework. Recommends unified HealthCheck interface with
HealthCheckRunner, migrating existing startup_reconciliation and
container_monitor to the new interface, adding Tier 1 programmatic
checks (phase output presence, state consistency, repeated failure
patterns) and Tier 2 LLM-based agent inspector.

Key design features: two-strike FAIL_PIPELINE confirmation,
HEALTH_CHECK_MODE kill-switch (enforce/observe/disabled), exception
isolation at every layer, per-pipeline AgentCircuitBreaker instances.

13-phase implementation plan across 6 stages with 12 technical
decisions documented. Addresses plan reviewer feedback (v2).
Analysis confirmed accurate after PRs #852, #854, #855 on main.

Issue: #850
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant