Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
45e7d98
README.md
cod3SK Mar 19, 2025
501c1e2
README.md
cod3SK Mar 19, 2025
320d997
Harden config and gate network-response endpoints
cod3SK Jun 14, 2026
c991a4a
Add API test suite and CI
cod3SK Jun 14, 2026
12aa6e6
Add ADRs and model card; expand README
cod3SK Jun 14, 2026
31faddc
Add desktop installer and clean up simulation subsystem
cod3SK Jun 14, 2026
3b605bf
Document desktop installer and fix stale wording in README
cod3SK Jun 14, 2026
b364a2a
Merge fork main; keep current README over old planning doc
cod3SK Jun 14, 2026
8c989bc
Fix killswitch to block all interfaces and remove token gate
cod3SK Jun 15, 2026
d209227
Update docs to reflect killswitch ungating and all-interface scope
cod3SK Jun 15, 2026
45071a2
Fix test suite broken by killswitch ungating
cod3SK Jun 15, 2026
ea1eca2
Surface killswitch OS failure to the frontend
cod3SK Jun 15, 2026
22f4d33
Document killswitch Docker-on-Windows limitation
cod3SK Jun 15, 2026
f451961
Refactor to Windows-native: replace Redis/RQ with ThreadPoolExecutor
cod3SK Jun 15, 2026
6c812ca
Fix flows not appearing: default to absolute SQLite path for dev
cod3SK Jun 16, 2026
e022ae3
Remove stale Redis/RQ references from spec and desktop requirements
cod3SK Jun 16, 2026
08e18b1
Add .gitignore and check_db.py debug script
cod3SK Jun 16, 2026
1e7bbe0
Add in-process capture agent with interface selection UI
cod3SK Jun 16, 2026
555c8e1
Fail fast if port 5000 is already in use at startup
cod3SK Jun 16, 2026
b7db442
Prefer system tshark over bundled copy
cod3SK Jun 16, 2026
f505604
Add UAC elevation + Npcap detection; prefer bundled tshark when admin
cod3SK Jun 16, 2026
470f28a
Add unit test suite: 84 Python + 13 frontend tests
cod3SK Jun 16, 2026
3b75176
Bundle dumpcap.exe alongside tshark to fix empty interface list
cod3SK Jun 16, 2026
5c695aa
Fix ESLint errors: empty catch blocks and unused import
cod3SK Jun 16, 2026
1e84fd9
Add dumpcap unit tests (16 tests)
cod3SK Jun 16, 2026
4611633
UI tabbed layout, installer v0.0.1, and ADR updates
cod3SK Jun 16, 2026
6774179
Add logo and wire icon into installer and exe
cod3SK Jun 16, 2026
a031057
Fix port 5000 not releasing on exit and desktop icon missing
cod3SK Jun 16, 2026
04183d8
Installer: require admin elevation, fix npm-less build, use common sh…
cod3SK Jun 16, 2026
3b9b8e9
Drop /S silent flag from Npcap install — driver signing blocks it
cod3SK Jun 16, 2026
dae8d02
Batch capture pipeline, Batch Analysis tab, and locale-safe interface…
cod3SK Jun 17, 2026
b00c3ab
Auto-start capture, embedded batch agent, single-model detection
cod3SK Jun 17, 2026
273d1f9
Fix auto-detect picking virtual adapters (Local Area Connection* N)
cod3SK Jun 17, 2026
4c0d1a1
Fix batch capture: glob also matches .pcapng ring-buffer files
cod3SK Jun 17, 2026
94dc6a8
Version system + fix batch capture loop
cod3SK Jun 17, 2026
eedea92
Remove redundant AppVersion from installer — version is already in Ap…
cod3SK Jun 17, 2026
16eb742
Fix model scoring path in PyInstaller bundle + expose batch tshark er…
cod3SK Jun 17, 2026
3b1327d
Fix Inno Setup AppVerName requirement + stamp v0.00.003
cod3SK Jun 17, 2026
e887b59
Auto-kill leftover process on port 5000 at startup
cod3SK Jun 17, 2026
25e3713
Fix _kill_port: use Get-NetTCPConnection instead of netstat parsing
cod3SK Jun 17, 2026
a933791
Fix port reclaim: kill by process name first, then by port ownership
cod3SK Jun 17, 2026
a80dd25
Capture Flask startup exception and surface it in the error dialog
cod3SK Jun 17, 2026
755facb
Bundle xgboost.dll explicitly — collect_all misses native DLL
cod3SK Jun 17, 2026
219e325
Fix scoring: bundle postgresql dialect + guard import in tasks.py
cod3SK Jun 17, 2026
6596dea
Fix 0.000 scores: skip broken xgboost estimator, add model health UI
cod3SK Jun 17, 2026
486e86f
v0.01.000: fix xgboost bundle, tray quit, batch conv regex; add model…
cod3SK Jun 17, 2026
f41f05a
Add Gotham Dataset 2025 corpus pipeline and cross-eval
cod3SK Jun 18, 2026
09aff8b
Fix corpus integrity: chunked pass-B, quarantine, flood cap, honest m…
cod3SK Jun 18, 2026
67c20b7
Phase 0+1: NFStream freeze fix, extractor parity, CLAUDE.md
cod3SK Jun 20, 2026
4d249e4
Phase 2: NFStream corpus migration, three-corpus rebuild, 27 new tests
cod3SK Jun 20, 2026
276b11c
Gate + cross-eval: NFStream findings reproduce; CLAUDE.md updated
cod3SK Jun 21, 2026
901d161
Phase 3–6: NFStream migration complete — single extraction path, no t…
cod3SK Jun 22, 2026
0b107c8
PR close-out: loud absent-model failure, Git LFS for model, CLAUDE.md…
cod3SK Jun 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
# Database credentials (consumed by docker-compose for the postgres service
# and woven into SQLALCHEMY_DATABASE_URI below). Change these before any
# non-local deployment.
POSTGRES_USER=adns
POSTGRES_PASSWORD=adns_password
POSTGRES_DB=adns

