- Updated TODO.md with the latest status and coverage metrics. - Added date and datetime adapters for SQLite in db_manager.py to improve date handling. - Refactored repeater_manager.py to ensure atomic database operations within transactions, enhancing data integrity. - Implemented CSRF protection and security headers in web_viewer/app.py to safeguard against cross-origin requests and improve response security. - Enforced authentication for non-loopback interface binding in web_viewer/integration.py to prevent unauthorized access. These changes enhance the overall security, reliability, and maintainability of the application.
25 KiB
TODO
Task list for meshcore-bot development. Auto-updated sections are regenerated
by running python scripts/update_todos.py (see Auto-Update).
Last updated: 2026-03-29 — coverage at 36.86% (2,139 passed / 29 skipped); fail_under=35; target 40%; 25 PR branches pushed to KG7QIN fork (PRs #122–#124 open against agessaman:dev); CI matrix fixed (Python 3.9 removed, ruff/mypy/ShellCheck all green)
In Progress
-
TASK-14: Push test coverage to ≥40% (currently 36.72%, 2,140 passed / 29 skipped;
fail_under=35; hardware-dependent modules cap realistic ceiling at ~40–42%)- (2026-03-15)
tests/test_enums.py— enum values and flag combinations - (2026-03-15)
tests/test_models.py— MeshMessage dataclass - (2026-03-15)
tests/test_transmission_tracker.py— full TransmissionTracker - (2026-03-15)
tests/test_message_handler.py— path parsing, cache, message routing - (2026-03-15)
tests/test_repeater_manager.py— role detection, ACL, device type - (2026-03-15)
tests/test_core.py— config loading, radio settings, reload - (2026-03-15)
tests/test_feed_manager.py— queue insert, deduplication via feed_activity, interval due-check - (2026-03-15)
tests/test_scheduler_logic.py— scheduled message dispatch, interval advertising setup - (2026-03-15)
tests/test_command_manager.py— full command dispatch, keyword matching - (2026-03-15)
tests/test_channel_manager_logic.py— cache lifecycle, fetch-all, sorted cache, connectivity guard - (2026-03-16)
tests/test_channel_manager.py— generate_hashtag_key, cache lookups, add_channel validation (47 tests) - (2026-03-16)
tests/test_web_viewer.py— 19 new tests for stream_data, update_channel, maintenance status (220 total) - (2026-03-16) Fixed failing
test_weekly_on_wrong_day_does_not_run— was patchingnowinstead offake_now
TASK-14 sub-tasks — prioritized target list (2026-03-16 coverage scan):
Tier 1 — High impact, core logic:
- T1-A: Realtime viewer panels blank bug — FIXED (third pass: root cause was
<script type="module">creating a competing Socket.IO manager; fixed by converting to regular<script>with dynamicimport(), removingforceNew: truefrom base.html, raisingping_timeout5→20 s, and adding missingsubscribed_messageskey) - T1-B:
message_handler.py— extended (139 total tests);decode_meshcore_packet,parse_advert, RF correlation,_get_path_from_rf_data,handle_rf_log_data; BUG-028 discovered (byte_dataUnboundLocalError in except handler) - T1-C:
repeater_manager.py— extended (131 total tests);track_contact_advertisement,_track_daily_advertisement,_determine_device_typegaps,_auto_purge_repeaters,_get_companions_for_purging - T1-D:
scheduler.py— extended (106 total tests);_get_mesh_info,_send_scheduled_message_async,_run_data_retention,_collect_email_stats - T1-E:
feed_manager.py— partially done; polling loop still needed - T1-F:
web_viewer/app.py(41%, ~2,269 uncovered) — greeter, bans, packets/messages endpoints, export, SocketIO, firmware routes - T1-G:
web_viewer/integration.py— newtests/test_web_viewer_integration.py(circuit breaker, JSON serializer, packet capture, channel message)
Tier 2 — Medium impact, mostly testable:
- T2-A:
utils.py(60%, ~403 uncovered) —format_keyword_response,calculate_path_distances,get_major_city_queries - T2-B:
graph_trace_helper.py(2%, ~159 uncovered) — pure graph/trace algorithm, zero hardware deps - T2-C:
db_manager.py(54%, ~147 uncovered) —AsyncDBManagerasync methods, write queue,executemanybatch - T2-D:
discord_bridge_service.py(31%, ~239 uncovered) — message formatting, webhook dispatch, rate-limit warn - T2-E:
telegram_bridge_service.py(36%, ~195 uncovered) — message relay, topic routing, listener lifecycle - T2-F:
greeter_command.py(15%, ~557 uncovered) — greeting detection, per-channel greetings, new-contact detection - T2-G:
rate_limiter.py— extended to 98%; only actual sleep lines remain - T2-H:
stats_command.py— extended (66 total tests);_get_adverts_leaderboard,get_stats_summary,cleanup_old_stats, exception paths, data-populated leaderboards (61% coverage) - T2-I:
i18n.py— newtests/test_i18n.py(98% coverage); fallback loops, format failure, PermissionError, get_value break
Tier 3 — Smaller commands, good test bang-for-buck:
- T3-A:
trace_command.py— newtests/test_trace_command.py(88% coverage); path extract, parse, format inline/vertical, reciprocal, execute paths - T3-B:
announcements_command.py— newtests/test_announcements_command.py; parse, record_trigger, execute all paths - T3-C:
channels_command.py(86%, ~33 uncovered) — remaining paths - T3-D:
help_command.py— newtests/test_help_command.py; format list, channel filter, general/specific help, execute - T3-E:
aurora_command.py— newtests/test_aurora_command.py; KP index parsing, alert level logic, execute paths - T3-F:
joke_command.py— newtests/test_joke_command.py(seasonal, format, split, dark, execute) - T3-G:
dadjoke_command.py— newtests/test_dadjoke_command.py(format, split, length, execute) - T3-H:
webviewer_command.py— 100% coverage (no test file needed) - T3-I:
trace_runner.py(24%, ~50 uncovered) — trace execution, path assembly - T3-J:
earthquake_service.py(16%, ~119 uncovered) — alert threshold, message format (USGS API mockable) - T3-K:
moon_command.py— newtests/test_moon_command.py; phase calc, execute success/error - T4-A:
multitest_command.py(33%, ~220 uncovered) — multi-channel test sequences; pure logic + async - T3-L:
hacker_command.py(17%, ~101 uncovered) — text transform logic - T3-M:
sports_command.py(16%, ~325 uncovered) — score formatting, schedule display - T3-O:
repeater_command.py(10%, ~363 uncovered) — repeater list/info formatting
Tier 4 — API/hardware heavy, skip for now:
wx_command.py(6%),weather_service.py(6%),solar_conditions.py(7%),solarforecast_command.py(8%),packet_capture_service.py(5%),map_uploader_service.py(10%),airplanes_command.py(10%),aqi_command.py(11%),alert_command.py(13%),prefix_command.py(10%),packet_capture_utils.py(12%)
- (2026-03-15)
MQTT Test Framework (NEW 2026-03-16)
tests/test_mqtt_live.py— schema validation + live MQTT integration tests- Connects to LAN broker (
10.0.2.123:1883) or letsmesh (mqtt-us-v1.letsmesh.net:443/ws) - Subscribes to
meshcore/SEA/+/packets; validates packet JSON against known schema - Live tests:
pytest tests/test_mqtt_live.py -m mqtt - Offline fixture tests:
pytest tests/test_mqtt_live.py -m "not mqtt" - Collect fixtures:
python tests/test_mqtt_live.py --collect-fixtures - Auto-saves fixtures when live tests succeed (for offline fallback)
- Connects to LAN broker (
tests/mqtt_test_config.ini— broker/topic/timeout config (primary: LAN, fallback: letsmesh)tests/fixtures/mqtt_packets.json— 8 real packets from SEA region (offline fixtures)- Add packet content parser tests using fixture data (decode raw hex, validate payload types)
Planned Features
Bridges
- Two-way Discord bridge — receive messages from Discord and relay to MeshCore
- Two-way Telegram bridge — relay Telegram messages back into MeshCore channels
- Telegram
message_thread_idsupport — route bridged messages to forum topics - Bridge DM support — optional, opt-in bridging of DMs (requires consent mechanism)
Web Viewer
- (2026-03-15) Authentication —
web_viewer_passwordin[Web_Viewer]; login page + session auth + SocketIO guard - (2026-03-15) Radio reboot button — disconnect + reconnect bot-to-radio from web UI (confirmation modal, operation queue)
- (2026-03-15) Radio connect/disconnect button — toggle bot connection from web UI (live status polling via
bot_metadata) - (2026-03-15) Live packet streaming — Live Activity panel on dashboard; SocketIO packet/command/message feed; pause/clear
- (2026-03-15) Real-time message monitoring —
capture_channel_message()→packet_stream;message_dataSocketIO event; Live Channel Messages panel - (2026-03-15) Interactive contact management — star any contact type; Purge Inactive modal with threshold selector + preview
- (2026-03-15) Export functionality —
GET /api/export/contactsand/api/export/paths; CSV/JSON with time-range; Export dropdown in toolbar - (2026-03-15) Configuration tab —
/configpage; SMTP + nightly email toggle; log rotation; DB backup; stored inbot_metadata - (2026-03-15) Real-time log viewer —
/logspage; SocketIOsubscribe_logs/log_line; level-based coloring; pause/clear/filter; log tail thread; "Logs" nav link - Mobile-responsive improvements — optimize layout for small screens
- (TASK-01 2026-03-15) Remove firmware config + reboot UI — radio.html: Firmware Configuration card and Reboot Radio button removed; JS handlers removed; 4 tests added
- (TASK-02 2026-03-15) Fix realtime stream blank on load — added 50-row history replay to
subscribe_commands; fixedlast_timestamp = 0→time.time() - 300in polling thread; 5 tests added (BUG-023 fixed) - (TASK-03 2026-03-15) Dashboard: connected agents popup —
GET /api/connected_clients; count is clickable link; Bootstrap modal with client table; 5 tests added ⏸ paused 2026-03-15 20:10 — see SESSION_RESUME.md - (TASK-04 2026-03-15) DB backup dir validation on save —
POST /api/config/maintenancereturns 400 with error ifdb_backup_dirdoes not exist; inline error in config.html; 5 tests added - (TASK-06 2026-03-15) DB backup: Backup Now button —
POST /api/maintenance/backup_now; spinner + status in Config tab; 4 tests added - (TASK-07 2026-03-15) DB backup: Restore button —
POST /api/maintenance/restore;GET /api/maintenance/list_backups; SQLite magic-byte validation; modal with path input + backup list; 7 tests added - (TASK-08 2026-03-15) Database Operations: purge by age —
POST /api/maintenance/purge; keep all/1/7/14/30/60/90 days; confirmation dialog + results table; 7 tests added - (2026-03-15) (TASK-12) Dashboard live activity controls — scroll top/bottom buttons (
live-scroll-top/live-scroll-bottom); type-filter checkboxes (Packets/Commands/Messages) withdata-typeattributes;applyFilters()logic hides/shows entries; 1 test added - (2026-03-16) (TASK-13) Realtime page scroll/filter — scroll top/bottom on each stream panel;
[#channel] messageformat; type-filter checkboxes; 1 test added - (2026-03-16) (TASK-16) Fix blank realtime monitor (BUG-029) —
app.pyresolveddb_pathrelative to hardcoded code root instead of config file directory; fixed viaconfig_base = Path(config_path).parent.resolve(); subscribe replay errors elevated DEBUG→WARNING; INFO log of resolved db_path; 4 new tests inTestDbPathResolutionFromConfigDir; pre-existing mypy errors fixed inapp.pyandmesh_graph.py - (2026-03-16) (TASK-16b) BUG-029 follow-up —
config_basestored asself._config_baseinstance attribute; dead_get_db_path()removed;subscribe_logs+_start_log_tailingnow resolve viaself._config_base; realtime status badges start as "Connecting…" and update on actual SocketIO connect
Maintenance and Notifications
- (2026-03-15) Log rotation configuration —
log_max_bytes/log_backup_countin[Logging]; Config tab Log Rotation card; live-apply via scheduler - (2026-03-15) Nightly maintenance email dispatch — digest every 24h; uptime, contact counts, DB size, log error counts, rotation detection
- (2026-03-15) Pre-rotation email hook —
maint.email_attach_log = trueattaches log file (≤ 5 MB) to nightly email - (2026-03-15) DB backup scheduling —
sqlite3.Connection.backup(); daily/weekly/manual; retention pruning; Config tab Database Backup card - (2026-03-15) Maintenance task status API —
GET /api/maintenance/status; Maintenance Status card in Config tab
Commands and Features
- (2026-03-15) Inbound webhook —
POST /webhookrelays HTTP payloads to MeshCore channels/DMs; bearer token auth - (2026-03-15) Per-channel rate limiting —
ChannelRateLimiterinrate_limiter.py;[Rate_Limits] channel.<name>_seconds; checked in_check_rate_limits(channel=) - (2026-03-15) Command aliases —
[Aliases]config section injects shorthands into command keywords - (2026-03-15) Scheduled message preview —
!schedulecommand (DM-only); shows times, channels, message previews, advert interval !wxnon-US improvement — promotewx_international.pyto default with US fallback- (2026-03-15) (TASK-11) Fix help + long response truncation —
split_text_into_chunks+get_max_message_lengthinCommandManager; keyword dispatch chunks long responses viasend_response_chunked; mypy fixes across 7 modules +check_untyped_defsadded to 4 more modules (BUG-026) - (2026-03-15)
!pathgeographic scoring toggle —[Path_Command] geographic_scoring_enabled = true/falseconfig flag; no restart required
Infrastructure
- (2026-03-15) Virtual environment / Makefile —
make install/dev/test/test-no-cov/lint/fix/deb/config/clean - (2026-03-15)
ruff checkCI gate —lintjob in CI; 9262 auto-fixed, legacy patterns in ignore list - (2026-03-15)
mypystrict mode — incremental: global safe options + per-moduledisallow_untyped_defs;typecheckCI job - (2026-03-15) HTML/JS test framework —
package.json+ ESLint (eslint-plugin-html) + HTMLHint;lint-frontendCI job - (2026-03-15) ShellCheck CI gate —
lint-shelljob checks all.shfiles at--severity=warning - (2026-03-15) Database migration versioning —
MigrationRunner; 5 numbered migrations;schema_versiontable - (2026-03-15) Docker multi-arch build —
linux/amd64+linux/arm64+linux/arm/v7; SBOM + provenance - (2026-03-15) Structured JSON logging —
json_logging = truein[Logging];_JsonFormatter; Loki/ES/Splunk compatible - (2026-03-15) aiosqlite async DB —
AsyncDBManagerindb_manager.py;bot.async_db_managerin core;aiosqlite>=0.19.0dep - (2026-03-15) .deb packaging —
scripts/build-deb.sh;DEBIAN/control/postinst/prerm/postrm; systemd unit;make deb - (2026-03-15) ncurses config TUI —
scripts/config_tui.py; browse/edit/save; validate; migrate from example;make config;rrename key,aadd key,d/Delete remove key; dynamic sections suppress?marker - (2026-03-15) APScheduler migration —
BackgroundScheduler+CronTrigger; replacesschedulelib - (2026-03-15) Rate-limiter observability —
GET /api/stats/rate_limiters; exposes stats for all 4 limiter types - (2026-03-15) Map uploader configurable interval —
min_reupload_intervalin config (fallback 3600 s) - (2026-03-15) Per-channel greeter messages —
channel_greetings/per_channel_greetingsconfig keys - (2026-03-15) Radio firmware config UI — Migration 6 (
payload_data);firmware_read/firmware_writeop types;POST /api/radio/firmware/config/read|write; Firmware Configuration card in web UI - (2026-03-15) Werkzeug WebSocket fix —
_apply_werkzeug_websocket_fix()patchesSimpleWebSocketWSGI.__call__at import time; 5 tests - (2026-03-15) pytest-timeout runaway prevention —
pytest-timeout>=2.1.0;timeout=30per test;asyncio_mode="auto" - (2026-03-15) SMTP timeout —
SMTP/SMTP_SSLconstructed withtimeout=30; nightly email never hangs - (2026-03-15) Real-time monitoring history replay —
subscribe_packets/subscribe_messages/subscribe_logsreplay last 50/50/200 items on connect - Coverage threshold enforcement —
fail_under=35(raised 2026-03-16); raise to 40 once 40% confirmed; target 40% (TASK-14) - (TASK-09 2026-03-15) Message processing performance — write queue + background drain thread; per-packet
sqlite3.connect()eliminated;executemanybatch insert every 0.5s; shutdown flushes remaining rows; 6 tests added - (TASK-05 2026-03-15) Fix DB backup scheduler interval guard —
last_db_backup_runnow updated after each call; added 2-min fire window (won't trigger on late startup); seeds last-run from DB on restart; 8 tests added (BUG-024 fixed) - (TASK-00) Fix meshcore IndexError crash — asyncio exception handler for
IndexErrorfrom meshcore parser (BUG-022) ⏸ paused 2026-03-15 19:19 — see SESSION_RESUME.md - (TASK-10 2026-03-15) Retry
no_event_receivedchannel sends —_is_no_event_received()helper + retry loop insend_channel_message(max 2 retries, 2s delay); 5 tests added (BUG-025 fixed) - (TASK-INFRA 2026-03-15) Context checkpoint system —
scripts/context_checkpoint.sh,scripts/post_tool_counter.sh,.claude/hooks.json; cron every 15 min
Backlog
- Evaluate moving web viewer to a separate installable package
- Repeater auto-purge dry-run mode — log what would be purged without acting
- Feed manager: add support for JSON API feeds (not just RSS/Atom)
- Mobile-responsive web viewer improvements — optimize layout for small screens
Recently Completed
-
(2026-03-17) PR split — 22 logical PR branches created from
dev-kg7qin-changescommits and pushed toKG7QIN/meshcore-bot; stacked onpr-base(upstream/dev + 2 catch-up commits); each targetsagessaman/meshcore-bot:dev -
(2026-03-17) Alias refactor — aliases moved from global
[Aliases]config section to per-commandaliases =key in each command's own section; loaded byBaseCommand._load_aliases_from_config()at startup;CommandManager.load_aliases()and_apply_aliases()removed -
(2026-03-17) Discord bridge test fix —
test_discord_bridge_multi_webhooks.pyassertions corrected:ConfigParserlowercases all keys sobridge.Publicstores as"public"; test expectations updated to match actual (correct) lowercase key behaviour -
(2026-03-15) Radio firmware config UI — Migration 6 (
payload_data);firmware_read/firmware_writeop types;POST /api/radio/firmware/config/read|write; Firmware Configuration card (path.hash.mode + loop.detect) -
(2026-03-15) APScheduler migration —
BackgroundScheduler+CronTrigger; removesschedulelib dependency -
(2026-03-15) Rate-limiter observability —
GET /api/stats/rate_limiters; all 4 limiter types exposed -
(2026-03-15) Map uploader configurable interval —
min_reupload_intervalconfig key (fallback 3600 s) -
(2026-03-15) Per-channel greeter messages —
channel_greetings/per_channel_greetingsconfig keys -
(2026-03-15)
!pathgeographic scoring toggle —[Path_Command] geographic_scoring_enabled = true/false; tests intest_path_geo_toggle.py -
(2026-03-15) Real-time monitoring history replay — last 50/50/200 items replayed on
subscribe_packets/subscribe_messages/subscribe_logs -
(2026-03-15) Werkzeug WebSocket fix —
_apply_werkzeug_websocket_fix()patchesSimpleWebSocketWSGI.__call__; 5 tests -
(2026-03-15) Radio reboot firmware command — sends
meshcore.commands.reboot()before disconnect; 8 s wait; 10 s disconnect timeout -
(2026-03-15) pytest-timeout —
pytest-timeout>=2.1.0;timeout=30per test;asyncio_mode="auto" -
(2026-03-15) SMTP timeout —
timeout=30on allSMTP/SMTP_SSLconstructors; nightly email no longer hangs -
(2026-03-15) Per-channel rate limiting —
ChannelRateLimiter;[Rate_Limits]config section; integrated into_check_rate_limitsandsend_channel_message -
(2026-03-15) Real-time log viewer —
/logspage; SocketIOsubscribe_logs/log_line; log tail background thread; "Logs" nav link; toggle from/realtime -
(2026-03-15) HTML/JS test framework —
package.json, ESLint +eslint-plugin-html, HTMLHint;lint-frontendCI job -
(2026-03-15) ShellCheck CI gate —
lint-shelljob; all.shfiles checked at--severity=warning -
(2026-03-15) .deb packaging —
scripts/build-deb.sh; DEBIAN control/postinst/prerm/postrm; systemd unit;make deb -
(2026-03-15) aiosqlite
AsyncDBManager—db_manager.py;aiosqlite>=0.19.0;bot.async_db_managerin core -
(2026-03-15) ncurses config TUI —
scripts/config_tui.py; read/create/edit/save/validate/migrate;make config;r/a/dkey management; dynamic-section?fix -
(2026-03-15) Makefile — added
make debandmake configtargets;cleannow removesdist/deb-build/ -
(2026-03-15) .gitignore — added
node_modules/,.npm,package-lock.json,dist/deb-build/ -
(2026-03-15) Export functionality —
GET /api/export/contacts+/api/export/paths; CSV/JSON with time-range; Export dropdown in contacts.html -
(2026-03-15) Live packet streaming — Live Activity panel in
index.html; SocketIO color-coded feed with pause/clear -
(2026-03-15) Real-time message monitoring —
capture_channel_message()→packet_stream;message_dataSocketIO event; Live Channel Messages panel -
(2026-03-15) Maintenance status API —
GET /api/maintenance/status; Maintenance Status card in Config tab -
(2026-03-15) DB backup scheduling —
scheduler._run_db_backup(); daily/weekly/manual; retention pruning; Config tab card; status inmaint.status.* -
(2026-03-15) Pre-rotation email hook —
maint.email_attach_log = trueattaches log file (≤ 5 MB) to nightly digest -
(2026-03-15) Log rotation configuration —
log_max_bytes/log_backup_countin[Logging]; Config tab card; live-apply via scheduler -
(2026-03-15) Nightly email dispatch —
_send_nightly_email()every 24h; uptime, contacts, DB size, log errors; STARTTLS/SSL/plain -
(2026-03-15) Configuration tab —
/configpage;GET/POST /api/config/notifications; SMTP settings stored asnotif.*inbot_metadata -
(2026-03-15) Interactive contact management — star all contact types;
GET /api/contacts/purge-preview+POST /api/contacts/purge; Purge Inactive modal -
(2026-03-15) Structured JSON logging —
json_logging = true;_JsonFormatter; Loki/Elasticsearch/Splunk compatible -
(2026-03-15) Radio connect/disconnect button —
GET /api/radio/status;POST /api/radio/connect; live status frombot_metadata -
(2026-03-15) Radio reboot button —
POST /api/radio/rebootqueuesradio_rebootop; scheduler callsreconnect_radio() -
(2026-03-15) Docker multi-arch — QEMU;
linux/amd64+linux/arm64+linux/arm/v7; SBOM + provenance -
(2026-03-15) mypy incremental strict mode — global safe options + per-module
disallow_untyped_defs;typecheckCI job -
(2026-03-15) ruff CI gate — clean pass;
lintCI job; 9262 auto-fixed -
(2026-03-15) Database migration versioning —
MigrationRunner; 5 numbered migrations;schema_versiontable -
(2026-03-15) Command aliases —
[Aliases]config section injects shorthands into keywords -
(2026-03-15) Inbound webhook service —
POST /webhook; bearer token auth; relay to channel or DM -
(2026-03-15) Makefile —
make install/dev/test/test-no-cov/lint/fix/clean -
(2026-03-15) Fixed BUG-001 web viewer authentication (Flask session auth, login/logout, SocketIO guard)
-
(2026-03-15) Fixed BUG-002 DB migration missing columns (channel_operations, feed_message_queue)
-
(2026-03-15) Fixed BUG-003 geocoding rate-limit skip logged at INFO with full context
-
(2026-03-15) Fixed
RepeaterManagerignoringauto_manage_contacts = false -
(2026-03-15) Fixed timezone handling in
format_elapsed_display(issue #75) -
(2026-03-15) Fixed
TraceCommandreversed path nodes and truncated return paths -
(2026-03-15) Fixed shutdown log spam after streams closed
-
(2026-03-15) Added Discord and Telegram one-way bridges
-
(2026-03-15) Added chunked message sending for rate-limit-aware large responses
-
(2026-03-15) Multi-byte prefix (2-byte) support throughout codebase
-
(2026-03-15) Added
ScheduleCommand— lists scheduled messages and advert interval (DM-only by default) -
(2026-03-15) Created 10 test modules covering enums, models, transmission_tracker, message_handler, repeater_manager, core, feed_manager, scheduler_logic, command_manager, channel_manager_logic
Auto-Update
The Inline TODOs section below is auto-generated by scanning source files for
# TODO, # FIXME, and # HACK markers. Regenerate it with:
python scripts/update_todos.py
The script also updates the **Last updated:** date at the top of this file.
Or run it as part of a pre-commit hook by adding to .pre-commit-config.yaml:
- repo: local
hooks:
- id: update-todos
name: Update TODO.md inline scan
language: python
entry: python scripts/update_todos.py
pass_filenames: false
Inline TODOs (auto-generated)
Last scanned: 2026-03-29. No
# TODO,# FIXME, or# HACKmarkers found inmodules/ortests/. Runpython scripts/update_todos.pyto refresh.