schema_version: gas_migration_wave2_4.v1 generated_at: '2026-06-10' playbook_ref: suggest/quant_engine_refactor_playbook_v1.yaml#P5-T01 total_findings: 103 wave: "2-4" wave_size: 78 wave_items: - idx: 25 file: gas_data_feed.gs line: 656 text: 'priceBasis = Number.isFinite(tp2Price) ? "TAKE_PROFIT_TIER2_PRICE" : "PRIOR_CLOSE_X_0.998";' classification: MIGRATE_TO_PYTHON rationale: GAS determines price basis label and fallback in take-profit dispatch logic. Python should select and return priceBasis as part of TAKE_PROFIT_LADDER_V2 output. python_path: src/quant_engine/ formula_id: TAKE_PROFIT_LADDER_V2 - idx: 26 file: gas_data_feed.gs line: 665 text: 'priceBasis = Number.isFinite(tp2Price) ? "TAKE_PROFIT_TIER2_PRICE" : "PRIOR_CLOSE_X_0.998";' classification: MIGRATE_TO_PYTHON rationale: Duplicate of idx=25 in adjacent branch; same priceBasis fallback decision. python_path: src/quant_engine/ formula_id: TAKE_PROFIT_LADDER_V2 - idx: 27 file: gas_data_feed.gs line: 674 text: 'priceBasis = Number.isFinite(tp1Price) ? "TAKE_PROFIT_TIER1_PRICE" : "PRIOR_CLOSE_X_0.998";' classification: MIGRATE_TO_PYTHON rationale: Tier1 variant of priceBasis fallback; same migration target as idx=25. python_path: src/quant_engine/ formula_id: TAKE_PROFIT_LADDER_V2 - idx: 28 file: gas_data_feed.gs line: 678 text: 'action = "TAKE_PROFIT_TIER1";' classification: MIGRATE_TO_PYTHON rationale: GAS directly assigns action string — this is a decision outcome that should come from Python. python_path: src/quant_engine/ formula_id: TAKE_PROFIT_LADDER_V2 - idx: 29 file: gas_data_feed.gs line: 683 text: 'priceBasis = Number.isFinite(tp1Price) ? "TAKE_PROFIT_TIER1_PRICE" : "PRIOR_CLOSE_X_0.998";' classification: MIGRATE_TO_PYTHON rationale: Another branch of same priceBasis fallback; TAKE_PROFIT_LADDER_V2 migration target. python_path: src/quant_engine/ formula_id: TAKE_PROFIT_LADDER_V2 - idx: 30 file: gas_data_feed.gs line: 741 text: '// SL003_PRIORITY_MATRIX: 복수 손절 조건 동시 발동 시 max(prices) 적용 — spec/exit/stop_loss.yaml' classification: COMMENT_FALSE_POSITIVE rationale: Comment referencing spec/exit/stop_loss.yaml; no code logic. python_path: null formula_id: null - idx: 31 file: gas_data_feed.gs line: 742 text: '// TP 계열(PROFIT_TRIM_*, TAKE_PROFIT_TIER1)은 별도 프레임워크이므로 이 블록 적용 제외' classification: COMMENT_FALSE_POSITIVE rationale: Documentation comment only. python_path: null formula_id: null - idx: 32 file: gas_data_feed.gs line: 1577 text: 'score += THRESHOLDS["SP_TAKE_PROFIT"];' classification: MIGRATE_TO_PYTHON rationale: GAS computes a score by adding the SP_TAKE_PROFIT threshold. Score computation must move to Python. python_path: src/quant_engine/ formula_id: SELL_PRIORITY_SCORING_V1 - idx: 33 file: gas_data_feed.gs line: 1578 text: 'breakdown.push(`take_profit:+${THRESHOLDS["SP_TAKE_PROFIT"]}`);' classification: MIGRATE_TO_PYTHON rationale: "Part of the same score breakdown accumulation as idx=32. Migration target: Python returns the breakdown list." python_path: src/quant_engine/ formula_id: SELL_PRIORITY_SCORING_V1 - idx: 34 file: gas_data_feed.gs line: 2164 text: 'TAKE_PROFIT_BASE: 10,' classification: MIGRATE_TO_PYTHON rationale: Threshold constant defined inline in GAS constants object. Should be in spec/calibration_registry.yaml (source=SPEC_DERIVED, owner_formula=TAKE_PROFIT_LADDER_V2). python_path: spec/calibration_registry.yaml formula_id: TAKE_PROFIT_LADDER_V2 migration_action: Register TAKE_PROFIT_BASE=10 in calibration_registry.yaml. - idx: 35 file: gas_data_feed.gs line: 2259 text: "+ ' h5.decisions=' + ((h5 && h5[\"decisions\"]) ? h5[\"decisions\"].length : 0)" classification: ADAPTER_OK rationale: Log line reading length of Python decisions array; no business logic. python_path: null formula_id: null - idx: 36 file: gas_data_feed.gs line: 2330 text: 'var routeCount = ((h5 && h5["decisions"]) ? h5["decisions"].length : 0);' classification: ADAPTER_OK rationale: Reading Python decisions count for logging/routing. No decision made. python_path: null formula_id: null - idx: 37 file: gas_data_feed.gs line: 2339 text: "+ ' | decisions=' + routeCount" classification: ADAPTER_OK rationale: Log string interpolation; no business logic. python_path: null formula_id: null - idx: 38 file: gas_data_feed.gs line: 2343 text: "Logger.log('[LOG_METRIC_MISMATCH_WARN] decisions>0 이지만 sellCandidates=0');" classification: ADAPTER_OK rationale: Warning log only; no score or decision computation. python_path: null formula_id: null - idx: 39 file: gas_data_feed.gs line: 3172 text: "formula_id: 'ROUTING_DECISION_EXPLAIN_LOCK_V1'," classification: ADAPTER_OK rationale: Setting formula_id field in output packet using a string constant; no computation. python_path: null formula_id: null - idx: 40 file: gas_data_feed.gs line: 3285 text: "formula_id: 'ROUTING_SERVING_DECISION_TRACE_V2'" classification: ADAPTER_OK rationale: Formula ID tag in output struct; no computation. python_path: null formula_id: null - idx: 41 file: gas_data_feed.gs line: 3399 text: "* spec/exit/take_profit.yaml:secular_leader_profit_lock.activation_required_all 완전 구현." classification: COMMENT_FALSE_POSITIVE rationale: JSDoc comment referencing spec; no code logic. python_path: null formula_id: null - idx: 42 file: gas_data_feed.gs line: 5246 text: 'var profitLockBase = SP["TAKE_PROFIT_BASE"];' classification: ADAPTER_OK rationale: Reading TAKE_PROFIT_BASE from SP constants object to pass downstream. The constant itself (idx=34) is the migration target; this read is adapter use. python_path: null formula_id: null - idx: 43 file: gas_data_feed.gs line: 5472 text: '* TAKE_PROFIT_LADDER_V2 (tier1/tier2) → TICK_NORMALIZER_V1' classification: COMMENT_FALSE_POSITIVE rationale: JSDoc comment describing data flow; no logic. python_path: null formula_id: null - idx: 44 file: gas_data_feed.gs line: 5551 text: '// ── TAKE_PROFIT_LADDER_V2 ─────────────────────────────────────────────' classification: COMMENT_FALSE_POSITIVE rationale: Section header comment only. python_path: null formula_id: null - idx: 45 file: gas_data_feed.gs line: 5571 text: '// spec/exit/take_profit.yaml:profit_lock_ratchet.ratchet_table 기준' classification: COMMENT_FALSE_POSITIVE rationale: Comment citing spec; no logic. python_path: null formula_id: null - idx: 46 file: gas_data_feed.gs line: 5714 text: '* spec/09_decision_flow.yaml 핵심 경로 GAS 구현' classification: COMMENT_FALSE_POSITIVE rationale: JSDoc comment; no logic. python_path: null formula_id: null - idx: 47 file: gas_data_feed.gs line: 5895 text: 'return { ["decisions"]: routes, traces: traces, lock: true };' classification: MIGRATE_TO_PYTHON rationale: GAS function returns a decisions array it built (routes). Decision routing belongs in Python; GAS should receive this as input. python_path: src/quant_engine/ formula_id: ROUTING_SERVING_DECISION_TRACE_V2 - idx: 48 file: gas_data_feed.gs line: 5920 text: "if (holding && holding.stopBreach) return 'STOP_LOSS';" classification: MIGRATE_TO_PYTHON rationale: GAS evaluates stopBreach condition and returns 'STOP_LOSS' — this is a sell decision in GAS that must live in Python stop_loss logic. python_path: src/quant_engine/ formula_id: STOP_LOSS_TRIGGER_V1 - idx: 49 file: gas_data_feed.gs line: 5941 text: "var h5RouteRows_ = (h5 && h5[\"decisions\"]) ? h5[\"decisions\"] : [];" classification: ADAPTER_OK rationale: Reading Python decisions array with null-guard; no computation. python_path: null formula_id: null - idx: 50 file: gas_data_feed.gs line: 5992 text: "} else if (orderType === 'STOP_LOSS') {" classification: ADAPTER_OK rationale: Dispatching on Python-provided orderType string; routing-only, not making the stop_loss decision. python_path: null formula_id: null - idx: 51 file: gas_data_feed.gs line: 6028 text: '["take_profit_price_krw"]: validation === "PASS" ? (priceRow.tp1_price || null) : null,' classification: ADAPTER_OK rationale: Reading Python-provided tp1_price with validation gate check. No price computation. python_path: null formula_id: null - idx: 52 file: gas_data_feed.gs line: 6029 text: '["take_profit_quantity"]: validation === "PASS" ? (priceRow.tp1_qty || null) : null,' classification: ADAPTER_OK rationale: Reading Python-provided tp1_qty; same pattern as idx=51. python_path: null formula_id: null - idx: 53 file: gas_data_feed.gs line: 6058 text: "if (ot !== 'SELL' && ot !== 'STOP_LOSS') {" classification: ADAPTER_OK rationale: Filtering on Python-provided order type string; dispatch logic only. python_path: null formula_id: null - idx: 54 file: gas_data_feed.gs line: 6206 text: "|| (row.order_type || '').toString().toUpperCase() === 'STOP_LOSS';" classification: ADAPTER_OK rationale: Reading order_type from Python-provided row; string comparison for filtering. python_path: null formula_id: null - idx: 55 file: gas_data_feed.gs line: 6688 text: '["distribution_risk_score"]: Math.min(100, Math.max(0, score)),' classification: DELETE_DUPLICATE rationale: GAS computes distribution_risk_score; Python already has DISTRIBUTION_RISK_SCORE_V1. Remove GAS computation, read Python output instead. python_path: src/quant_engine/compute_formula_outputs.py formula_id: DISTRIBUTION_RISK_SCORE_V1 migration_action: Delete GAS computation block (L6658-6700 approx), read Python result from sheet row. - idx: 56 file: gas_data_feed.gs line: 6692 text: "formula_id: 'DISTRIBUTION_RISK_SCORE_V1'" classification: DELETE_DUPLICATE rationale: Part of same GAS computation block as idx=55; remove with the block. python_path: src/quant_engine/compute_formula_outputs.py formula_id: DISTRIBUTION_RISK_SCORE_V1 - idx: 57 file: gas_data_feed.gs line: 6774 text: '["late_chase_risk_score"]: Math.min(100, Math.max(0, Math.round(lateChaseRisk))),' classification: DELETE_DUPLICATE rationale: GAS computes late_chase_risk_score; Python has this via LATE_CHASE_RISK_SCORE_V1. Remove GAS block, read Python output. python_path: src/quant_engine/compute_formula_outputs.py formula_id: LATE_CHASE_RISK_SCORE_V1 migration_action: Delete GAS computation block (L6740-6780 approx), read Python result from alpha sheet row. - idx: 58 file: gas_data_feed.gs line: 6902 text: 'var distributionRiskScore = distRow && typeof distRow["distribution_risk_score"] === "number" ? distRow["distribution_risk_score"]...' classification: ADAPTER_OK rationale: Reading distribution_risk_score from a sheet row (Python output); null-safe read. python_path: null formula_id: null - idx: 59 file: gas_data_feed.gs line: 6903 text: 'var lateChaseRiskScore = alphaRow && typeof alphaRow["late_chase_risk_score"] === "number" ? alphaRow["late_chase_risk_score"]...' classification: ADAPTER_OK rationale: Reading late_chase_risk_score from alphaRow (Python output); null-safe read. python_path: null formula_id: null - idx: 60 file: gas_data_feed.gs line: 7285 text: 'if (bqRow.breakout_quality_gate === "BLOCKED_LATE_CHASE" || alphaRow["late_chase_risk_score"] >= 70)' classification: MIGRATE_TO_PYTHON rationale: GAS applies a score threshold (>=70) to make a gate decision. This threshold comparison should live in Python as part of the anti-late-entry gate. python_path: src/quant_engine/ formula_id: ANTI_LATE_ENTRY_GATE_V2 migration_action: Move threshold check to Python; GAS reads gate result string. - idx: 61 file: gas_data_feed.gs line: 7315 text: '["late_chase_risk_score"]: alphaRow["late_chase_risk_score"] != null ? alphaRow["late_chase_risk_score"]...' classification: ADAPTER_OK rationale: Null-guarded read from alphaRow; no computation. python_path: null formula_id: null - idx: 62 file: gas_data_feed.gs line: 7995 text: '* 외국인 순매도 연속일·USD/KRW·FOMC·VIX 등 거시 변수를 macro_risk_score로 환산.' classification: COMMENT_FALSE_POSITIVE rationale: JSDoc comment describing inputs; no logic. python_path: null formula_id: null - idx: 63 file: gas_data_feed.gs line: 8877 text: '// stop_loss: final_stop_price/stop_price(없는 키) → protected_stop_price/auto_trailing_stop.' classification: COMMENT_FALSE_POSITIVE rationale: Comment describing field mapping; no logic. python_path: null formula_id: null - idx: 64 file: gas_data_feed.gs line: 8891 text: '["stop_loss"]: [pp0.auto_trailing_stop, pp0.protected_stop_price, pp0.profit_preservation_state]' classification: ADAPTER_OK rationale: Assembling stop_loss fields from Python-computed pp0 object; no decision logic. python_path: null formula_id: null - idx: 65 file: gas_data_feed.gs line: 8968 text: "{ id: 'Stage_04_macro', key: 'macro_risk_score' }," classification: ADAPTER_OK rationale: Stage config entry referencing a Python-provided key; no computation. python_path: null formula_id: null - idx: 66 file: gas_data_feed.gs line: 9047 text: "{ yaml: 'TAKE_PROFIT_LADDER_V1', gs: 'calcTpQuantityLadder_' }," classification: ADAPTER_OK rationale: GAS/YAML function mapping table entry; registration metadata, not logic. python_path: null formula_id: null - idx: 67 file: gas_data_feed.gs line: 9133 text: "{ yaml: 'ROUTING_SERVING_DECISION_TRACE_V2', gs: 'buildRoutingServingTraceV2_' }," classification: ADAPTER_OK rationale: Function mapping table entry; no computation. python_path: null formula_id: null - idx: 68 file: gas_data_feed.gs line: 9138 text: "{ yaml: 'ROUTING_DECISION_EXPLAIN_LOCK_V1', gs: 'calcRoutingExplainLockV1_' }," classification: ADAPTER_OK rationale: Function mapping table entry; no computation. python_path: null formula_id: null - idx: 69 file: gas_data_feed.gs line: 9508 text: '["stop_loss_calc"]: bp["stop_loss"] || df["stop_loss_price"] || null,' classification: ADAPTER_OK rationale: Reading Python-provided stop_loss with fallback to df field; no computation. python_path: null formula_id: null - idx: 70 file: gas_data_feed.gs line: 9509 text: '["take_profit_calc"]: bp["take_profit"] || df["tp1_price"] || null,' classification: ADAPTER_OK rationale: Reading Python-provided take_profit/tp1_price with null fallback; no computation. python_path: null formula_id: null - idx: 71 file: gas_harness_rows.gs line: 3 text: '// Pure output assembly - no decision logic. Rarely changes after V stabilizes.' classification: COMMENT_FALSE_POSITIVE rationale: File-level comment; no logic. python_path: null formula_id: null - idx: 72 file: gas_harness_rows.gs line: 60 text: '* source_manifest_json, decision_trace_json 등에 사용.' classification: COMMENT_FALSE_POSITIVE rationale: JSDoc comment; no logic. python_path: null formula_id: null - idx: 73 file: gas_harness_rows.gs line: 166 text: 'var p6DecisionMap = {};' classification: ADAPTER_OK rationale: Initializing a lookup map to organize Python decisions for sheet writing; no business logic. python_path: null formula_id: null - idx: 74 file: gas_harness_rows.gs line: 167 text: '(h5.decisions || []).forEach(function(row) { p6DecisionMap[row.ticker] = row; });' classification: ADAPTER_OK rationale: Building ticker→decision lookup map from Python h5.decisions array; pure organization. python_path: null formula_id: null - idx: 75 file: gas_harness_rows.gs line: 187 text: 'Object.keys(p6DecisionMap).forEach(function(t) { p6Tickers[t] = true; });' classification: ADAPTER_OK rationale: Building ticker set from Python decisions for iteration; no computation. python_path: null formula_id: null - idx: 76 file: gas_harness_rows.gs line: 193 text: 'var da = p6DecisionMap[a] || {};' classification: ADAPTER_OK rationale: Null-safe lookup of Python decision by ticker; no computation. python_path: null formula_id: null - idx: 77 file: gas_harness_rows.gs line: 194 text: 'var db = p6DecisionMap[b] || {};' classification: ADAPTER_OK rationale: Null-safe lookup of Python decision by ticker; no computation. python_path: null formula_id: null - idx: 78 file: gas_harness_rows.gs line: 200 text: "if (action.indexOf('SELL') >= 0 || action.indexOf('TRIM') >= 0 || action.indexOf('EXIT') >= 0 || act..." classification: ADAPTER_OK rationale: Sorting rows by Python-provided action string category for sheet display order; presentation logic. python_path: null formula_id: null - idx: 79 file: gas_harness_rows.gs line: 227 text: 'var d = p6DecisionMap[ticker] || {};' classification: ADAPTER_OK rationale: Null-safe lookup from Python decisions map. python_path: null formula_id: null - idx: 80 file: gas_harness_rows.gs line: 235 text: "if (finalAction.indexOf('SELL') >= 0 || finalAction.indexOf('TRIM') >= 0 || finalAction.indexOf('EXI..." classification: ADAPTER_OK rationale: Categorizing Python-provided finalAction string for sheet rendering; display logic. python_path: null formula_id: null - idx: 81 file: gas_harness_rows.gs line: 265 text: "} else if (finalAction.indexOf('TAKE_PROFIT') >= 0 || orderType.indexOf('TAKE_PROFIT') >= 0) {" classification: ADAPTER_OK rationale: Categorizing Python-provided finalAction for display; presentation routing. python_path: null formula_id: null - idx: 82 file: gas_harness_rows.gs line: 464 text: "['decisions_json', JSON.stringify(h5.decisions)]," classification: ADAPTER_OK rationale: Serializing Python h5.decisions to sheet; no computation. python_path: null formula_id: null - idx: 83 file: gas_harness_rows.gs line: 465 text: "['decision_trace_json', (function() { ..." classification: ADAPTER_OK rationale: Serializing Python decision_trace to sheet cell; no computation. python_path: null formula_id: null - idx: 84 file: gas_harness_rows.gs line: 475 text: "['decision_lock', 'true']," classification: ADAPTER_OK rationale: Writing static lock flag to sheet; no business logic. python_path: null formula_id: null - idx: 85 file: gas_harness_rows.gs line: 489 text: "['decision_trace_checksum', computeStringChecksum_(JSON.stringify(h5.traces))]," classification: ADAPTER_OK rationale: Computing integrity checksum of Python trace data for audit; sheet-writing utility, not business logic. python_path: null formula_id: null - idx: 86 file: gas_harness_rows.gs line: 699 text: "'ALPHA_LEAD_SCORE_V1,FOLLOW_THROUGH_CONFIRM_V1,DISTRIBUTION_RISK_SCORE_V1,'" classification: ADAPTER_OK rationale: String literal listing formula IDs for a manifest field; no computation. python_path: null formula_id: null - idx: 87 file: gas_harness_rows.gs line: 728 text: "['macro_risk_score', (hApex || {}).macro_risk_score !== undefined ? String(...)..." classification: ADAPTER_OK rationale: Reading Python macro_risk_score from hApex for sheet writing; null-safe adapter. python_path: null formula_id: null - idx: 88 file: gas_harness_rows.gs line: 1133 text: "+ '▶ 재계산 금지: sell_priority_lock·quantities_lock·prices_lock·decision_lock...'" classification: COMMENT_FALSE_POSITIVE rationale: UI warning string constant embedded in a log/display message; not decision logic. python_path: null formula_id: null - idx: 89 file: gas_harness_rows.gs line: 1267 text: "['routing_decision_explain_json', JSON.stringify((hApex || {}).routing_decision_explain_json || {})]" classification: ADAPTER_OK rationale: Serializing Python routing explanation to sheet; no computation. python_path: null formula_id: null - idx: 90 file: gas_harness_rows.gs line: 1299 text: "'decision_lock', 'blueprint_row_count', 'blueprint_checksum', 'blueprint_hash_algo'," classification: ADAPTER_OK rationale: Column name list for sheet schema definition; no computation. python_path: null formula_id: null - idx: 91 file: gas_harness_rows.gs line: 1300 text: "'source_manifest_checksum', 'decision_trace_checksum', 'checksum_hash_algo'," classification: ADAPTER_OK rationale: Column name list; no computation. python_path: null formula_id: null - idx: 92 file: gas_harness_rows.gs line: 1305 text: "'prices_json', 'decisions_json', 'decision_trace_json'," classification: ADAPTER_OK rationale: Column name list; no computation. python_path: null formula_id: null - idx: 93 file: gas_harness_rows.gs line: 1419 text: "'cashflow_stability_json','routing_decision_explain_json'" classification: ADAPTER_OK rationale: Column name list; no computation. python_path: null formula_id: null - idx: 94 file: gas_lib.gs line: 145 text: '"Setup_Decision","Exit_Reason"' classification: ADAPTER_OK rationale: Column header list; no computation. python_path: null formula_id: null - idx: 95 file: gas_lib.gs line: 158 text: '"Timing_Score_Entry","Timing_Score_Exit","T1_Forced_Sell_Risk_Score","Sell_Conflict_Score",' classification: ADAPTER_OK rationale: Column header list; no computation. python_path: null formula_id: null - idx: 96 file: gas_lib.gs line: 946 text: '"Sector_Score","Sector_Rank","Alert_Level","Data_Quality","Decision_Use","Reason","AsOfDate"' classification: ADAPTER_OK rationale: Column header list; no computation. python_path: null formula_id: null - idx: 97 file: gas_lib.gs line: 1091 text: '"Flow_Breadth_5D","Alert_Level","Data_Quality","Decision_Use","ETF_Liquidity_Status","ETF_Execution_..."' classification: ADAPTER_OK rationale: Column header list; no computation. python_path: null formula_id: null - idx: 98 file: gas_lib.gs line: 1226 text: '"Alert_Level","Data_Quality","Decision_Use","Reason","RW1","RW3","AsOfDate",' classification: ADAPTER_OK rationale: Column header list; no computation. python_path: null formula_id: null - idx: 99 file: gas_lib.gs line: 1411 text: '// MARKET_RISK_SCORE_V1' classification: COMMENT_FALSE_POSITIVE rationale: Section comment only. python_path: null formula_id: null - idx: 100 file: gas_lib.gs line: 1517 text: '// spec/05_position_sizing.yaml:net_return_feedback' classification: COMMENT_FALSE_POSITIVE rationale: Comment referencing spec; no logic. python_path: null formula_id: null - idx: 101 file: gas_lib.gs line: 1553 text: 'rows.push(["MRS_COMPUTED", "Market_Risk_Score", "Computed", mrs, ...]' classification: ADAPTER_OK rationale: Assembling a display row with Python-computed mrs value; sheet output assembly. python_path: null formula_id: null - idx: 102 file: gas_lib.gs line: 2128 text: 'const mrsRow = byName["Market_Risk_Score"] ?? {};' classification: ADAPTER_OK rationale: Null-safe lookup of Market_Risk_Score row from Python-provided data; no computation. python_path: null formula_id: null wave2_4_summary: ADAPTER_OK: 50 COMMENT_FALSE_POSITIVE: 14 MIGRATE_TO_PYTHON: 11 DELETE_DUPLICATE: 3 total_wave2_4: 78 full_migration_summary: wave1: ADAPTER_OK: 17 COMMENT_FALSE_POSITIVE: 7 MIGRATE_TO_PYTHON: 1 DELETE_DUPLICATE: 0 total: 25 wave2_4: ADAPTER_OK: 50 COMMENT_FALSE_POSITIVE: 14 MIGRATE_TO_PYTHON: 11 DELETE_DUPLICATE: 3 total: 78 all_103: ADAPTER_OK: 67 COMMENT_FALSE_POSITIVE: 21 MIGRATE_TO_PYTHON: 12 DELETE_DUPLICATE: 3 grand_total: 103 migration_priority: phase1_delete_duplicates: - note: "3 DELETE_DUPLICATE items — GAS computations that duplicate Python exactly" - gas_data_feed.gs:6688 distribution_risk_score (DISTRIBUTION_RISK_SCORE_V1) - gas_data_feed.gs:6692 formula_id reference for above (remove with block) - gas_data_feed.gs:6774 late_chase_risk_score (LATE_CHASE_RISK_SCORE_V1) phase2_migrate_to_python: - note: "12 MIGRATE_TO_PYTHON items — logic that must move to Python" - gas_data_feed.gs:186 SP_TAKE_PROFIT=10 threshold (→ calibration_registry.yaml) [wave1] - gas_data_feed.gs:2164 TAKE_PROFIT_BASE=10 constant (→ calibration_registry.yaml) - gas_data_feed.gs:656/665/674/678/683 priceBasis + action for TAKE_PROFIT (→ TAKE_PROFIT_LADDER_V2 output) - gas_data_feed.gs:1577/1578 score += SP_TAKE_PROFIT (→ SELL_PRIORITY_SCORING_V1) - gas_data_feed.gs:5895 return decisions (→ ROUTING_SERVING_DECISION_TRACE_V2) - gas_data_feed.gs:5920 stopBreach → STOP_LOSS (→ STOP_LOSS_TRIGGER_V1) - gas_data_feed.gs:7285 late_chase_risk_score >= 70 gate (→ ANTI_LATE_ENTRY_GATE_V2) phase3_comment_cleanup: - note: "21 COMMENT_FALSE_POSITIVE items — no code changes needed, scanner false positives" phase4_adapter_ok: - note: "67 ADAPTER_OK items — compliant thin-adapter reads; no changes needed" action_items: - id: REGISTER_SP_TAKE_PROFIT status: TODO file: spec/calibration_registry.yaml action: Add SP_TAKE_PROFIT=10, source=SPEC_DERIVED, owner_formula=TAKE_PROFIT_LADDER_V2 - id: REGISTER_TAKE_PROFIT_BASE status: TODO file: spec/calibration_registry.yaml action: Add TAKE_PROFIT_BASE=10, source=SPEC_DERIVED, owner_formula=TAKE_PROFIT_LADDER_V2 - id: DELETE_DISTRIBUTION_RISK_GAS status: TODO file: gas_data_feed.gs action: Delete distribution_risk_score computation block (~L6658-6700), replace with read from Python output sheet row - id: DELETE_LATE_CHASE_RISK_GAS status: TODO file: gas_data_feed.gs action: Delete late_chase_risk_score computation block (~L6740-6780), replace with read from Python output alpha row - id: MIGRATE_PRICEBASIS_TO_PYTHON status: TODO file: gas_data_feed.gs + src/quant_engine/ action: Move priceBasis/action assignment (L656-683) to TAKE_PROFIT_LADDER_V2 Python output; GAS reads result - id: MIGRATE_SCORE_CALCULATION status: TODO file: gas_data_feed.gs + src/quant_engine/ action: Move score += THRESHOLDS["SP_TAKE_PROFIT"] + breakdown.push (L1577-1578) to SELL_PRIORITY_SCORING_V1 Python - id: MIGRATE_STOP_BREACH_DECISION status: TODO file: gas_data_feed.gs + src/quant_engine/ action: Move stopBreach → STOP_LOSS decision (L5920) to Python STOP_LOSS_TRIGGER_V1 - id: MIGRATE_DECISIONS_ROUTING status: TODO file: gas_data_feed.gs + src/quant_engine/ action: Move decisions route-building (L5895 return block) to Python ROUTING_SERVING_DECISION_TRACE_V2 - id: MIGRATE_LATE_CHASE_GATE status: TODO file: gas_data_feed.gs + src/quant_engine/ action: Move late_chase_risk_score >= 70 threshold gate (L7285) to Python ANTI_LATE_ENTRY_GATE_V2 - id: UPDATE_GAS_SCANNER_FALSE_POSITIVES status: TODO file: tools/validate_gas_thin_adapter_v2.py action: Add 21 confirmed false-positive patterns to scanner exclusion list to reduce noise in future runs