# Backend / API
SQLALCHEMY_DATABASE_URI=postgresql://adns:adns_password@127.0.0.1/adns
ADNS_REDIS_URL=redis://127.0.0.1:6379/0

# Admin token for the network-response endpoints (/block_ip, /unblock_ip,
# /killswitch). Leave blank to keep these endpoints disabled. When set, callers
# must send `Authorization: Bearer <token>` (or `X-Admin-Token: <token>`).
ADNS_ADMIN_TOKEN=
ADNS_RQ_QUEUE=flow_scores
ADNS_RQ_JOB_TIMEOUT=120
ADNS_RQ_BATCH_SIZE=100
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
api/model_artifacts/*.joblib filter=lfs diff=lfs merge=lfs -text
60 changes: 60 additions & 0 deletions .github/workflows/build-installer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Build Windows Installer

on:
push:
tags:
- "v*" # trigger on version tags: v1.0.0, v1.2.3, etc.
workflow_dispatch: # allow manual runs from the Actions tab

jobs:
build:
runs-on: windows-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
cache-dependency-path: frontend/adns-frontend/package-lock.json

- name: Build React frontend
working-directory: frontend/adns-frontend
run: |
npm ci
npm run build

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"

- name: Install Python dependencies
run: pip install -r requirements-desktop.txt pyinstaller

- name: Build with PyInstaller
run: pyinstaller ADNS.spec

- name: Build installer with Inno Setup
run: |
$iscc = "C:\Program Files (x86)\Inno Setup 6\ISCC.exe"
& $iscc installer.iss
shell: pwsh

- name: Upload installer artifact
uses: actions/upload-artifact@v4
with:
name: ADNS_installer
path: Output\ADNS_installer.exe
retention-days: 30

- name: Create GitHub Release
if: startsWith(github.ref, 'refs/tags/')
uses: softprops/action-gh-release@v2
with:
files: Output\ADNS_installer.exe
generate_release_notes: true
45 changes: 45 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: CI

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
api-tests:
name: API tests (pytest)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install test dependencies
run: pip install -r api/requirements-test.txt
- name: Run tests
working-directory: api
run: python -m pytest

frontend-build:
name: Frontend lint & build
runs-on: ubuntu-latest
defaults:
run:
working-directory: frontend/adns-frontend
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: frontend/adns-frontend/package-lock.json
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Build
run: npm run build
36 changes: 27 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,31 @@
# Python
__pycache__/
*.pyc
.venv/
*.pyo
*.pyd
*.egg-info/
.env
venv/
node_modules/
.venv/

# SQLite dev DB
api/instance/

# PyInstaller output
dist/
build/
.env
*.env
*.pem
data/
outputs/
.vs/
**/.vs/

# Model artifacts are tracked via Git LFS (.gitattributes), not ignored.

# Frontend build
frontend/adns-frontend/dist/
frontend/adns-frontend/node_modules/
node_modules/

# OS
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
145 changes: 145 additions & 0 deletions ADNS.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# PyInstaller spec for ADNS desktop application.
# Run from repo root after:
# npm run build (inside frontend/adns-frontend)
# pip install -r requirements-desktop.txt

import os

