fix(core): critical-leak synthetic risk_vector hardcoded to stale 18-length RISK_SCHEMA - #1220
Merged
Merged
Conversation
…length RISK_SCHEMA galaxyscope.py's CRITICAL LEAKS synthetic-node path (forces a file flagged by the Aperture secrets scanner onto the 3D map even though it never went through normal parsing) built risk_vector as a hardcoded literal: `[0.0] * 13 + [0.0, 0.0, 0.0, 0.0, 100.0]` -- an 18-element vector with a comment claiming "Index 17 is secrets_risk". RISK_SCHEMA is actually 13 elements now (secrets_risk at index 12), so this path has been emitting a 5-element-too-long risk_vector for a while. Harmless on its own, but record_keeper.py's SQLite INSERT builds its column list from the live RISK_SCHEMA length -- any file taking this path made record_mission() raise `sqlite3.OperationalError: N values for M columns` and abort `--db-only` output entirely for the whole scan, not just that one file. Found while building a tree-sitter-based ground-truth accuracy pass for JavaScript (mirroring ast_accuracy_audit.py's Python methodology, #1200): `galaxyscope <path> --db-only` crashed on expressjs/express because its committed `.npmrc` trips the hardcoded-secrets detector. Reproduced, isolated to this exact literal via a cursor.execute proxy that dumped the column/value counts at the failing INSERT, confirmed by reverting it. Fix: size risk_vector from `len(SignalProcessor.RISK_SCHEMA)` (matching the sibling AI-MODEL-WEIGHTS synthetic-node path a few lines down, which already did this correctly) and set the secrets_risk slot by name lookup instead of a hardcoded index, mirroring the hit_vector/sec_hardcoded_secrets pattern already used right below it. tests/core_engine/test_galaxyscope.py::test_synthetic_node_generation asserted `risk_vector[17] == 100.0` -- also stale, and silently correct by coincidence since the old 18-length hardcoded vector still had a real value at index 17. Updated to assert against the live RISK_SCHEMA length and the schema-resolved secrets_risk index, so a future RISK_SCHEMA resize can't silently reintroduce this drift. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
2 tasks
squid-protocol
added a commit
that referenced
this pull request
Aug 10, 2026
…pass (#1223) * fix(core): critical-leak synthetic risk_vector hardcoded to stale 18-length RISK_SCHEMA galaxyscope.py's CRITICAL LEAKS synthetic-node path (forces a file flagged by the Aperture secrets scanner onto the 3D map even though it never went through normal parsing) built risk_vector as a hardcoded literal: `[0.0] * 13 + [0.0, 0.0, 0.0, 0.0, 100.0]` -- an 18-element vector with a comment claiming "Index 17 is secrets_risk". RISK_SCHEMA is actually 13 elements now (secrets_risk at index 12), so this path has been emitting a 5-element-too-long risk_vector for a while. Harmless on its own, but record_keeper.py's SQLite INSERT builds its column list from the live RISK_SCHEMA length -- any file taking this path made record_mission() raise `sqlite3.OperationalError: N values for M columns` and abort `--db-only` output entirely for the whole scan, not just that one file. Found while building a tree-sitter-based ground-truth accuracy pass for JavaScript (mirroring ast_accuracy_audit.py's Python methodology, #1200): `galaxyscope <path> --db-only` crashed on expressjs/express because its committed `.npmrc` trips the hardcoded-secrets detector. Reproduced, isolated to this exact literal via a cursor.execute proxy that dumped the column/value counts at the failing INSERT, confirmed by reverting it. Fix: size risk_vector from `len(SignalProcessor.RISK_SCHEMA)` (matching the sibling AI-MODEL-WEIGHTS synthetic-node path a few lines down, which already did this correctly) and set the secrets_risk slot by name lookup instead of a hardcoded index, mirroring the hit_vector/sec_hardcoded_secrets pattern already used right below it. tests/core_engine/test_galaxyscope.py::test_synthetic_node_generation asserted `risk_vector[17] == 100.0` -- also stale, and silently correct by coincidence since the old 18-length hardcoded vector still had a real value at index 17. Updated to assert against the live RISK_SCHEMA length and the schema-resolved secrets_risk index, so a future RISK_SCHEMA resize can't silently reintroduce this drift. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs: add JavaScript language-status doc, first tree-sitter-based §9 pass Follows python.md's structure (language-status skill), extending its §9 "measured accuracy" methodology beyond Python for the first time using tree-sitter-language-pack against real code -- exactly the path python.md's own §9 proposed for scaling past Python's stdlib `ast`. Measured against two corpora with different shapes (expressjs/express v5.2.1: small, mostly top-level functions and middleware callbacks; and GitGalaxy's own site/js/ WebGPU visualizer: heavily class-based). Confirms #1209/#1216's args capture-group fix works on real code (100% args-count exact match on every function found, both corpora) and surfaces: - A blocking infra bug that crashed --db-only on any repo with a flagged secret (fixed same-day in #1220, needed before this measurement could run at all -- express's own committed .npmrc trips the detector). - #1221 (open): func_start's method-shorthand branch has no trailing-`{` requirement, unlike args' own "Invocation Shield" for the same shape -- bare call statements (`next();`) get misidentified as definitions. Confirmed to also affect typescript/java/csharp/apex/dart/groovy. - #1222 (open): real, differently-named functions can be silently dropped from function_data even though func_start's regex finds them correctly -- most severe for ES6 class methods (one file lost 9 of 10 real methods). Likely the same _slice_by_braces mechanism #789 diagnosed and left unfixed for csharp. Neither new defect fixed here (docs-only pass, per the language-status skill's scope discipline) -- both need the fuller harden-language-extraction treatment given they touch shared detector.py slicing logic. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This was referenced Aug 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
galaxyscope.py's CRITICAL LEAKS synthetic-node path (forces a file flagged by the Aperture secrets scanner onto the 3D map even though it never went through normal parsing) builtrisk_vectoras a hardcoded literal:[0.0] * 13 + [0.0, 0.0, 0.0, 0.0, 100.0]— an 18-element vector with a comment claiming "Index 17 is secrets_risk".RISK_SCHEMAis actually 13 elements now (secrets_riskat index 12), so this path has been emitting a 5-element-too-longrisk_vector.Harmless in isolation, but
record_keeper.py's SQLiteINSERTbuilds its column list from the liveRISK_SCHEMAlength — any file taking this path maderecord_mission()raisesqlite3.OperationalError: N values for M columnsand abort--db-onlyoutput for the entire scan, not just that one file.How found
Building a tree-sitter-based ground-truth accuracy pass for JavaScript (mirroring
ast_accuracy_audit.py's Python methodology, #1200):galaxyscope <path> --db-onlycrashed scanningexpressjs/expressbecause its committed.npmrctrips the hardcoded-secrets detector. Isolated to this exact literal via acursor.executeproxy dumping column/value counts at the failingINSERT(deterministic: fails on the file whoseclassification == "critical_secret_leak"), confirmed by reverting.Fix
Size
risk_vectorfromlen(SignalProcessor.RISK_SCHEMA)(matching the sibling AI-MODEL-WEIGHTS synthetic-node path a few lines down, which already did this correctly) and set thesecrets_riskslot by name lookup instead of a hardcoded index — mirroring thehit_vector/sec_hardcoded_secretspattern already used right below it.tests/core_engine/test_galaxyscope.py::test_synthetic_node_generationassertedrisk_vector[17] == 100.0— also stale, silently "correct" only by coincidence since the old 18-length hardcoded vector still had a real value at index 17. Updated to assert against the liveRISK_SCHEMAlength and the schema-resolvedsecrets_riskindex, so a futureRISK_SCHEMAresize can't silently reintroduce this drift.Test plan
python -m pytest tests/core_engine/test_galaxyscope.py -q(45 passed)python tests/tools/audit_check.py(ruff/mypy/dead-key/ast-accuracy all clear)expressjs/express(v5.2.1) before/after:galaxyscope <path> --db-onlynow succeeds;.npmrcrow correctly recordsrisk_secrets_risk = 100.0🤖 Generated with Claude Code