From 46da6d567faa23a89efa9a089916188ed36c8e03 Mon Sep 17 00:00:00 2001 From: Joe Esquibel Date: Sat, 5 Sep 2026 09:28:08 -0400 Subject: [PATCH] fix(core-engine): freeze the security frame's dead func_internal_density read (#2714) `security_auditor._construct_feature_matrix` read `func_internal_density` out of artifact telemetry, but nothing has ever written that key there: signal_processor's `telemetry_payload`, galaxyscope's augmentation block and the ecosystem pass all skip it, and the density is computed only inside `record_keeper.py` (~L496) while the `file_data` row is written. The `.get` default therefore fired for every file on every scan -- the column has been a constant 0.0 in the security training frame since it was added, the same shape as the `prompt_injection`/`agentic_rce` placeholders documented in `analysis_lens.py` (#1020). Freeze it as an explicit, documented 0.0 rather than delete it. `audit_repository` aligns the frame by name via `df.reindex(columns=self.feature_names, fill_value=np.nan)`, so dropping the key would hand a trained model NaN where it has always seen 0.0 -- identical only if no tree splits on the feature, which is unverifiable here (the model artifact has never lived in this repo). Populating it for real is a scored-model input change and needs a retrain; that stays open, not bundled here. Swept the rest of the row for the same defect: `control_flow_ratio`, `func_complexity_gini`, `ownership_entropy`, `author_distribution`, `densities.cog_raw`, `ecosystem_baseline_cluster`, `ecosystem_z_score` and `dist_to_0..10` all have live writers. This was the only dead read. The new test pins the constant against a telemetry payload that *does* carry the key, so the frame can't start moving by accident if some future pass begins emitting it. Verified it fails against the old read. No golden-master bless owed: the feature matrix is only built when a model loads, and no fixture records this column. Co-Authored-By: Claude Opus 5 (1M context) --- gitgalaxy/security/security_auditor.py | 17 +++++++++++++- tests/ruff_audit_baseline.json | 2 +- .../test_security_auditor.py | 23 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/gitgalaxy/security/security_auditor.py b/gitgalaxy/security/security_auditor.py index abed1c583..8e97a17ec 100644 --- a/gitgalaxy/security/security_auditor.py +++ b/gitgalaxy/security/security_auditor.py @@ -382,7 +382,22 @@ def _construct_feature_matrix(self, artifacts): "log_max_func_complexity": np.log1p(np.maximum(max_func_comp, 0)), "log_avg_func_args": np.log1p(np.maximum(avg_func_args, 0)), "func_complexity_gini": float(tel.get("func_complexity_gini", 0.0)), - "func_internal_density": float(tel.get("func_internal_density", 0.0)), + # func_internal_density (#2714): a permanent 0.0 placeholder, + # not a live feature. No telemetry writer has ever emitted + # this key -- signal_processor's telemetry_payload, the + # galaxyscope augmentation block and the ecosystem pass all + # skip it, and the density is computed only inside + # record_keeper.py (~L496) while the file_data row is + # written. The old tel.get(...) read therefore took its 0.0 + # default for every file, every scan, exactly like the + # prompt_injection/agentic_rce placeholders documented in + # analysis_lens.py. The column is frozen rather than deleted + # because audit_repository aligns the frame by name via + # df.reindex(columns=self.feature_names, fill_value=np.nan): + # dropping it would feed a trained model NaN where it has + # always seen 0.0. Populating it for real is a scored-model + # input change that needs a retrain, not this fix. + "func_internal_density": 0.0, "orphaned_logic": float(hit_dict.get("orphaned_logic", 0)), "duplicate_logic": float(hit_dict.get("duplicate_logic", 0)), "log_direct_upstream": np.log1p(np.maximum(dep.get("direct_upstream", 0), 0)), diff --git a/tests/ruff_audit_baseline.json b/tests/ruff_audit_baseline.json index 2a62db1f2..213f921c2 100644 --- a/tests/ruff_audit_baseline.json +++ b/tests/ruff_audit_baseline.json @@ -44,7 +44,7 @@ "gitgalaxy/recorders/record_keeper.py:965: W291": "Trailing whitespace", "gitgalaxy/recorders/sbom_recorder.py:221: PERF401": "Use `list.extend` to create a transformed list", "gitgalaxy/security/security_auditor.py:359: RUF046": "Value being cast to `int` is already an integer", - "gitgalaxy/security/security_auditor.py:426: PERF203": "`try`-`except` within a loop incurs performance overhead", + "gitgalaxy/security/security_auditor.py:441: PERF203": "`try`-`except` within a loop incurs performance overhead", "gitgalaxy/security/security_lens.py:443: SIM102": "Use a single `if` statement instead of nested `if` statements", "gitgalaxy/standards/config_resolver.py:254: UP045": "Use `X | None` for type annotations", "gitgalaxy/standards/config_resolver.py:255: UP045": "Use `X | None` for type annotations", diff --git a/tests/security_auditing/test_security_auditor.py b/tests/security_auditing/test_security_auditor.py index 8ca7ab5a1..0eb3158a5 100644 --- a/tests/security_auditing/test_security_auditor.py +++ b/tests/security_auditing/test_security_auditor.py @@ -93,6 +93,29 @@ def test_construct_feature_matrix(mock_artifacts): assert "log_logic_loc" in df.columns +def test_func_internal_density_is_a_frozen_placeholder(mock_artifacts): + """#2714: the frame's func_internal_density column is a permanent 0.0. + + Nothing ever writes that key into artifact telemetry -- the density is + computed only inside record_keeper.py while the file_data row is written -- + so the column has been a constant 0.0 in every frame the model was ever + scored or trained against. Making it vary is a scored-model input change + that needs a retrain, so this pins the constant: if some future pass does + start emitting the telemetry key, the security frame must not silently + start moving with it. + """ + auditor = SecurityAuditor() + auditor.SIGNAL_SCHEMA = ["high_risk_execution", "io", "state_mutation", "safety", "dead_code"] + + mock_artifacts[0]["telemetry"]["func_internal_density"] = 0.87 + + auditor._resolve_dependency_graph(mock_artifacts) + df = auditor._construct_feature_matrix(mock_artifacts) + + assert "func_internal_density" in df.columns + assert (df["func_internal_density"] == 0.0).all() + + def test_construct_feature_matrix_exception_fallback(): """Proves a corrupted artifact payload generates a safe, empty fallback row.""" auditor = SecurityAuditor()