Skip to content

fix(core-engine): freeze the security frame's dead func_internal_density read (#2714) - #2746

Merged
squid-protocol merged 1 commit into
mainfrom
fix/2714-dead-func-internal-density-read
Sep 5, 2026
Merged

fix(core-engine): freeze the security frame's dead func_internal_density read (#2714)#2746
squid-protocol merged 1 commit into
mainfrom
fix/2714-dead-func-internal-density-read

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Closes #2714.

The bug

security_auditor._construct_feature_matrix (L385) read func_internal_density out of artifact telemetry, but nothing has ever written that key there. Telemetry is assembled in three places and none of them emit it:

  • signal_processor.telemetry_payload (~L829)
  • the galaxyscope augmentation block (galaxyscope.py L2311 — control_flow_ratio, popularity, identity keys)
  • the ecosystem pass (signal_processor.py L1197-1200 — ecosystem_*, dist_to_N)

The density is computed only inside record_keeper.py (~L496) while the file_data row is written. So the .get default fired for every file on every scan: the column has been a constant 0.0 in the security frame since it was added — the same shape as the prompt_injection / agentic_rce placeholders documented in analysis_lens.py (#1020).

I 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 fix: freeze, don't delete

The issue offered two options; this takes the conservative one, with a wrinkle worth recording.

Deleting the key is not a no-op. audit_repository aligns the frame by namedf.reindex(columns=self.feature_names, fill_value=np.nan) — so dropping the column would hand a trained model np.nan where it has always seen 0.0, and XGBoost routes NaN down a tree's default branch. That is identical only if no tree splits on the feature, which is near-certain for a constant training column but unverifiable here: gitgalaxy_malware_xgb_multiclass.json has never existed in this repo (no file, no git history, no training script, not shipped by pyproject/MANIFEST.in), so the model is an external artifact users supply.

So the key stays, as an explicit 0.0 with a comment naming it a permanent placeholder and pointing at record_keeper as the metric's real home. Output is byte-identical for any model, and the code no longer implies a live feature.

Populating it stays open, deliberately. Making the column vary is a scored-model input change: it needs a retrain and a look at what consumes the frame, and it does not belong in a cleanup PR.

Verification

  • New test test_func_internal_density_is_a_frozen_placeholder pins the constant against a telemetry payload that does carry the key — so the frame cannot start moving by accident if some future pass begins emitting it. Confirmed it fails against the old tel.get(...) read and passes on the fix.
  • tests/security_auditing + tests/core_engine/test_zero_dependency.py: 200 passed.
  • audit_check.py: all clear (the one ruff finding was a pure line-shift of the pre-existing PERF203 in this file, baseline regenerated).
  • No golden-master bless owed. The feature matrix is only built when a model loads (audit_repository returns early otherwise), and no fixture records this column.

Related: #2705 (where this was found), #1020 (placeholder-feature precedent).

🤖 Generated with Claude Code

…ity 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) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

@squid-protocol
squid-protocol merged commit e7ac3c6 into main Sep 5, 2026
29 checks passed
@squid-protocol
squid-protocol deleted the fix/2714-dead-func-internal-density-read branch September 5, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

security_auditor reads func_internal_density from telemetry, but signal_processor never writes it — a permanently-zero feature in the security frame

1 participant