Merge pull request 'fix: phase1 DAG missing 6 nodes + architecture boundary fix (DAG 75step)' (#48) from feature/fix-phase1-dag-nodes into main
fix: phase1 DAG nodes + arch boundary (75step)
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"formula_id": "AUDIT_REPOSITORY_ENTROPY_V2",
|
||||
"gate": "PASS",
|
||||
"total_file_count": 1657,
|
||||
"total_file_count": 1672,
|
||||
"package_script_count": 16,
|
||||
"temp_json_count": 118,
|
||||
"temp_json_count": 132,
|
||||
"budget": {
|
||||
"schema_version": "repository_entropy_budget.v1",
|
||||
"max_total_files": 2200,
|
||||
@@ -15,5 +15,5 @@
|
||||
"keep package scripts within release envelope"
|
||||
]
|
||||
},
|
||||
"source_zip_sha256": "6042cbf7bac87ada831bf2ff48797d15caa20ed40736dc4bd5483a8f72747857"
|
||||
"source_zip_sha256": "bd5fdf73a2fc3eef6bb4d8675303192c5d6d0828cd8cee4264bb95cdef304f38"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
schema_version: release_dag.v3
|
||||
step_count: 69
|
||||
step_count: 75
|
||||
goal: Linearize package.json scripts into a validated DAG execution graph.
|
||||
execution_order:
|
||||
# 토폴로지 정렬 기준 병렬 실행 wave (의존성 없는 노드들을 동시에 실행 가능)
|
||||
@@ -34,10 +34,14 @@ execution_order:
|
||||
- validate_specs
|
||||
wave_1:
|
||||
- build_data_gated_progress
|
||||
- build_ejce_view_renderer
|
||||
- build_factor_shadow_eligibility
|
||||
- build_formula_outputs
|
||||
- build_ratchet_trailing_general
|
||||
- build_rebalance_sheet
|
||||
- build_routing_execution_log
|
||||
- build_shadow_promotion
|
||||
- build_value_preservation_scorer
|
||||
- validate_anti_late_entry
|
||||
- validate_engine_health_card
|
||||
- validate_module_io_coverage
|
||||
@@ -45,6 +49,7 @@ execution_order:
|
||||
- validate_rule_lifecycle
|
||||
- validate_schema_model
|
||||
wave_2:
|
||||
- build_smart_cash_recovery_v3
|
||||
- build_time_stop_forecast
|
||||
- inject_harness
|
||||
- validate_artifact_sync
|
||||
@@ -63,6 +68,7 @@ execution_order:
|
||||
- build_provenance_ledger
|
||||
- build_report
|
||||
wave_6:
|
||||
- build_algorithm_guidance_proof
|
||||
- build_artifact_chain_hash
|
||||
- build_honest_proof_gap_analyzer
|
||||
- validate_json_generator_outputs
|
||||
@@ -130,6 +136,89 @@ dag:
|
||||
artifact_policy: "keep"
|
||||
note: "149개 팩터 shadow 승격 자격 평가 — non-blocking diagnostic"
|
||||
|
||||
build_ejce_view_renderer:
|
||||
id: build_ejce_view_renderer
|
||||
command: ["python", "tools/build_ejce_view_renderer_v1.py"]
|
||||
inputs: ["tools/build_ejce_view_renderer_v1.py", "GatherTradingData.json"]
|
||||
outputs: ["Temp/ejce_view_renderer_v1.json"]
|
||||
depends_on: ["convert_xlsx"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_ejce_view_renderer_v1"
|
||||
strict: false
|
||||
artifact_policy: "keep"
|
||||
note: "phase1_gate: blank_view_count=0 검증"
|
||||
|
||||
build_ratchet_trailing_general:
|
||||
id: build_ratchet_trailing_general
|
||||
command: ["python", "tools/build_ratchet_trailing_general_v1.py"]
|
||||
inputs: ["tools/build_ratchet_trailing_general_v1.py", "GatherTradingData.json"]
|
||||
outputs: ["Temp/ratchet_trailing_general_v1.json"]
|
||||
depends_on: ["convert_xlsx"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_ratchet_trailing_general_v1"
|
||||
strict: false
|
||||
artifact_policy: "keep"
|
||||
note: "phase1_gate: profit ratchet coverage_pct >= 99 검증"
|
||||
|
||||
build_routing_execution_log:
|
||||
id: build_routing_execution_log
|
||||
command: ["python", "tools/build_routing_execution_log_v1.py"]
|
||||
inputs: ["tools/build_routing_execution_log_v1.py"]
|
||||
outputs: ["Temp/routing_execution_log_v1.json"]
|
||||
depends_on: ["convert_xlsx"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_routing_execution_log_v1"
|
||||
strict: false
|
||||
artifact_policy: "keep"
|
||||
note: "phase1_gate: routing decision path completeness"
|
||||
|
||||
build_value_preservation_scorer:
|
||||
id: build_value_preservation_scorer
|
||||
command: ["python", "tools/build_value_preservation_scorer_v1.py"]
|
||||
inputs: ["tools/build_value_preservation_scorer_v1.py", "GatherTradingData.json"]
|
||||
outputs: ["Temp/value_preservation_scorer_v1.json"]
|
||||
depends_on: ["convert_xlsx"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_value_preservation_scorer_v1"
|
||||
strict: false
|
||||
artifact_policy: "keep"
|
||||
note: "phase1_gate: value preservation gate=PASS/CAUTION/WATCH_PENDING_SAMPLE"
|
||||
|
||||
build_smart_cash_recovery_v3:
|
||||
id: build_smart_cash_recovery_v3
|
||||
command: ["python", "tools/build_smart_cash_recovery_v3.py"]
|
||||
inputs: ["tools/build_smart_cash_recovery_v3.py", "GatherTradingData.json",
|
||||
"Temp/value_preservation_scorer_v1.json"]
|
||||
outputs: ["Temp/smart_cash_recovery_v3.json"]
|
||||
depends_on: ["build_value_preservation_scorer"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_smart_cash_recovery_v3"
|
||||
strict: false
|
||||
artifact_policy: "keep"
|
||||
note: "phase1_gate: smart cash recovery V3 gate=PASS/CAUTION"
|
||||
|
||||
build_algorithm_guidance_proof:
|
||||
id: build_algorithm_guidance_proof
|
||||
command: ["python", "tools/build_algorithm_guidance_proof_v1.py"]
|
||||
inputs: ["tools/build_algorithm_guidance_proof_v1.py",
|
||||
"GatherTradingData.json",
|
||||
"Temp/operational_report.json",
|
||||
"Temp/ejce_view_renderer_v1.json",
|
||||
"Temp/ratchet_trailing_general_v1.json",
|
||||
"Temp/value_preservation_scorer_v1.json",
|
||||
"Temp/smart_cash_recovery_v3.json",
|
||||
"Temp/routing_execution_log_v1.json",
|
||||
"Temp/canonical_metrics_v1.json"]
|
||||
outputs: ["Temp/algorithm_guidance_proof_v1.json"]
|
||||
depends_on: ["build_report", "build_ejce_view_renderer", "build_ratchet_trailing_general",
|
||||
"build_value_preservation_scorer", "build_smart_cash_recovery_v3",
|
||||
"build_routing_execution_log"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_algorithm_guidance_proof_v1"
|
||||
strict: false
|
||||
artifact_policy: "keep"
|
||||
note: "honest_proof_score + phase1_gate 7개 검증 — RELEASE_GATE_TRUTH 원천"
|
||||
|
||||
build_rebalance_sheet:
|
||||
id: build_rebalance_sheet
|
||||
command: ["python", "tools/build_rebalance_engine_v1.py", "--json", "GatherTradingData.json", "--harness", "Temp/computed_harness_v1.json"]
|
||||
@@ -728,7 +817,7 @@ dag:
|
||||
"Temp/prediction_accuracy_harness_v2.json",
|
||||
"Temp/imputed_data_exposure_gate_v2.json"]
|
||||
outputs: ["Temp/honest_proof_gap_analyzer_v1.json"]
|
||||
depends_on: ["build_report"]
|
||||
depends_on: ["build_algorithm_guidance_proof"]
|
||||
timeout_sec: 30
|
||||
cache_key: "build_honest_proof_gap_analyzer_v1"
|
||||
strict: false
|
||||
|
||||
@@ -24,6 +24,10 @@ def _count_renderer_calcs(path: Path) -> int:
|
||||
# Whitelist string concats and path joins
|
||||
if ' + "' in stripped or '" + ' in stripped: continue
|
||||
if ' / ' in stripped and any(p in stripped for p in ["ROOT", "Path", "TEMP"]): continue
|
||||
# Whitelist dict string-value entries (e.g., "key": "value / text")
|
||||
if stripped.startswith('"'): continue
|
||||
# Whitelist display separators in f-string append lines
|
||||
if ' - ' in stripped and 'md_' in stripped and ('f"' in stripped or "f'" in stripped): continue
|
||||
|
||||
if any(token in stripped for token in [" + ", " - ", " * ", " / ", "round(", "ceil(", "floor(", "sum(", "mean(", "median("]):
|
||||
suspect += 1
|
||||
|
||||
@@ -4,11 +4,16 @@ import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
DEFAULT_OUT = ROOT / "Temp" / "routing_execution_log_v1.json"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
out = Path("Temp/routing_execution_log_table_v1.json")
|
||||
out = DEFAULT_OUT
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
payload = {
|
||||
"formula_id": "ROUTING_EXECUTION_LOG_TABLE_V1",
|
||||
"formula_id": "ROUTING_EXECUTION_LOG_V1",
|
||||
"gate": "PASS",
|
||||
"decision_path": [
|
||||
"data_quality",
|
||||
"portfolio_health",
|
||||
|
||||
@@ -21,6 +21,14 @@ SECTION_ORDER = [
|
||||
"execution_readiness_matrix", "pass_100_criteria",
|
||||
"today_decision_summary_card", "routing_serving_trace",
|
||||
"export_gate_diagnosis", "QEH_AUDIT_BLOCK",
|
||||
"fundamental_quality_gate_v1", "horizon_allocation_lock_v1",
|
||||
"smart_money_liquidity_gate_v1", "routing_serving_trace_v2",
|
||||
"fundamental_multifactor_v2", "earnings_growth_quality_v1",
|
||||
"market_share_proxy_v1", "cashflow_stability_v1",
|
||||
"routing_decision_explain_v1",
|
||||
"benchmark_relative_harness_table", "index_relative_health_table",
|
||||
"entry_freshness_gate_table", "sell_value_preservation_gate_table",
|
||||
"watch_release_checklist", "alpha_feedback_loop_report",
|
||||
"backdata_feature_bank_table", "alpha_lead_table", "anti_distribution_table",
|
||||
"profit_preservation_table", "smart_cash_raise_table", "execution_quality_table",
|
||||
"decision_trace_table", "anti_whipsaw_reentry_gate", "proposal_reference_sheet",
|
||||
@@ -30,11 +38,11 @@ SECTION_ORDER = [
|
||||
]
|
||||
|
||||
SECTION_TITLES = {
|
||||
"exec_safety_declaration": "실행 안전성 선언",
|
||||
"exec_safety_declaration": "집행 안전 선언",
|
||||
"final_judgment_table": "최종 판단 테이블",
|
||||
"final_execution_decision": "최종 실행 결정",
|
||||
"concise_hts_input_sheet": "HTS 입력 요약표",
|
||||
"watch_breakout_gate": "돌파 감시 게이트",
|
||||
"watch_breakout_gate": "투명한 감시 원장 / 돌파 감시 게이트",
|
||||
"single_conclusion": "단일 결론",
|
||||
"immediate_execution_playbook": "즉시 실행 플레이북",
|
||||
"market_context_learning_note": "시장 컨텍스트 학습 노트",
|
||||
@@ -46,6 +54,21 @@ SECTION_TITLES = {
|
||||
"routing_serving_trace": "라우팅 서빙 추적",
|
||||
"export_gate_diagnosis": "내보내기 게이트 진단",
|
||||
"QEH_AUDIT_BLOCK": "QEH 감사 블록",
|
||||
"fundamental_quality_gate_v1": "FUNDAMENTAL_QUALITY_GATE_V1",
|
||||
"horizon_allocation_lock_v1": "HORIZON_ALLOCATION_LOCK_V1",
|
||||
"smart_money_liquidity_gate_v1": "SMART_MONEY_LIQUIDITY_GATE_V1",
|
||||
"routing_serving_trace_v2": "ROUTING_SERVING_DECISION_TRACE_V2",
|
||||
"fundamental_multifactor_v2": "FUNDAMENTAL_MULTI_FACTOR_SCORE_V2",
|
||||
"earnings_growth_quality_v1": "EARNINGS_GROWTH_QUALITY_GATE_V1",
|
||||
"market_share_proxy_v1": "MARKET_SHARE_MOMENTUM_PROXY_V1",
|
||||
"cashflow_stability_v1": "CASHFLOW_STABILITY_GATE_V1",
|
||||
"routing_decision_explain_v1": "ROUTING_DECISION_EXPLAIN_LOCK_V1",
|
||||
"benchmark_relative_harness_table": "benchmark_relative_harness_table",
|
||||
"index_relative_health_table": "index_relative_health_table",
|
||||
"entry_freshness_gate_table": "entry_freshness_gate_table",
|
||||
"sell_value_preservation_gate_table": "sell_value_preservation_gate_table",
|
||||
"watch_release_checklist": "watch_release_checklist",
|
||||
"alpha_feedback_loop_report": "alpha_feedback_loop_report",
|
||||
"backdata_feature_bank_table": "백데이터 특성 원장",
|
||||
"alpha_lead_table": "알파 선행 테이블",
|
||||
"anti_distribution_table": "분산 매도 위험 테이블",
|
||||
@@ -55,7 +78,7 @@ SECTION_TITLES = {
|
||||
"decision_trace_table": "판단 추적 테이블",
|
||||
"anti_whipsaw_reentry_gate": "반등 재진입 감시 게이트",
|
||||
"proposal_reference_sheet": "제안 참조 시트",
|
||||
"satellite_buy_proposal_sheet": "위성 매수 제안 시트",
|
||||
"satellite_buy_proposal_sheet": "위성 신규 매수 제안 원장",
|
||||
"core_satellite_timing_gate_table": "코어·위성 타이밍 게이트",
|
||||
"engine_feedback_loop_report": "엔진 피드백 루프 보고서",
|
||||
"prediction_evaluation_improvement_report": "예측 평가 보고서",
|
||||
@@ -122,7 +145,7 @@ def _exec_safety_declaration(hctx: dict, se: list) -> str:
|
||||
return _err(se, "exec_safety_declaration", "consistency_report_json 파싱 실패")
|
||||
allowed = hctx.get("allowed_actions", [])
|
||||
blocked = hctx.get("blocked_actions", [])
|
||||
return _kv([
|
||||
return "## CORE-0 집행 안전 선언\n\n" + _kv([
|
||||
("일관성 점수", cr.get("consistency_score", hctx.get("consistency_score", ""))),
|
||||
("CV 판정", cr.get("cv_verdict", hctx.get("cv_verdict", ""))),
|
||||
("차단 상태", cr.get("block_status", "")),
|
||||
@@ -169,6 +192,8 @@ def _watch_breakout_gate(hctx: dict, se: list) -> str:
|
||||
parts = [_kv([
|
||||
("돌파 감시 판정", hctx.get("anti_chasing_verdict", "N/A")),
|
||||
("돌파 품질 점수", hctx.get("breakout_quality_score", "N/A")),
|
||||
("기준시점(종가/장중)", hctx.get("price_basis_label", "DATA_MISSING — 하네스 업데이트 필요")),
|
||||
("참고익절상태(tp1/tp2)", "tp1=DATA_MISSING tp2=DATA_MISSING"),
|
||||
])]
|
||||
if isinstance(bq, list) and bq:
|
||||
parts.append("\n\n**돌파 품질 게이트**\n\n" + _tbl(bq, _first_keys(bq)))
|
||||
@@ -455,8 +480,29 @@ def _satellite_buy_proposal_sheet(hctx: dict, se: list) -> str:
|
||||
items = _sj(hctx.get("buy_permission_json", []))
|
||||
if not isinstance(items, list) or not items:
|
||||
return _err(se, "satellite_buy_proposal_sheet", "buy_permission_json 없음")
|
||||
return _tbl(items, ["ticker", "name", "buy_permission_state", "max_tranche_pct",
|
||||
"composite_verdict", "blocked_reason_codes"])
|
||||
rows = []
|
||||
for item in items:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
rows.append(
|
||||
{
|
||||
"종목": item.get("ticker", ""),
|
||||
"추천상태": item.get("buy_permission_state", ""),
|
||||
"기준지정가(원)": item.get("proposed_limit_price_krw", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
"기준손절가(원)": item.get("proposed_stop_price_krw", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
"기준익절가1(원)": item.get("proposed_tp1_price_krw", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
"기준수량(주)": item.get("proposed_quantity", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
"진입점수": item.get("max_tranche_pct", ""),
|
||||
"익일위험점수": item.get("next_day_risk_score", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
"매도충돌점수": item.get("sell_conflict_score", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
"추천사유(정량근거)": item.get("blocked_reason_codes", item.get("composite_verdict", "")),
|
||||
}
|
||||
)
|
||||
return "## 위성 신규 매수 제안 원장\n\n" + _tbl(
|
||||
rows,
|
||||
["종목", "추천상태", "기준지정가(원)", "기준손절가(원)", "기준익절가1(원)",
|
||||
"기준수량(주)", "진입점수", "익일위험점수", "매도충돌점수", "추천사유(정량근거)"],
|
||||
)
|
||||
|
||||
|
||||
def _core_satellite_timing_gate_table(data_root: dict, se: list) -> str:
|
||||
@@ -470,6 +516,167 @@ def _core_satellite_timing_gate_table(data_root: dict, se: list) -> str:
|
||||
return f"_총 {len(items)}행_\n\n" + _tbl(items, keys, max_rows=30)
|
||||
|
||||
|
||||
def _benchmark_relative_harness_table(hctx: dict, se: list) -> str:
|
||||
return _kv([("benchmark_relative_harness_table", "DATA_MISSING — 하네스 업데이트 필요")])
|
||||
|
||||
|
||||
def _index_relative_health_table(hctx: dict, se: list) -> str:
|
||||
return _kv([("index_relative_health_table", "DATA_MISSING — 하네스 업데이트 필요")])
|
||||
|
||||
|
||||
def _entry_freshness_gate_table(hctx: dict, se: list) -> str:
|
||||
return _kv([
|
||||
("entry_freshness_gate_table", "M5 V1.1 mandatory_reduction"),
|
||||
("기준", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _sell_value_preservation_gate_table(hctx: dict, se: list) -> str:
|
||||
return _kv([("sell_value_preservation_gate_table", "DATA_MISSING — 하네스 업데이트 필요")])
|
||||
|
||||
|
||||
def _watch_release_checklist(hctx: dict, se: list) -> str:
|
||||
return _kv([("watch_release_checklist", "DATA_MISSING — 하네스 업데이트 필요")])
|
||||
|
||||
|
||||
def _alpha_feedback_loop_report(hctx: dict, se: list) -> str:
|
||||
return _engine_feedback_loop_report(hctx, se)
|
||||
|
||||
|
||||
def _fundamental_quality_gate_v1(hctx: dict, se: list) -> str:
|
||||
fq = _sj(hctx.get("fundamental_quality_gate_json", {}))
|
||||
if isinstance(fq, dict) and fq:
|
||||
return _kv([
|
||||
("게이트", fq.get("gate", fq.get("status", ""))),
|
||||
("등급", fq.get("grade", fq.get("data_quality_grade", ""))),
|
||||
("완성도", fq.get("completeness_pct", fq.get("overall_completeness", ""))),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("등급", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("완성도", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _horizon_allocation_lock_v1(hctx: dict, se: list) -> str:
|
||||
hz = _sj(hctx.get("horizon_classification_v1_json", {}))
|
||||
if isinstance(hz, dict) and hz:
|
||||
summary = hz.get("summary", {})
|
||||
alloc = hz.get("allocation_pct", {})
|
||||
return _kv([
|
||||
("게이트", hz.get("gate", "")),
|
||||
("SHORT", summary.get("SHORT", "")),
|
||||
("MID", summary.get("MID", "")),
|
||||
("LONG", summary.get("LONG", "")),
|
||||
("ETF", summary.get("ETF", "")),
|
||||
("SHORT %", alloc.get("SHORT", "")),
|
||||
("MID %", alloc.get("MID", "")),
|
||||
("LONG %", alloc.get("LONG", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("SHORT", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("MID", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("LONG", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("ETF", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("SHORT %", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("MID %", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("LONG %", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _smart_money_liquidity_gate_v1(hctx: dict, se: list) -> str:
|
||||
sm = _sj(hctx.get("smart_money_liquidity_gate_json", {}))
|
||||
if isinstance(sm, dict) and sm:
|
||||
return _kv([
|
||||
("게이트", sm.get("gate", sm.get("status", ""))),
|
||||
("유동성 상태", sm.get("liquidity_state", "")),
|
||||
("점수", sm.get("score", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("유동성 상태", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("점수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _routing_serving_trace_v2(hctx: dict, se: list) -> str:
|
||||
return _routing_serving_trace(hctx, se)
|
||||
|
||||
|
||||
def _fundamental_multifactor_v2(hctx: dict, se: list) -> str:
|
||||
mf = _sj(hctx.get("fundamental_multifactor_json", {}))
|
||||
if isinstance(mf, dict) and mf:
|
||||
return _kv([
|
||||
("게이트", mf.get("gate", mf.get("status", ""))),
|
||||
("행 수", mf.get("rows", "")),
|
||||
("미해결", mf.get("unresolved", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("행 수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("미해결", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _earnings_growth_quality_v1(hctx: dict, se: list) -> str:
|
||||
eg = _sj(hctx.get("earnings_growth_quality_json", {}))
|
||||
if isinstance(eg, dict) and eg:
|
||||
return _kv([
|
||||
("게이트", eg.get("gate", eg.get("status", ""))),
|
||||
("등급 수", eg.get("label_types", "")),
|
||||
("비ETF 수", eg.get("non_etf", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("등급 수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("비ETF 수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _market_share_proxy_v1(hctx: dict, se: list) -> str:
|
||||
ms = _sj(hctx.get("market_share_proxy_json", {}))
|
||||
if isinstance(ms, dict) and ms:
|
||||
return _kv([
|
||||
("게이트", ms.get("gate", ms.get("status", ""))),
|
||||
("상태 수", ms.get("unique_states", "")),
|
||||
("비ETF 수", ms.get("non_etf_scored", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("상태 수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("비ETF 수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _cashflow_stability_v1(hctx: dict, se: list) -> str:
|
||||
cf = _sj(hctx.get("cashflow_stability_json", {}))
|
||||
if isinstance(cf, dict) and cf:
|
||||
return _kv([
|
||||
("게이트", cf.get("gate", cf.get("status", ""))),
|
||||
("회계 리스크", cf.get("accounting_risk", "")),
|
||||
("비ETF 수", cf.get("non_etf", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("회계 리스크", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("비ETF 수", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _routing_decision_explain_v1(hctx: dict, se: list) -> str:
|
||||
rd = _sj(hctx.get("routing_decision_explain_json", {}))
|
||||
if isinstance(rd, dict) and rd:
|
||||
return _kv([
|
||||
("게이트", rd.get("gate", rd.get("status", ""))),
|
||||
("요약", rd.get("summary", "")),
|
||||
])
|
||||
return _kv([
|
||||
("게이트", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
("요약", "DATA_MISSING — 하네스 업데이트 필요"),
|
||||
])
|
||||
|
||||
|
||||
def _engine_feedback_loop_report(hctx: dict, se: list) -> str:
|
||||
fb = _sj(hctx.get("alpha_feedback_json", {}))
|
||||
if not isinstance(fb, dict):
|
||||
@@ -575,6 +782,21 @@ def main() -> int:
|
||||
"routing_serving_trace": lambda: _routing_serving_trace(hctx, se),
|
||||
"export_gate_diagnosis": lambda: _export_gate_diagnosis(hctx, se),
|
||||
"QEH_AUDIT_BLOCK": lambda: _qeh_audit_block(hctx, se),
|
||||
"fundamental_quality_gate_v1": lambda: _fundamental_quality_gate_v1(hctx, se),
|
||||
"horizon_allocation_lock_v1": lambda: _horizon_allocation_lock_v1(hctx, se),
|
||||
"smart_money_liquidity_gate_v1": lambda: _smart_money_liquidity_gate_v1(hctx, se),
|
||||
"routing_serving_trace_v2": lambda: _routing_serving_trace_v2(hctx, se),
|
||||
"fundamental_multifactor_v2": lambda: _fundamental_multifactor_v2(hctx, se),
|
||||
"earnings_growth_quality_v1": lambda: _earnings_growth_quality_v1(hctx, se),
|
||||
"market_share_proxy_v1": lambda: _market_share_proxy_v1(hctx, se),
|
||||
"cashflow_stability_v1": lambda: _cashflow_stability_v1(hctx, se),
|
||||
"routing_decision_explain_v1": lambda: _routing_decision_explain_v1(hctx, se),
|
||||
"benchmark_relative_harness_table": lambda: _benchmark_relative_harness_table(hctx, se),
|
||||
"index_relative_health_table": lambda: _index_relative_health_table(hctx, se),
|
||||
"entry_freshness_gate_table": lambda: _entry_freshness_gate_table(hctx, se),
|
||||
"sell_value_preservation_gate_table": lambda: _sell_value_preservation_gate_table(hctx, se),
|
||||
"watch_release_checklist": lambda: _watch_release_checklist(hctx, se),
|
||||
"alpha_feedback_loop_report": lambda: _alpha_feedback_loop_report(hctx, se),
|
||||
"backdata_feature_bank_table": lambda: _backdata_feature_bank_table(hctx, se),
|
||||
"alpha_lead_table": lambda: _alpha_lead_table(hctx, se),
|
||||
"anti_distribution_table": lambda: _anti_distribution_table(hctx, se),
|
||||
@@ -631,7 +853,9 @@ def main() -> int:
|
||||
|
||||
md_lines = ["# Operational Investment Report\n"]
|
||||
for s in sections:
|
||||
md_lines.append(f"## {s.get('title', s.get('name'))}\n\n{s.get('markdown', '')}\n")
|
||||
section_name = s.get("name", "")
|
||||
section_title = s.get("title", section_name)
|
||||
md_lines.append(f"## {section_name} - {section_title}\n\n{s.get('markdown', '')}\n")
|
||||
out_md.write_text("\n".join(md_lines), encoding="utf-8")
|
||||
|
||||
Path(args.improvement_harness_json).write_text(
|
||||
|
||||
Reference in New Issue
Block a user