Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
67 changes: 67 additions & 0 deletions .gemini/skills/logging-standards/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: logging-standards
description: Logging conventions for NetAlertX backend Python code. Use this when adding, modifying, or reviewing log statements.
---

# Logging Standards

## Import

```python
from logger import mylog
```

Never import `logging` directly in application code. Use `mylog` exclusively.

## Function Signature

```python
mylog(level, message_or_list)
```

`message_or_list` can be a plain string or a list of values — the logger joins them with spaces.

## Log Levels

Levels from least to most verbose (higher number = more output):

| Level | Numeric | When to use |
|-------|---------|-------------|
| `"none"` | 0 | Always printed regardless of user setting. Reserve for startup, fatal errors, and one-time permission checks. |
| `"minimal"` | 1 | Important state transitions visible by default (scan start/end, plugin finish, restart). |
| `"verbose"` | 2 | Informational progress — what the system is doing without clutter (e.g. "No changes to report"). |
| `"debug"` | 3 | Developer-level detail — loop decisions, branch taken, counts. |
| `"trace"` | 4 | Granular per-item tracing — individual device rows, SQL queries, raw values. |

## Message Format

Prefix every message with a `[Module]` tag matching the file/function context:

```python
mylog("debug", [f"[device_handling] Processing MAC: {mac}"])
mylog("verbose", ["[Scan] Scan complete — devices updated:", count])
```

Use `f-strings` inside a list element, not string concatenation:

```python
# Correct
mylog("debug", [f"[NIC] parent={parent_mac} nic_online={nic_online}"])

# Avoid
mylog("debug", "[NIC] parent=" + parent_mac + " nic_online=" + str(nic_online))
```

## Timestamp

`mylog` / `file_print` prepend the current local-timezone time automatically via `timeNowTZ`. Do **not** add a timestamp manually inside the message.

## What NOT to Log

- Do not log raw user input without sanitization.
- Do not log full SQL query strings at `"none"` or `"minimal"` — use `"trace"` at most.
- Do not use `print()` in server code — use `mylog`. `file_print` is an internal helper; do not call it directly.

## Log File Location

Written to `{logPath}/app.log` (`logPath` from `const.py` → `/tmp/logs` at runtime). Do not hardcode this path.
61 changes: 61 additions & 0 deletions .gemini/skills/pr-analysis/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
name: pr-analysis
description: How to analyze and respond to GitHub PR review comments in NetAlertX. Use this whenever you are addressing PR feedback, review threads, or inline code comments.
---

# PR Analysis

## Before Writing Any Test Code — Non-Negotiable Checklist

Run through this before creating or editing any file under `test/`:

1. **Helpers first:** Check `test/db_test_helpers.py` for existing factories (`make_db`, `make_device_dict`, `insert_device_from_dict`, `DummyDB`). Use them. If what you need doesn't exist, add it there — never define it locally in the test file.
2. **MAC literals must be lowercase:** Every MAC string in fixtures, parametrize, assertions, docstrings, and comments must be lowercase hex (e.g. `aa:bb:cc:dd:ee:01`). No exceptions.
3. **Test file location:** Place tests under a subdirectory of `test/` that mirrors the source path (e.g. `test/scan/` for `server/scan/`). Never put test files directly in `test/`.
4. **No inline imports:** All imports at the top of the file.

## Before Acting on Any PR Comment

1. Load `code-standards` skill — all code changes must comply with it before replying.
2. Load `testing-workflow` skill — any test additions or changes must follow it.
3. Load any domain-specific skill relevant to the files being changed (e.g. `database-patterns` for DB writes, `settings` for config).

## Comment Classification

For each comment, determine:

| Type | Action |
|------|--------|
| Request for code change | Make the change, validate it, then reply with the short commit hash |
| Question about code | Reply with a concise answer (no restatement of the question) |
| Suggestion / feedback | Decide if it is actionable. If yes, act and reply. If not, do not reply. |
| General / praise | Do not reply. |

## Acting on Comments — Step by Step

1. **Identify all actionable comments** before touching any file.
2. **Load relevant skills** to understand conventions that apply.
3. **Prepare a plan** — list each file and the exact change required.
4. **Make changes one comment at a time** — keep commits focused.
5. **Run targeted tests** after each change (`testing-workflow` skill).
6. **Reply** only after the commit is pushed. Include the short SHA.

## Reply Guidelines

- Be concise. Do not summarize or restate the original comment.
- State what was done and (optionally) why.
- Include the short commit hash when relevant.
- Do not thank or compliment the reviewer.

## What to Check After Every Batch of Changes

