diff --git a/docs/wiki/08-01-methodology.md b/docs/wiki/08-01-methodology.md
index ee7693f6..36379355 100644
--- a/docs/wiki/08-01-methodology.md
+++ b/docs/wiki/08-01-methodology.md
@@ -1,50 +1,69 @@
-# Overview of Methodology
+# Overview of Methodology & Risk Exposure Index
> **The Core Philosophy: From Raw Text to Relational Knowledge Graph**
>
> GitGalaxy does not measure subjective "Code Quality," which implies judgment. Instead, it measures objective **Risk Exposures**.
>
> By utilizing deterministic keyword heuristics, the engine parses raw text to build a massive, interconnected knowledge graph of the entire repository. We extract structural markers from the code (the data) and translate them into visible risk heatmaps (the projection). This allows architecture teams to instantly see where their system is drifting into dangerous territory without reading a single line of code.
+>
+> **The Structural Taxonomy of GitGalaxy**
+>
+> GitGalaxy assesses functions against 50+ metrics. We then roll these measurements up to the class, file, folder and repo level.
-## The Universal Risk Spectrum (A11y Standard)
-
-To reduce cognitive load on the user, GitGalaxy abandons distinct color palettes for individual metrics. Instead, we project the knowledge graph's telemetry using a single, unified **High-Contrast Spectrum** for all risk and exposure dashboards.
+## The Universal Risk Spectrum
-Regardless of the metric being viewed, the visual translation is always the same:
-* 🟦 **Deep Blue:** Very Low Exposure (Safe / Cold / Clean)
+Regardless of the risk metric being viewed, the visual translation is always the same color palette:
+* 🟦 **Blue:** Very Low Exposure
* 🩵 **Cyan:** Low Exposure
* 🟨 **Yellow:** Moderate / Intermediate Exposure
* 🟧 **Orange:** High Exposure
* 🟥 **Bright Red:** Critical / Extreme Exposure (Hot / Dangerous)
-## The Exposure Metrics (Graph Telemetry)
-
-When a user selects a metric from the HUD, the visualizer queries the underlying knowledge graph and recolors the nodes using the Universal Spectrum. The table below defines what the engine's heuristics are actively hunting for, and what a "Red" (Critical) state represents for each mode.
-
-| Labeling Mode | Heuristic Target | The "Red" (Critical) State Indicates... |
-| :--- | :--- | :--- |
-| **Cognitive Load** | **How hard is it to read?** Scans for deeply nested logic, sprawling methods, and high control-flow complexity. | The logic is incredibly difficult for a human to follow. A prime target for refactoring. |
-| **Deep Churn** | **How often does it change?** Identifies files that are constantly being rewritten, patched, or reverted based on Git history. | The file refuses to settle down. It is highly fluid and likely a source of recurring bugs. |
-| **Error & Exception Exposure** | **Is it fragile?** Compares the ratio of defensive code (error handling, guards) against aggressive logic. | The file lacks safety nets. It is performing complex logic without adequate exception handling. |
-| **Tech Debt** | **Are there shortcuts?** Scans for `TODO`s, `FIXME`s, known hacks, and temporary architectural band-aids. | The file is heavily burdened by unfinished business and documented technical debt. |
-| **Documentation Risk** | **Is it explained?** Measures the ratio and quality of instructional literature against the raw executable code. | The file is essentially undocumented. It operates as a "black box" to new developers. |
-| **Verification (Tests)** | **Is it proven?** Checks if the file has a corresponding safety net of tests proving it works. | The code is heavily exposed due to a severe lack of testing and verification coverage. |
-| **Stability (Heat)** | **Is it fresh?** Shows where work is happening *right now* vs. code that was written months ago via OS `mtime` or Git logs. | The file is "Hot." It has been actively edited or committed in the very recent past. |
-| **Graveyard** | **Is there dead code?** Finds massive blocks of code that were commented out and abandoned. | The file is hoarding historical, dead code that needs to be purged. |
-| **API Exposure** | **Is it public?** Highlights the entry points and network routers where the system talks to the outside world. | The file serves as a major public endpoint, demanding strict security scrutiny. |
-| **Concurrency** | **Is it multitasking?** Highlights complex timing, threads, or asynchronous execution logic. | Heavy reliance on asynchronous timing, introducing severe risks for race conditions. |
-| **State Flux** | **Is the data changing?** Highlights variables that are constantly being modified or mutated in memory. | "Boiling" data. The file mutates state aggressively, making it hard to track standard values. |
-| **Ownership Entropy** | **Who wrote this?** Measures the Shannon Entropy of Git blame data to see if a file is owned by one person or many. | A "Community" file. It has been touched by so many different developers that no single person truly owns it. |
+## Primary Risk Exposures
+
+**Definition:** The mathematical output of parsing regex heuristics, file boundaries, version control counts, and ecosystem multipliers. These metrics represent the unified risk calculations applied across the repository.
+
+| Metric | Level 1: Function
([count based](08-02-sub-equations.md))
(0-infinity) | Level 2: Class
([count based](08-02-sub-equations.md))
(0-infinity) | Level 3: File
([Sigmoid normalized](08-03-transforming-regex-counts.md))
(0-100) | Level 4: Folder
(Weighted Avg)
(0-100) | Level 5: Repo
(Weighted Avg)
(0-100) |
+| :--- | :--- | :--- | :--- | :--- | :--- |
+| **[Cognitive Load](08-05-cognitive-load.md)** | # of branches, mutations, and danger triggers, adjusted | Sum of function counts + Gini | Normalized via sigmoid function + GuideStar Shield | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[State Flux](08-16-state-flux-exposure.md)** | # of variable mutations, adjusted | Sum of function counts + LCOM | Normalized via sigmoid function | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Concurrency](08-15-concurrency-exposure.md)** | # of async/thread operations minus locks, adjusted | Sum of function counts | Normalized via sigmoid function | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Technical Debt](08-08-technical-debt.md)** | # of engineer comments (ex: HACK, TODO), adjusted | Sum of function counts | Normalized via sigmoid function | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Structural Fortification](08-07-structural-fortification.md)**| # of attacker vs. defender keywords, adjusted | Sum of function counts | Normalized via sigmoid function w/ Breach Floor | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Graveyard](08-13-graveyard-detector.md)** | N/A | N/A | Commented out code lines, normalized via sigmoid function | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Specification Alignment](08-18-specification-alignment.md)**| # of functions with Spec tags, adjusted | Sum of function counts w/ Spec mapping | Percentage of entities lacking spec tags, adjusted | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Civil War (Tabs/Spaces)](08-12-civil-war.md)** | N/A | N/A | Ratio of tab vs space indented lines, percentage | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Ownership Entropy](08-04-ownership-entropy.md)** | N/A | N/A | Distribution of git authors, normalized via Shannon entropy | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Deep Churn](08-06-deep-churn.md)** | N/A | N/A | Total git commits over time, normalized via log curve | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[File Stability (Heat)](08-10-file-stability.md)**| N/A | N/A | Time since last commit, normalized via time distance | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Verification Risk (Test Coverage)](08-11-test-coverage.md)**| # of unverified execution paths, adjusted | Sum of function counts | Normalized via sigmoid function * Cross-File Test Tethers | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Documentation Risk Exposure](08-09-documentation-risk.md)**| # of missing docstrings, comments, and readmes, adjusted | Sum of function counts | Normalized via sigmoid function * Bus Factor | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[API Exposure](08-14-api-exposure.md)** | # of export/public modifiers, adjusted | Sum of function counts + Public interfaces | Normalized via ratio and volume * Network Blast Radius | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Algorithmic DoS Exposure](08-24-Big-O-Detection.md)** | # of deep loops interacting with data/network, adjusted | Sum of function counts | Normalized via sigmoid function * Network Blast Radius | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Logic Bomb Exposure](08-20-logic-bomb-exposure.md)** | # of conditions leading to payloads, adjusted | Sum of function counts | Normalized via sigmoid function * Taint Flow Tracking | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Injection Surface Exposure](08-21-injection-surface-exposure.md)**| # of inputs flowing to execution, adjusted | Sum of function counts | Normalized via sigmoid function * Taint Flow Tracking | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Memory Corruption Exposure](08-22-memory-corruption-exposure.md)**| # of pointers/allocations minus cleanups, adjusted | Sum of function counts | Normalized via sigmoid function * ML Archetype Map | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Obscured Payload Exposure](08-19-obscured-payload-exposure.md)**| # of obfuscation and intent triggers, adjusted | Sum of function counts | Normalized via sigmoid function * Biaxial Drift | Mass-Weighted Avg | Mass-Weighted Avg |
+| **[Hardcoded Secrets Exposure](08-23-hardcoded-secrets-exposure.md)**| N/A | N/A | Detected credential strings, normalized via sigmoid function | Mass-Weighted Avg | Mass-Weighted Avg |
## Custom Topological Scales
-Certain metrics do not represent a "Safe to Dangerous" pipeline, but rather a difference in structural style or identity within the graph. These bypass the Universal Spectrum and use custom rendering palettes.
+Certain metrics do not represent a "Safe to Dangerous" pipeline, but rather a difference in structural style within the graph. These bypass the Universal Spectrum and use custom rendering palettes.
* **Civil War (Tabs vs. Spaces):** Checks for indentation consistency across the codebase.
* 🟩 **Green:** Strictly uses Tabs.
* 🟨 **Yellow:** Strictly uses Spaces.
* 🟦 **Blue:** A chaotic, mixed indentation style (The "Warzone").
-* **Language Identity:** Colors the file based on its evaluated taxonomy (e.g., JavaScript is Yellow, Python is Blue, Rust is Orange) to create a visual map of the system's tech stack.
+
+
+---
+
+## Expanding the Physics Framework
+
+These documents outline the specific variables and mathematical normalization strategies that power the equations detailed in the matrix above.
+
+* [08-02: Sub-Equations (Scanner Variables)](08-02-sub-equations.md)
+* [08-03: Transforming Regex Counts (The UEF)](08-03-transforming-regex-counts.md)
@@ -61,4 +80,4 @@ This documentation is part of the [GitGalaxy Ecosystem](https://github.com/squid
---
-**[⬅️ Back to Master Index](index.md)**
+**[⬅️ Back to Master Index](index.md)**
\ No newline at end of file
diff --git a/docs/wiki/08-11-test-coverage.md b/docs/wiki/08-11-test-coverage.md
index d8caab26..e7c6f4d4 100644
--- a/docs/wiki/08-11-test-coverage.md
+++ b/docs/wiki/08-11-test-coverage.md
@@ -1,103 +1,94 @@
-# Testing & Verification Exposure
-
-> **Metric: Verification Density (Internal Assertions & Sibling Coverage)**
->
-> **Summary:** Visualizes the "Security Blanket" of the knowledge graph. In GitGalaxy, we distinguish between *Defensive Code* (handling errors at runtime) and *Verified Code* (proving correctness at design time). Because this metric has been unified into the Risk Exposure model, a high score now indicates a *lack* of verification (high risk), while a low score indicates ironclad, verified code.
->
-> **Effect:** Maps directly to the GitGalaxy Universal Risk Spectrum.
-> * 🟦 **IRONCLAD (Score 15-20):** Fortified. The code is heavily backed by internal assertions, mocks, or a dedicated sibling test suite. *(Note: The deterministic engine enforces a hard minimum floor of 15.0, acknowledging that no code is 100% perfectly safe).*
-> * 🟨 **MODERATE (Score 40-59):** Partial verification. Meets the bare minimum threshold.
-> * 🟥 **VERY HIGH (Score 80-100):** Speculative. The code might work, but there is no programmatic proof. It relies entirely on hope.
-
-## The Inputs (Verification Signals)
-
-We combine internal evidence (assertions) with external evidence (sibling files). The file system checks are now abstracted, passing an `is_protected` boolean directly into the deterministic engine.
-
-| Variable | Target Syntax / System | Weight | Structural Definition |
-| :--- | :--- | :--- | :--- |
-| `test_hits` | `assert`, `describe`, `mock` | 5.0x | **Internal Tests.** Assertions, mocks, and test definitions inside the file itself. |
-| `is_protected` | `X.test.js` next to `X.js` | +30.0 (Flat) | **Sibling Match.** External Coverage. This flat density bonus represents strong verification intent. |
-| `Mass Penalty` | `LOC > 300` | Variable | **Monolith Penalty.** Files over 300 lines gain a stacking risk penalty up to +40. Massive files cannot be adequately verified by unit tests alone. |
-
-## Universal Framework Integration
-
-**Exemptions:** Untestable files (e.g., Markdown, Makefiles, CMake, or specific extensions configured in the asset masks) bypass the engine entirely, returning a $0.0$ risk score.
-
-* **$Fc$ (Fidelity Coefficient):** Applied as an inverted multiplier ($2.0 - Fc$). We trust explicit verification in high-fidelity languages more than loose assertions in implicit languages.
-* **$Irc$ (Implicit Risk Correction):** Added to the Threshold. Implicit languages (Python, Ruby) rely entirely on tests for type safety, meaning they require a *higher* density of tests to clear the risk bar.
-* **$Mp$ (Path Modifier):** Scales the Threshold. Critical infrastructure (`core/`) gets a higher bar; notoriously hard-to-test views (`UI/`) get a lower bar.
-
-## The Equation: The Verification Sigmoid
-
-**Step A: The Exemption Bypass**
-If the file matches known untestable patterns (e.g., `readme`, `makefile`), the engine immediately returns $0.0$.
-
-**Step B: Calculate Verification Density**
-We calculate the density of internal tests and add the flat Sibling Bonus ($+30.0$). The bonus is added directly to the density because the existence of a test file implies coverage of the whole module.
-
-$$InternalDensity = \left( \frac{test\_hits \times 5.0}{\max(LOC, 1)} \right) \times 100.0$$
-$$TotalDensity = InternalDensity + SiblingBonus$$
-
-**Step C: Determine The Bar (Dynamic Threshold)**
-This is the "Passing Grade" the density must overcome to lower the risk score.
-
-$$Threshold = (15.0 + (Irc \times 3.0)) \times Mp$$
-
-**Step D: The Inverse Sigmoid Map**
-We map density against the dynamic threshold using a positive exponent. As Verification Density *increases*, the denominator grows, and the Risk Exposure mathematically *decreases*.
-
-$$RawExposure = \frac{100.0}{1 + e^{0.25 \times (TotalDensity - Threshold)}}$$
-
-**Step E: Trust Adjustment & Mass Penalty**
-We multiply the result by the inverted Fidelity score ($2.0 - Fc$). If the file size exceeds the `MASSIVE_FILE_THRESHOLD` (300 lines), we calculate and add a structural mass penalty, capping the final calculation between the $15.0$ risk floor and $100.0$ maximum.
-
-$$FinalExposure = \min(\max((RawExposure \times (2.0 - Fc)) + MassPenalty, 15.0), 100.0)$$
-
-## Implementation (Python Reference)
-
-```python
-import math
-import os
-from typing import Dict
-
-def _calc_verification(self, loc: int, file_path: str, is_protected: bool, eq: Dict[str, int], irc: int, fc: float, mp: float, umbrella_bonus: float = 0.0) -> float:
- filename = os.path.basename(file_path).lower()
- ext = filename.split('.')[-1] if '.' in filename else ""
-
- exempt_exts = self.asset_masks.get("UNTESTABLE_EXTENSIONS", set())
- exempt_names = self.asset_masks.get("UNTESTABLE_NAMES", set())
-
- # Step A: Untestable Bypass
- if ext in exempt_exts or filename in exempt_names or filename.startswith('readme') or 'makefile' in filename or 'cmake' in filename:
- return 0.0
-
- t = self.risk_tuning.get("verification", {})
- safe_loc = max(loc, 1)
-
- # Step B: Verification Density
- sibling_bonus = t.get("sibling_bonus", 30.0) if is_protected else 0.0
- internal_density = (eq.get("test", 0) * t.get("internal_test_mult", 5.0) / safe_loc) * 100.0
- total_density = internal_density + sibling_bonus
-
- # Step C: Dynamic Threshold
- threshold = (t.get("threshold_base", 15.0) + (irc * t.get("irc_mult", 3.0))) * mp
-
- # Step D: Inverse Sigmoid Map
- try:
- raw_exposure = 100.0 / (1.0 + math.exp(t.get("sigmoid_slope", 0.25) * (total_density - threshold)))
- except OverflowError:
- raw_exposure = 0.0 if total_density > threshold else 100.0
-
- # Step E: Trust Adjustment
- final_exposure = raw_exposure * (2.0 - fc)
-
- # Step F: The Mass Penalty
- if safe_loc > self.MASSIVE_FILE_THRESHOLD:
- mass_penalty = min((safe_loc - self.MASSIVE_FILE_THRESHOLD) / t.get("mass_penalty_div", 20.0), t.get("mass_penalty_max", 40.0))
- final_exposure += mass_penalty
-
- # Enforce the 15.0 Risk Floor
- return min(max(final_exposure, t.get("risk_floor", 15.0)), 100.0)
+# Verification Risk Exposure (Test Coverage)
+
+GitGalaxy measures test coverage not by counting lines, but by assessing the complexity and magnitude of the logic against the amount and size of the tests defending it. We calculate an initial raw structural impact for every function which can be reduced by testing, either with internal assertions or external testing files that reference that function. This reveals the remaining **Untested Impact** for each function and these scores are rolled up into classes. At the file level, we have enough data to normalize the raw values. The raw untested impact values are normalized for coding loc, network importance and by the presence of golden image tests and subjected to a sigmoidal threshold scoring system that ranges from 0-100.
+
+ **Effect:** Maps directly to the GitGalaxy Universal Risk Spectrum.
+ * 🟦 **VERY LOW (Score 0-19):** Heavy Shielding. The largest, small and large functions are heavily dampened by proportional, targeted unit tests or component-level golden images.
+ * 🟨 **INTERMEDIATE (Score 40-59):** Moderate Exposure. Standard logic has basic coverage, but some functions lack sufficient defensive mass, leaving noticeable residual risk.
+ * 🟥 **VERY HIGH (Score 80-100+):** Blind Execution. Many functions and files with very low testing verification.
+
+### Level 1: Function
+
+Range: 0 - Max
+
+This level starts with the initial the raw structural impact value of the function and reduces that impact if it has tests targeting it, and uses that relative ratio to mathematically crush the risk into a residual **Untested Impact**.
+
+**Step A: The Base Impact**
+We take the raw `Function Impact` score and subtract the explicitly defined internal defenses located physically inside the function boundaries. To ensure accuracy across all languages, the engine calculates this defense by combining exactly **three specific metrics** from the 51-Element Universal Schema:
+* **Verification (`test`):** Inline assertions and test macros (e.g., `assert()`, `expect()`).
+* **Safety (`safety`):** Guard clauses, type-guards, and strict boundary management (e.g., `require()`).
+* **Bypassed Tests (`test_skip`):** A negative modifier that aggressively *subtracts* defensive mass if an assertion is explicitly disabled (e.g., `it.skip`).
+
+$$BaseImpact = \max(FunctionImpact - ((Verification + Safety - (Bypassed \times 2.0)) \times Fc), 0.0)$$
+
+**Step B: The Defensive Ratio (Effective Mass)**
+We calculate the `EffectiveTestImpact` of every external test targeting the function. To prevent "safety theater" and structural blind spots, a test's raw impact is modified by three strict rules before summation:
+* **Assertion Density:** If the external test lacks internal assertions (zero `test` schema hits), its mass is zeroed out—a massive test without assertions verifies nothing.
+* **External Bypass (Sabotage):** If the external test contains a skip/bypass trigger (`test_skip`), its defensive tether is severed and its mass is completely nullified.
+* **Parameterization Multiplier:** If the test utilizes data-driven parameterization macros (e.g., `@pytest.mark.parametrize`), a multiplier is applied to its mass to accurately reflect its dynamic execution weight.
+
+Each test's effective impact is then divided by the total number of production functions it targets ($TargetCount$) to dilute sprawling integration tests.
+
+$$DefensiveRatio = \frac{\sum (EffectiveTestImpact / TargetCount)}{FunctionImpact}$$
+
+**Step C: The Asymptotic Dampener**
+We feed that `DefensiveRatio` into the inverse decay equation. If the tests are physically tiny compared to the function, the ratio is low, and the dampener barely reduces the risk. If the tests are massive compared to the function, the ratio is high, and the risk is violently crushed toward zero.
+
+$$UntestedImpact = BaseImpact \times \left( \frac{1}{1 + (C_t \times DefensiveRatio)} \right)$$
+
+### Level 2: Class
+
+Range: 0 - Max
+
+Classes act strictly as containment boundaries to roll up the math.
+
+* **The Mechanics:** We sum the residual **Untested Impact** scores from all the functions contained within the class architecture.
+* **The Math:**
+$$ClassUntestedImpact = \sum (FunctionUntestedImpact)$$
+
+### Level 3: File
+
+Range: 0-100
+
+This level translates the raw, accumulated unverified impact scores into a true risk percentage. Following the Universal Exposure Framework, we normalize the risk against the file's coding loc, apply environmental multipliers, and finally push the adjusted density through our sigmoidal model.
+
+* **Step A: Executable Density Normalization**
+We take the sum of all `Untested Impact` from the file's functions and divide this total by the `coding_loc` (Total LOC minus comments and whitespace) to establish the base density. By stripping out comments and whitespace, we prevent bloated formatting from artificially diluting the risk.
+
+To account for the "Opacity Tax" of highly dynamic or implicit languages, we multiply this base density by the language's **Opacity Tax Multiplier**. This ensures that the penalty for the language's implicit ambiguity scales proportionally with the amount of unverified logic.
+$$RawDensity = \left( \frac{\sum ClassUntestedImpact}{\max(CodingLOC, 1)} \right) \times Ot$$
+
+* **Step B: Ecosystem Modifiers (Pre-Curve Normalization)**
+Before plugging this into our sigmoidal equation, we adjust the density based on the file's physical surroundings and network gravity:
+ * **The GuideStar Umbrella (Dampener):** If the file is protected by directory-level golden image tests or visual regression snapshots, we apply a dampening fraction to shrink the density.
+ * **Network Blast Radius (Amplifier):** We multiply the density by the file's PageRank centrality. If the file is a highly imported global router, its lack of verification is exponentially more dangerous, artificially swelling its density.
+$$AdjustedDensity = (RawDensity \times GuideStarDampener) \times BlastRadius$$
+
+* **Step C: Sigmoidal Normalization**
+The `AdjustedDensity` is pushed through the logistic sigmoid function. This acts as a strict noise gate: files with trace amounts of unverified mass stay near 0 (Safe/Blue). Once the unverified density crosses the critical threshold, the sigmoidal model normalizes the value, spiking rapidly toward 100 (Critical/Red).
+$$BaseScore = \min\left( \frac{100.0}{1 + e^{-Slope \times (AdjustedDensity - Threshold)}}, 100.0 \right)$$
+
+* **Step D: The Path Modifier & Breach Cap**
+Finally, we apply the Path Modifier ($Mp$). If the file itself is a test suite (e.g., `router.spec.js` or located in `/tests/`), $Mp$ is set to $0.0$, immediately neutralizing the risk. For production files ($Mp = 1.0$), we evaluate the **Breach Cap**: if the total unverified mass is overwhelmingly larger than the verified mass, the file is hard-capped to a minimum "Fragile" rating, ensuring no amount of mathematical noise-gating can hide a fundamentally untested file.
+$$FinalFileScore = BaseScore \times Mp$$
+
+### Level 4: Folder
+
+Range: 0-100
+
+This level determines the testing risk exposure of different folders.
+
+* The Testing Risk Exposure scores for each file, ranging from 0-100, within a directory are rolled up using a Mass-Weighted Average coding LOC of each file.
+* **The Result:** A massive, complex God Object that scores a 95 (Critical Risk) will exert immense averaging pull on the parent folder's overall health score. A tiny, 15-line helper script with zero tests that also scores a 95 will barely move the needle, preventing small utility files from skewing the local aggregate metrics.
+
+### Level 5: Repo
+
+Range: 0-100
+
+This level determines the ultimate testing risk exposure of the entire codebase.
+
+* The Testing Risk Exposure scores for each directory under root, ranging from 0-100, are rolled up using a Mass-Weighted Average coding LOC of each folder.
+* **The Physics:** A massive, highly complex core directory saturated with risk will drag down the gravitational health of the entire project. Conversely, a highly risky but lightweight experimental folder will be safely absorbed by the stabilizing mass of a well-tested, fortified core.
@@ -107,11 +98,10 @@ def _calc_verification(self, loc: int, file_path: str, is_protected: bool, eq: D
This documentation is part of the [GitGalaxy Ecosystem](https://github.com/squid-protocol/gitgalaxy), an AST-free, LLM-free heuristic knowledge graph engine.
+* 🧠 **[Deep Dive into the Physics Source Code](https://github.com/squid-protocol/gitgalaxy/tree/main/gitgalaxy/physics)** to see the math in action.
* 🪐 **[Explore the GitHub Repository](https://github.com/squid-protocol/gitgalaxy)** for code, tools, and updates.
* 🔭 **[Visualize your own repository at GitGalaxy.io](https://gitgalaxy.io/)** using our interactive 3D WebGPU dashboard.
-
-
---
-**[⬅️ Back to Master Index](index.md)**
+**[⬅️ Back to Master Index](index.md)**
\ No newline at end of file
diff --git a/gitgalaxy/core/network_risk_sensor.py b/gitgalaxy/core/network_risk_sensor.py
index 7d41df18..b3ed35c7 100644
--- a/gitgalaxy/core/network_risk_sensor.py
+++ b/gitgalaxy/core/network_risk_sensor.py
@@ -31,6 +31,70 @@ def __init__(self, parent_logger: Optional[logging.Logger] = None):
self.logger = parent_logger.getChild("network_sensor") if parent_logger else logging.getLogger("network_sensor")
self.RISK_SCHEMA = RECORDING_SCHEMAS.get("RISK_SCHEMA", [])
+ def extract_test_coverage_mapping(self, files: List[Dict[str, Any]]) -> Dict[str, Dict[str, List[Dict[str, Any]]]]:
+ """
+ Maps function calls from test files to their imported production targets.
+ Returns a dictionary mapping: production_file_path -> { production_function_name: [test_function_data] }
+ """
+ coverage_map = {}
+ resolution_map = {}
+
+ # 1. Build resolution map
+ for f in files:
+ path = f.get("path", "")
+ if path:
+ resolution_map[path] = path
+ resolution_map[Path(path).name] = path
+ resolution_map[Path(path).stem] = path
+
+ # 2. Identify Test Files and extract their outgoing invocations
+ for f in files:
+ path = f.get("path", "")
+ low_path = path.lower()
+
+ # Structural heuristic for test files
+ is_test = any(x in low_path for x in ["/test/", "/tests/", "test_", "_test", ".spec.", ".test."])
+ if not is_test:
+ continue
+
+ # Identify which production files this test file imports
+ target_paths = set()
+ for imp in f.get("raw_imports", []):
+ target_token = imp[0] if isinstance(imp, tuple) and len(imp) == 2 else imp
+ target_path = resolution_map.get(target_token)
+
+ if target_path and target_path != path:
+ target_paths.add(target_path)
+
+ if not target_paths:
+ continue
+
+ # Map each test function's payload to the production functions it calls
+ for test_func in f.get("functions", []):
+ calls_out = test_func.get("calls_out_to", [])
+ if not calls_out:
+ continue
+
+ target_count = len(calls_out)
+ test_payload = {
+ "impact": test_func.get("impact", 0.0),
+ "target_count": target_count,
+ "test_hits": test_func.get("hit_vector", {}).get("test", 0),
+ "test_skip_hits": test_func.get("hit_vector", {}).get("test_skip", 0),
+ "decorators": test_func.get("hit_vector", {}).get("decorators", 0),
+ }
+
+ for target_path in target_paths:
+ if target_path not in coverage_map:
+ coverage_map[target_path] = {}
+
+ for called_func_name in calls_out:
+ if called_func_name not in coverage_map[target_path]:
+ coverage_map[target_path][called_func_name] = []
+ coverage_map[target_path][called_func_name].append(test_payload)
+
+ return coverage_map
+
def map_ecosystem(self, stars: List[Dict[str, Any]]) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]:
"""
Builds the directed graph and calculates multi-dimensional risk vectors.
diff --git a/gitgalaxy/galaxyscope.py b/gitgalaxy/galaxyscope.py
index adebf146..64fb88dc 100644
--- a/gitgalaxy/galaxyscope.py
+++ b/gitgalaxy/galaxyscope.py
@@ -1455,6 +1455,15 @@ def _second_pass_relational(self):
self.used_tokens.update(meta.get("named_tokens", []))
# ==============================================================
+ # ==============================================================
+ # ---> TEST COVERAGE MAPPING <---
+ # Sweep the galaxy for test files and map their outbound calls
+ # directly to the production functions they verify.
+ # ==============================================================
+ logger.info("PASS_2: Extracting Test Coverage Mapping...")
+ test_coverage_map = self.network_sensor.extract_test_coverage_mapping(list(self.cryolink.values()))
+ # ==============================================================
+
# ==============================================================
# ---> NEW: CALCULATE INSTRUCTIONAL DENSITY MULTIPLIERS <---
# Aggregate markdown heuristics to upgrade the doc_umbrella shields
@@ -1565,6 +1574,9 @@ def _second_pass_relational(self):
]
meta["is_protected"] = any(cand in self.census for cand in sibling_candidates)
+ # Pass the mapped test coverage data to the risk engine
+ meta["test_coverage_map"] = test_coverage_map.get(rel_path, {})
+
# The physics engine natively handles the Exposed Secret and Documentation bypass protocols.
# We unconditionally route to the Signal Processor so it can execute the 18-point math.
forensic_result = self.processor.calculate_risk_vector(
diff --git a/gitgalaxy/physics/signal_processor.py b/gitgalaxy/physics/signal_processor.py
index dcaa6fb4..fd0d0a3f 100644
--- a/gitgalaxy/physics/signal_processor.py
+++ b/gitgalaxy/physics/signal_processor.py
@@ -230,12 +230,12 @@ def calculate_risk_vector(
loc = max(int(meta.get("coding_loc", 1)), 1)
except (ValueError, TypeError):
loc = 1
-
+
try:
total_loc = max(int(meta.get("total_loc", loc)), 1)
except (ValueError, TypeError):
total_loc = loc
-
+
try:
doc_lines = int(meta.get("doc_loc", 0))
except (ValueError, TypeError):
@@ -434,6 +434,7 @@ def calculate_risk_vector(
tier = self._get_tier(lang_id)
fc = self.TIER_VARS[tier]["fc"]
irc = self.TIER_VARS[tier]["irc"]
+ ot = self.TIER_VARS[tier].get("ot", 1.0)
# Environmental Context (Path-based overrides)
mp_map = self._get_locational_multipliers(rel_path)
@@ -441,24 +442,7 @@ def calculate_risk_vector(
folder_lang = ghost_meta.get("folder_dominant_lang", lang_id)
eco_mp = self._get_context_multipliers(lang_id, folder_lang)
- self.logger.debug(f"[{rel_path}] Physics Calc | Lang: {lang_id} (Fc: {fc:.2f}, Irc: {irc})")
-
- hit_vector = [equations.get(key, 0) for key in self.SIGNAL_SCHEMA]
-
- # ==================================================================
- # 1. ACTIVE PHYSICS ENGINE (For normal executable code)
- # ==================================================================
- tier = self._get_tier(lang_id)
- fc = self.TIER_VARS[tier]["fc"]
- irc = self.TIER_VARS[tier]["irc"]
-
- # Environmental Context (Path-based overrides)
- mp_map = self._get_locational_multipliers(rel_path)
-
- folder_lang = ghost_meta.get("folder_dominant_lang", lang_id)
- eco_mp = self._get_context_multipliers(lang_id, folder_lang)
-
- self.logger.debug(f"[{rel_path}] Physics Calc | Lang: {lang_id} (Fc: {fc:.2f}, Irc: {irc})")
+ self.logger.debug(f"[{rel_path}] Physics Calc | Lang: {lang_id} (Fc: {fc:.2f}, Irc: {irc}, Ot: {ot:.2f})")
hit_vector = [equations.get(key, 0) for key in self.SIGNAL_SCHEMA]
@@ -690,9 +674,11 @@ def calculate_risk_vector(
rel_path,
meta.get("is_protected", False),
equations,
- irc,
+ ot,
fc,
mp_map.get("test", 1.0),
+ functions,
+ meta.get("test_coverage_map", {}),
umbrella_bonus=umbrella_bonus,
popularity=popularity,
)
@@ -1574,53 +1560,104 @@ def _calc_verification(
rel_path: str,
is_protected: bool,
eq: Dict[str, int],
- irc: int,
+ ot: float,
fc: float,
mp: float,
+ functions: List[Dict[str, Any]],
+ test_coverage_map: Dict[str, List[Dict[str, Any]]],
umbrella_bonus: float = 0.0,
popularity: int = 0,
) -> float:
"""
- YIN: Test assertions (test).
- YANG: Bypassed/Mocked tests (test_skip).
- Returns 100.0 for HIGH risk (no tests), 0.0 for LOW risk (well tested).
+ Calculates Verification Risk Exposure by comparing structural function complexity
+ against the scope of tests validating it via asymptotic dampening.
"""
- tuning = self.risk_tuning.get("verification", {})
- loc_padding = tuning.get("loc_padding", 150)
+ t = self.risk_tuning.get("verification", {})
+ ct = t.get("asymptotic_dampener", 1.5)
+
+ total_untested_impact = 0.0
+ total_function_impact = 0.0
- test_hits = float(eq.get("test", 0))
- test_skips = float(eq.get("test_skip", 0))
+ if functions:
+ for func in functions:
+ name = func.get("name", "")
+ func_impact = func.get("impact", 0.0)
+ total_function_impact += func_impact
+
+ if func_impact == 0:
+ continue
- # THERMODYNAMIC BALANCE: Penalize "Safety Theater".
- # 1 bypassed test neutralizes 2 real assertions.
- true_verification = max(0.0, test_hits - (test_skips * 2.0))
+ # Step A: The Base Impact
+ hit_vector = func.get("hit_vector", {})
+ verification = float(hit_vector.get("test", 0))
+ safety = float(hit_vector.get("safety", 0))
+ bypassed = float(hit_vector.get("test_skip", 0))
- density = true_verification / max(loc + loc_padding, 1)
+ internal_defenses = (verification + safety - (bypassed * 2.0)) * fc
+ base_impact = max(func_impact - internal_defenses, 0.0)
- threshold = tuning.get("threshold_base", 15.0)
- slope = tuning.get("sigmoid_slope", 0.25)
+ # Step B: The Defensive Ratio (Effective Mass)
+ targeting_tests = test_coverage_map.get(name, [])
+ effective_test_impact_sum = 0.0
+
+ for test in targeting_tests:
+ # Assertion Density: Ignore empty test shells
+ if test.get("test_hits", 0) == 0:
+ continue
+
+ # Sabotage: Ignore skipped/bypassed tests
+ if test.get("test_skip_hits", 0) > 0:
+ continue
+
+ raw_impact = test.get("impact", 0.0)
+ target_count = max(test.get("target_count", 1), 1)
+
+ # Parameterization Multiplier
+ param_multiplier = 2.0 if test.get("decorators", 0) > 0 else 1.0
+
+ effective_test_impact_sum += (raw_impact * param_multiplier) / target_count
+
+ defensive_ratio = effective_test_impact_sum / func_impact
+
+ # Step C: The Asymptotic Dampener
+ untested_impact = base_impact * (1.0 / (1.0 + (ct * defensive_ratio)))
+ total_untested_impact += untested_impact
- # Calculate coverage (100% = fully tested)
- coverage = self._sigmoid(density, threshold, slope) * 100.0
+ # Add file-level danger as raw unverified mass
+ file_level_danger = float(eq.get("danger", 0))
+ total_untested_impact += file_level_danger
- # Re-apply the architectural bonuses
- coverage = min(coverage + umbrella_bonus, 100.0)
+ # Step D: Executable Density Normalization & Ecosystem Modifiers
+ # Apply the Opacity Tax (ot) directly to the density
+ raw_density = (total_untested_impact / max(loc, 1)) * ot
- # Mass Penalty: Massive files require exponentially more tests to prove safety.
- mass_penalty = 0.0
- if loc > 300:
- mass_penalty = min(((loc - 300) / 100) * 5.0, 40.0)
+ # The GuideStar Umbrella (Dampener)
+ # umbrella_bonus is max 50.0. If bonus is 50, dampener is 0.5.
+ guidestar_dampener = max(1.0 - (umbrella_bonus / 100.0), 0.1)
- # ---> THE LOAD-BEARER PENALTY <---
- # If this file is a foundational pillar (highly imported), a lack of tests
- # threatens the entire ecosystem.
- if popularity > 5:
- mass_penalty += min(popularity * 2.0, 30.0)
+ # Network Blast Radius (Amplifier)
+ blast_radius = mp + min(popularity * 0.2, 3.0)
- final_coverage = max(0.0, coverage - mass_penalty)
+ adjusted_density = (raw_density * guidestar_dampener) * blast_radius
- # INVERT FOR RISK: 100% Coverage = 0% Risk Exposure.
- return 100.0 - final_coverage
+ # Step E: Sigmoidal Normalization
+ threshold = t.get("threshold_base", 15.0)
+ slope = t.get("sigmoid_slope", 0.25)
+
+ try:
+ base_score = 100.0 / (1.0 + math.exp(-slope * (adjusted_density - threshold)))
+ except OverflowError:
+ base_score = 100.0 if adjusted_density > threshold else 0.0
+
+ # Step F: The Path Modifier & Breach Cap
+ if mp == 0.0 or is_protected:
+ return 0.0
+
+ # Breach Cap: If untested mass is overwhelmingly larger than verified, cap to Fragile (80+)
+ if total_untested_impact > (total_function_impact * 0.8) and total_function_impact > 50.0:
+ return max(base_score, 80.0)
+
+ return min(base_score, 100.0)
def _calc_graveyard(self, total_loc: float, eq: Dict[str, int], mp: float) -> float:
hits = eq.get("graveyard", 0)
@@ -2217,7 +2254,9 @@ def get_cumulative_risk(f):
if not isinstance(rv, list):
return 0.0
# Sum all exposures except civil_war
- return sum(val for i, val in enumerate(rv) if i != civil_war_idx and i < len(rv) and isinstance(val, (int, float)))
+ return sum(
+ val for i, val in enumerate(rv) if i != civil_war_idx and i < len(rv) and isinstance(val, (int, float))
+ )
sorted_by_cumulative = sorted(active_files, key=get_cumulative_risk, reverse=True)
@@ -2242,9 +2281,21 @@ def get_cumulative_risk(f):
close = net.get("closeness_score") or 0.0
pr = net.get("normalized_blast_radius") or 0.0
- flux_risk = float(rv[flux_idx]) if flux_idx >= 0 and len(rv) > flux_idx and isinstance(rv[flux_idx], (int, float)) else 0.0
- err_risk = float(rv[err_idx]) if err_idx >= 0 and len(rv) > err_idx and isinstance(rv[err_idx], (int, float)) else 0.0
- doc_risk = float(rv[doc_idx]) if doc_idx >= 0 and len(rv) > doc_idx and isinstance(rv[doc_idx], (int, float)) else 0.0
+ flux_risk = (
+ float(rv[flux_idx])
+ if flux_idx >= 0 and len(rv) > flux_idx and isinstance(rv[flux_idx], (int, float))
+ else 0.0
+ )
+ err_risk = (
+ float(rv[err_idx])
+ if err_idx >= 0 and len(rv) > err_idx and isinstance(rv[err_idx], (int, float))
+ else 0.0
+ )
+ doc_risk = (
+ float(rv[doc_idx])
+ if doc_idx >= 0 and len(rv) > doc_idx and isinstance(rv[doc_idx], (int, float))
+ else 0.0
+ )
bottlenecks["contagious_mutation"].append(
{
diff --git a/gitgalaxy/recorders/llm_recorder.py b/gitgalaxy/recorders/llm_recorder.py
index a4f4cb43..d7327999 100644
--- a/gitgalaxy/recorders/llm_recorder.py
+++ b/gitgalaxy/recorders/llm_recorder.py
@@ -252,7 +252,7 @@ def _build_markdown(
"> 3. **Tech Debt Exposure:** Measures the density of developer-annotated structural stress. `Density(TODOs [1x] + FIXMEs/Hacks [3x] + Empty Stubs [0.5x])`. High scores indicate a high volume of temporary workarounds, fragile logic, and incomplete implementations relative to the file size."
)
lines.append(
- "> 4. **Verification (Testing) Risk Exposure:** Measures the density of unit testing and programmatic assertions. Evaluates `Test Density` + `Sibling Bonus` (if a dedicated test file exists). High scores (100% risk) mean the logic lacks internal test coverage and has no dedicated sibling test file, increasing the risk of silent failures during refactoring. **Mass Penalty:** Files over 300 LOC get an automatic risk penalty because massive files are inherently harder to test completely."
+ "> 4. **Verification Risk Exposure:** Evaluates test coverage by comparing a function's structural complexity against the scope of the tests validating it. The engine calculates a function's base complexity and mathematically reduces it using an asymptotic dampener powered by internal assertions and external test tethers. High scores (100% risk) indicate massive, load-bearing architecture operating with near-zero internal assertions or external test coverage."
)
lines.append(
"> 5. **API Risk Exposure:** Measures the public surface area of a module. `Ratio(API Hits / Total Functions & Classes)`. Weighted by logarithmic volume. High scores indicate that a large percentage of the file's functions and classes are explicitly exported or publicly accessible by external systems."
diff --git a/gitgalaxy/standards/analysis_lens.py b/gitgalaxy/standards/analysis_lens.py
index a0caa906..4d678d2a 100644
--- a/gitgalaxy/standards/analysis_lens.py
+++ b/gitgalaxy/standards/analysis_lens.py
@@ -65,9 +65,9 @@ def get_policy(mode="baseline"):
"WEIGHT_DEFENSE": 1.0,
# Trust Dampeners & Opacity Taxes
"TIER_VARS": {
- "tier1": {"fc": 1.0, "irc": 0}, # Explicit (Rust, Go, Java)
- "tier2": {"fc": 0.85, "irc": 2}, # Structured (Python, TS)
- "tier3": {"fc": 0.60, "irc": 5}, # Implicit (Shell, Groovy)
+ "tier1": {"fc": 1.0, "ot": 1.00, "irc": 0}, # Explicit (Rust, Go, Java)
+ "tier2": {"fc": 0.85, "ot": 1.15, "irc": 2}, # Structured (Python, TS)
+ "tier3": {"fc": 0.60, "ot": 1.40, "irc": 5}, # Implicit (Shell, Groovy)
},
# Math constraints
"TESTING_RISK_FLOOR": 15.0,
diff --git a/tests/core_engine/test_signal_processor.py b/tests/core_engine/test_signal_processor.py
index d3b71646..3505fc00 100644
--- a/tests/core_engine/test_signal_processor.py
+++ b/tests/core_engine/test_signal_processor.py
@@ -179,13 +179,17 @@ def test_signal_processor_civil_war(physics_engine):
# ==============================================================================
def test_signal_processor_sibling_test_bonus(physics_engine):
"""Proves the umbrella_bonus parameter halves the testing risk penalty."""
- m1, e1 = create_synthetic_star(physics_engine, "logic", 200, {"branch": 20})
- m2, e2 = create_synthetic_star(physics_engine, "logic", 200, {"branch": 20})
+ m1, e1 = create_synthetic_star(physics_engine, "logic", 100)
+ m1["functions"] = [{"name": "mock_func", "impact": 5000.0, "hit_vector": {}}]
+
+ m2, e2 = create_synthetic_star(physics_engine, "logic", 100)
+ m2["functions"] = [{"name": "mock_func", "impact": 5000.0, "hit_vector": {}}]
high_risk = physics_engine.calculate_risk_vector(m1, e1, umbrella_bonus=0.0)
- low_risk = physics_engine.calculate_risk_vector(m2, e2, umbrella_bonus=0.5)
+ low_risk = physics_engine.calculate_risk_vector(m2, e2, umbrella_bonus=50.0)
- assert low_risk["risk_vector"][3] < high_risk["risk_vector"][3], "Sibling Test Bonus failed to apply!"
+ idx_test = physics_engine.RISK_SCHEMA.index("verification")
+ assert low_risk["risk_vector"][idx_test] < high_risk["risk_vector"][idx_test], "Sibling Test Bonus failed to apply!"
# ==============================================================================
@@ -437,26 +441,27 @@ def test_signal_processor_algorithmic_dos(physics_engine):
# ==============================================================================
def test_signal_processor_security_lenses(physics_engine):
"""Ensures all security lens risk equations return valid floats and properly scale."""
-
+
# 1. Logic Bomb
- m_lb, e_lb = create_synthetic_star(physics_engine, "logic_bomb", 100, {
- "branch": 50, "sec_danger": 20, "sec_tainted_injection": 5
- })
-
+ m_lb, e_lb = create_synthetic_star(
+ physics_engine, "logic_bomb", 100, {"branch": 50, "sec_danger": 20, "sec_tainted_injection": 5}
+ )
+
# 2. Obscured Payload (Requires intent_mass via sec_danger to bypass the 95% false-positive shield)
- m_ob, e_ob = create_synthetic_star(physics_engine, "obscured", 100, {
- "sec_heat_triggers": 20, "sec_bitwise_hits": 50, "sec_shadow_imports": 5, "sec_danger": 10
- })
-
+ m_ob, e_ob = create_synthetic_star(
+ physics_engine,
+ "obscured",
+ 100,
+ {"sec_heat_triggers": 20, "sec_bitwise_hits": 50, "sec_shadow_imports": 5, "sec_danger": 10},
+ )
+
# 3. Injection Surface
- m_inj, e_inj = create_synthetic_star(physics_engine, "injection", 100, {
- "sec_io": 30, "sec_danger": 30
- })
-
+ m_inj, e_inj = create_synthetic_star(physics_engine, "injection", 100, {"sec_io": 30, "sec_danger": 30})
+
# 4. Memory Corruption (Requires native memory language like 'c' + malicious intent to bypass the 95% shield)
- m_mem, e_mem = create_synthetic_star(physics_engine, "memory", 100, {
- "pointers": 50, "memory_alloc": 20, "sec_danger": 10
- })
+ m_mem, e_mem = create_synthetic_star(
+ physics_engine, "memory", 100, {"pointers": 50, "memory_alloc": 20, "sec_danger": 10}
+ )
m_mem["lang_id"] = "c"
r_lb = physics_engine.calculate_risk_vector(m_lb, e_lb)
@@ -468,10 +473,10 @@ def test_signal_processor_security_lenses(physics_engine):
idx_ob = physics_engine.RISK_SCHEMA.index("obscured_payload")
idx_inj = physics_engine.RISK_SCHEMA.index("injection_surface")
idx_mem = physics_engine.RISK_SCHEMA.index("memory_corruption")
-
+
assert isinstance(r_lb["risk_vector"][idx_lb], float), "Logic bomb must return a float!"
assert r_lb["risk_vector"][idx_lb] > 10.0, "Logic bomb failed to register!"
-
+
assert isinstance(r_ob["risk_vector"][idx_ob], float), "Obscured payload must return a float!"
assert r_ob["risk_vector"][idx_ob] > 10.0, "Obscured payload failed to register!"
@@ -487,17 +492,13 @@ def test_signal_processor_security_lenses(physics_engine):
# ==============================================================================
def test_signal_processor_structural_metrics(physics_engine):
"""Ensures Graveyard and Spec Match exposures calculate correctly."""
-
+
# Graveyard (High dead code)
- m_grave, e_grave = create_synthetic_star(physics_engine, "graveyard", 100, {
- "graveyard": 80
- })
-
+ m_grave, e_grave = create_synthetic_star(physics_engine, "graveyard", 100, {"graveyard": 80})
+
# Spec Match (0 specs for 10 functions = 100% risk)
- m_spec, e_spec = create_synthetic_star(physics_engine, "spec", 100, {
- "func_start": 10, "spec_exposure": 0
- })
-
+ m_spec, e_spec = create_synthetic_star(physics_engine, "spec", 100, {"func_start": 10, "spec_exposure": 0})
+
r_grave = physics_engine.calculate_risk_vector(m_grave, e_grave)
r_spec = physics_engine.calculate_risk_vector(m_spec, e_spec)
@@ -505,7 +506,9 @@ def test_signal_processor_structural_metrics(physics_engine):
idx_spec = physics_engine.RISK_SCHEMA.index("spec_match")
assert r_grave["risk_vector"][idx_grave] > 50.0, "Graveyard risk failed to register!"
- assert r_spec["risk_vector"][idx_spec] == 100.0, "Spec match risk failed to register maximum exposure on undocumented functions!"
+ assert (
+ r_spec["risk_vector"][idx_spec] == 100.0
+ ), "Spec match risk failed to register maximum exposure on undocumented functions!"
# ==============================================================================
@@ -513,56 +516,55 @@ def test_signal_processor_structural_metrics(physics_engine):
# ==============================================================================
def test_signal_processor_design_slop(physics_engine):
"""Proves that silent design slop (orphans/duplicates) exponentially spikes Tech Debt."""
-
+
# 1. Clean Debt: Only explicit TODOs
- m_clean, e_clean = create_synthetic_star(physics_engine, "clean_debt", 100, {
- "planned_debt": 10
- })
-
+ m_clean, e_clean = create_synthetic_star(physics_engine, "clean_debt", 100, {"planned_debt": 10})
+
# 2. Sloppy Debt: Explicit TODOs + Invisible Slop
- m_slop, e_slop = create_synthetic_star(physics_engine, "sloppy_debt", 100, {
- "planned_debt": 10, "design_slop_orphans": 5, "design_slop_duplicates": 2
- })
-
+ m_slop, e_slop = create_synthetic_star(
+ physics_engine, "sloppy_debt", 100, {"planned_debt": 10, "design_slop_orphans": 5, "design_slop_duplicates": 2}
+ )
+
r_clean = physics_engine.calculate_risk_vector(m_clean, e_clean)
r_slop = physics_engine.calculate_risk_vector(m_slop, e_slop)
idx_debt = physics_engine.RISK_SCHEMA.index("tech_debt")
-
- assert r_slop["risk_vector"][idx_debt] > r_clean["risk_vector"][idx_debt], "Design Slop failed to amplify Tech Debt!"
+
+ assert (
+ r_slop["risk_vector"][idx_debt] > r_clean["risk_vector"][idx_debt]
+ ), "Design Slop failed to amplify Tech Debt!"
assert r_slop["risk_vector"][idx_debt] > 50.0, "Severe slop failed to trigger high exposure!"
# ==============================================================================
-# TEST 19: VERIFICATION THERMODYNAMICS (Skips & Mass Penalty)
+# TEST 19: VERIFICATION THERMODYNAMICS (Skips & Breach Cap)
# ==============================================================================
def test_signal_processor_verification_thermodynamics(physics_engine):
- """Proves skipped tests neutralize assertions, and massive files receive a testing penalty."""
-
- # 1. Safe: 50 tests, standard LOC
- m_safe, e_safe = create_synthetic_star(physics_engine, "safe_test", 100, {
- "test": 50, "test_skip": 0
- })
-
- # 2. Bypassed: 50 tests, but 25 skipped (Thermodynamic cancellation)
- m_skip, e_skip = create_synthetic_star(physics_engine, "skip_test", 100, {
- "test": 50, "test_skip": 25
- })
-
- # 3. Massive: 50 tests, but 1000 LOC (Mass Penalty)
- m_mass, e_mass = create_synthetic_star(physics_engine, "mass_test", 1000, {
- "test": 50, "test_skip": 0
- })
-
+ """Proves skipped tests neutralize assertions, and highly unverified files hit the breach cap."""
+
+ # 1. Safe: High impact, lots of tests
+ m_safe, e_safe = create_synthetic_star(physics_engine, "safe_logic", 100)
+ m_safe["functions"] = [{"name": "func", "impact": 5000.0, "hit_vector": {"test": 2500, "test_skip": 0}}]
+
+ # 2. Bypassed: High impact, tests neutralized by skips
+ m_skip, e_skip = create_synthetic_star(physics_engine, "skip_logic", 100)
+ m_skip["functions"] = [{"name": "func", "impact": 5000.0, "hit_vector": {"test": 2500, "test_skip": 1250}}]
+
+ # 3. Breached: Almost entirely unverified logic
+ m_breach, e_breach = create_synthetic_star(physics_engine, "breach_logic", 100)
+ m_breach["functions"] = [{"name": "func", "impact": 5000.0, "hit_vector": {"test": 50, "test_skip": 0}}]
+
r_safe = physics_engine.calculate_risk_vector(m_safe, e_safe)
r_skip = physics_engine.calculate_risk_vector(m_skip, e_skip)
- r_mass = physics_engine.calculate_risk_vector(m_mass, e_mass)
+ r_breach = physics_engine.calculate_risk_vector(m_breach, e_breach)
idx_test = physics_engine.RISK_SCHEMA.index("verification")
-
+
# Higher score = Higher Risk Exposure (Worse Verification)
- assert r_safe["risk_vector"][idx_test] < r_skip["risk_vector"][idx_test], "Test skips failed to neutralize assertions!"
- assert r_safe["risk_vector"][idx_test] < r_mass["risk_vector"][idx_test], "Mass penalty failed to increase testing risk on giant files!"
+ assert (
+ r_safe["risk_vector"][idx_test] < r_skip["risk_vector"][idx_test]
+ ), "Test skips failed to neutralize assertions!"
+ assert r_breach["risk_vector"][idx_test] >= 80.0, "Overwhelmingly unverified file failed to hit the breach cap!"
# ==============================================================================
@@ -570,9 +572,9 @@ def test_signal_processor_verification_thermodynamics(physics_engine):
# ==============================================================================
def test_signal_processor_god_function_gini(physics_engine):
"""Proves that concentrating complexity into a single function spikes Cognitive Load."""
-
+
# Both files have 100 LOC and 20 Branches total.
-
+
# 1. Flat Distribution (4 functions, 5 branches each) -> Low Gini
m_flat, e_flat = create_synthetic_star(physics_engine, "flat_dist", 100, {"branch": 20})
m_flat["functions"] = [
@@ -581,7 +583,7 @@ def test_signal_processor_god_function_gini(physics_engine):
{"name": "f3", "branch": 5, "loc": 25},
{"name": "f4", "branch": 5, "loc": 25},
]
-
+
# 2. God Function (1 massive function, 3 empty) -> High Gini
m_god, e_god = create_synthetic_star(physics_engine, "god_func", 100, {"branch": 20})
m_god["functions"] = [
@@ -590,13 +592,15 @@ def test_signal_processor_god_function_gini(physics_engine):
{"name": "f3", "branch": 0, "loc": 3},
{"name": "f4", "branch": 0, "loc": 4},
]
-
+
r_flat = physics_engine.calculate_risk_vector(m_flat, e_flat)
r_god = physics_engine.calculate_risk_vector(m_god, e_god)
idx_cog = physics_engine.RISK_SCHEMA.index("cognitive_load")
-
- assert r_god["risk_vector"][idx_cog] > r_flat["risk_vector"][idx_cog], "God function Gini index failed to amplify Cognitive Load!"
+
+ assert (
+ r_god["risk_vector"][idx_cog] > r_flat["risk_vector"][idx_cog]
+ ), "God function Gini index failed to amplify Cognitive Load!"
# ==============================================================================
@@ -604,27 +608,29 @@ def test_signal_processor_god_function_gini(physics_engine):
# ==============================================================================
def test_signal_processor_concurrency_thermodynamics(physics_engine):
"""Proves sync locks mitigate async risk, and high Big-O spikes thread starvation."""
-
+
# 1. High Async, No Locks
m_async, e_async = create_synthetic_star(physics_engine, "pure_async", 100, {"concurrency": 20})
-
+
# 2. High Async, Mitigated by Locks (1 lock mitigates 1.5 async hits)
- m_sync, e_sync = create_synthetic_star(physics_engine, "locked_async", 100, {
- "concurrency": 20, "sync_locks": 15
- })
-
+ m_sync, e_sync = create_synthetic_star(physics_engine, "locked_async", 100, {"concurrency": 20, "sync_locks": 15})
+
# 3. Thread Starvation (Async + High Big-O)
m_starve, e_starve = create_synthetic_star(physics_engine, "starved_async", 100, {"concurrency": 20})
m_starve["functions"] = [{"name": "heavy_thread", "loc": 50, "big_o_depth": 3, "hit_vector": {"concurrency": 5}}]
-
+
r_async = physics_engine.calculate_risk_vector(m_async, e_async)
r_sync = physics_engine.calculate_risk_vector(m_sync, e_sync)
r_starve = physics_engine.calculate_risk_vector(m_starve, e_starve)
-
+
idx_async = physics_engine.RISK_SCHEMA.index("concurrency")
-
- assert r_sync["risk_vector"][idx_async] < r_async["risk_vector"][idx_async], "Sync locks failed to mitigate concurrency risk!"
- assert r_starve["risk_vector"][idx_async] > r_async["risk_vector"][idx_async], "Thread starvation (Big-O + Async) failed to amplify risk!"
+
+ assert (
+ r_sync["risk_vector"][idx_async] < r_async["risk_vector"][idx_async]
+ ), "Sync locks failed to mitigate concurrency risk!"
+ assert (
+ r_starve["risk_vector"][idx_async] > r_async["risk_vector"][idx_async]
+ ), "Thread starvation (Big-O + Async) failed to amplify risk!"
# ==============================================================================
@@ -632,21 +638,23 @@ def test_signal_processor_concurrency_thermodynamics(physics_engine):
# ==============================================================================
def test_signal_processor_api_echo_chamber(physics_engine):
"""Proves that APIs with no inbound network connections receive a massive risk dampener."""
-
+
# 1. Orphaned API (Exposes 50 APIs, but 0 popularity)
m_orphan, e_orphan = create_synthetic_star(physics_engine, "orphan_api", 100, {"api": 50})
m_orphan["popularity"] = 0
-
+
# 2. Networked API (Exposes 50 APIs, highly popular)
m_network, e_network = create_synthetic_star(physics_engine, "network_api", 100, {"api": 50})
m_network["popularity"] = 20
-
+
r_orphan = physics_engine.calculate_risk_vector(m_orphan, e_orphan)
r_network = physics_engine.calculate_risk_vector(m_network, e_network)
-
+
idx_api = physics_engine.RISK_SCHEMA.index("api_exposure")
-
- assert r_orphan["risk_vector"][idx_api] < (r_network["risk_vector"][idx_api] * 0.5), "Echo chamber fix failed: Orphaned APIs were not properly dampened!"
+
+ assert r_orphan["risk_vector"][idx_api] < (
+ r_network["risk_vector"][idx_api] * 0.5
+ ), "Echo chamber fix failed: Orphaned APIs were not properly dampened!"
# ==============================================================================
@@ -654,21 +662,22 @@ def test_signal_processor_api_echo_chamber(physics_engine):
# ==============================================================================
def test_signal_processor_flux_immutability(physics_engine):
"""Proves that immutable data declarations (freeze_hits) neutralize state flux."""
-
+
# 1. Pure Flux (High mutation)
m_flux, e_flux = create_synthetic_star(physics_engine, "high_flux", 100, {"flux": 30})
-
+
# 2. Frozen Flux (High mutation, but heavily mitigated by freeze/const/final)
- m_frozen, e_frozen = create_synthetic_star(physics_engine, "frozen_flux", 100, {
- "flux": 30, "freeze_hits": 40
- })
-
+ m_frozen, e_frozen = create_synthetic_star(physics_engine, "frozen_flux", 100, {"flux": 30, "freeze_hits": 40})
+
r_flux = physics_engine.calculate_risk_vector(m_flux, e_flux)
r_frozen = physics_engine.calculate_risk_vector(m_frozen, e_frozen)
-
+
idx_flux = physics_engine.RISK_SCHEMA.index("state_flux")
-
- assert r_frozen["risk_vector"][idx_flux] < r_flux["risk_vector"][idx_flux], "Immutability (freeze_hits) failed to mitigate state flux risk!"
+
+ assert (
+ r_frozen["risk_vector"][idx_flux] < r_flux["risk_vector"][idx_flux]
+ ), "Immutability (freeze_hits) failed to mitigate state flux risk!"
+
# ==============================================================================
# TEST 24: EXTENSION DECEPTION SENSOR
@@ -677,10 +686,10 @@ def test_signal_processor_extension_deception(physics_engine):
"""Proves the engine flags files that claim to be inert data but contain executable logic."""
m_dec, e_dec = create_synthetic_star(physics_engine, "data", 100)
m_dec["path"] = "src/data.json" # Claims to be JSON
- m_dec["lang_id"] = "python" # Actually evaluated as Python!
+ m_dec["lang_id"] = "python" # Actually evaluated as Python!
r_dec = physics_engine.calculate_risk_vector(m_dec, e_dec)
-
+
idx_mismatch = physics_engine.SIGNAL_SCHEMA.index("sec_extension_mismatch")
assert r_dec["hit_vector"][idx_mismatch] == 1, "Extension Deception Sensor failed to flag the mismatch!"
@@ -691,16 +700,16 @@ def test_signal_processor_extension_deception(physics_engine):
def test_signal_processor_alien_entity(physics_engine):
"""Proves that a Systems language hiding in a Web folder receives severe threat multipliers."""
# 1. Native C (C code inside a C/CPP folder)
- m_native, e_native = create_synthetic_star(physics_engine, "native", 100, {
- "branch": 50, "sec_danger": 20, "sec_tainted_injection": 5
- })
+ m_native, e_native = create_synthetic_star(
+ physics_engine, "native", 100, {"branch": 50, "sec_danger": 20, "sec_tainted_injection": 5}
+ )
m_native["lang_id"] = "c"
m_native["metadata"] = {"folder_dominant_lang": "cpp"}
# 2. Alien C (C code inside a Javascript/Web folder)
- m_alien, e_alien = create_synthetic_star(physics_engine, "alien", 100, {
- "branch": 50, "sec_danger": 20, "sec_tainted_injection": 5
- })
+ m_alien, e_alien = create_synthetic_star(
+ physics_engine, "alien", 100, {"branch": 50, "sec_danger": 20, "sec_tainted_injection": 5}
+ )
m_alien["lang_id"] = "c"
m_alien["metadata"] = {"folder_dominant_lang": "javascript"}
@@ -708,7 +717,7 @@ def test_signal_processor_alien_entity(physics_engine):
r_alien = physics_engine.calculate_risk_vector(m_alien, e_alien)
idx_lb = physics_engine.RISK_SCHEMA.index("logic_bomb")
-
+
assert r_alien["risk_vector"][idx_lb] > r_native["risk_vector"][idx_lb], "Alien entity penalty failed to apply!"
@@ -719,16 +728,20 @@ def test_signal_processor_science_shield(physics_engine):
"""Proves that Scientific/Math logic dampens the false-positive threat of Logic Bombs."""
# 1. Standard executable with dangerous triggers
m_std, e_std = create_synthetic_star(physics_engine, "standard", 100, {"branch": 30, "sec_danger": 20})
-
+
# 2. Scientific executable with the exact same triggers
- m_sci, e_sci = create_synthetic_star(physics_engine, "science", 100, {"branch": 30, "sec_danger": 20, "scientific": 10})
+ m_sci, e_sci = create_synthetic_star(
+ physics_engine, "science", 100, {"branch": 30, "sec_danger": 20, "scientific": 10}
+ )
r_std = physics_engine.calculate_risk_vector(m_std, e_std)
r_sci = physics_engine.calculate_risk_vector(m_sci, e_sci)
idx_lb = physics_engine.RISK_SCHEMA.index("logic_bomb")
-
- assert r_sci["risk_vector"][idx_lb] < r_std["risk_vector"][idx_lb], "Scientific shield failed to dampen the Logic Bomb false positive!"
+
+ assert (
+ r_sci["risk_vector"][idx_lb] < r_std["risk_vector"][idx_lb]
+ ), "Scientific shield failed to dampen the Logic Bomb false positive!"
# ==============================================================================
@@ -739,28 +752,29 @@ def test_signal_processor_catastrophic_fallbacks(physics_engine):
# 1. Force a catastrophic math crash (string instead of int)
m_crash, e_crash = create_synthetic_star(physics_engine, "crash", 100)
m_crash["coding_loc"] = "THIS_WILL_BREAK_MATH"
-
+
r_crash = physics_engine.calculate_risk_vector(m_crash, e_crash)
-
+
assert "error" in r_crash["telemetry"], "Engine failed to catch and log the catastrophic physics failure!"
- assert r_crash["risk_vector"] == [0.0] * len(physics_engine.RISK_SCHEMA), "Crash fallback did not safely zero out the risk vector!"
-
+ assert r_crash["risk_vector"] == [0.0] * len(
+ physics_engine.RISK_SCHEMA
+ ), "Crash fallback did not safely zero out the risk vector!"
+
# 2. Force an empty global synthesis
empty_summary = physics_engine.summarize_galaxy_metrics([], [])
assert empty_summary == {}, "Summarizer failed to safely exit on an empty repository!"
+
# ==============================================================================
# TEST 28: CIVIL WAR VOID STATE (Zero Indentation)
# ==============================================================================
def test_signal_processor_civil_war_void(physics_engine):
"""Proves the Civil War exposure safely defaults to 50.0 (Neutral) if a file has no indentation."""
- m_void, e_void = create_synthetic_star(physics_engine, "void_file", 10, {
- "indent_tabs": 0, "indent_spaces": 0
- })
-
+ m_void, e_void = create_synthetic_star(physics_engine, "void_file", 10, {"indent_tabs": 0, "indent_spaces": 0})
+
r_void = physics_engine.calculate_risk_vector(m_void, e_void)
idx_civil = physics_engine.RISK_SCHEMA.index("civil_war")
-
+
assert r_void["risk_vector"][idx_civil] == 50.0, "Void state failed to default to 50.0% neutral exposure!"
@@ -771,18 +785,20 @@ def test_signal_processor_agentic_rce(physics_engine):
"""Proves that pairing an LLM Orchestrator with dynamic execution creates a massive Injection Surface spike."""
# 1. Standard dynamic execution
m_std, e_std = create_synthetic_star(physics_engine, "std_exec", 100, {"sec_danger": 10})
-
+
# 2. Agentic dynamic execution
- m_agent, e_agent = create_synthetic_star(physics_engine, "agent_exec", 100, {
- "sec_danger": 10, "llm_orchestrator": 5, "ai_tools": 5
- })
+ m_agent, e_agent = create_synthetic_star(
+ physics_engine, "agent_exec", 100, {"sec_danger": 10, "llm_orchestrator": 5, "ai_tools": 5}
+ )
r_std = physics_engine.calculate_risk_vector(m_std, e_std)
r_agent = physics_engine.calculate_risk_vector(m_agent, e_agent)
idx_inj = physics_engine.RISK_SCHEMA.index("injection_surface")
-
- assert r_agent["risk_vector"][idx_inj] > r_std["risk_vector"][idx_inj], "Agentic RCE spike failed to amplify injection risk!"
+
+ assert (
+ r_agent["risk_vector"][idx_inj] > r_std["risk_vector"][idx_inj]
+ ), "Agentic RCE spike failed to amplify injection risk!"
# ==============================================================================
@@ -791,22 +807,33 @@ def test_signal_processor_agentic_rce(physics_engine):
def test_signal_processor_crypto_professionalism_shield(physics_engine):
"""Proves that heavy documentation, safety blocks, and crypto math dampen obfuscation false positives."""
# 1. Raw obfuscation (High entropy, bitwise math) + malicious intent
- m_raw, e_raw = create_synthetic_star(physics_engine, "raw_obf", 100, {
- "sec_heat_triggers": 50, "sec_bitwise_hits": 50, "sec_danger": 10
- })
-
+ m_raw, e_raw = create_synthetic_star(
+ physics_engine, "raw_obf", 100, {"sec_heat_triggers": 50, "sec_bitwise_hits": 50, "sec_danger": 10}
+ )
+
# 2. Professional cryptography (Same obfuscation, but heavily documented and safe)
- m_pro, e_pro = create_synthetic_star(physics_engine, "pro_crypto", 100, {
- "sec_heat_triggers": 50, "sec_bitwise_hits": 50, "sec_danger": 10,
- "doc": 100, "safety": 20, "cryptography": 10
- })
+ m_pro, e_pro = create_synthetic_star(
+ physics_engine,
+ "pro_crypto",
+ 100,
+ {
+ "sec_heat_triggers": 50,
+ "sec_bitwise_hits": 50,
+ "sec_danger": 10,
+ "doc": 100,
+ "safety": 20,
+ "cryptography": 10,
+ },
+ )
r_raw = physics_engine.calculate_risk_vector(m_raw, e_raw)
r_pro = physics_engine.calculate_risk_vector(m_pro, e_pro)
idx_ob = physics_engine.RISK_SCHEMA.index("obscured_payload")
-
- assert r_pro["risk_vector"][idx_ob] < r_raw["risk_vector"][idx_ob], "Crypto/Professionalism shield failed to dampen obfuscation risk!"
+
+ assert (
+ r_pro["risk_vector"][idx_ob] < r_raw["risk_vector"][idx_ob]
+ ), "Crypto/Professionalism shield failed to dampen obfuscation risk!"
# ==============================================================================
@@ -815,14 +842,15 @@ def test_signal_processor_crypto_professionalism_shield(physics_engine):
def test_signal_processor_llm_api_secrets(physics_engine):
"""Proves that hardcoded secrets mixed with LLM APIs trigger a massive careless amplifier."""
# 1. Standard secret leak (Requires sec_heat_triggers to bypass the 2.0 clamp)
- _unused_m_std, e_std = create_synthetic_star(physics_engine, "std_leak", 500, {
- "sec_private_info": 1, "globals": 1, "sec_heat_triggers": 1
- })
-
+ _unused_m_std, e_std = create_synthetic_star(
+ physics_engine, "std_leak", 500, {"sec_private_info": 1, "globals": 1, "sec_heat_triggers": 1}
+ )
+
# 2. Careless LLM API secret leak (Calling APIs without using global variables)
- m_llm, _unused_e_llm = create_synthetic_star(physics_engine, "llm_leak", 500, {
- "sec_private_info": 1, "llm_api": 5, "globals": 0, "sec_heat_triggers": 1
- })
+ m_llm, _unused_e_llm = create_synthetic_star(
+ physics_engine, "llm_leak", 500, {"sec_private_info": 1, "llm_api": 5, "globals": 0, "sec_heat_triggers": 1}
+ )
+
# ==============================================================================
# TEST 32: SAFE MINIFIED VENDOR FILE
@@ -831,10 +859,12 @@ def test_signal_processor_safe_minified(physics_engine):
"""Proves that minified files with zero malicious intent safely bypass the tripwire."""
m_safe, e_safe = create_synthetic_star(physics_engine, "jquery_min", 100, {"branch": 50, "flux": 20})
m_safe["is_minified"] = True
-
+
r_safe = physics_engine.calculate_risk_vector(m_safe, e_safe)
-
- assert r_safe["risk_vector"] == [0.0] * len(physics_engine.RISK_SCHEMA), "Safe minified file failed to zero out risks!"
+
+ assert r_safe["risk_vector"] == [0.0] * len(
+ physics_engine.RISK_SCHEMA
+ ), "Safe minified file failed to zero out risks!"
assert r_safe["telemetry"]["domain_context"]["alert"] == "MINIFIED VENDOR BYPASS", "Minified bypass flag missing!"
@@ -846,7 +876,7 @@ def test_signal_processor_lazy_evaluation_shield(physics_engine):
# 1. Ticking OOM Bomb (O(N^3) + High Flux + No Lazy Eval)
m_oom, e_oom = create_synthetic_star(physics_engine, "oom_bomb", 100, {"flux": 20})
m_oom["functions"] = [{"name": "heavy_loop", "loc": 50, "big_o_depth": 3}]
-
+
# 2. Safe Stream (O(N^3) + High Flux + Lazy Evaluation)
m_lazy, e_lazy = create_synthetic_star(physics_engine, "lazy_stream", 100, {"flux": 20, "lazy_evaluation": 10})
m_lazy["functions"] = [{"name": "generator", "loc": 50, "big_o_depth": 3}]
@@ -855,7 +885,9 @@ def test_signal_processor_lazy_evaluation_shield(physics_engine):
r_lazy = physics_engine.calculate_risk_vector(m_lazy, e_lazy)
idx_flux = physics_engine.RISK_SCHEMA.index("state_flux")
- assert r_lazy["risk_vector"][idx_flux] < r_oom["risk_vector"][idx_flux], "Lazy evaluation failed to dampen the OOM Bomb multiplier!"
+ assert (
+ r_lazy["risk_vector"][idx_flux] < r_oom["risk_vector"][idx_flux]
+ ), "Lazy evaluation failed to dampen the OOM Bomb multiplier!"
# ==============================================================================
@@ -867,7 +899,7 @@ def test_signal_processor_ai_topology_dl_ml(physics_engine):
m_dl, e_dl = create_synthetic_star(physics_engine, "pytorch_model", 100, {"dl_frameworks": 10})
r_dl = physics_engine.calculate_risk_vector(m_dl, e_dl)
m_dl.update(r_dl)
-
+
# Traditional ML
m_ml, e_ml = create_synthetic_star(physics_engine, "xgboost_model", 100, {"ml_traditional": 10})
r_ml = physics_engine.calculate_risk_vector(m_ml, e_ml)
@@ -875,34 +907,39 @@ def test_signal_processor_ai_topology_dl_ml(physics_engine):
# Summarize DL
sum_dl = physics_engine.summarize_galaxy_metrics([m_dl], [])
- assert sum_dl["ai_topology"]["classification"] == "Deep Learning Architecture", "Failed to classify DL Architecture!"
-
+ assert (
+ sum_dl["ai_topology"]["classification"] == "Deep Learning Architecture"
+ ), "Failed to classify DL Architecture!"
+
# Summarize ML
sum_ml = physics_engine.summarize_galaxy_metrics([m_ml], [])
- assert sum_ml["ai_topology"]["classification"] == "Statistical Machine Learning", "Failed to classify Traditional ML!"
+ assert (
+ sum_ml["ai_topology"]["classification"] == "Statistical Machine Learning"
+ ), "Failed to classify Traditional ML!"
+
# ==============================================================================
# TEST 35: PARANOID MODE ACTIVATION
# ==============================================================================
def test_signal_processor_paranoid_mode(physics_engine):
"""Proves that Paranoid Mode tightens the Sigmoid thresholds across security lenses."""
- m_para, e_para = create_synthetic_star(physics_engine, "paranoid_file", 500, {
- "sec_danger": 5, "sec_io": 5
- })
-
+ m_para, e_para = create_synthetic_star(physics_engine, "paranoid_file", 500, {"sec_danger": 5, "sec_io": 5})
+
# Calculate in Standard Mode
physics_engine.is_paranoid = False
r_std = physics_engine.calculate_risk_vector(m_para, e_para)
-
+
# Calculate in Paranoid Mode
physics_engine.is_paranoid = True
r_para = physics_engine.calculate_risk_vector(m_para, e_para)
-
+
# Reset the engine state so subsequent tests aren't affected
physics_engine.is_paranoid = False
-
+
idx_inj = physics_engine.RISK_SCHEMA.index("injection_surface")
- assert r_para["risk_vector"][idx_inj] > r_std["risk_vector"][idx_inj], "Paranoid mode failed to amplify the risk exposure!"
+ assert (
+ r_para["risk_vector"][idx_inj] > r_std["risk_vector"][idx_inj]
+ ), "Paranoid mode failed to amplify the risk exposure!"
# ==============================================================================
@@ -911,23 +948,21 @@ def test_signal_processor_paranoid_mode(physics_engine):
def test_signal_processor_ai_topology_rag_cloud(physics_engine):
"""Ensures the AI topology summarizer correctly identifies RAG pipelines and Cloud wrappers."""
# RAG Pipeline
- m_rag, e_rag = create_synthetic_star(physics_engine, "rag_bot", 100, {
- "llm_vector_store": 10, "llm_api": 5
- })
+ m_rag, e_rag = create_synthetic_star(physics_engine, "rag_bot", 100, {"llm_vector_store": 10, "llm_api": 5})
r_rag = physics_engine.calculate_risk_vector(m_rag, e_rag)
m_rag.update(r_rag)
-
+
# Cloud API Wrapper
- m_cloud, e_cloud = create_synthetic_star(physics_engine, "cloud_bot", 100, {
- "llm_api": 10
- })
+ m_cloud, e_cloud = create_synthetic_star(physics_engine, "cloud_bot", 100, {"llm_api": 10})
r_cloud = physics_engine.calculate_risk_vector(m_cloud, e_cloud)
m_cloud.update(r_cloud)
# Summarize RAG
sum_rag = physics_engine.summarize_galaxy_metrics([m_rag], [])
- assert sum_rag["ai_topology"]["classification"] == "RAG Pipeline (Retrieval-Augmented Generation)", "Failed to classify RAG Pipeline!"
-
+ assert (
+ sum_rag["ai_topology"]["classification"] == "RAG Pipeline (Retrieval-Augmented Generation)"
+ ), "Failed to classify RAG Pipeline!"
+
# Summarize Cloud
sum_cloud = physics_engine.summarize_galaxy_metrics([m_cloud], [])
assert sum_cloud["ai_topology"]["classification"] == "Cloud API Wrapper", "Failed to classify Cloud API Wrapper!"
@@ -939,24 +974,26 @@ def test_signal_processor_ai_topology_rag_cloud(physics_engine):
def test_signal_processor_sigmoid_overflow(physics_engine):
"""Proves the Sigmoid curve safely catches math.exp OverflowErrors on extreme densities."""
# Create a file with mathematically impossible levels of safety to force a massive negative density
- m_safe, e_safe = create_synthetic_star(physics_engine, "super_shield", 1, {
- "safety": 15000, "test": 15000, "doc": 15000, "freeze_hits": 15000
- })
-
+ m_safe, e_safe = create_synthetic_star(
+ physics_engine, "super_shield", 1, {"safety": 15000, "test": 15000, "doc": 15000, "freeze_hits": 15000}
+ )
+
# Create a file with mathematically impossible danger to force a massive positive density
- m_danger, e_danger = create_synthetic_star(physics_engine, "super_bomb", 1, {
- "branch": 15000, "concurrency": 15000, "flux": 15000, "sec_danger": 15000
- })
+ m_danger, e_danger = create_synthetic_star(
+ physics_engine, "super_bomb", 1, {"branch": 15000, "concurrency": 15000, "flux": 15000, "sec_danger": 15000}
+ )
# If these execute without crashing the test runner, the except blocks are working perfectly.
r_safe = physics_engine.calculate_risk_vector(m_safe, e_safe)
r_danger = physics_engine.calculate_risk_vector(m_danger, e_danger)
-
+
idx_saf = physics_engine.RISK_SCHEMA.index("safety_score")
-
+
# The OverflowError should gracefully return either 0.0 or 100.0 depending on the threat trajectory
assert r_safe["risk_vector"][idx_saf] == 0.0, "Overflow fallback failed to zero out the mathematically safe file!"
- assert r_danger["risk_vector"][idx_saf] == 100.0, "Overflow fallback failed to max out the mathematically dangerous file!"
+ assert (
+ r_danger["risk_vector"][idx_saf] == 100.0
+ ), "Overflow fallback failed to max out the mathematically dangerous file!"
# ==============================================================================
@@ -965,34 +1002,39 @@ def test_signal_processor_sigmoid_overflow(physics_engine):
def test_signal_processor_standalone_init_and_silo():
"""Ensures the processor initializes without a parent logger and handles 0-commit silo math."""
from gitgalaxy.physics.signal_processor import SignalProcessor
-
+
# Test standalone initialization
standalone_engine = SignalProcessor(parent_logger=None)
assert standalone_engine is not None, "SignalProcessor failed to initialize without a parent logger!"
-
+
# Test the silo math directly on a 0-commit developer void state
zero_silo = standalone_engine._calculate_silo_risk({"dev_a": 0, "dev_b": 0})
assert zero_silo == 0.0, "Silo risk failed to safely return 0.0 on a void state!"
+
# ==============================================================================
# TEST 39: THE LOAD-BEARER PENALTY (Verification Risk)
# ==============================================================================
def test_signal_processor_load_bearer_penalty(physics_engine):
"""Proves that highly imported files receive a massive penalty for lacking tests."""
# 1. Standard file with 0 tests
- m_std, e_std = create_synthetic_star(physics_engine, "std_untested", 100, {"test": 0})
+ m_std, e_std = create_synthetic_star(physics_engine, "std_untested", 100)
+ m_std["functions"] = [{"name": "func", "impact": 5000.0, "hit_vector": {}}]
m_std["popularity"] = 0
-
+
# 2. Foundational pillar with 0 tests
- m_pillar, e_pillar = create_synthetic_star(physics_engine, "pillar_untested", 100, {"test": 0})
+ m_pillar, e_pillar = create_synthetic_star(physics_engine, "pillar_untested", 100)
+ m_pillar["functions"] = [{"name": "func", "impact": 5000.0, "hit_vector": {}}]
m_pillar["popularity"] = 20 # Highly imported
r_std = physics_engine.calculate_risk_vector(m_std, e_std)
r_pillar = physics_engine.calculate_risk_vector(m_pillar, e_pillar)
idx_ver = physics_engine.RISK_SCHEMA.index("verification")
-
- assert r_pillar["risk_vector"][idx_ver] > r_std["risk_vector"][idx_ver], "Load-bearer penalty failed to amplify verification risk!"
+
+ assert (
+ r_pillar["risk_vector"][idx_ver] > r_std["risk_vector"][idx_ver]
+ ), "Load-bearer penalty failed to amplify verification risk!"
# ==============================================================================
@@ -1003,7 +1045,7 @@ def test_signal_processor_kinetic_blindness(physics_engine):
# 1. Complex function WITH a docstring
m_doc, e_doc = create_synthetic_star(physics_engine, "documented_heavy", 100, {"doc": 10})
m_doc["functions"] = [{"name": "heavy_func", "loc": 50, "big_o_depth": 3, "docstring": True}]
-
+
# 2. Complex function WITHOUT a docstring
m_blind, e_blind = create_synthetic_star(physics_engine, "blind_heavy", 100, {"doc": 10})
m_blind["functions"] = [{"name": "heavy_func", "loc": 50, "big_o_depth": 3, "docstring": False}]
@@ -1012,8 +1054,10 @@ def test_signal_processor_kinetic_blindness(physics_engine):
r_blind = physics_engine.calculate_risk_vector(m_blind, e_blind)
idx_doc = physics_engine.RISK_SCHEMA.index("documentation")
-
- assert r_blind["risk_vector"][idx_doc] > r_doc["risk_vector"][idx_doc], "Kinetic blindness failed to penalize undocumented heavy functions!"
+
+ assert (
+ r_blind["risk_vector"][idx_doc] > r_doc["risk_vector"][idx_doc]
+ ), "Kinetic blindness failed to penalize undocumented heavy functions!"
# ==============================================================================
@@ -1023,19 +1067,21 @@ def test_signal_processor_tech_debt_slop(physics_engine):
"""Proves that unacknowledged slop multiplies the severity of fragile debt."""
# 1. Just fragile debt
m_debt, e_debt = create_synthetic_star(physics_engine, "fragile_only", 500, {"fragile_debt": 2})
-
+
# 2. Fragile debt PLUS orphans/duplicates
- m_slop, e_slop = create_synthetic_star(physics_engine, "fragile_slop", 500, {
- "fragile_debt": 2, "design_slop_orphans": 2, "design_slop_duplicates": 1
- })
+ m_slop, e_slop = create_synthetic_star(
+ physics_engine, "fragile_slop", 500, {"fragile_debt": 2, "design_slop_orphans": 2, "design_slop_duplicates": 1}
+ )
r_debt = physics_engine.calculate_risk_vector(m_debt, e_debt)
r_slop = physics_engine.calculate_risk_vector(m_slop, e_slop)
idx_debt = physics_engine.RISK_SCHEMA.index("tech_debt")
-
+
# The multiplier is 1.5x, so the slop score should be significantly higher
- assert r_slop["risk_vector"][idx_debt] > (r_debt["risk_vector"][idx_debt] * 1.2), "Tech debt slop failed to multiply fragile debt severity!"
+ assert r_slop["risk_vector"][idx_debt] > (
+ r_debt["risk_vector"][idx_debt] * 1.2
+ ), "Tech debt slop failed to multiply fragile debt severity!"
# ==============================================================================
@@ -1044,20 +1090,21 @@ def test_signal_processor_tech_debt_slop(physics_engine):
def test_signal_processor_report_fallback(physics_engine):
"""Ensures the report generator safely handles missing keys and malformed telemetry."""
malformed_files = [
- {"name": "missing_risk_vector", "path": "src/bad1.py"}, # No risk_vector key
- {"name": "string_risk_vector", "path": "src/bad2.py", "risk_vector": "INVALID"}, # Wrong type
- {"name": "short_risk_vector", "path": "src/bad3.py", "risk_vector": [0.0]} # Index out of bounds
+ {"name": "missing_risk_vector", "path": "src/bad1.py"}, # No risk_vector key
+ {"name": "string_risk_vector", "path": "src/bad2.py", "risk_vector": "INVALID"}, # Wrong type
+ {"name": "short_risk_vector", "path": "src/bad3.py", "risk_vector": [0.0]}, # Index out of bounds
]
-
+
# Should execute smoothly without raising a KeyError, TypeError, or IndexError
report = physics_engine.generate_forensic_report(malformed_files)
-
+
assert "exposures" in report, "Report generator completely failed on malformed data!"
-
+
# The lowest/highest rankings should have safely defaulted the values to 0.0
for exposure_key, ranking in report["exposures"].items():
assert ranking["highest"][0]["value"] == 0.0, f"Fallback failed to zero out invalid data for {exposure_key}!"
+
# ==============================================================================
# TEST 43: CRITICAL LEAK BYPASS (Absolute Maximum Risk)
# ==============================================================================
@@ -1066,14 +1113,16 @@ def test_signal_processor_critical_leak_bypass(physics_engine):
m_leak, e_leak = create_synthetic_star(physics_engine, "aws_key", 10, {})
m_leak["path"] = "config/production.pem"
m_leak["metadata"] = {"aperture_reason": "CRITICAL LEAK DETECTED"}
-
+
r_leak = physics_engine.calculate_risk_vector(m_leak, e_leak)
-
+
idx_sec = physics_engine.RISK_SCHEMA.index("secrets_risk")
-
+
assert r_leak["file_impact"] == 150.0, "Critical leak failed to trigger the 150.0 mass spike!"
assert r_leak["risk_vector"][idx_sec] == 100.0, "Critical leak failed to max out secrets risk!"
- assert r_leak["telemetry"]["domain_context"]["alert"] == "CRITICAL LEAK BYPASS", "Bypass alert missing from telemetry!"
+ assert (
+ r_leak["telemetry"]["domain_context"]["alert"] == "CRITICAL LEAK BYPASS"
+ ), "Bypass alert missing from telemetry!"
# ==============================================================================
@@ -1082,10 +1131,10 @@ def test_signal_processor_critical_leak_bypass(physics_engine):
def test_signal_processor_darkness_ratio(physics_engine):
"""Ensures global synthesis survives a completely broken repository (0 parsed, 10 unparsable)."""
unparsable_files = [{"name": f"broken_{i}.py"} for i in range(10)]
-
+
# 0 parsed files, 10 unparsable files
summary = physics_engine.summarize_galaxy_metrics([], unparsable_files)
-
+
assert summary["summary"]["total_files"] == 10, "Failed to count unparsable files in total!"
assert summary["summary"]["verified_files"] == 0, "Verified files should be 0!"
assert summary["summary"]["Percent_Visible"] == 0.0, "Darkness ratio failed to calculate 0% visibility!"
@@ -1099,18 +1148,20 @@ def test_signal_processor_hardware_bridge_shield(physics_engine):
"""Proves that Hardware Bridges (Serial/USB I/O) are forgiven for dynamic execution."""
# 1. Raw Execution (Malicious)
m_raw, e_raw = create_synthetic_star(physics_engine, "raw_exec", 100, {"sec_danger": 10, "sec_io": 10})
-
+
# 2. Hardware Execution (Expected Arduino/Serial behavior)
- m_hw, e_hw = create_synthetic_star(physics_engine, "hw_exec", 100, {
- "sec_danger": 10, "sec_io": 10, "hardware_bridge": 10
- })
+ m_hw, e_hw = create_synthetic_star(
+ physics_engine, "hw_exec", 100, {"sec_danger": 10, "sec_io": 10, "hardware_bridge": 10}
+ )
r_raw = physics_engine.calculate_risk_vector(m_raw, e_raw)
r_hw = physics_engine.calculate_risk_vector(m_hw, e_hw)
idx_inj = physics_engine.RISK_SCHEMA.index("injection_surface")
-
- assert r_hw["risk_vector"][idx_inj] < r_raw["risk_vector"][idx_inj], "Hardware bridge shield failed to dampen injection risk!"
+
+ assert (
+ r_hw["risk_vector"][idx_inj] < r_raw["risk_vector"][idx_inj]
+ ), "Hardware bridge shield failed to dampen injection risk!"
# ==============================================================================
@@ -1121,10 +1172,10 @@ def test_signal_processor_algorithmic_dos_linear_bypass(physics_engine):
m_linear, e_linear = create_synthetic_star(physics_engine, "linear_loop", 100, {"api": 10})
# big_o_depth = 1 is standard O(N)
m_linear["functions"] = [{"name": "safe_loop", "loc": 50, "big_o_depth": 1, "db_complexity": 5}]
-
+
r_linear = physics_engine.calculate_risk_vector(m_linear, e_linear)
idx_dos = physics_engine.RISK_SCHEMA.index("algorithmic_dos")
-
+
# Because depth is < 2, the loop `continue` triggers and mass remains 0.0
assert r_linear["risk_vector"][idx_dos] == 0.0, "O(N) linear loops should not trigger Algorithmic DoS!"
@@ -1136,9 +1187,47 @@ def test_signal_processor_tier_3_language(physics_engine):
"""Ensures esoteric/unstructured languages trigger Tier 3 physics modifiers."""
m_t3, e_t3 = create_synthetic_star(physics_engine, "esoteric", 100, {"branch": 20})
# "haskell" is not in the Tier 1 or Tier 2 explicit sets
- m_t3["lang_id"] = "haskell"
-
+ m_t3["lang_id"] = "haskell"
+
r_t3 = physics_engine.calculate_risk_vector(m_t3, e_t3)
-
+
# If it didn't crash, the _get_tier fallback successfully returned "tier3" and pulled the correct physics vars
- assert r_t3 is not None, "Tier 3 language fallback crashed the physics engine!"
\ No newline at end of file
+ assert r_t3 is not None, "Tier 3 language fallback crashed the physics engine!"
+
+
+# ==============================================================================
+# TEST 48: EXTERNAL TEST COVERAGE MAPPING
+# ==============================================================================
+def test_signal_processor_external_test_coverage(physics_engine):
+ """Proves that external test files dampen unverified impact via the coverage map."""
+
+ # 1. Completely unverified function
+ m_blind, e_blind = create_synthetic_star(physics_engine, "blind", 100)
+ m_blind["functions"] = [{"name": "target_func", "impact": 50.0}]
+
+ # 2. Verified function (has a test targeting it)Skip to main content
+ m_verified, e_verified = create_synthetic_star(physics_engine, "verified", 100)
+ m_verified["functions"] = [{"name": "target_func", "impact": 50.0}]
+ m_verified["test_coverage_map"] = {
+ "target_func": [{"impact": 25.0, "target_count": 1, "test_hits": 5, "test_skip_hits": 0, "decorators": 0}]
+ }
+
+ # 3. Parameterized Verified function (gets a 2.0x multiplier via decorators)
+ m_param, e_param = create_synthetic_star(physics_engine, "param_verified", 100)
+ m_param["functions"] = [{"name": "target_func", "impact": 50.0}]
+ m_param["test_coverage_map"] = {
+ "target_func": [{"impact": 25.0, "target_count": 1, "test_hits": 5, "test_skip_hits": 0, "decorators": 1}]
+ }
+
+ r_blind = physics_engine.calculate_risk_vector(m_blind, e_blind)
+ r_verified = physics_engine.calculate_risk_vector(m_verified, e_verified)
+ r_param = physics_engine.calculate_risk_vector(m_param, e_param)
+
+ idx_ver = physics_engine.RISK_SCHEMA.index("verification")
+
+ assert (
+ r_verified["risk_vector"][idx_ver] < r_blind["risk_vector"][idx_ver]
+ ), "External test coverage failed to dampen verification risk!"
+ assert (
+ r_param["risk_vector"][idx_ver] < r_verified["risk_vector"][idx_ver]
+ ), "Parameterization multiplier failed to increase defensive mass!"
diff --git a/tests/security_auditing/test_api_network_map.py b/tests/security_auditing/test_api_network_map.py
index 57c36514..493af249 100644
--- a/tests/security_auditing/test_api_network_map.py
+++ b/tests/security_auditing/test_api_network_map.py
@@ -16,10 +16,10 @@
# ==============================================================================
-# TEST 1: The Core Framework Regex Traps (All Languages)
+# TEST 1: Framework Regex Extraction (All Supported Languages)
# ==============================================================================
-def test_all_framework_regex_traps(tmp_path):
- """Proves the physical mapper correctly extracts endpoints from all supported backends."""
+def test_framework_regex_extraction(tmp_path):
+ """Verifies the physical mapper correctly extracts endpoints from all supported backends."""
repo_dir = tmp_path / "all_frameworks_repo"
repo_dir.mkdir()
@@ -37,7 +37,7 @@ def test_all_framework_regex_traps(tmp_path):
physical_apis, frameworks = map_physical_codebase(repo_dir)
# Verify all frameworks were successfully detected
- assert len(frameworks) == 9, "Not all frameworks were detected by the regex traps!"
+ assert len(frameworks) == 9, "Not all frameworks were detected by the extraction rules!"
endpoints = set(physical_apis.keys())
assert "GET /api/py" in endpoints
assert "POST /api/js" in endpoints
@@ -51,10 +51,33 @@ def test_all_framework_regex_traps(tmp_path):
# ==============================================================================
-# TEST 2: Swagger Parser (JSON, YAML, and Exceptions)
+# TEST 2: Path Variable Extraction
# ==============================================================================
-def test_swagger_parser_yaml_and_errors(tmp_path, capsys):
- """Proves the parser handles YAML specs and correctly raises SystemExit on corruption."""
+def test_endpoint_variable_extraction(tmp_path):
+ """Verifies that different framework syntaxes for path variables are extracted as-is."""
+ repo_dir = tmp_path / "normalization_repo"
+ repo_dir.mkdir()
+
+ # Different frameworks use different variable syntaxes (Flask: , Express: :id, Spring: {id})
+ (repo_dir / "app.py").write_text('@app.get("/api/users/")', encoding="utf-8")
+ (repo_dir / "server.js").write_text('router.get("/api/users/:userId")', encoding="utf-8")
+ (repo_dir / "Controller.java").write_text('@GetMapping("/api/users/{id}")', encoding="utf-8")
+
+ physical_apis, _ = map_physical_codebase(repo_dir)
+ endpoints = set(physical_apis.keys())
+
+ # The engine retains the raw syntax from the code
+ assert "GET /api/users/" in endpoints, "Flask variable extraction failed!"
+ assert "GET /api/users/:userId" in endpoints, "Express variable extraction failed!"
+ assert "GET /api/users/{id}" in endpoints, "Spring variable extraction failed!"
+ assert len(endpoints) == 3, "Variable routes were incorrectly merged!"
+
+
+# ==============================================================================
+# TEST 3: Swagger Parser (YAML, JSON, and Corruption)
+# ==============================================================================
+def test_swagger_parser_yaml_and_corruption(tmp_path, capsys):
+ """Verifies the parser handles YAML specs and correctly exits on file corruption."""
# 1. Valid YAML
yaml_file = tmp_path / "openapi.yaml"
yaml_data = {"paths": {"/api/yaml": {"get": {}}}}
@@ -63,7 +86,7 @@ def test_swagger_parser_yaml_and_errors(tmp_path, capsys):
routes = parse_official_swagger(yaml_file)
assert "GET /api/yaml" in routes
- # 2. Corrupted File Exception Trap
+ # 2. Corrupted File Check
bad_file = tmp_path / "bad.json"
bad_file.write_text("{ CORRUPTED JSON", encoding="utf-8")
@@ -76,14 +99,41 @@ def test_swagger_parser_yaml_and_errors(tmp_path, capsys):
# ==============================================================================
-# TEST 3: Auto-Discovery Engine (Fast Path vs Deep Grep)
+# TEST 4: Swagger Parser (Empty Paths & Greedy Key Extraction)
# ==============================================================================
-def test_auto_discover_swagger_logic(tmp_path):
- """Proves the engine finds exact filenames OR deep-greps for Swagger signatures."""
+def test_swagger_parser_edge_cases(tmp_path):
+ """Verifies the parser survives schemas without paths and grabs all path keys."""
+ # 1. Missing "paths" object
+ empty_file = tmp_path / "empty_spec.json"
+ empty_file.write_text('{"openapi": "3.0.0", "info": {"title": "Empty"}}', encoding="utf-8")
+ routes_empty = parse_official_swagger(empty_file)
+ assert len(routes_empty) == 0, "Parser failed to handle missing 'paths' object!"
+
+ # 2. Greedy Key Extraction
+ invalid_methods_file = tmp_path / "vendor_spec.json"
+ spec_data = {
+ "openapi": "3.0.0",
+ "paths": {"/api/data": {"get": {}, "parameters": [], "x-internal-routing": {}, "servers": []}},
+ }
+ invalid_methods_file.write_text(json.dumps(spec_data), encoding="utf-8")
+ routes_invalid = parse_official_swagger(invalid_methods_file)
+
+ # The parser grabs everything under the path and uppercases it
+ assert "GET /api/data" in routes_invalid
+ assert "PARAMETERS /api/data" in routes_invalid
+ assert "X-INTERNAL-ROUTING /api/data" in routes_invalid
+ assert len(routes_invalid) == 4, "Parser failed to extract all path keys!"
+
+
+# ==============================================================================
+# TEST 5: Auto-Discovery Engine (Detection & Deep Grep)
+# ==============================================================================
+def test_auto_discover_files(tmp_path):
+ """Verifies the engine finds exact filenames OR deep-greps for OpenAPI signatures."""
# 1. Fast Path (Exact name match)
(tmp_path / "swagger.json").write_text("{}", encoding="utf-8")
- # 2. Deep Grep (Weird name, but contains OpenAPI signature)
+ # 2. Deep Grep (Unconventional name, but contains OpenAPI signature)
(tmp_path / "hidden_spec.yml").write_text('openapi: "3.0.0"\npaths: {}', encoding="utf-8")
# 3. Decoy (Valid extension, no signature)
@@ -98,24 +148,52 @@ def test_auto_discover_swagger_logic(tmp_path):
# ==============================================================================
-# TEST 4: Physical Codebase I/O Exception Trap
+# TEST 6: Auto-Discovery Engine (Recursive Greediness)
+# ==============================================================================
+def test_auto_discover_directories(tmp_path):
+ """Verifies that the auto-discovery engine recursively searches all directories."""
+ # Create directories
+ test_dir = tmp_path / "tests"
+ mock_dir = tmp_path / "mock"
+ docs_dir = tmp_path / "docs"
+ node_dir = tmp_path / "node_modules"
+
+ for d in [test_dir, mock_dir, docs_dir, node_dir]:
+ d.mkdir()
+ (d / "swagger.json").write_text('{"openapi": "3.0.0", "paths": {}}', encoding="utf-8")
+
+ # Valid schema in a standard folder
+ src_dir = tmp_path / "src"
+ src_dir.mkdir()
+ (src_dir / "openapi.json").write_text('{"openapi": "3.0.0", "paths": {}}', encoding="utf-8")
+
+ candidates = auto_discover_swagger(tmp_path)
+ paths = [str(c.relative_to(tmp_path)).replace("\\", "/") for c in candidates]
+
+ assert len(paths) == 5, "Engine failed to recursively locate all Swagger files!"
+ assert "src/openapi.json" in paths
+ assert "node_modules/swagger.json" in paths
+
+
# ==============================================================================
-def test_physical_mapper_exception_trap(tmp_path):
- """Proves the physical mapper skips unreadable files without crashing."""
+# TEST 7: Physical Codebase I/O Exception Handling
+# ==============================================================================
+def test_physical_mapper_exception_handling(tmp_path):
+ """Verifies the physical mapper skips unreadable or corrupted files without crashing."""
(tmp_path / "app.py").write_text('@app.get("/api/test")', encoding="utf-8")
# Mock Path.read_text to raise an exception
with patch("pathlib.Path.read_text", side_effect=PermissionError("Locked file!")):
apis, frameworks = map_physical_codebase(tmp_path)
- assert len(apis) == 0, "The engine failed to swallow the I/O exception!"
+ assert len(apis) == 0, "The engine failed to safely catch and ignore the I/O exception!"
# ==============================================================================
-# TEST 5: CLI Main - Missing Target Error
+# TEST 8: CLI Main - Missing Target Directory
# ==============================================================================
-def test_main_missing_target(capsys):
- """Proves the CLI aborts if the target directory doesn't exist."""
+def test_cli_missing_target(capsys):
+ """Verifies the CLI aborts gracefully if the target directory doesn't exist."""
with patch("sys.argv", ["api_map", "missing_repo_12345"]):
with pytest.raises(SystemExit) as exc_info:
main()
@@ -124,10 +202,10 @@ def test_main_missing_target(capsys):
# ==============================================================================
-# TEST 6: CLI Main - No Swagger Found Error
+# TEST 9: CLI Main - No Swagger Found Error
# ==============================================================================
-def test_main_no_swagger_found(tmp_path, capsys):
- """Proves the CLI aborts if auto-discovery finds zero Swagger files."""
+def test_cli_no_swagger_found(tmp_path, capsys):
+ """Verifies the CLI aborts gracefully if auto-discovery finds zero schemas."""
repo_dir = tmp_path / "empty_repo"
repo_dir.mkdir()
@@ -139,10 +217,10 @@ def test_main_no_swagger_found(tmp_path, capsys):
# ==============================================================================
-# TEST 7: CLI Main - Ambiguous Swaggers Error (No Merge Flag)
+# TEST 10: CLI Main - Ambiguous Swaggers (Requires Intervention)
# ==============================================================================
-def test_main_ambiguous_swaggers(tmp_path, capsys):
- """Proves the CLI halts and requires intervention if multiple primary Swaggers exist."""
+def test_cli_ambiguous_swaggers(tmp_path, capsys):
+ """Verifies the CLI halts and requires intervention if multiple primary schemas exist."""
repo_dir = tmp_path / "multi_repo"
repo_dir.mkdir()
@@ -163,18 +241,18 @@ def test_main_ambiguous_swaggers(tmp_path, capsys):
# ==============================================================================
-# TEST 8: CLI Main - Ambiguous Swaggers WITH --merge-all
+# TEST 11: CLI Main - Ambiguous Swaggers WITH --merge-all
# ==============================================================================
-def test_main_ambiguous_merge_all(tmp_path, capsys):
- """Proves the --merge-all flag unifies multiple Swaggers into one state."""
+def test_cli_ambiguous_merge_all(tmp_path, capsys):
+ """Verifies the --merge-all flag unifies multiple schemas into one verified state."""
repo_dir = tmp_path / "multi_repo_merge"
repo_dir.mkdir()
- # We must inject the "openapi" signature so the Deep Grep engine recognizes them!
+ # Inject the "openapi" signature so the Deep Grep engine recognizes them
(repo_dir / "swagger1.json").write_text('{"openapi": "3.0.0", "paths":{"/api/one":{"get":{}}}}', encoding="utf-8")
(repo_dir / "swagger2.json").write_text('{"openapi": "3.0.0", "paths":{"/api/two":{"post":{}}}}', encoding="utf-8")
- # Add a physical file so the dashboard prints cleanly
+ # Add physical files to match the documentation
(repo_dir / "app.py").write_text('@app.get("/api/one")\n@app.post("/api/two")', encoding="utf-8")
with patch("sys.argv", ["api_map", str(repo_dir), "--merge-all"]):
@@ -187,10 +265,10 @@ def test_main_ambiguous_merge_all(tmp_path, capsys):
# ==============================================================================
-# TEST 9: CLI Main - Explicit --swagger Flag (Valid and Invalid)
+# TEST 12: CLI Main - Explicit --swagger Flag
# ==============================================================================
-def test_main_explicit_swagger_flag(tmp_path, capsys):
- """Proves the --swagger flag bypasses discovery, and traps invalid paths."""
+def test_cli_explicit_swagger_flag(tmp_path, capsys):
+ """Verifies the --swagger flag bypasses discovery, handling both valid and invalid paths."""
repo_dir = tmp_path / "explicit_repo"
repo_dir.mkdir()
@@ -198,10 +276,7 @@ def test_main_explicit_swagger_flag(tmp_path, capsys):
spec_path.write_text('{"paths":{"/api/explicit":{"get":{}}}}', encoding="utf-8")
# Invalid Path
- with patch(
- "sys.argv",
- ["api_map", str(repo_dir), "--swagger", str(repo_dir / "missing.json")],
- ):
+ with patch("sys.argv", ["api_map", str(repo_dir), "--swagger", str(repo_dir / "missing.json")]):
with pytest.raises(SystemExit) as exc_info:
main()
assert "Error: Provided Swagger file" in capsys.readouterr().out
@@ -214,20 +289,20 @@ def test_main_explicit_swagger_flag(tmp_path, capsys):
# ==============================================================================
-# TEST 10: CLI Main - Presentation Dashboard (Shadow and Ghost APIs)
+# TEST 13: CLI Main - Presentation Dashboard (Shadow and Ghost APIs)
# ==============================================================================
-def test_main_presentation_dashboard(tmp_path, capsys):
- """Proves the CLI successfully prints the full Shadow/Ghost API dashboard."""
+def test_cli_presentation_dashboard_findings(tmp_path, capsys):
+ """Verifies the CLI successfully prints the full Shadow/Ghost API dashboard."""
repo_dir = tmp_path / "dashboard_repo"
repo_dir.mkdir()
- # 1. Official Swagger (Has a Ghost)
+ # 1. Official Swagger (Has a Ghost API)
(repo_dir / "swagger.json").write_text(
'{"paths":{"/api/ghost":{"get":{}}, "/api/shared":{"post":{}}}}',
encoding="utf-8",
)
- # 2. Source Code (Has a Shadow and the Shared endpoint)
+ # 2. Source Code (Has a Shadow API and the Shared endpoint)
(repo_dir / "app.py").write_text('@app.post("/api/shared")\n@app.delete("/api/shadow")', encoding="utf-8")
with patch("sys.argv", ["api_map", str(repo_dir)]):
@@ -242,13 +317,33 @@ def test_main_presentation_dashboard(tmp_path, capsys):
# ==============================================================================
-# TEST 11: Programmatic Edge Cases (run_api_audit)
+# TEST 14: CLI Main - Presentation Dashboard (Perfect Match)
# ==============================================================================
-def test_run_api_audit_edge_cases(tmp_path):
- """Proves the programmatic entry point safely returns edge case dictionaries."""
- # 1. No Swagger
+def test_cli_presentation_dashboard_perfect(tmp_path, capsys):
+ """Verifies the CLI correctly displays a clean bill of health when schemas and code match."""
+ repo_dir = tmp_path / "perfect_repo"
+ repo_dir.mkdir()
+
+ (repo_dir / "swagger.json").write_text('{"paths":{"/api/perfect":{"get":{}}}}', encoding="utf-8")
+ (repo_dir / "app.py").write_text('@app.get("/api/perfect")', encoding="utf-8")
+
+ with patch("sys.argv", ["api_map", str(repo_dir)]):
+ main()
+
+ captured = capsys.readouterr().out
+ assert "No Shadow APIs detected" in captured
+ assert "No Ghost APIs detected" in captured
+
+
+# ==============================================================================
+# TEST 15: Programmatic API - Edge Cases (No Swagger, Ambiguous)
+# ==============================================================================
+def test_programmatic_edge_cases(tmp_path):
+ """Verifies the programmatic entry point safely returns structured error states."""
repo_dir = tmp_path / "prog_repo"
repo_dir.mkdir()
+
+ # 1. No Swagger
res1 = run_api_audit(repo_dir)
assert res1["status"] == "no_swagger"
@@ -263,26 +358,19 @@ def test_run_api_audit_edge_cases(tmp_path):
# ==============================================================================
-# TEST 12: Programmatic Success (Test Auto-Bypass)
+# TEST 16: Programmatic API - Standard Success
# ==============================================================================
-def test_run_api_audit_success(tmp_path):
- """Proves the programmatic entry point succeeds and bypasses test schemas."""
+def test_programmatic_success(tmp_path):
+ """Verifies the programmatic entry point successfully maps a standard repo."""
repo_dir = tmp_path / "prog_success"
repo_dir.mkdir()
- # Primary Spec
- (repo_dir / "openapi.json").write_text('{"paths":{"/api/real":{"get":{}}}}', encoding="utf-8")
-
- # Test Spec (Should be ignored automatically)
- # The programmatic entry point strictly looks for "test", not "tests"
- test_dir = repo_dir / "test"
- test_dir.mkdir()
- (test_dir / "swagger.json").write_text('{"paths":{"/api/test":{"get":{}}}}', encoding="utf-8")
-
- # Source Code
+ (repo_dir / "openapi.json").write_text('{"openapi": "3.0.0", "paths":{"/api/real":{"get":{}}}}', encoding="utf-8")
(repo_dir / "app.py").write_text('@app.get("/api/real")\n@app.post("/api/shadow")', encoding="utf-8")
+ # Standard programmatic execution
result = run_api_audit(repo_dir)
+
assert result["status"] == "success"
assert result["shadow_count"] == 1
assert "POST /api/shadow" in result["shadow_apis"]