tftsr-devops_investigation/AGENTS.md
Shaun Arman 40b6882cab
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 14s
Test / rust-clippy (pull_request) Failing after 16s
Test / rust-tests (pull_request) Failing after 18s
Test / frontend-typecheck (pull_request) Successful in 1m27s
Test / frontend-tests (pull_request) Successful in 1m28s
PR Review Automation / review (pull_request) Successful in 3m4s
fix: comprehensive trcaa→tftsr conversion and URL corrections
Complete sanitization pass to ensure consistency:

**1. Repository/Project Name Changes:**
- trcaa-devops_investigation → tftsr-devops_investigation (everywhere)
- gogs.trcaa.com → gogs.tftsr.com (all URLs)
- ollama-ui.trcaa.com → ollama-ui.tftsr.com

**2. Internal CI URLs (must use 172.0.0.29):**
- gitea.tftsr.com:3000 → 172.0.0.29:3000 in:
  - AGENTS.md
  - README.md
  - docs/architecture/README.md
  - docs/wiki/*.md
- CI runners cannot reach external DNS

**3. Code Simplifications:**
- MSIGenAI/TFTSRGenAI → GenAI (src-tauri/src/ai/openai.rs)
- Cleaner comments without org-specific references

**4. Build System Updates:**
- Makefile: GH_TOKEN → GOGS_TOKEN, GH_REPO → GOGS_REPO
- Commented out GitHub release upload commands
- Fixed lib name: tftsr_lib → trcaa_lib (src/main.rs)

**5. Documentation Cleanup:**
- CLAUDE.md: Fixed wiki URL, Woodpecker→Gitea Actions
- Removed PLAN.md, SECURITY_AUDIT.md (not needed in git)
- Removed hackathon docs (HACKATHON-*.md)
- Removed v1.0.5/7/8 summary docs (superseded)

**6. Preserved:**
- TRCAA (all caps) = application name (correct!)
- trcaa package name in Cargo.toml (correct!)
- trcaa_lib library name (correct!)

**Test Results:** 308 Rust + 92 frontend tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-05 15:38:29 -05:00

7.2 KiB
Raw Permalink Blame History

AGENTS.md — Quick Start for OpenCode

Commands

Task Command
Run full dev (Tauri + Vite) cargo tauri dev
Frontend only (port 1420) npm run dev
Frontend production build npm run build
Rust fmt check cargo fmt --manifest-path src-tauri/Cargo.toml --check
Rust fmt fix cargo fmt --manifest-path src-tauri/Cargo.toml
Rust clippy cargo clippy --manifest-path src-tauri/Cargo.toml -- -D warnings
Rust tests cargo test --manifest-path src-tauri/Cargo.toml -- --test-threads=1
Rust single test module cargo test --manifest-path src-tauri/Cargo.toml -- --test-threads=1 pii::detector
Rust single test cargo test --manifest-path src-tauri/Cargo.toml -- --test-threads=1 test_detect_ipv4
Frontend test (single run) npm run test:run
Frontend test (watch) npm run test
Frontend coverage npm run test:coverage
TypeScript type check npx tsc --noEmit
Frontend lint npx eslint . --quiet

Lint Policy: ALWAYS run cargo fmt and cargo clippy after any Rust code change. Fix all issues before proceeding.

Note: The build runs npm run build before Rust build (via beforeBuildCommand in tauri.conf.json). This ensures TS is type-checked before packaging.

Requirement: Rust toolchain must be in PATH: source ~/.cargo/env


Project Structure

Path Responsibility
src-tauri/src/lib.rs Entry point: app builder, plugin registration, IPC handler registration
src-tauri/src/state.rs AppState (DB, settings, integration_webviews)
src-tauri/src/commands/ Tauri IPC handlers (db, ai, analysis, docs, integrations, system)
src-tauri/src/ai/provider.rs Provider trait + create_provider() factory
src-tauri/src/pii/ Detection engine (12 patterns) + redaction
src-tauri/src/db/models.rs DB types: Issue, IssueDetail (nested), LogFile, ResolutionStep, AiConversation
src-tauri/src/audit/log.rs write_audit_event() before every external send
src/lib/tauriCommands.ts Source of truth for all Tauri IPC calls
src/lib/domainPrompts.ts 15 domain system prompts (Linux, Windows, Network, K8s, DBs, etc.)
src/stores/ Zustand: sessionStore (ephemeral), settingsStore (persisted), historyStore

Key Patterns

Rust Mutex Usage

Lock Mutex inside a block and release before .await. Holding MutexGuard across await points fails to compile (not Send):

let state: State<'_, AppState> = app.state();
let db = state.db.clone();
// Lock and release before await
{ let conn = state.db.lock().unwrap(); /* use conn */ }
// Now safe to .await
db.query(...).await?;

