tftsr-devops_investigation/AGENTS.md

142 lines
5.5 KiB
Markdown
Raw Normal View History

# AGENTS.md
## Commands & Tools
### Development
- **Full dev server**: `cargo tauri dev` (requires `source ~/.cargo/env` first)
- **Frontend only**: `npm run dev` (Vite at localhost:1420)
- **Production build**: `cargo tauri build``src-tauri/target/release/bundle/`
### Testing & Verification
**Order matters:**
1. `cargo fmt --manifest-path src-tauri/Cargo.toml --check`
2. `cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings`
3. `cargo test --manifest-path src-tauri/Cargo.toml`
4. `npx tsc --noEmit`
5. `npm run test:run`
**Single Rust test**: `cargo test --manifest-path src-tauri/Cargo.toml pii::detector`
**Single Rust test by name**: `cargo test --manifest-path src-tauri/Cargo.toml test_detect_ipv4`
---
## Architecture Highlights
### Rust Backend (Tauri 2)
- **State**: `AppState` wraps `Mutex<Connection>` + `Mutex<AppSettings>` — lock inside `{ }` blocks and **release before `.await`**
- **IPC entry point**: `src-tauri/src/lib.rs``run()` registers all handlers in `generate_handler![]`
- **AI providers**: `ai/provider.rs::create_provider()` dispatches on `provider_type` (or `name` fallback)
- **PII before AI**: Every external send must call `apply_redactions()` and log SHA-256 hash via `audit::log::write_audit_event()`
- **DB encryption**: `debug_assertions` → plain SQLite; release → SQLCipher. Keys from `TFTSR_DB_KEY` / `TFTSR_ENCRYPTION_KEY` env vars
### Frontend (React + TypeScript)
- **IPC layer**: `src/lib/tauriCommands.ts` — single source of truth for typed `invoke()` wrappers
- **Stores** (Zustand):
- `sessionStore.ts`: Ephemeral triage session (not persisted)
- `settingsStore.ts`: AI providers, theme, Ollama URL — persisted to `localStorage` as `"tftsr-settings"`
- `historyStore.ts`: Read-only cache of past issues
- **Domain prompts**: `src/lib/domain Prompts.ts` — 8 IT domains injected as first message in triage conversations
### Key Data Types
- **IssueDetail** (Rust): Nested struct — `detail.issue.title`, NOT `detail.title`
- **IssueDetail** (TS): Mirrors Rust — use `issue.title`, `issue.status`, etc.
- **PII spans**: `PiiDetector::detect()` returns non-overlapping spans (longest wins on overlap), applies in reverse order
---
## CI/CD
**Branch protection**: `master` requires PR + `sarman` approval + all 5 CI checks green
**Gitea Actions workflows** (`.gitea/workflows/`):
- `test.yml`: rustfmt · clippy · cargo test (64) · tsc · vitest (13) — every push/PR
- `auto-tag.yml`: Auto-tag + multi-platform release build on push to `master`
**Runners**:
- `amd64-docker-runner`: linux/amd64 + windows/amd64 builds
- `arm64-native-runner`: native linux/arm64 builds
**CI test binary requirement**: `npm run test:e2e` needs `TAURI_BINARY_PATH=./src-tauri/target/release/tftsr`
---
## Database & Settings
**DB path**: `~/.local/share/tftsr/tftsr.db` (Linux), override via `TFTSR_DATA_DIR`
**SQLite schema**: `db/migrations.rs` tracks 10 migrations; schema in `_migrations` table
**Environment variables**:
- `TFTSR_DATA_DIR`: DB location override
- `TFTSR_DB_KEY`: SQLCipher encryption key (required release)
- `TFTSR_ENCRYPTION_KEY`: API key encryption (required release)
- `RUST_LOG`: tracing level (`debug`, `info`, `warn`, `error`)
---
## PII Detection & Redaction
**Patterns detected**: IPv4/IPv6, emails, tokens, passwords, SSNs, credit cards
**Flow**:
1. `detect_pii(log_file_id)``Vec<PiiSpan>` (sorted, non-overlapping)
2. UI shows diff viewer for approval
3. `apply_redactions(log_file_id, approved_span_ids)` → creates redacted file
4. **Mandatory**: SHA-256 hash of redacted content logged via `audit::log::write_audit_event()` before any AI send
---
## AI Providers
**Supported**: OpenAI (compatible), Anthropic, Google Gemini, Mistral, Ollama (local)
**Adding a provider**:
1. Implement `Provider` trait in `ai/*.rs`
2. Add match arm in `ai/provider.rs::create_provider()`
**Ollama defaults**: `http://localhost:11434`, default model `llama3.2:3b` (≥8 GB RAM) or `llama3.1:8b` (≥16 GB RAM)
---
## Wiki Maintenance
**Source of truth**: `docs/wiki/` — automated sync to Gitea wiki on every push to `master`
**Update these files when changing code**:
| Area | Wiki file |
|------|-----------|
| Tauri commands | `IPC-Commands.md` |
| DB schema/migrations | `Database.md` |
| AI providers | `AI-Providers.md` |
| PII detection | `PII-Detection.md` |
| CI/CD changes | `CICD-Pipeline.md` |
| Architecture | `Architecture.md` |
| Security changes | `Security-Model.md` |
| Dev setup | `Development-Setup.md` |
---
## Common Gotchas
1. **Mutex deadlock**: Never hold `MutexGuard` across `.await` — release before async calls
2. **PII enforcement**: Redaction + hash audit is mandatory before any network send
3. **Testing order**: Run `cargo check`/`cargo fmt`/`cargo clippy` before `cargo test` (order matters for CI)
4. **DB encryption**: Release builds require `TFTSR_DB_KEY` and `TFTSR_ENCRYPTION_KEY` or will fail at runtime
5. **Type mismatch**: `get_issue()` returns `IssueDetail` with nested `issue` field in both Rust and TS
6. **Integration stubs**: `integrations/` modules are v0.2 stubs — not functionally complete
7. **Rust version**: 1.88+ required (for `cookie_store`, `time`, `darling`)
8. **Linux deps**: Must install webkit2gtk4.1 + libsoup3 + openssl before `cargo build`
---
## Prerequisites (Linux/Fedora)
```bash
sudo dnf install -y glib2-devel gtk3-devel webkit2gtk4.1-devel \
libsoup3-devel openssl-devel librsvg2-devel
```
**Rust**: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh && source ~/.cargo/env`
**Node**: 22+ (via package manager)