# Bundle npcap installer if present in repo root (download from https://npcap.com).
# Npcap (the packet capture driver) must still be installed on the target machine.
_npcap_datas = []
_npcap_installer = os.path.join(os.path.abspath("."), "npcap-installer.exe")
if os.path.isfile(_npcap_installer):
_npcap_datas.append((_npcap_installer, "."))

from PyInstaller.utils.hooks import collect_all, collect_data_files
import importlib.util as _ilu

block_cipher = None

# Collect all sklearn files — it uses a lot of data files and Cython extensions
sklearn_datas, sklearn_binaries, sklearn_hiddenimports = collect_all("sklearn")
webview_datas, webview_binaries, webview_hiddenimports = collect_all("webview")
pystray_datas, pystray_binaries, pystray_hiddenimports = collect_all("pystray")

# collect_all bundles xgboost Python files but misses the native DLL on Windows — add it explicitly.
import xgboost as _xgb
xgboost_datas, xgboost_binaries, xgboost_hiddenimports = collect_all("xgboost")
_xgb_lib = os.path.join(os.path.dirname(_xgb.__file__), "lib", "xgboost.dll")
if os.path.isfile(_xgb_lib) and not any(_xgb_lib == src for src, _ in xgboost_binaries):
xgboost_binaries.append((_xgb_lib, "xgboost/lib"))

# NFStream: collect Python package + _lib_engine.pyd (CFFI extension at site-packages root).
# collect_all("nfstream") finds only the Python package — the native .pyd is one level up.
nfstream_datas, nfstream_binaries_pkg, nfstream_hiddenimports = collect_all("nfstream")
_lib_engine_spec = _ilu.find_spec("_lib_engine")
_nfstream_extra_binaries = []
if _lib_engine_spec and _lib_engine_spec.origin:
_nfstream_extra_binaries.append((_lib_engine_spec.origin, "."))

a = Analysis(
["launcher.py"],
pathex=["api", "ml"], # api: 'from app import ...' resolves; ml: adns_flows package
binaries=(sklearn_binaries + webview_binaries + pystray_binaries + xgboost_binaries
+ nfstream_binaries_pkg + _nfstream_extra_binaries),
datas=[
# React production build
("frontend/adns-frontend/dist", "dist"),
# Trained model artifacts — REQUIRED for detection. Absent model blocks
# /capture/autostart with HTTP 503 (not silent). See api/model_runner.py.
# nfstream_model.joblib is tracked via Git LFS; run `git lfs pull` after clone.
("api/model_artifacts", "model_artifacts"),
# Flask app source files (all modules in api/)
("api/*.py", "api"),
# App icon (used by the desktop shortcut)
("assets/icon.ico", "assets"),
] + sklearn_datas + webview_datas + pystray_datas + xgboost_datas
+ nfstream_datas + _npcap_datas,
hiddenimports=[
# Flask ecosystem
"flask_cors",
"flask_sqlalchemy",
"sqlalchemy.dialects.sqlite",
"sqlalchemy.dialects.sqlite.pysqlite",
"sqlalchemy.dialects.postgresql",
"sqlalchemy.dialects.postgresql.base",
"sqlalchemy.pool.impl",
# ML stack
"joblib",
"numpy",
"pandas",
# pywebview Windows backends
"webview.platforms.winforms",
"webview.platforms.edgechromium",
"clr",
"pystray",
"pystray._win32",
"PIL",
"PIL.Image",
# adns_flows shared extractor (ml/adns_flows/ — on pathex, but api/*.py are data
# files so PyInstaller won't trace their imports automatically)
"adns_flows",
"adns_flows.schema",
"adns_flows.extract_nfstream",
"adns_flows.nfstream_config",
"adns_flows.extract",
"adns_flows.assemble",
# NFStream serving module (api/ data file, imports not auto-traced)
"serving_nfstream",
# NFStream sub-modules (collect_all may miss lazy-imported ones)
"nfstream",
"nfstream.streamer",
"nfstream.meter",
"nfstream.plugin",
"nfstream.engine",
"nfstream.utils",
# multiprocessing spawn protocol (NFStream meter workers use spawn on Windows)
"multiprocessing.spawn",
"multiprocessing.forkserver",
"multiprocessing.popen_spawn_win32",
] + sklearn_hiddenimports + webview_hiddenimports + pystray_hiddenimports
+ xgboost_hiddenimports + nfstream_hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=["pyi_hooks/rthook_nfstream_npcap.py"],
excludes=[
"psycopg2",
"psycopg2_binary",
"alembic",
"tkinter",
"matplotlib",
"IPython",
"jupyter",
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name="ADNS",
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False, # no terminal window on Windows
icon="assets/icon.ico",
)

coll = COLLECT(
exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name="ADNS",
)
Loading
Loading