schema_version: gas_logic_migration_ledger.v1 source: governance/gas_logic_migration_ledger_v1.yaml authored: 2026-06-10 total_findings: 15 classification_summary: decision_logic: 4 score_logic: 5 price_qty_logic: 4 pure_mapping: 1 display_text: 1 unclassified_findings: 0 # Canonical classification of GAS thin-adapter findings identified by # validate_gas_thin_adapter_v1.py. Each finding is classified by what type # of logic it contains and paired with a migration_action. findings: - id: F01 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 186 text: "SP_TAKE_PROFIT: 10, // Profit_Pct >= 10% (익절 후보)" classification: score_logic migration_action: REGISTER_SP_TAKE_PROFIT target_file: formulas/score_thresholds_v1.py status: TODO - id: F02 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 656 text: "priceBasis = Number.isFinite(tp2Price) ? \"TAKE_PROFIT_TIER2_PRICE\" : \"PRIOR_CLOSE_X_0.998\";" classification: price_qty_logic migration_action: MIGRATE_PRICEBASIS_TO_PYTHON target_file: formulas/price_basis_v1.py status: TODO blocking_on: F03 F04 (same function, migrate together) - id: F03 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 665 text: "priceBasis = Number.isFinite(tp2Price) ? \"TAKE_PROFIT_TIER2_PRICE\" : \"PRIOR_CLOSE_X_0.998\";" classification: price_qty_logic migration_action: MIGRATE_PRICEBASIS_TO_PYTHON target_file: formulas/price_basis_v1.py status: TODO blocking_on: F02 F04 - id: F04 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 674 text: "priceBasis = Number.isFinite(tp1Price) ? \"TAKE_PROFIT_TIER1_PRICE\" : \"PRIOR_CLOSE_X_0.998\";" classification: price_qty_logic migration_action: MIGRATE_PRICEBASIS_TO_PYTHON target_file: formulas/price_basis_v1.py status: TODO - id: F05 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 678 text: "action = \"TAKE_PROFIT_TIER1\";" classification: decision_logic migration_action: MIGRATE_DECISIONS_ROUTING target_file: formulas/execution_decision_v1.py status: TODO - id: F06 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 683 text: "priceBasis = Number.isFinite(tp1Price) ? \"TAKE_PROFIT_TIER1_PRICE\" : \"PRIOR_CLOSE_X_0.998\";" classification: price_qty_logic migration_action: MIGRATE_PRICEBASIS_TO_PYTHON target_file: formulas/price_basis_v1.py status: TODO - id: F07 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 1577 text: "score += THRESHOLDS[\"SP_TAKE_PROFIT\"];" classification: score_logic migration_action: MIGRATE_SCORE_CALCULATION target_file: formulas/score_thresholds_v1.py status: TODO - id: F08 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 1578 text: "breakdown.push(`take_profit:+${THRESHOLDS[\"SP_TAKE_PROFIT\"]}`)" classification: display_text migration_action: DISPLAY_TEXT_PASSTHROUGH notes: display_text stays in GAS adapter as rendering concern status: KEEP_IN_GAS - id: F09 file: src/gas_adapter_parts/gdf_01_price_metrics.gs line: 2164 text: "TAKE_PROFIT_BASE: 10," classification: score_logic migration_action: REGISTER_TAKE_PROFIT_BASE target_file: formulas/score_thresholds_v1.py status: TODO - id: F10 file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs line: 1335 text: "return { [\"decisions\"]: routes, traces: traces, lock: true };" classification: decision_logic migration_action: MIGRATE_DECISIONS_ROUTING target_file: formulas/routing_decision_v1.py status: TODO - id: F11 file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs line: 1360 text: "if (holding && holding.stopBreach) return 'STOP_LOSS';" classification: decision_logic migration_action: MIGRATE_STOP_BREACH_DECISION target_file: formulas/stop_loss_gate_v1.py status: TODO - id: F12 file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs line: 2128 text: "[\"distribution_risk_score\"]: Math.min(100, Math.max(0, score))," classification: score_logic migration_action: DELETE_DISTRIBUTION_RISK_GAS target_file: formulas/distribution_risk_v1.py status: TODO notes: Python canonical (build_distribution_risk_v1.py) already exists; GAS version is duplicate - id: F13 file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs line: 2132 text: "formula_id: 'DISTRIBUTION_RISK_SCORE_V1'" classification: pure_mapping migration_action: DELETE_DISTRIBUTION_RISK_GAS status: TODO notes: formula_id tag stays with Python canonical; remove from GAS - id: F14 file: src/gas_adapter_parts/gdf_03_portfolio_gates.gs line: 2214 text: "[\"late_chase_risk_score\"]: Math.min(100, Math.max(0, Math.round(lateChaseRisk)))," classification: score_logic migration_action: DELETE_LATE_CHASE_RISK_GAS target_file: formulas/late_chase_risk_v1.py status: TODO notes: Python canonical (build_alpha_lead_table_v1.py) computes late_chase_risk; GAS version is duplicate - id: F15 file: src/gas_adapter_parts/gdf_04_execution_quality.gs line: 479 text: "if (bqRow.breakout_quality_gate === 'BLOCKED_LATE_CHASE' || alphaRow[\"late_chase_risk_score\"] >= 70)" classification: decision_logic migration_action: MIGRATE_LATE_CHASE_GATE target_file: formulas/late_chase_gate_v1.py status: TODO # Migration action summary (9 actions) migration_actions: - action_id: REGISTER_SP_TAKE_PROFIT findings: [F01] description: Register SP_TAKE_PROFIT threshold (value=10) in Python score_thresholds canonical priority: LOW - action_id: REGISTER_TAKE_PROFIT_BASE findings: [F09] description: Register TAKE_PROFIT_BASE threshold (value=10) in Python score_thresholds canonical priority: LOW - action_id: DELETE_DISTRIBUTION_RISK_GAS findings: [F12, F13] description: Remove distribution_risk_score calculation from gdf_03; Python canonical exists priority: HIGH blocker: verify build_distribution_risk_v1.py output matches GAS output before delete - action_id: DELETE_LATE_CHASE_RISK_GAS findings: [F14] description: Remove late_chase_risk_score from gdf_03; Python canonical in alpha_lead_table_v1 priority: HIGH blocker: verify parity before delete - action_id: MIGRATE_PRICEBASIS_TO_PYTHON findings: [F02, F03, F04, F06] description: priceBasis string selection (TIER1/TIER2 or PRIOR_CLOSE_X_0.998) → Python canonical priority: MEDIUM - action_id: MIGRATE_SCORE_CALCULATION findings: [F07] description: score += THRESHOLDS["SP_TAKE_PROFIT"] pattern → Python canonical scorer priority: MEDIUM - action_id: MIGRATE_STOP_BREACH_DECISION findings: [F11] description: holding.stopBreach → STOP_LOSS decision → Python canonical stop_loss_gate priority: HIGH notes: critical path — must match validate_stop_loss_policy_v1 spec - action_id: MIGRATE_DECISIONS_ROUTING findings: [F05, F10] description: TAKE_PROFIT_TIER1 action assignment and routing lock decision → Python canonical priority: MEDIUM - action_id: MIGRATE_LATE_CHASE_GATE findings: [F15] description: BLOCKED_LATE_CHASE gate check (threshold 70) → Python canonical gate formula priority: HIGH blocker: late_chase_risk_score must come from Python before GAS gate can be removed