The open review threads on this branch were all grounded in real issues:
a committed API key in handover docs, Unix-only locking and timeout
mechanisms, synchronous network I/O inside an async API path, and missing
retry/session reuse on market-data calls. This change removes the leaked
credential from the tracked docs, makes the portfolio and profiling paths
portable across platforms, moves live price fetches off the event loop,
and reuses the existing yfinance retry/session helpers where the review
called for them.
While verifying these fixes, the branch also failed to import parts of the
TradingAgents graph because two utility modules referenced by the new code
were absent. I restored those utilities with minimal implementations so the
relevant regression tests and import graph work again in this PR.
Constraint: No new dependencies; portability fixes had to stay in the standard library
Rejected: Add portalocker or filelock | unnecessary new dependency for a small compatibility gap
Rejected: Keep signal.alarm and fcntl as Unix-only behavior | leaves the reported review blockers unresolved
Confidence: medium
Scope-risk: moderate
Reversibility: clean
Directive: Keep shared runtime paths cross-platform and keep async handlers free of direct blocking network I/O
Tested: python -m pytest -q web_dashboard/backend/tests/test_portfolio_api.py orchestrator/tests/test_quant_runner.py orchestrator/tests/test_profile_stage_chain.py tradingagents/tests/test_stockstats_utils.py
Tested: python -m pytest -q orchestrator/tests/test_trading_graph_config.py tradingagents/tests/test_research_guard.py
Not-tested: Full repository test suite and GitHub-side post-push checks
The earlier Phase 1-4 recovery left one unique worker-1 slice unrecovered: provenance extraction logic was still duplicated in the runner and the full-state log path still dropped the structured research fields. This change centralizes provenance extraction in agent state helpers, reuses it from the LLM runner, and writes the same structured fields into TradingAgents full-state logs with focused regression tests.\n\nConstraint: Preserve the existing debate-string output shape while making provenance reuse consistent across runner and state-log surfaces\nRejected: Cherry-pick worker-1 auto-checkpoint wholesale | it mixed duplicate A/B files and uv.lock churn with the useful provenance helper changes\nConfidence: high\nScope-risk: narrow\nDirective: Keep research provenance extraction centralized; new consumers should call the helper instead of re-listing field names by hand\nTested: python -m pytest -q tradingagents/tests/test_research_guard.py orchestrator/tests/test_trading_graph_config.py orchestrator/tests/test_llm_runner.py orchestrator/tests/test_profile_stage_chain.py orchestrator/tests/test_profile_ab.py orchestrator/tests/test_contract_v1alpha1.py orchestrator/tests/test_live_mode.py\nTested: python -m compileall tradingagents/agents/utils/agent_states.py tradingagents/graph/trading_graph.py orchestrator/llm_runner.py orchestrator/tests/test_trading_graph_config.py tradingagents/tests/test_research_guard.py\nNot-tested: Live-provider end-to-end analysis run that emits a new full_states_log file
Research provenance now rides with the debate state, cache metadata, live payloads, and trace dumps so degraded research no longer masquerades as a normal sample. Bull/Bear/Manager nodes also return explicit guarded fallbacks on timeout or exception, which gives the graph a real node budget boundary without rewriting the bull/bear output shape or removing debate.\n\nConstraint: Must preserve bull/bear debate structure and output shape while adding provenance and node guards\nRejected: Skip bull/bear debate in compact mode | would trade away analysis quality before A/B evidence exists\nConfidence: high\nScope-risk: moderate\nReversibility: clean\nDirective: Treat research_status and data_quality as rollout gates; do not collapse degraded research back into normal success samples\nTested: python -m pytest tradingagents/tests/test_research_guard.py orchestrator/tests/test_llm_runner.py orchestrator/tests/test_live_mode.py web_dashboard/backend/tests/test_executors.py web_dashboard/backend/tests/test_services_migration.py web_dashboard/backend/tests/test_api_smoke.py -q; python -m compileall tradingagents/graph/setup.py tradingagents/agents/utils/agent_states.py tradingagents/graph/propagation.py orchestrator/llm_runner.py orchestrator/live_mode.py orchestrator/profile_stage_chain.py; python orchestrator/profile_stage_chain.py --ticker 600519.SS --date 2026-04-10 --provider anthropic --model MiniMax-M2.7-highspeed --base-url https://api.minimaxi.com/anthropic --selected-analysts market --analysis-prompt-style compact --timeout 45 --max-retries 0 --overall-timeout 120 --dump-raw-on-failure\nNot-tested: Full successful live-provider completion through Portfolio Manager after the post-research connection failure