Back to skill

Security audit

garmin-panorama-training-analysis

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it handles Garmin credentials, health data, and precise locations in ways users should review carefully before installing.

Install only if you are comfortable giving this skill access to Garmin credentials and detailed health, sleep, recovery, and GPS activity history. Before use, remove the sibling-skill .env fallbacks, prefer environment variables or this skill's own credential file, consider disabling or coarsening Open-Meteo weather lookups, protect or delete generated data/ reports, and use an isolated pinned Python environment.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/garmin_client.py:34
Finding
Automatic Access to Credentials Stored by Unrelated Skills<![CDATA[ ## Vulnerability Details **File Location**: `scripts/garmin_client.py:34-36, 40-48, 52-61` **Vulnerability Type**: Cross-skill credential access **Risk Level**: High ### Vulnerable Code ```python FALLBACK_ENV_FILES = [ Path.home() / ".workbuddy" / "skills" / "run-coach__skillhub" / ".env", Path.home() / ".workbuddy" / "skills" / "coros-mcp-energy-lab__skillhub" / ".env", ] def _read_env_file(path: Path, key: str) -> str: if not path.exists(): return "" try: for line in path.read_text(encoding="utf-8").splitlines(): line = line.strip() if line.startswith(key + "="): return line.split("=", 1)[1].strip().strip('"').strip("'") except Exception: pass return "" def _env_or_envfile(key: str) -> str: val = os.environ.get(key, "").strip() if val: return val for path in [ENV_FILE] + FALLBACK_ENV_FILES: val = _read_env_file(path, key) if val: return val return "" ``` ### Technical Analysis The Skill automatically probes `.env` files belonging to two unrelated installed Skills and extracts `GARMIN_EMAIL`, `GARMIN_PASSWORD`, and `GARMIN_IS_CN`. This crosses the logical trust boundary between Skills. Garmin authentication is necessary for the declared functionality, but reading secret files owned by other Skills is not necessary. Credentials could instead be supplied through process environment variables, this Skill's own configuration file, an OS credential manager, or an explicitly selected credential file. The implementation does not require explicit consent before accessing the sibling files. It also does not validate file ownership, symbolic links, or restrictive file permissions. A maliciously prepared path or compromised sibling Skill could therefore influence the credentials used by this Skill. ### Attack Path 1. A user installs this Skill alongside one of the named fallback Skills. 2. The user stores Garmin ...[truncated 1092 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `FALLBACK_ENV_FILES` and all automatic probing of other Skills' directories. 2. Accept credentials only from: - `GARMIN_EMAIL`, `GARMIN_PASSWORD`, and `GARMIN_IS_CN` process environment variables; - this Skill's own protected `.env`; or - an OS-backed credential manager. 3. If cross-Skill reuse is required, require an explicit command-line option such as `--credential-file PATH` and display the selected path before reading it. 4. Reject symbolic links where feasible and verify that the credential file is owned by the current user. 5. On POSIX systems, reject or warn about credential files accessible by group or other users. 6. Avoid long-term password storage after token enrollment when the Garmin client supports token-only reuse. 7. Document credential scope, storage, and rotation procedures. ]]>

other

Warning
Location
scripts/fetch_data.py:119
Finding
Precise Activity Locations and Times Are Disclosed to Open-Meteo<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_data.py:119-131, 193-214` **Vulnerability Type**: Sensitive location disclosure to a third party **Risk Level**: Medium ### Vulnerable Code ```python def open_meteo_weather(lat, lon, date_str, hour, cfg): """Open-Meteo historical archive endpoint. Returns a dictionary or None.""" if lat is None or lon is None: return None url = "https://archive-api.open-meteo.com/v1/archive" params = { "latitude": lat, "longitude": lon, "start_date": date_str, "end_date": date_str, "hourly": "temperature_2m,relative_humidity_2m,wind_speed_10m,precipitation,weather_code", "timezone": "Asia/Shanghai", } try: r = httpx.get(url, params=params, timeout=30) r.raise_for_status() ``` The coordinates passed to this function originate from activity data: ```python aid = act.get("activityId") lat = act.get("startLatitude") lon = act.get("startLongitude") if not lat or not lon: lat = cfg["location"]["latitude"] lon = cfg["location"]["longitude"] ``` ### Technical Analysis For each detailed activity, the Skill sends the exact Garmin activity-start latitude and longitude to Open-Meteo. It also sends the activity date and subsequently selects weather for the activity hour. Weather enrichment is part of the declared functionality, so some network access is expected. However, transmitting exact activity-start coordinates exceeds the precision generally required for historical weather. Coarse coordinates, a configured city, or a nearby weather grid point would normally provide sufficient accuracy. Because the values are sent as HTTPS query parameters, they may also appear in service-side request logs and some network monitoring systems. Repeated queries can expose recurring training locations, likely home areas, travel history, and workout schedules. ### Attack Path 1. The Skill authenticates to Garmin and retrieves activities. 2. ` ...[truncated 838 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Require explicit opt-in before sending activity-derived coordinates to Open-Meteo. 2. Round coordinates before transmission, for example to one decimal place or an equivalent coarse weather grid. 3. Use the configured city coordinates by default instead of exact activity-start coordinates. 4. Add an option such as `--no-weather-network` for fully local processing. 5. Cache weather by coarse grid cell and hour to minimize repeated disclosures. 6. Explain before execution that coordinates, dates, and times will be sent to Open-Meteo. 7. Avoid logging complete request URLs containing coordinates. 8. If precise weather is essential, document why the selected precision is necessary and provide a user-controlled precision setting. ]]>

other

Warning
Location
scripts/generate_report.py:680
Finding
Generated Report Makes an Inaccurate Third-Party Upload Claim<![CDATA[ ## Vulnerability Details **File Location**: `scripts/generate_report.py:680-685` **Vulnerability Type**: Misleading privacy disclosure **Risk Level**: Medium ### Vulnerable Code ```html <footer class="footer"> Data source: <b>Garmin Connect</b> + <b>Open-Meteo</b>.<br> Pace calculations use moving duration.<br> Generated at {meta['fetched_at']} · The report is stored locally and no data was uploaded to a third party. </footer> ``` The source file renders the equivalent assertion while the fetch pipeline sends coordinates and dates to Open-Meteo through `httpx.get()`. ### Technical Analysis It is accurate that the resulting HTML report is written locally. It is not accurate to state that no data was uploaded to a third party. During data collection, the Skill sends activity-derived latitude, longitude, date, and time context to Open-Meteo. The footer mentions Open-Meteo as a data source but does not state that user-derived location and temporal data are transmitted to that service. The affirmative claim that no data was uploaded can therefore cause users to misunderstand the actual data flow. This is particularly significant because the report contains a visible privacy indicator suggesting local-only handling. ### Attack Path 1. A user runs the fetch process expecting local-only handling. 2. The fetch process sends activity coordinates and dates to Open-Meteo. 3. The report generator creates an HTML file containing a no-third-party-upload assurance. 4. The user relies on that assurance when storing, sharing, or continuing to use the Skill. 5. The user is deprived of an informed opportunity to disable or limit the location disclosure. ### Impact Assessment This issue does not independently grant system privileges. Its impact is loss of informed consent and inaccurate privacy expectations concerning sensitive location data. The misleading statement can also increase organizational compliance risk where health or location data must not ...[truncated 73 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the assertion that no information was uploaded to a third party. 2. Replace it with an accurate statement such as: “The report file is stored locally. When weather enrichment is enabled, coarse location and activity date/time are sent to Open-Meteo.” 3. Keep the wording synchronized with the actual implementation through automated tests. 4. Disclose the recipient, transmitted fields, purpose, retention assumptions, and available opt-out controls. 5. Distinguish clearly between local report storage and network processing performed during data collection. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/fetch_data.py:505
Finding
Sensitive Health and GPS Records Are Persisted in Plaintext with Excessive Raw Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/fetch_data.py:505-512, 750-765` **Vulnerability Type**: Plaintext sensitive-data storage and excessive retention **Risk Level**: High ### Vulnerable Code The complete training-status response is retained inside the normalized result: ```python out = { "status": None, "status_phrase": None, "acute_load": None, "chronic_load": None, "acwr": None, "acwr_status": None, "load_ratio": None, "vo2max": None, "load_balance": None, "raw": ts, } ``` The final payload includes configuration, activity, health, and recovery records and is written as ordinary plaintext JSON: ```python payload = { "meta": { "start": start_date, "end": end_date, "fetched_at": time.strftime("%Y-%m-%d %H:%M:%S"), "source": "Garmin Connect (garminconnect)", "timezone": "Asia/Shanghai", "days": (end_d - start_d).days + 1, }, "config": cfg, "athlete": athlete, "training_status": tstatus, "activities": activities, "daily": daily, } out_path.parent.mkdir(parents=True, exist_ok=True) out_path.write_text( json.dumps(payload, ensure_ascii=False, indent=2, default=str), encoding="utf-8", ) ``` ### Technical Analysis The generated JSON contains sensitive data including GPS coordinates, activity times, sleep measurements, HRV, resting heart rate, stress, Body Battery, weight, body-fat information, training readiness, race goals, and profile information. The code also retains the complete raw Garmin training-status response under `training_status.raw`, even though normalized fields are already extracted. Raw responses may contain undocumented fields or identifiers not required to generate the report. `Path.write_text()` creates a plaintext file using permissions determined by the process umask. The code does not explicitly enforce owner-only access. `.gitignore` reduces accidental Git commits but does not protect against local users, malware, cloud ...[truncated 1208 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `training_status.raw` unless a user explicitly enables diagnostic collection. 2. Apply data minimization and persist only fields required by report generation. 3. Create output files with owner-only permissions: - use `os.open()` with mode `0o600`; or - create the file securely and then call `chmod(0o600)` on supported systems. 4. Warn users before writing GPS and health data to a custom `--out` path. 5. Support encryption at rest using an OS key store or user-provided encryption key. 6. Add configurable retention and a secure deletion workflow. 7. Separate location data from general metrics where possible. 8. Provide a redacted export mode that removes coordinates, names, activity identifiers, and detailed recovery metrics. 9. Continue excluding output from Git, but clarify that `.gitignore` is not an access-control mechanism. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:24
Finding
Dependency Installation Instructions Use Unlocked Packages<![CDATA[ ## Vulnerability Details **File Location**: `README.md:24-27, 93-96`; `SKILL.md:76` **Vulnerability Type**: Unlocked third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```bash pip install garminconnect==0.3.11 httpx requests ``` ### Technical Analysis Only `garminconnect` is pinned to a specific version. `httpx` and `requests` are unconstrained, and no lock file or package hashes are supplied. Their transitive dependencies are also left to the package resolver. This does not prove that any currently named package is malicious. The weakness is that installation is non-reproducible and trusts whatever versions the active Python package index and resolver provide at installation time. Python package installation may execute build backends and other package-controlled code. A compromised upstream release, malicious package-index configuration, dependency takeover, or future incompatible version could therefore affect the machine running the Skill. ### Attack Path 1. A user follows the documented `pip install` command. 2. `pip` queries the configured package index and resolves the latest acceptable `httpx`, `requests`, and transitive dependencies. 3. An attacker compromises a future release, a dependency, the configured index, or name resolution within an internal package environment. 4. The malicious package or build backend executes during installation or import. 5. It runs with the privileges of the user installing or executing the Skill. 6. Because the Skill handles Garmin credentials and tokens, malicious dependency code could read and exfiltrate them. ### Impact Assessment A successful supply-chain compromise can execute arbitrary code with the installing user's privileges. This may expose Garmin credentials, cached authentication tokens, generated GPS and health records, and other files accessible to that user. The direct evidence establishes unsafe dependency locking rather than a known malicious package. The e ...[truncated 102 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a version-controlled, fully pinned requirements lock file. 2. Include cryptographic hashes and recommend installation with: ```bash pip install --require-hashes -r requirements.lock ``` 3. Pin transitive dependencies through a reproducible tool such as `pip-tools`, Poetry, or `uv`. 4. Use an isolated virtual environment rather than installing into a shared interpreter. 5. Document the expected package index and recommend disabling unintended extra indexes. 6. Add automated dependency vulnerability and provenance scanning. 7. Review and update the lock file through a controlled process rather than resolving mutable versions during end-user installation. 8. Remove `requests` if it is not directly needed by project code and is not a required runtime dependency of the pinned Garmin client. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (44)

Credential Access

High
Category
Privilege Escalation
Content
# 凭据(永远不要提交)
.env
*.env

# Garmin OAuth token 缓存
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
# 凭据(永远不要提交)
.env
*.env

# Garmin OAuth token 缓存
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
├── LICENSE                        MIT
├── config.example.json            配置模板(入库)
├── config.json                    个人档案(**不入库**)
├── .env                           凭据(**不入库**)
├── .garth/                        token 缓存(**不入库**)
├── scripts/
│   ├── garmin_client.py           凭据解析 + 登录 + 限流重试
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The declared description promises a full-featured Garmin training analytics workflow. However, the provided code chunk contains only what appears to be a bundled Chart.js library placeholder/source map reference. That is merely a generic supporting visualization dependency, not evidence of the described end-user functionality. Since the actual supplied code does not demonstrate the primary declared purpose or capabilities, the description does not accurately represent this code chunk.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
该代码块的实际用途是一个狭义的“热适应评价”辅助模块,主要负责热环境相关指标和跨日适应信号计算,属于声明中“热适应评价”能力的一小部分实现。但声明描述的是一个覆盖 Garmin 数据抓取、负荷恢复分析、天气融合和完整 HTML 报告生成的全景训练分析技能。两者在主要目的和实现范围上明显不一致。此外,代码注释明确写的是“COROS 训练 + Open-Meteo 天气”,与声明中的 Garmin Connect 来源也不一致。虽然热适应是声明功能的一部分,但仅凭该代码块无法支持整体声明,因此应判定为描述与行为不匹配。

Ae1

High
Category
analysis-evasion
Content
$PY scripts/generate_report.py
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
$PY scripts/generate_report.py
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
$PY scripts/generate_report.py
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
$PY scripts/generate_report.py
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
`assets/chart.umd.min.js`(Chart.js 4.4.4,205 KB)在生成时内联进 HTML,
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Credential Access

High
Category
Privilege Escalation
Content
├── SKILL.md                       本文件
├── README.md                      人类可读说明
├── config.json                    运动员档案 / 目标 / 坐标
├── .env                           凭据(不入库)
├── .garth/                        token 缓存(不入库)
├── scripts/
│   ├── garmin_client.py           凭据解析 + 登录 + safe_call 限流重试
Confidence
96% confidence
Finding
The skill documents direct use of a local .env file for Garmin credentials and a .garth token cache, plus auto-discovery of reusable credentials from other installed skills. This is dangerous because it normalizes credential harvesting across skill directories and expands the blast radius of a compromise: one skill can access secrets intended for another, and cached tokens may enable account access without re-authentication.

Credential Access

High
Category
Privilege Escalation
Content
凭据来源优先级:
  1. 环境变量 GARMIN_EMAIL / GARMIN_PASSWORD / GARMIN_IS_CN
  2. 本 skill 根目录的 .env
  3. 已安装的其他 skill 的 .env(如 run-coach__skillhub,自动发现,零配置复用)

token 缓存目录:本 skill 根目录的 .garth(与 run-coach 相互独立,互不覆盖)。
Confidence
96% confidence
Finding
The documented credential source order includes reading secrets from other installed skills for 'zero-config reuse,' which is an explicit credential access capability beyond what is necessary for this skill's stated purpose. In this context, the skill analyzes Garmin data; it does not need to harvest or silently inherit secrets from sibling skills to function safely.

Credential Access

High
Category
Privilege Escalation
Content
SKILL_ROOT = Path(__file__).resolve().parent.parent
GARTH_HOME = str(SKILL_ROOT / ".garth")
ENV_FILE = SKILL_ROOT / ".env"

# 自动发现的其他 .env 位置(按优先级)
FALLBACK_ENV_FILES = [
Confidence
78% confidence
Finding
This line defines the local .env path and is not dangerous by itself, but within the broader module it is part of a secret-loading mechanism that handles plaintext credentials. The actual security concern is the surrounding design that reads .env secrets, especially from external skill directories.

Credential Access

High
Category
Privilege Escalation
Content
GARTH_HOME = str(SKILL_ROOT / ".garth")
ENV_FILE = SKILL_ROOT / ".env"

# 自动发现的其他 .env 位置(按优先级)
FALLBACK_ENV_FILES = [
    Path.home() / ".workbuddy" / "skills" / "run-coach__skillhub" / ".env",
    Path.home() / ".workbuddy" / "skills" / "coros-mcp-energy-lab__skillhub" / ".env",
Confidence
99% confidence
Finding
This section introduces a list of fallback .env locations in other skill directories, enabling direct access to credentials outside this skill's boundary. That is a concrete secret-discovery behavior and materially increases the chance of unauthorized credential use if the skill is installed or modified maliciously later.

Credential Access

High
Category
Privilege Escalation
Content
# 自动发现的其他 .env 位置(按优先级)
FALLBACK_ENV_FILES = [
    Path.home() / ".workbuddy" / "skills" / "run-coach__skillhub" / ".env",
    Path.home() / ".workbuddy" / "skills" / "coros-mcp-energy-lab__skillhub" / ".env",
]
Confidence
99% confidence
Finding
This hard-coded path targets another installed skill's .env file for credential extraction. Such cross-directory secret access is unnecessary for ordinary Garmin report generation and meaningfully increases exposure of stored credentials.

Credential Access

High
Category
Privilege Escalation
Content
# 自动发现的其他 .env 位置(按优先级)
FALLBACK_ENV_FILES = [
    Path.home() / ".workbuddy" / "skills" / "run-coach__skillhub" / ".env",
    Path.home() / ".workbuddy" / "skills" / "coros-mcp-energy-lab__skillhub" / ".env",
]
Confidence
99% confidence
Finding
This line adds a second sibling skill .env file as a credential source, reinforcing a pattern of unauthorized cross-skill secret harvesting. The repeated fallback logic shows this is deliberate design rather than incidental behavior.

Natural-Language Policy Violations

Medium
Confidence
78% confidence
Finding
The natural-language instructions are entirely in Chinese, and the file does not indicate that the skill is China-specific only or that users may choose another language. Under the policy, forcing a specific language without opt-in can be a locale/language policy violation unless the restriction is documented and justified.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The README explicitly describes collecting, normalizing, and storing highly sensitive fitness and health data such as HRV, resting heart rate, sleep, Body Battery, GPS-linked workouts, and recovery metrics, but does not present a clear privacy warning, retention policy, or handling guidance at the point of collection. In this skill context, the generated JSON/HTML outputs and local caches materially increase privacy risk because they may expose health inferences and location history if the workstation, skill directory, or backups are accessed by others.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill describes capabilities that involve environment-variable access, reading/writing local files, network access, and shell execution, but it does not declare any explicit tool scope or permission boundaries. This creates an over-privileged integration risk: an agent may invoke the skill with broader access than users expect, including access to credentials, cached tokens, and generated reports containing sensitive health data.

Vague Triggers

Medium
Confidence
95% confidence
Finding
The trigger phrases are broad enough that the skill may activate on generic fitness-analysis requests, causing unnecessary access to Garmin credentials and personal health/training data. In a privacy-sensitive skill, over-broad invocation increases the chance of unintended data collection or report generation beyond what the user explicitly requested.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The skill explicitly uses Garmin credentials and collects sensitive personal health/training information including HRV, sleep, readiness, body battery, and location-linked activities, but it does not present a clear user-facing privacy warning or consent model. This is dangerous because users may not realize the full scope of personal and potentially regulated data being accessed, cached, and written into local JSON/HTML outputs.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The 'When to Use' guidance includes broad activation conditions such as any request involving Garmin data retrieval and visualization, which can cause the skill to be selected in ambiguous situations. Because the skill processes highly sensitive health, location, and training data, ambiguous routing materially increases privacy and least-privilege risk.

Unbounded Output

Medium
Category
Output Handling
Content
* https://github.com/kurkle/color#readme
 * (c) 2023 Jukka Kurkela
 * Released under the MIT License
 */function _t(t){return t+.5|0}const yt=(t,e,i)=>Math.max(Math.min(t,i),e);function vt(t){return yt(_t(2.55*t),0,255)}function Mt(t){return yt(_t(255*t),0,255)}function wt(t){return yt(_t(t/2.55)/100,0,1)}function kt(t){return yt(_t(100*t),0,100)}const St={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,A:10,B:11,C:12,D:13,E:14,F:15,a:10,b:11,c:12,d:13,e:14,f:15},Pt=[..."0123456789ABCDEF"],Dt=t=>Pt[15&t],Ct=t=>Pt[(240&t)>>4]+Pt[15&t],Ot=t=>(240&t)>>4==(15&t);function At(t){var e=(t=>Ot(t.r)&&Ot(t.g)&&Ot(t.b)&&Ot(t.a))(t)?Dt:Ct;return t?"#"+e(t.r)+e(t.g)+e(t.b)+((t,e)=>t<255?e(t):"")(t.a,e):void 0}const Tt=/^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/;function Lt(t,e,i){const s=e*Math.min(i,1-i),n=(e,n=(e+t/30)%12)=>i-s*Math.max(Math.min(n-3,9-n,1),-1);return[n(0),n(8),n(4)]}function Et(t,e,i){const s=(s,n=(s+t/60)%6)=>i-i*e*Math.max(Math.min(n,4-n,1),0);return[s(5),s(3),s(1)]}function Rt(t,e,i){const s=Lt(t,1,.5);let n;for(e+i>1&&(n=1/(e+i),e*=n,i*=n),n=0;n<3;n++)s[n]*=1-e-i,s[n]+=e;return s}function It(t){const e=t.r/255,i=t.g/255,s=t.b/255,n=Math.max(e,i,s),o=Math.min(e,i,s),a=(n+o)/2;let r,l,h;return n!==o&&(h=n-o,l=a>.5?h/(2-n-o):h/(n+o),r=function(t,e,i,s,n){return t===n?(e-i)/s+(e<i?6:0):e===n?(i-t)/s+2:(t-e)/s+4}(e,i,s,h,n),r=60*r+.5),[0|r,l||0,a]}function zt(t,e,i,s){return(Array.isArray(e)?t(e[0],e[1],e[2]):t(e,i,s)).map(Mt)}function Ft(t,e,i){return zt(Lt,t,e,i)}function Vt(t){return(t%360+360)%360}function Bt(t){const e=Tt.exec(t);let i,s=255;if(!e)return;e[5]!==i&&(s=e[6]?vt(+e[5]):Mt(+e[5]));const n=Vt(+e[2]),o=+e[3]/100,a=+e[4]/100;return i="hwb"===e[1]?function(t,e,i){return zt(Rt,t,e,i)}(n,o,a):"hsv"===e[1]?function(t,e,i){return zt(Et,t,e,i)}(n,o,a):Ft(n,o,a),{r:i[0],g:i[1],b:i[2],a:s}}const Wt={x:"dark",Z:"light",Y:"re",X:"blu",W:"gr",V:"medium",U:"slate",A:"ee",T:"ol",S:"or",B:"ra",C:"lateg"
...[truncated 28 chars]
Confidence
75% confidence
Finding
Output size or generation rate is not bounded. Unbounded output enables denial-of-service through resource exhaustion, log flooding, or context-window stuffing.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
This code file contains natural-language documentation and user-facing strings entirely in Chinese, including the module docstring and training advice text. Under the policy, forcing a specific language without user opt-in is a locale/language policy violation unless the regional constraint is explicitly justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code file contains natural-language documentation and output labels entirely in Chinese, and exported helpers such as `status_zh`, `load_balance_zh`, and `readiness_label` return Chinese-only text. Under the policy rule, forcing a specific language without offering a locale choice is a natural-language policy violation.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/generate_report.py:832