Navegador

navegador / docs / guide / analysis.md
Source Blame History 287 lines
89816aa… lmata 1 # Structural Analysis
89816aa… lmata 2
89816aa… lmata 3 Navegador's analysis commands answer questions about how code fits together: what breaks if this function changes, where does data flow, which code is never called, and which tests cover what.
89816aa… lmata 4
89816aa… lmata 5 All analysis commands work against the live graph. Run `navegador ingest` first to populate it.
89816aa… lmata 6
89816aa… lmata 7 ---
89816aa… lmata 8
89816aa… lmata 9 ## Impact analysis
89816aa… lmata 10
89816aa… lmata 11 `navegador impact` traces the downstream effect of changing a function, class, or file. It follows `CALLS`, `INHERITS`, and `IMPORTS` edges to find everything that depends on the target — directly or transitively.
89816aa… lmata 12
89816aa… lmata 13 ```bash
89816aa… lmata 14 navegador impact validate_token
89816aa… lmata 15 navegador impact PaymentProcessor --depth 3
89816aa… lmata 16 navegador impact src/auth/service.py --format json
89816aa… lmata 17 ```
89816aa… lmata 18
89816aa… lmata 19 ### Options
89816aa… lmata 20
89816aa… lmata 21 | Flag | Effect |
89816aa… lmata 22 |---|---|
89816aa… lmata 23 | `--depth N` | How many hops to follow (default: unlimited) |
89816aa… lmata 24 | `--format json` | Machine-readable output |
89816aa… lmata 25 | `--include-tests` | Include test files in the impact set |
89816aa… lmata 26
89816aa… lmata 27 ### Output
89816aa… lmata 28
89816aa… lmata 29 ```
89816aa… lmata 30 validate_token (Function — src/auth/service.py:42)
89816aa… lmata 31 Direct dependents (3):
89816aa… lmata 32 check_permissions src/auth/permissions.py:18
89816aa… lmata 33 require_auth src/auth/decorators.py:7
89816aa… lmata 34 middleware_auth src/middleware/auth.py:31
89816aa… lmata 35
89816aa… lmata 36 Transitive dependents (11):
89816aa… lmata 37 process_payment src/payments/processor.py:56
89816aa… lmata 38 create_order src/orders/service.py:23
89816aa… lmata 39 ... (8 more)
89816aa… lmata 40
89816aa… lmata 41 Affected files (5):
89816aa… lmata 42 src/auth/permissions.py
89816aa… lmata 43 src/auth/decorators.py
89816aa… lmata 44 src/middleware/auth.py
89816aa… lmata 45 src/payments/processor.py
89816aa… lmata 46 src/orders/service.py
89816aa… lmata 47 ```
89816aa… lmata 48
89816aa… lmata 49 ### Use cases
89816aa… lmata 50
89816aa… lmata 51 - Before refactoring: understand the blast radius before changing a shared utility
89816aa… lmata 52 - Code review: verify a PR's changes are limited to the expected scope
89816aa… lmata 53 - Dependency triage: identify high-fan-out functions that deserve extra test coverage
89816aa… lmata 54
89816aa… lmata 55 ---
89816aa… lmata 56
89816aa… lmata 57 ## Flow tracing
89816aa… lmata 58
89816aa… lmata 59 `navegador flow` traces the execution path from one function to another, returning every call chain that connects them.
89816aa… lmata 60
89816aa… lmata 61 ```bash
89816aa… lmata 62 navegador flow create_order process_payment
89816aa… lmata 63 navegador flow handle_request save_to_db --max-paths 5
89816aa… lmata 64 ```
89816aa… lmata 65
89816aa… lmata 66 ### Options
89816aa… lmata 67
89816aa… lmata 68 | Flag | Effect |
89816aa… lmata 69 |---|---|
89816aa… lmata 70 | `--max-paths N` | Maximum number of paths to return (default: 3) |
89816aa… lmata 71 | `--format json` | Machine-readable output |
89816aa… lmata 72
89816aa… lmata 73 ### Output
89816aa… lmata 74
89816aa… lmata 75 ```
89816aa… lmata 76 Paths from create_order to process_payment:
89816aa… lmata 77
89816aa… lmata 78 Path 1 (3 hops):
89816aa… lmata 79 create_order → validate_cart → charge_card → process_payment
89816aa… lmata 80
89816aa… lmata 81 Path 2 (4 hops):
89816aa… lmata 82 create_order → apply_discount → charge_card → process_payment
89816aa… lmata 83 ```
89816aa… lmata 84
89816aa… lmata 85 ### Use cases
89816aa… lmata 86
89816aa… lmata 87 - Debugging: find all code paths that reach a problematic function
89816aa… lmata 88 - Security review: trace every path to a sensitive operation (e.g., `delete_user`, `transfer_funds`)
89816aa… lmata 89 - Onboarding: understand how a high-level action maps to low-level implementation
89816aa… lmata 90
89816aa… lmata 91 ---
89816aa… lmata 92
89816aa… lmata 93 ## Dead code detection
89816aa… lmata 94
89816aa… lmata 95 `navegador dead-code` finds functions and classes that are never called, never imported, and not decorated as entry points.
89816aa… lmata 96
89816aa… lmata 97 ```bash
89816aa… lmata 98 navegador dead-code ./src
89816aa… lmata 99 navegador dead-code ./src --exclude-tests --format json
89816aa… lmata 100 ```
89816aa… lmata 101
89816aa… lmata 102 ### Options
89816aa… lmata 103
89816aa… lmata 104 | Flag | Effect |
89816aa… lmata 105 |---|---|
89816aa… lmata 106 | `--exclude-tests` | Skip test files |
89816aa… lmata 107 | `--min-age-days N` | Only report code not called in the last N days (requires git history) |
89816aa… lmata 108 | `--format json` | Machine-readable output |
89816aa… lmata 109 | `--threshold N` | Minimum confidence score to report (0–100, default: 80) |
89816aa… lmata 110
89816aa… lmata 111 ### Output
89816aa… lmata 112
89816aa… lmata 113 ```
89816aa… lmata 114 Potentially dead code (12 items):
89816aa… lmata 115
89816aa… lmata 116 [Function] legacy_hash_password src/auth/legacy.py:14
89816aa… lmata 117 [Function] _format_receipt_v1 src/payments/receipt.py:88
89816aa… lmata 118 [Class] OldPaymentAdapter src/payments/adapters.py:201
89816aa… lmata 119 ...
89816aa… lmata 120 ```
89816aa… lmata 121
89816aa… lmata 122 !!! note
89816aa… lmata 123 Navegador performs static call graph analysis. Dynamic dispatch, `getattr`, and string-based imports are not traced. Review candidates before deleting them.
89816aa… lmata 124
89816aa… lmata 125 ### Use cases
89816aa… lmata 126
89816aa… lmata 127 - Codebase cleanup: identify safe-to-delete code before a release
89816aa… lmata 128 - Migration audits: find old adapter classes after a library upgrade
89816aa… lmata 129
89816aa… lmata 130 ---
89816aa… lmata 131
89816aa… lmata 132 ## Cycle detection
89816aa… lmata 133
89816aa… lmata 134 `navegador cycles` finds circular dependency chains in the call graph and import graph.
89816aa… lmata 135
89816aa… lmata 136 ```bash
89816aa… lmata 137 navegador cycles ./src
89816aa… lmata 138 navegador cycles ./src --type imports
89816aa… lmata 139 navegador cycles ./src --type calls --format json
89816aa… lmata 140 ```
89816aa… lmata 141
89816aa… lmata 142 ### Options
89816aa… lmata 143
89816aa… lmata 144 | Flag | Effect |
89816aa… lmata 145 |---|---|
89816aa… lmata 146 | `--type calls` | Find circular call chains (default) |
89816aa… lmata 147 | `--type imports` | Find circular import chains |
89816aa… lmata 148 | `--type both` | Find both |
89816aa… lmata 149 | `--min-length N` | Only report cycles with at least N nodes (default: 2) |
89816aa… lmata 150 | `--format json` | Machine-readable output |
89816aa… lmata 151
89816aa… lmata 152 ### Output
89816aa… lmata 153
89816aa… lmata 154 ```
89816aa… lmata 155 Import cycles (2 found):
89816aa… lmata 156
89816aa… lmata 157 Cycle 1 (length 3):
89816aa… lmata 158 src/payments/processor.py
89816aa… lmata 159 → src/payments/validators.py
89816aa… lmata 160 → src/payments/utils.py
89816aa… lmata 161 → src/payments/processor.py
89816aa… lmata 162
89816aa… lmata 163 Cycle 2 (length 2):
89816aa… lmata 164 src/auth/service.py
89816aa… lmata 165 → src/auth/models.py
89816aa… lmata 166 → src/auth/service.py
89816aa… lmata 167 ```
89816aa… lmata 168
89816aa… lmata 169 ### Use cases
89816aa… lmata 170
89816aa… lmata 171 - CI gate: fail builds that introduce new circular imports
89816aa… lmata 172 - Refactoring prep: identify modules to split before a large restructure
89816aa… lmata 173
89816aa… lmata 174 ---
89816aa… lmata 175
89816aa… lmata 176 ## Test mapping
89816aa… lmata 177
89816aa… lmata 178 `navegador test-map` maps test functions to the production code they exercise, using call graph analysis.
89816aa… lmata 179
89816aa… lmata 180 ```bash
89816aa… lmata 181 navegador test-map ./src ./tests
89816aa… lmata 182 navegador test-map ./src ./tests --target process_payment
89816aa… lmata 183 navegador test-map ./src ./tests --format json
89816aa… lmata 184 ```
89816aa… lmata 185
89816aa… lmata 186 ### Options
89816aa… lmata 187
89816aa… lmata 188 | Flag | Effect |
89816aa… lmata 189 |---|---|
89816aa… lmata 190 | `--target <name>` | Only show tests that cover a specific function |
89816aa… lmata 191 | `--uncovered` | Show production functions with no covering tests |
89816aa… lmata 192 | `--format json` | Machine-readable output |
89816aa… lmata 193
89816aa… lmata 194 ### Output
89816aa… lmata 195
89816aa… lmata 196 ```
89816aa… lmata 197 Test coverage map:
89816aa… lmata 198
89816aa… lmata 199 process_payment (src/payments/processor.py:56)
89816aa… lmata 200 tests/payments/test_processor.py::test_process_payment_success
89816aa… lmata 201 tests/payments/test_processor.py::test_process_payment_duplicate
89816aa… lmata 202 tests/integration/test_checkout.py::test_full_checkout_flow
89816aa… lmata 203
89816aa… lmata 204 validate_token (src/auth/service.py:42)
89816aa… lmata 205 tests/auth/test_service.py::test_validate_token_valid
89816aa… lmata 206 tests/auth/test_service.py::test_validate_token_expired
89816aa… lmata 207
89816aa… lmata 208 Uncovered functions (4):
89816aa… lmata 209 legacy_hash_password src/auth/legacy.py:14
89816aa… lmata 210 _format_receipt_v1 src/payments/receipt.py:88
89816aa… lmata 211 ...
89816aa… lmata 212 ```
89816aa… lmata 213
89816aa… lmata 214 ### Use cases
89816aa… lmata 215
89816aa… lmata 216 - Coverage by semantics, not just lines: see which tests actually call a function
89816aa… lmata 217 - Regression targeting: when a function changes, which tests should run?
89816aa… lmata 218 - Review prep: check that new code has corresponding tests before merging
89816aa… lmata 219
89816aa… lmata 220 ---
89816aa… lmata 221
89816aa… lmata 222 ## Combining analysis with knowledge
89816aa… lmata 223
89816aa… lmata 224 All analysis commands understand the knowledge layer. Add `--include-knowledge` to see rules, concepts, and decisions linked to the affected nodes:
89816aa… lmata 225
89816aa… lmata 226 ```bash
89816aa… lmata 227 navegador impact process_payment --include-knowledge
89816aa… lmata 228 ```
89816aa… lmata 229
89816aa… lmata 230 Output will include knowledge nodes like:
89816aa… lmata 231
89816aa… lmata 232 ```
89816aa… lmata 233 Governed by:
89816aa… lmata 234 Rule: RequireIdempotencyKey (critical)
89816aa… lmata 235 Concept: Idempotency
89816aa… lmata 236 Decisions:
89816aa… lmata 237 UseStripeForPayments (accepted, 2025-01-15)
89816aa… lmata 238 ```
89816aa… lmata 239
89816aa… lmata 240 ---
89816aa… lmata 241
89816aa… lmata 242 ## Python API
89816aa… lmata 243
89816aa… lmata 244 ```python
89816aa… lmata 245 from navegador.graph import GraphStore
89816aa… lmata 246 from navegador.analysis import (
89816aa… lmata 247 ImpactAnalyzer,
89816aa… lmata 248 FlowTracer,
89816aa… lmata 249 DeadCodeDetector,
89816aa… lmata 250 CycleDetector,
89816aa… lmata 251 TestMapper,
89816aa… lmata 252 )
89816aa… lmata 253
89816aa… lmata 254 store = GraphStore.sqlite(".navegador/navegador.db")
89816aa… lmata 255
89816aa… lmata 256 # impact analysis
89816aa… lmata 257 analyzer = ImpactAnalyzer(store)
89816aa… lmata 258 result = analyzer.analyze("validate_token", depth=3)
89816aa… lmata 259 print(result.direct_dependents)
89816aa… lmata 260 print(result.transitive_dependents)
89816aa… lmata 261
89816aa… lmata 262 # flow tracing
89816aa… lmata 263 tracer = FlowTracer(store)
89816aa… lmata 264 paths = tracer.trace("create_order", "process_payment", max_paths=5)
89816aa… lmata 265 for path in paths:
89816aa… lmata 266 print(" -> ".join(path.nodes))
89816aa… lmata 267
89816aa… lmata 268 # dead code
89816aa… lmata 269 detector = DeadCodeDetector(store)
89816aa… lmata 270 candidates = detector.find("./src", exclude_tests=True)
89816aa… lmata 271 for item in candidates:
89816aa… lmata 272 print(f"{item.label}: {item.name} {item.file}:{item.line}")
89816aa… lmata 273
89816aa… lmata 274 # cycle detection
89816aa… lmata 275 cycle_detector = CycleDetector(store)
89816aa… lmata 276 cycles = cycle_detector.find_import_cycles("./src")
89816aa… lmata 277 for cycle in cycles:
89816aa… lmata 278 print(" -> ".join(cycle.path))
89816aa… lmata 279
89816aa… lmata 280 # test mapping
89816aa… lmata 281 mapper = TestMapper(store)
89816aa… lmata 282 coverage = mapper.map("./src", "./tests")
89816aa… lmata 283 for fn, tests in coverage.items():
89816aa… lmata 284 print(f"{fn}: {len(tests)} tests")
89816aa… lmata 285 ```
89816aa… lmata 286
89816aa… lmata 287 See the [Analysis API reference](../api/analysis.md) for full method signatures.

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button