codedd-cli 0.1.5__tar.gz → 0.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/PKG-INFO +3 -2
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/README.md +1 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/__init__.py +3 -3
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/api/client.py +2 -5
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/api/endpoints.py +9 -2
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/api/exceptions.py +24 -24
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/archetype_classifier.py +33 -6
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/architecture_analyzer.py +646 -188
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/architecture_prompts.py +6 -2
- codedd_cli-0.1.7/codedd_cli/auditor/architecture_schema_contract.py +150 -0
- codedd_cli-0.1.7/codedd_cli/auditor/audit_checkpoint.py +440 -0
- codedd_cli-0.1.7/codedd_cli/auditor/audit_progress_sync.py +124 -0
- codedd_cli-0.1.7/codedd_cli/auditor/commit_classifier.py +1068 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/complexity_analyzer.py +9 -4
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/dependency_scanner.py +1 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/enhanced_architecture_detectors.py +653 -381
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/file_auditor.py +30 -10
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/git_stats_collector.py +35 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/response_parser.py +611 -484
- codedd_cli-0.1.7/codedd_cli/auditor/sub_audit_runner.py +987 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/__init__.py +17 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/agents.py +2031 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/cli_ai_auditor.py +228 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/cli_orchestrator.py +398 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/cli_settings.py +43 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/file_io.py +27 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/__init__.py +99 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/_generic.py +240 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/c_cpp.py +83 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/csharp.py +48 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/go.py +43 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/java.py +49 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/js_ts.py +57 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/kotlin.py +46 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/php.py +48 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/ruby.py +42 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/rust.py +45 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/scala.py +46 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/shell.py +43 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/swift.py +43 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_ast/taint.py +126 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/lang_snippets.py +288 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/langgraph_runner.py +842 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/planner.py +241 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/prompts.py +41 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/scope.py +180 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/security_patterns.py +664 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/semgrep_runner.py +210 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/state.py +260 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_analysis/tools.py +1161 -0
- codedd_cli-0.1.7/codedd_cli/auditor/vulnerability_validator.py +90 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auth/session.py +9 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auth/token_manager.py +6 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/__init__.py +1 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/ai_docs_cmd.py +1115 -1000
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/audit_cmd.py +359 -104
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/audits_cmd.py +37 -6
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/auth_cmd.py +7 -21
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/config_cmd.py +30 -31
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/fix_cmd.py +1173 -72
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/commands/scope_cmd.py +188 -61
- codedd_cli-0.1.7/codedd_cli/config/constants.py +64 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/config/fix_session.py +47 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/config/settings.py +117 -17
- codedd_cli-0.1.7/codedd_cli/config/url_validation.py +139 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/models/audit.py +11 -11
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/scanner/file_classifier.py +92 -33
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/scanner/file_walker.py +39 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/scanner/line_counter.py +1 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/utils/__init__.py +1 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/utils/directory_validator.py +11 -1
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/utils/display.py +81 -41
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/utils/payload_inspector.py +1 -1
- codedd_cli-0.1.7/codedd_cli/utils/safe_path.py +51 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/utils/validators.py +6 -7
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/pyproject.toml +69 -67
- codedd_cli-0.1.5/codedd_cli/auditor/audit_checkpoint.py +0 -179
- codedd_cli-0.1.5/codedd_cli/auditor/commit_classifier.py +0 -350
- codedd_cli-0.1.5/codedd_cli/auditor/sub_audit_runner.py +0 -775
- codedd_cli-0.1.5/codedd_cli/auditor/vulnerability_validator.py +0 -497
- codedd_cli-0.1.5/codedd_cli/config/constants.py +0 -37
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/LICENSE +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/__main__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/api/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auditor/tier_definitions.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/auth/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/cli.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/config/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/llm/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/llm/key_manager.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/models/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/models/account.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/models/local_directory.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/scanner/__init__.py +0 -0
- {codedd_cli-0.1.5 → codedd_cli-0.1.7}/codedd_cli/utils/security.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codedd-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
4
4
|
Summary: CLI tool for CodeDD — run code audits from your terminal
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -25,6 +25,7 @@ Requires-Dist: defusedxml (>=0.7.1)
|
|
|
25
25
|
Requires-Dist: esprima (>=4.0.0) ; extra == "esprima"
|
|
26
26
|
Requires-Dist: httpx (>=0.27.0)
|
|
27
27
|
Requires-Dist: keyring (>=25.0.0)
|
|
28
|
+
Requires-Dist: langgraph (>=0.2.0)
|
|
28
29
|
Requires-Dist: lizard (>=1.17.0)
|
|
29
30
|
Requires-Dist: radon (>=6.0.0)
|
|
30
31
|
Requires-Dist: rich (>=13.0.0)
|
|
@@ -257,7 +258,7 @@ Run: codedd audit start
|
|
|
257
258
|
| `codedd config show-keys` | List which providers have keys configured (not the keys themselves) |
|
|
258
259
|
| `codedd config remove-key <anthropic\|openai>` | Remove a stored LLM API key from keychain |
|
|
259
260
|
| `codedd config provider [anthropic\|openai\|both]` | Set preferred LLM provider |
|
|
260
|
-
| `codedd config concurrency <n>` | Set max concurrent LLM requests (default
|
|
261
|
+
| `codedd config concurrency <n>` | Set max concurrent LLM requests (1–75, default 4) |
|
|
261
262
|
|
|
262
263
|
---
|
|
263
264
|
|
|
@@ -220,7 +220,7 @@ Run: codedd audit start
|
|
|
220
220
|
| `codedd config show-keys` | List which providers have keys configured (not the keys themselves) |
|
|
221
221
|
| `codedd config remove-key <anthropic\|openai>` | Remove a stored LLM API key from keychain |
|
|
222
222
|
| `codedd config provider [anthropic\|openai\|both]` | Set preferred LLM provider |
|
|
223
|
-
| `codedd config concurrency <n>` | Set max concurrent LLM requests (default
|
|
223
|
+
| `codedd config concurrency <n>` | Set max concurrent LLM requests (1–75, default 4) |
|
|
224
224
|
|
|
225
225
|
---
|
|
226
226
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"""CodeDD CLI — run code audits from your terminal."""
|
|
2
|
-
|
|
3
|
-
__version__ = "0.1.
|
|
1
|
+
"""CodeDD CLI — run code audits from your terminal."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.7"
|
|
@@ -24,6 +24,7 @@ from codedd_cli.config.constants import (
|
|
|
24
24
|
USER_AGENT_PREFIX,
|
|
25
25
|
)
|
|
26
26
|
from codedd_cli.config.settings import ConfigManager
|
|
27
|
+
from codedd_cli.config.url_validation import should_verify_tls_for_api_url
|
|
27
28
|
|
|
28
29
|
|
|
29
30
|
class CodeDDClient:
|
|
@@ -42,11 +43,7 @@ class CodeDDClient:
|
|
|
42
43
|
self._base_url = self._config.api_url.rstrip("/")
|
|
43
44
|
self._token = token if token is not None else TokenManager.retrieve()
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
# For HTTPS, always verify certificates
|
|
47
|
-
verify_tls = not self._base_url.startswith("http://localhost") and not self._base_url.startswith(
|
|
48
|
-
"http://127.0.0.1"
|
|
49
|
-
)
|
|
46
|
+
verify_tls = should_verify_tls_for_api_url(self._base_url)
|
|
50
47
|
|
|
51
48
|
self._client = httpx.Client(
|
|
52
49
|
base_url=self._base_url,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Server endpoint path constants.
|
|
3
3
|
|
|
4
|
-
All paths are
|
|
4
|
+
All paths are absolute from the server host root (they include the ``/api/``
|
|
5
|
+
prefix). The ``api_url`` in CLI config is the host only, e.g.
|
|
6
|
+
``https://api.codedd.ai`` or ``http://localhost:8000``.
|
|
5
7
|
"""
|
|
6
8
|
|
|
7
9
|
|
|
@@ -17,7 +19,7 @@ class Endpoints:
|
|
|
17
19
|
# Scope
|
|
18
20
|
REGISTER_SCOPE = "/api/cli/scope/register/"
|
|
19
21
|
SCOPE_FILES = "/api/cli/scope/files/"
|
|
20
|
-
DELETE_REPO_FROM_SCOPE = "/delete_repo_from_scope/"
|
|
22
|
+
DELETE_REPO_FROM_SCOPE = "/api/delete_repo_from_scope/"
|
|
21
23
|
|
|
22
24
|
# Audit lifecycle
|
|
23
25
|
AUDIT_CAN_START = "/api/cli/audit/can-start/"
|
|
@@ -27,6 +29,7 @@ class Endpoints:
|
|
|
27
29
|
|
|
28
30
|
# Local audit execution (CLI-side file auditing)
|
|
29
31
|
AUDIT_PLAN = "/api/cli/audit/plan/"
|
|
32
|
+
AUDIT_PROGRESS = "/api/cli/audit/progress/"
|
|
30
33
|
AUDIT_RESULTS = "/api/cli/audit/results/"
|
|
31
34
|
AUDIT_COMPLETE = "/api/cli/audit/complete/"
|
|
32
35
|
|
|
@@ -61,3 +64,7 @@ class Endpoints:
|
|
|
61
64
|
# Fix access control (remediation module)
|
|
62
65
|
FIX_ACCESS_STATUS = "/api/cli/fix/access/status/"
|
|
63
66
|
FIX_ACCESS_TOGGLE = "/api/cli/fix/access/toggle/"
|
|
67
|
+
|
|
68
|
+
# Issue Compass saved selections (flag-issue slices from the web explorer)
|
|
69
|
+
FIX_ISSUE_COMPASS_SELECTIONS = "/api/cli/fix/issue-compass-selections/"
|
|
70
|
+
FIX_ISSUE_COMPASS_SELECTIONS_CATALOG = "/api/cli/fix/issue-compass-selections/catalog/"
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
"""
|
|
2
|
-
API-layer exceptions with user-facing messages.
|
|
3
|
-
|
|
4
|
-
Raised when the CLI cannot reach the CodeDD server (connection refused,
|
|
5
|
-
timeout, server disconnected, etc.). Handled at the CLI entry point to
|
|
6
|
-
display a single, clear message instead of a full traceback.
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
# Pre-defined message shown when the remote is not responding.
|
|
10
|
-
CONNECTION_ERROR_MESSAGE = (
|
|
11
|
-
"Unable to reach CodeDD. "
|
|
12
|
-
"Check that the server is running and your network connection is available, "
|
|
13
|
-
"or try again later."
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class CodeDDConnectionError(Exception):
|
|
18
|
-
"""
|
|
19
|
-
Raised when a request to the CodeDD API fails due to connection
|
|
20
|
-
or transport errors (e.g. server not responding, timeout, disconnect).
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def __init__(self, message: str | None = None) -> None:
|
|
24
|
-
super().__init__(message or CONNECTION_ERROR_MESSAGE)
|
|
1
|
+
"""
|
|
2
|
+
API-layer exceptions with user-facing messages.
|
|
3
|
+
|
|
4
|
+
Raised when the CLI cannot reach the CodeDD server (connection refused,
|
|
5
|
+
timeout, server disconnected, etc.). Handled at the CLI entry point to
|
|
6
|
+
display a single, clear message instead of a full traceback.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# Pre-defined message shown when the remote is not responding.
|
|
10
|
+
CONNECTION_ERROR_MESSAGE = (
|
|
11
|
+
"Unable to reach CodeDD. "
|
|
12
|
+
"Check that the server is running and your network connection is available, "
|
|
13
|
+
"or try again later."
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CodeDDConnectionError(Exception):
|
|
18
|
+
"""
|
|
19
|
+
Raised when a request to the CodeDD API fails due to connection
|
|
20
|
+
or transport errors (e.g. server not responding, timeout, disconnect).
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, message: str | None = None) -> None:
|
|
24
|
+
super().__init__(message or CONNECTION_ERROR_MESSAGE)
|
|
@@ -16,12 +16,10 @@ identical tier definitions. The only difference is that it does NOT persist
|
|
|
16
16
|
results to PostgreSQL and operates without Phase 3 graph nodes/edges — the
|
|
17
17
|
_count_deployable_units method falls back to component-level heuristics when
|
|
18
18
|
graph data is unavailable.
|
|
19
|
-
|
|
20
|
-
Parity reference: E:/CodeDD/django/auditor/auditing_functions/functions/step_5/
|
|
21
|
-
architecture_analysis/archetype_classifier.py
|
|
22
19
|
"""
|
|
23
20
|
|
|
24
21
|
import logging
|
|
22
|
+
import re
|
|
25
23
|
import time
|
|
26
24
|
from typing import Any
|
|
27
25
|
|
|
@@ -133,9 +131,38 @@ class DimensionScorer:
|
|
|
133
131
|
patterns.append(val)
|
|
134
132
|
return patterns
|
|
135
133
|
|
|
134
|
+
@staticmethod
|
|
135
|
+
def _normalize_token(value: str) -> str:
|
|
136
|
+
"""Lowercase and collapse separators (``_ - . /`` + whitespace) to spaces.
|
|
137
|
+
|
|
138
|
+
This lets a single keyword match canonical tech ids regardless of the
|
|
139
|
+
separator style used upstream — e.g. ``spring`` matches ``spring_boot``,
|
|
140
|
+
``spring-boot`` and ``spring boot`` alike — while still respecting word
|
|
141
|
+
boundaries so ``spring`` does NOT match ``mainspring``.
|
|
142
|
+
"""
|
|
143
|
+
return re.sub(r"[\s_\-./]+", " ", value.lower()).strip()
|
|
144
|
+
|
|
145
|
+
def _matches(self, item: str, needle: str) -> bool:
|
|
146
|
+
"""Left-boundary match of *needle* within *item* after normalization.
|
|
147
|
+
|
|
148
|
+
Replaces the previous raw substring test, which produced mid-word false
|
|
149
|
+
positives (e.g. ``spring`` in ``offspring``/``mainspring``). We require
|
|
150
|
+
the needle to begin at a token boundary but deliberately do NOT require a
|
|
151
|
+
right boundary, so canonical tech ids that concatenate suffixes still
|
|
152
|
+
match (``express`` → ``expressjs``, ``next`` → ``nextjs``, ``postgres``
|
|
153
|
+
→ ``postgresql``). Multi-word needles (``api gateway``, ``kafka
|
|
154
|
+
streams``) work because both sides are separator-normalized first.
|
|
155
|
+
"""
|
|
156
|
+
item_norm = self._normalize_token(item)
|
|
157
|
+
needle_norm = self._normalize_token(needle)
|
|
158
|
+
if not needle_norm:
|
|
159
|
+
return False
|
|
160
|
+
pattern = rf"(?<![a-z0-9]){re.escape(needle_norm)}"
|
|
161
|
+
return re.search(pattern, item_norm) is not None
|
|
162
|
+
|
|
136
163
|
def _has_any(self, haystack: list[str], *needles: str) -> bool:
|
|
137
164
|
return any(
|
|
138
|
-
needle
|
|
165
|
+
self._matches(item, needle)
|
|
139
166
|
for item in haystack
|
|
140
167
|
for needle in needles
|
|
141
168
|
)
|
|
@@ -143,7 +170,7 @@ class DimensionScorer:
|
|
|
143
170
|
def _count_matches(self, haystack: list[str], *needles: str) -> int:
|
|
144
171
|
return sum(
|
|
145
172
|
1 for item in haystack
|
|
146
|
-
if any(needle
|
|
173
|
+
if any(self._matches(item, needle) for needle in needles)
|
|
147
174
|
)
|
|
148
175
|
|
|
149
176
|
def _evidence(
|
|
@@ -159,7 +186,7 @@ class DimensionScorer:
|
|
|
159
186
|
has already been credited in another dimension."""
|
|
160
187
|
credited_dims = self._tech_credit_ledger.get(tech_keyword, set())
|
|
161
188
|
if dimension in credited_dims:
|
|
162
|
-
return base_points
|
|
189
|
+
return base_points * ATTENUATION_FACTOR
|
|
163
190
|
if credited_dims:
|
|
164
191
|
self._tech_credit_ledger.setdefault(tech_keyword, set()).add(dimension)
|
|
165
192
|
return base_points * ATTENUATION_FACTOR
|