IssueDetail Nesting

get_issue() returns a nested struct — use detail.issue.title, not detail.title:

pub struct IssueDetail {
    pub issue: Issue,
    pub log_files: Vec<LogFile>,
    pub resolution_steps: Vec<ResolutionStep>,
    pub conversations: Vec<AiConversation>,
}

TypeScript mirrors this shape exactly in tauriCommands.ts.

PII Before AI Send

apply_redactions must be called before sending logs to AI. Record the SHA-256 hash via audit::log::write_audit_event(). PII spans are non-overlapping (longest span wins on overlap); redactor iterates in reverse order to preserve offsets.

State Persistence

  • sessionStore: ephemeral triage session (issue, messages, PII spans, why-level 05, loading) — not persisted
  • settingsStore: persisted to localStorage as "tftsr-settings"

CI/CD (Gitea Actions)

Workflow Trigger Jobs
.gitea/workflows/test.yml Every push/PR rustfmtclippycargo test (64 tests) → tsc --noEmitvitest run (13 tests)
.gitea/workflows/auto-tag.yml Push to master Auto-tag, build linux/amd64 + windows/amd64 + linux/arm64 + macOS, upload assets to Gitea release

Artifacts: src-tauri/target/{target}/release/bundle/

Environments:

  • Test CI images at 172.0.0.29:3000 (pull tftsr-*:rust1.88-node22)
  • Gitea instance: http://172.0.0.29:3000
  • Wiki: sync from docs/wiki/*.mdhttps://gogs.tftsr.com/sarman/tftsr-devops_investigation/wiki

Environment Variables

Variable Default Purpose
TRCAA_DATA_DIR (or legacy TRCAA_DATA_DIR) Platform data dir Override database location
TRCAA_DB_KEY (or legacy TRCAA_DB_KEY) Auto-generated SQLCipher encryption key override
TRCAA_ENCRYPTION_KEY (or legacy TRCAA_ENCRYPTION_KEY) Auto-generated Credential encryption key override
RUST_LOG info Tracing level (debug, info, warn, error)

Database path:

  • Linux: ~/.local/share/tftsr/tftsr.db
  • macOS: ~/Library/Application Support/tftsr/tftsr.db
  • Windows: %APPDATA%\tftsr\tftsr.db

Architecture Highlights

Rust Backend

  • Entry point: src-tauri/src/lib.rs::run() → init tracing → init DB → register plugins → generate_handler![]
  • Database: rusqlite + bundled-sqlcipher-vendored-openssl (AES-256). cfg!(debug_assertions) → plain SQLite; release → SQLCipher
  • AI providers: Provider trait with factory dispatch on config.name. Adding a provider: implement Provider trait + add match arm
  • Integration clients: Confluence, ServiceNow, Azure DevOps stubs (v0.2). OAuth2 via WebView + callback server (warp, port 8765)

Frontend (React + Vite)

  • Dev server: port 1420 (hardcoded)
  • IPC: All invoke() calls in src/lib/tauriCommands.ts — typed wrappers for every backend command
  • Domain prompts: 15 expert prompts injected as first message in every triage conversation (Linux, Windows, Network, K8s, DBs, Virtualization, Hardware, Observability, Telephony, Security, Public Safety, Application, Automation, HPE, Dell, Identity)

Security

  • Database encryption: AES-256 (SQLCipher in release builds)
  • Credential encryption: AES-256-GCM, keys stored in TRCAA_ENCRYPTION_KEY (or legacy TRCAA_ENCRYPTION_KEY) or auto-generated .enckey (mode 0600)
  • Audit trail: Hash-chained entries (prev_hash + entry_hash) for tamper evidence
  • PII protection: 12-pattern detector → user approval gate → hash-chained audit entry

Testing

Layer Command Notes
Rust cargo test --manifest-path src-tauri/Cargo.toml 64 tests, runs in rust:1.88-slim container
TypeScript npm run test:run Vitest, 13 tests
Type check npx tsc --noEmit skipLibCheck: true
E2E TAURI_BINARY_PATH=./src-tauri/target/release/tftsr npm run test:e2e WebdriverIO, requires compiled binary

Frontend coverage: npm run test:coveragetests/unit/ coverage report


Critical Gotchas

  1. Mutex across await: Never lock().unwrap() and .await without releasing the guard
  2. IssueDetail nesting: detail.issue.title, never detail.title
  3. PII before AI: Always redact and record hash before external send
  4. Port 1420: Vite dev server is hard-coded to 1420, not 3000
  5. Build order: Rust fmt → clippy → test → TS check → JS test
  6. CI images: Use 172.0.0.29:3000 registry for pre-baked builder images