- **MAC literals lowercase** — grep for uppercase hex in every changed test file: `grep -Pn '[0-9A-F]{2}:[0-9A-F]' test/` must be empty.
- **No local DB helpers** — no `DummyDB`, `make_db`, or inline DDL defined outside `test/db_test_helpers.py`.
- No inline imports — all imports at the top of the file.
- Tests live under a subdirectory of `test/` matching the source path, not in `test/` root.

## Stacked / Base-Branch Issues

When a PR targets a non-default branch (e.g. `next_release`):
- Do **not** retarget the branch yourself; note it in a reply so the author can do it from the GitHub UI.
- Check CI failures on the **base branch** first before checking your branch.
2 changes: 2 additions & 0 deletions .gemini/skills/skills-index/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Skills with the same purpose exist in both, sometimes under different names and
| Project navigation | `project-navigation` | `project-navigation` | Copilot version has full path tables and env vars; Gemini version is a brief reference |
| Plugin dev | `plugin-development` | `plugin-run-development` | Copilot version is comprehensive (data contract, phases, formats); Gemini version is a brief checklist pointing to `docs/PLUGINS_DEV.md` |
| Devcontainer | `devcontainer-management` | `devcontainer-services` + `devcontainer-setup` + `devcontainer-configs` | Gemini combines into one (uses `docker exec`); Copilot splits into 3 focused skills |
| PR review | `pr-analysis` | `pr-analysis` | How to classify and respond to PR comments; pre-flight skill loading checklist |
| Logging | `logging-standards` | `logging-standards` | `mylog` levels, message format, what not to log |

---

Expand Down
15 changes: 15 additions & 0 deletions .github/skills/code-standards/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ from db_test_helpers import make_db, DummyDB, insert_device, minutes_ago

If a helper you need doesn't exist yet, add it to `db_test_helpers.py` — not locally in the test file.

## MAC Literals in Tests — ALWAYS Lowercase

**MANDATORY:** Every MAC address literal used in test fixtures, parametrize decorators, assertions, or comments must be lowercase hex:

```python
# Correct
make_device_dict("aa:bb:cc:dd:ee:01", ...)

# Wrong — will be rejected in review
make_device_dict("AA:BB:CC:DD:EE:01", ...)
make_device_dict("Aa:Bb:Cc:Dd:Ee:01", ...)
```

This applies to hardcoded strings in `assert`, `pytest.mark.parametrize`, docstrings, and comments too. There are no exceptions.

## Path Hygiene

- Use environment variables for runtime paths
Expand Down
67 changes: 67 additions & 0 deletions .github/skills/logging-standards/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
name: netalertx-logging-standards
description: Logging conventions for NetAlertX backend Python code. Use this when adding, modifying, or reviewing log statements.
---

# Logging Standards

## Import

```python
from logger import mylog
```

Never import `logging` directly in application code. Use `mylog` exclusively.

## Function Signature

```python
mylog(level, message_or_list)
```

`message_or_list` can be a plain string or a list of values — the logger joins them with spaces.

## Log Levels

Levels from least to most verbose (higher number = more output):

| Level | Numeric | When to use |
|-------|---------|-------------|
| `"none"` | 0 | Always printed regardless of user setting. Reserve for startup, fatal errors, and one-time permission checks. |
| `"minimal"` | 1 | Important state transitions visible by default (scan start/end, plugin finish, restart). |
| `"verbose"` | 2 | Informational progress — what the system is doing without clutter (e.g. "No changes to report"). |
| `"debug"` | 3 | Developer-level detail — loop decisions, branch taken, counts. |
| `"trace"` | 4 | Granular per-item tracing — individual device rows, SQL queries, raw values. |

## Message Format

Prefix every message with a `[Module]` tag matching the file/function context:

```python
mylog("debug", [f"[device_handling] Processing MAC: {mac}"])
mylog("verbose", ["[Scan] Scan complete — devices updated:", count])
```

Use `f-strings` inside a list element, not string concatenation:

```python
# Correct
mylog("debug", [f"[NIC] parent={parent_mac} nic_online={nic_online}"])

# Avoid
mylog("debug", "[NIC] parent=" + parent_mac + " nic_online=" + str(nic_online))
```

## Timestamp

`mylog` / `file_print` prepend the current local-timezone time automatically via `timeNowTZ`. Do **not** add a timestamp manually inside the message.

## What NOT to Log

- Do not log raw user input without sanitization.
- Do not log full SQL query strings at `"none"` or `"minimal"` — use `"trace"` at most.
- Do not use `print()` in server code — use `mylog`. `file_print` is an internal helper; do not call it directly.

## Log File Location

Written to `{logPath}/app.log` (`logPath` from `const.py` → `/tmp/logs` at runtime). Do not hardcode this path.
62 changes: 62 additions & 0 deletions .github/skills/pr-analysis/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: netalertx-pr-analysis
description: How to analyze and respond to GitHub PR review comments in NetAlertX. Use this whenever you are addressing PR feedback, review threads, or inline code comments.
---

