Repository navigation
[Config Phase 0] Decide precedence order and merge semantics before building the resolver #332
Copy link
Copy link
Closed
Labels
core-engineModifications to the central physics and parsing engineModifications to the central physics and parsing engineepicLarge-scale architectural milestone or multi-issue initiativeLarge-scale architectural milestone or multi-issue initiativepriority: highCore feature broken, but workarounds existCore feature broken, but workarounds exist
Description
Context
#247 flagged "YAML and CLI overrides align better." Investigation found the
divergence is worse than a simple two-way mismatch -- there are currently
four separate, inconsistent override mechanisms:
gitgalaxy_config.pymodule constants (~18 of them: STRICT_IMPORT_MODE,
APPROVED_IMPORTS, BLACKLISTED_IMPORTS, APERTURE_CONFIG, GUIDESTAR_CONFIG,
etc.), imported by value at load time by 4 files (galaxyscope.py,
guidestar_lens.py, language_lens.py, supply_chain_firewall.py) --
permanently disconnected from anything that happens after import.- A generic
.galaxyscope.yaml->args.*interceptor in galaxyscope.py's
main(), which currently reaches nothing, because no argparse flag exists
for any gitgalaxy_config.py constant. - A separate, hand-coded YAML merge that ONLY touches APERTURE_CONFIG, and
only 4 of its keys (IGNORED_DIRECTORIES, CONTRABAND_PATTERNS,
VENDOR_MINIFICATION_PATHS, SECRETS_EXACT). - PROJECT_OVERRIDES -- a static Python dict in gitgalaxy_config.py, keyed
by project folder name, merged into the same two locals as (3).
Only two local variables in main() (merged_langs, merged_aperture) ever
receive any of this. The three files that import gitgalaxy_config.py
directly (guidestar_lens.py, language_lens.py, supply_chain_firewall.py)
never see any override, ever -- confirmed via import-site inspection.
This issue's deliverable
A written decision (as a markdown doc or a detailed issue comment, not code)
covering:
- Full key inventory. Every gitgalaxy_config.py constant, and for each:
should it be user-overridable at all? Via YAML, CLI, both? - Precedence order. Explicit ranking, e.g.
CLI flag > per-project PROJECT_OVERRIDES-by-name > .galaxyscope.yaml >
gitgalaxy_config.py default -- or whatever order is actually intended.
Must resolve the current unfixable case: a boolean set True by YAML can
never be forced back to False by a store_true CLI flag. - Merge semantics per key, not just per-source. Lists/sets (e.g.
BLACKLISTED_IMPORTS) -- does a YAML override extend the default, or
replace it entirely? Both are legitimate depending on the key; needs to
be explicit per key, not a single blanket rule. - Unknown-key handling. A YAML key that doesn't match anything should
fail loudly (error, not silent drop) -- decide the exact failure mode
(hard error vs. warning-and-ignore). - Scope of PROJECT_OVERRIDES. Does this stay a Python-only mechanism,
or does it become YAML-editable too? If it stays Python-only, is that
a deliberate choice (e.g. for maintainer-curated known-project dialects
vs. arbitrary user config)?
Explicitly out of scope
No code changes in this issue. Phases 1-3 (separate issues) implement
whatever gets decided here.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
core-engineModifications to the central physics and parsing engineModifications to the central physics and parsing engineepicLarge-scale architectural milestone or multi-issue initiativeLarge-scale architectural milestone or multi-issue initiativepriority: highCore feature broken, but workarounds existCore feature broken, but workarounds exist
Activity
squid-protocol commentedon Jul 23, 2026
Phase 0 Decision: Config precedence, merge semantics, and scope
Audited against the actual code on
fix/collision-resolved-confidence-clamp(commit 437007b), not just the symptoms described in the original issue.
Several things below correct or extend the issue's premise — see
"Corrections to the original writeup" first.
Corrections to the original writeup
PROJECT_OVERRIDESis not ingitgalaxy_config.py. It lives ingitgalaxy/standards/language_standards.py:10405. It is also not thesame kind of thing as the rest of the config — it's maintainer-curated,
per-project language-dialect patches (extension lists, compiled regex
overrides, directory shields) keyed by folder name (
freebsd-src,cpython,wrf-fortran,Apollo-11,AppFlowy,ansible,bugzilla,...). Decision below: it stays a separate, Python-only mechanism, not
a 4th tier of the general resolver.
5 files have the unreachable-direct-import bug, not 3. In addition to
guidestar_lens.py,language_lens.py,supply_chain_firewall.py:gitgalaxy/tools/supply_chain_security/vault_sentinel.py(importsALLOWLIST_PATHS,DENYLIST_PATTERNS)gitgalaxy/tools/supply_chain_security/binary_anomaly_detector.py(imports
ALLOWLIST_PATHS,DENYLIST_PATTERNS,XRAY_BYPASS_EXTENSIONS,XRAY_BYPASS_PATHS)Both use the same
try: from gitgalaxy.standards.gitgalaxy_config import (...) except ImportError: <hardcoded fallback>pattern. Phase 3's scopeshould expand to include these two files.
Two more consumers were never on anyone's radar and are also broken:
chronometer.py:23doesfrom gitgalaxy.standards import gitgalaxy_config as config, then readsCHRONOMETER_CONFIGandAPERTURE_CONFIGoff that raw module object — not the mergedfull_configthatgalaxyscope.py'smain()builds. So even the 4APERTURE_CONFIGkeys that main() does correctly merge today neverreach the Chronometer. Same unreachable-override bug, different shape.
gpu_recorder.py:23,364doesfrom gitgalaxy.standards import gitgalaxy_configand readsPROJECT_STORIESdirectly off it. Same bug.These need to be added to the Phase 3 file list (or a Phase 3b).
STATIC_ARCHETYPESdoesn't even reach its own default — this is alive bug, not an override gap.
signal_processor.py:19doesfrom gitgalaxy.standards import analysis_lens as config, then at lines338/382/428 reads
getattr(config, "STATIC_ARCHETYPES", {}).STATIC_ARCHETYPESis defined ingitgalaxy_config.py, notanalysis_lens.py— thegetattrfallback of{}fires unconditionally.Archetype labeling via this dict has never worked, independent of any
override mechanism. Recommend filing this as its own bug ticket
(wrong module aliased) rather than folding the fix into the Phase 1/2/3
resolver work — it's an "override never reaches" story, this is a
"default never loads" story, and conflating them will make the resolver
PR harder to review.
ORCHESTRATOR_RULES/POPULARITY_STOP_STEMSis dead code. Greppedwith no consumer anywhere outside its own definition. Recommend deleting
it in Phase 1 rather than building override plumbing for a key nothing
reads, or filing a one-line follow-up if someone confirms it's meant to
be wired up somewhere.
There's already an undocumented precedent for YAML-only keys with no
gitgalaxy_config.pydefault at all:SARIF_IGNORED_RULESandSARIF_IGNORED_PATHSare read straight out ofconfig_file_datainmain()(lines 2680-2681) with no CLI flag and no module constant. Therepo's own
.galaxyscope.yamluses exactly these two keys and nothingelse. The resolver should accommodate config keys that are YAML/CLI-only
with no compiled-in default, not assume every key originates in
gitgalaxy_config.py.Decisions
Precedence order
(
PROJECT_OVERRIDESdialect patches are explicitly not in this chain —see "Scope of PROJECT_OVERRIDES" below. They apply as a separate,
always-additive patch keyed by project name, orthogonal to CLI/YAML/default.)
Fixing the store-true-can't-force-False footgun: the current code
detects "was this overridden" by checking
getattr(args, arg_key) in (None, False, 0.0, "")— i.e. it can't distinguish "user didn't pass--paranoid"from "user explicitly wants paranoid mode off." Phase 1 must replace
action="store_true"with tri-state flags for anything that YAML can alsoset: argparse default
None(notFalse), soNoneunambiguously means"not specified on the CLI" and only then does YAML get a chance to fill it
in, and only when YAML doesn't set it either does the
gitgalaxy_config.pydefault apply. This resolves the general precedence rule as "first source
in the chain that actually specifies a value wins" rather than "first
source with a truthy value wins."
Unknown-key handling
Hard error. An unrecognized key in
.galaxyscope.yamlshould raise andrefuse to run the scan, not warn-and-continue. Justification: this is a
security-policy config file. A typo'd
STRICT_IMPORT_MODE(e.g.STRICT_IMPORT_MDOE) that silently no-ops leaves the supply-chain firewallin audit mode while the user believes they've turned on strict mode — a
silent security regression is worse than a scan that refuses to start.
This is also literally the failure mode #247 was filed to fix; a
warn-and-ignore resolver would just relocate the same silent-drop bug one
layer up instead of closing it.
Scope of PROJECT_OVERRIDES
Stays Python-only, and stays out of the general resolver's precedence
chain entirely. It's maintainer-curated dialect knowledge for specific,
known third-party repos gitgalaxy has been pointed at before — it includes
compiled regex objects (e.g.
wrf-fortran'sconcurrencypattern), whichisn't something that belongs in a YAML file a user hand-edits. Treat it as
a distinct "known project fixups" mechanism, applied unconditionally after
CLI/YAML/default resolution, keyed by
project_name— not a 4th precedencetier and not YAML-editable. If a future need arises for user-authored
per-project overrides, that should be a new, separate mechanism rather than
extending this one.
Full key inventory
Legend: Reach = does an override from any source actually get to the
consumer today. Merge = recommended semantics once Phase 1 exists.
STRICT_IMPORT_MODEsupply_chain_firewall.py(direct import — broken)--strict-imports, tri-state)APPROVED_IMPORTSsupply_chain_firewall.py(direct import — broken)BLACKLISTED_IMPORTSsupply_chain_firewall.py(direct import — broken)FIREWALL_NETWORK_WEIGHTINGsupply_chain_firewall.py(direct import — broken)DENYLIST_PATTERNSbinary_anomaly_detector.py,vault_sentinel.py(direct import — broken)ALLOWLIST_PATHSbinary_anomaly_detector.py,vault_sentinel.py,supply_chain_firewall.py(direct import — broken)XRAY_BYPASS_EXTENSIONSbinary_anomaly_detector.py(direct import — broken)XRAY_BYPASS_PATHSbinary_anomaly_detector.py(direct import — broken)APERTURE_CONFIG.SECRETS_EXTENSIONSaperture.py(viafull_config)APERTURE_CONFIG.SECRETS_EXACTaperture.py(viafull_config)APERTURE_CONFIG.IGNORED_DIRECTORIESaperture.py,chronometer.py(2nd path broken)APERTURE_CONFIG.IGNORED_EXTENSIONSaperture.py(viafull_config)APERTURE_CONFIG.CONTRABAND_PATTERNSaperture.py(viafull_config)APERTURE_CONFIG.VENDOR_MINIFICATION_PATHSaperture.py(viafull_config)APERTURE_CONFIG.MAX_LINE_LENGTH/MINIFICATION_SCAN_LIMIT/MAX_FILE_SIZE_MBaperture.py(viafull_config)APERTURE_CONFIG.BANDSaperture.py(viafull_config)PRIORITY_WHITELISTguidestar_lens.py(via constructor, but no merge logic exists)GUIDESTAR_CONFIG.MANIFEST_MAP/INTENT_BIASED_SECTORS/EXEC_PREFIX_MAPguidestar_lens.py(direct import — broken)LEXICAL_FAMILY_HEURISTICSlanguage_lens.py(via constructor, no merge logic)EXACT_FILE_MATCHlanguage_lens.py(direct import — broken)TEST_NAMING_CONVENTIONSgalaxyscope.py(viafull_config, no merge logic)CHRONOMETER_CONFIGchronometer.py(direct module import — broken)STATIC_ARCHETYPESsignal_processor.py(wrong module aliased — dead, see correction #4)PROJECT_STORIESgpu_recorder.py(direct import — broken)ORCHESTRATOR_RULES/POPULARITY_STOP_STEMSSARIF_IGNORED_RULES/SARIF_IGNORED_PATHSgalaxyscope.py main()(YAML-only today, no default)gitgalaxy_config.pydefault; keep as-is)PROJECT_OVERRIDES(inlanguage_standards.py)galaxyscope.py main()What Phase 1 needs to do differently from what the original issue assumed
APERTURE_CONFIGhand-mergepattern to "every key in
gitgalaxy_config.py" — it also has to becomethe thing that
chronometer.py,gpu_recorder.py,guidestar_lens.py,language_lens.py,supply_chain_firewall.py,vault_sentinel.py, andbinary_anomaly_detector.pyall pull from, replacing 7 independentdirect-import sites, not the 3 the issue named. That's really a Phase 1 +
Phase 3 scope correction — recommend updating issue [Config Phase 3] Migrate guidestar_lens.py, language_lens.py, supply_chain_firewall.py off direct gitgalaxy_config.py imports #335's file list
before starting that phase.
STATIC_ARCHETYPESandORCHESTRATOR_RULESshould be pulled out ofPhase 1's key-by-key merge work — one's a pre-existing bug unrelated to
overrides, the other looks like dead code. Fixing/deleting them inside
the resolver PR will make it harder to review; handle separately.
Explicitly out of scope (unchanged from original)
No code in this issue. Phases 1-3 implement the above.
[Config Phase 1] Add config_resolver.py: single ResolvedConfig merge …
Migrate galaxyscope.py main() to use the ResolvedConfig resolver (#334)
Migrate galaxyscope.py main() to use the ResolvedConfig resolver (#334)…
Migrate 7 direct gitgalaxy_config.py importers off module-level const…
Fix CLI/YAML sentinel-collision in the pipeline-flag interceptor (#247)…