Cover TSCM sweep metadata/cleared-devices/ignore-list/report category
filter features and the ADS-B Postgres password fix. Updates the
in-app dashboard changelog (config.py), CHANGELOG.md, and the GitHub
Pages TSCM feature description.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
setup.sh wrote/read the local Postgres wizard password under
INTERCEPT_ADSB_DB_PASS, but config.py and docker-compose.yml expect
INTERCEPT_ADSB_DB_PASSWORD — any custom password set via the wizard
was silently ignored. Also make docker-compose actually honor
INTERCEPT_ADSB_DB_PASSWORD instead of hardcoding "intercept" for both
the app and Postgres containers, and correct a misleading .env.example
comment about admin password auto-generation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
First-time run of ruff-format via pre-commit hook normalises quote
style, trailing commas, and whitespace across 188 Python files.
No logic changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes 4 linting errors that were failing CI:
- Remove unused `shutil` import from bin/import_artemis.py
- Sort/format import blocks in routes/signalid.py and
tests/test_signalid_match_route.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Four new features requested by TSCM users:
- Site/Location and Examiner name fields appear at the top of the
sweep config; both are embedded in HTML and PDF/annex reports.
- Mark Cleared button on every live device item dims the entry with a
CLEARED badge and excludes it from generated reports. Cleared state
resets at the start of each new sweep. The report executive summary
shows a count of cleared devices.
- Ignore List stores the examiner's own devices persistently in
localStorage. Ignored devices are filtered from the live display and
all report exports. An Ignore button appears on every device item;
the sidebar Examiner Ignore List section shows current entries with
per-item removal and a clear-all button.
- Site/examiner params forwarded to PDF and annex server routes so
the text report header includes them.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove docs/plans/, docs/specs/, and docs/design/ from tracking and
add them to .gitignore. History also purged of instance/intercept.db
(user auth DB accidentally committed in January).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Users can now choose which risk categories to include in generated
reports — High Interest, Needs Review, and Informational — via three
checkboxes that appear after a sweep completes. Applies to the HTML
report, PDF, JSON annex, and CSV annex. Defaults to High Interest +
Needs Review (Informational excluded) to keep reports concise.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bump version to 2.28.0, update changelog, and add Signal ID to the
GitHub Pages feature listing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Imports 574 signals from AresValley/Artemis-DB (v73) into data/signals.json,
growing the bundled offline database from 20 to 594 signals. Adds
bin/import_artemis.py to refresh the database when Artemis-DB releases updates.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Added signal-id-modal.js script to base_dashboard.html (nav button was silent on dashboard pages)
- Added else branch to clear "Searching…" status when zero matches returned
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removed unused `import pytest` from line 5. The file uses no pytest
fixtures, marks, or raises, making this import dead code and causing
an F401 lint violation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements lazy-cached load_signals() and pure match_signals() with
frequency/bandwidth/modulation/region scoring for the signal ID feature.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Create data/signals.json with 20 seed signals (FM broadcast, airband,
ISM bands, maritime VHF, AIS, ACARS, ADS-B, POCSAG, cellular, WiFi/BT,
amateur radio, DAB, PMR446, FRS/GMRS, NOAA weather radio). Point
frequencies adjusted to ±500 Hz windows; fixed-value bandwidth_ranges
widened to strict min < max windows required by schema.
Add tests/test_signals_json.py with 9 schema validation tests covering
id uniqueness, required string fields, frequency range validity,
bandwidth range, modulation casing, categories, region codes, and
sigidwiki URLs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix _pollUntilConnected overwriting real error with generic timeout
message — stop polling once backend reaches error state
- Fix battery % calculation: was battery_mv/42 (71% at empty); now
(battery_mv-3000)/12 for a proper 0-100% LiPo curve
- Improve auto-detect: scan available ports rather than blindly using
/dev/ttyUSB0; update label to show fallback so users know what to expect
- Add port refresh button (↻) — previously required switching modes
and back if device was plugged in after panel opened
- Add baud rate selector to serial config strip (default 115200,
options up to 921600) and wire it through to the connect request
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The body > *:not(#bg-canvas) rule carried ID-level specificity (1,0,1)
which overrode .lightbox's position:fixed and z-index:1000, leaving the
overlay stuck in document flow and invisible. Excluding #lightbox from
that rule lets the lightbox CSS take effect correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reverts the <a target="_blank"> wrappers added previously — those were
opening images in a new tab and interfering with the existing lightbox.
Images now click-to-expand via the overlay lightbox as intended.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The system metrics collector daemon thread ran vcgencmd via subprocess
every 3s even on non-Pi hosts, where it always failed — and leaked
Popen calls into any later test mocking subprocess (intermittent
test_weather_sat_decoder failure in full-suite runs).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
confidence_boost and the manufacturer-data-length signal applied without
any identifying indicator match, giving every device a phantom AirTag
baseline (a 22+ byte payload from any vendor scored 0.30 and was flagged
as an AirTag). Both now require a matched indicator, mirroring the
score>0 gating already used in _check_generic_tracker_indicators.
Name-pattern weight raised 0.15 -> 0.30 so a device advertising a known
tracker name yields a LOW-confidence detection, consistent with the
TSCM BLE scanner's name-only detection and the engine docstring.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bluetooth aggregator/api/heuristics tests updated to current behavior;
deauth detector integration test rewritten to exercise the tracker and
alert path directly instead of patching __globals__ (read-only on
Python 3.14).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Matches the agent's established try/except import convention; the
agent now starts and reports empty capabilities when utils.capabilities
(or its dependency chain) is unavailable.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Caught by test_dependency_files_integrity, which had been buried in the
never-reached tail of the test suite.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Phase 5 decision gate of the architecture refactor plan: dedicated
dashboard pages are the pattern for map-centric modes; APRS and
Meshtastic migrations to follow under separate plans.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
detect_mode_availability accepts a pre-computed dep_status so the agent
probes once; interface and fallback paths now have content-level tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
utils/capabilities.py now owns interface detection and mode
availability; the agent delegates via detect_interfaces() and
detect_mode_availability(). The agent keeps config gating and
tool_details population to preserve its result shape exactly.
The moved fallback path uses utils.dependencies.check_tool instead of
the agent's old shutil.which fallback; check_tool also searches
Homebrew paths, a strict superset (strictly better detection).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A failing mode init now logs instead of aborting the remainder of
switchMode (deliberate hardening; previously an exception skipped
title/visuals updates).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
requests/urllib3 collapse dot segments before sending, so traversal
like wifi/v2/../../x escaped the prefix allowlist. Only canonical
paths are now forwarded; regression tests included.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removes the one-off proxy_wifi_clients route and the dead getApiBase()
helper; the allowlisted passthrough now covers agent wifi traffic.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removes the agent's own CelesTrak download (the source of the stray
gp.php artifact) — the store is now the single TLE source for app and
agent alike.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Both silently fell back to static bundled TLEs after the removal of
routes.satellite._tle_cache.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
_resolve_satellite_request now operates on a caller-provided dict and
accumulates write-backs, flushed once per request behind a guard —
avoids per-satellite full-dict copies and store-cache thrash, and a
transient DB error can no longer fail a read request.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
data/satellites.py is no longer rewritten at runtime; it remains as
the read-only seed for the store.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- busy_timeout so concurrent app+agent writers wait instead of raising
- seed from _connect() so update-before-first-read can't drop the seed
- regression tests: seed ordering, concurrent writer, default DB path
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- document str defaults / bytes for binary-mode callers
- wire __exit__ to False so exceptions are not suppressed
- exercise exited-process path through subprocess.run
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>