# PR Analysis

## Before Writing Any Test Code — Non-Negotiable Checklist

Run through this before creating or editing any file under `test/`:

1. **Helpers first:** Check `test/db_test_helpers.py` for existing factories (`make_db`, `make_device_dict`, `insert_device_from_dict`, `DummyDB`). Use them. If what you need doesn't exist, add it there — never define it locally in the test file.
2. **MAC literals must be lowercase:** Every MAC string in fixtures, `parametrize`, assertions, docstrings, and comments must be lowercase hex (e.g. `aa:bb:cc:dd:ee:01`). No exceptions.
3. **Test file location:** Place tests under a subdirectory of `test/` that mirrors the source path (e.g. `test/scan/` for `server/scan/`). Never put test files directly in `test/`.
4. **No inline imports:** All imports at the top of the file.

## Before Acting on Any PR Comment

1. Load `code-standards` skill — all code changes must comply with it before replying.
2. Load `testing-workflow` skill — any test additions or changes must follow it.
3. Load any domain-specific skill relevant to the files being changed (e.g. `database-patterns` for DB writes, `settings-management` for config).

## Comment Classification

For each comment, determine:

| Type | Action |
|------|--------|
| Request for code change | Make the change, validate it, then reply with the short commit hash |
| Question about code | Reply with a concise answer (no restatement of the question) |
| Suggestion / feedback | Decide if it is actionable. If yes, act and reply. If not, do not reply. |
| General / praise | Do not reply. |

## Acting on Comments — Step by Step

1. **Identify all actionable comments** before touching any file.
2. **Load relevant skills** to understand conventions that apply.
3. **Prepare a plan** — list each file and the exact change required.
4. **Make changes one comment at a time** — keep commits focused.
5. **Run targeted tests** after each change (`testing-workflow` skill).
6. **Reply** only after the commit is pushed via `report_progress`. Include the short SHA.

## Reply Guidelines

- Be concise. Do not summarize or restate the original comment.
- State what was done and (optionally) why.
- Include the short commit hash when relevant.
- Do not thank or compliment the reviewer.

## What to Check After Every Batch of Changes

- **MAC literals lowercase** — grep for uppercase hex in every changed test file: `grep -Pn '[0-9A-F]{2}:[0-9A-F]' test/` must be empty.
- **No local DB helpers** — no `DummyDB`, `make_db`, or inline DDL defined outside `test/db_test_helpers.py`.
- No inline imports — all imports at the top of the file.
- Tests live under a subdirectory of `test/` matching the source path, not in `test/` root.
- Secret scan (`runtime-tools-secret_scanning`) before committing.

## Stacked / Base-Branch Issues

When a PR targets a non-default branch (e.g. `next_release`):
- Do **not** retarget the branch yourself; note it in a reply so the author can do it from the GitHub UI.
- Check CI failures on the **base branch** first before checking your branch.
2 changes: 2 additions & 0 deletions .github/skills/skills-overview/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ Skills with the same purpose exist in both, sometimes under different names and
| Project navigation | `project-navigation` | `project-navigation` | Copilot version has full path tables and env vars; Gemini version is a brief reference |
| Plugin dev | `plugin-run-development` | `plugin-development` | Copilot version is comprehensive (data contract, phases, formats); Gemini version is a brief checklist pointing to `docs/PLUGINS_DEV.md` |
| Devcontainer | `devcontainer-services` + `devcontainer-setup` + `devcontainer-configs` | `devcontainer-management` | Copilot splits into 3 focused skills; Gemini combines into one (uses `docker exec`) |
| PR review | `pr-analysis` | `pr-analysis` | How to classify and respond to PR comments; pre-flight skill loading checklist |
| Logging | `logging-standards` | `logging-standards` | `mylog` levels, message format, what not to log |

---

Expand Down
12 changes: 10 additions & 2 deletions server/scan/device_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -1270,9 +1270,17 @@ def update_devPresentLastScan_based_on_nics(db):
if nics:
nic_statuses = [nic.get("devPresentLastScan") == 1 for nic in nics]
if req_all:
new_present = int(all(nic_statuses))
nic_online = all(nic_statuses)
else:
new_present = int(any(nic_statuses))
nic_online = any(nic_statuses)

if original == 1:
# Parent was directly detected this scan — NIC children cannot
# force it offline. Leave new_present = original (no change).
pass
else:
# Parent was not directly detected — NICs determine presence.
new_present = 1 if nic_online else 0

# Only add update if changed
if original != new_present:
Expand Down
Loading
Loading