AGENTS.md

AGENTS.md

ATLANTIS turns NetFlow captures and CSV imports into queryable aggregate databases, then visualizes them in a web dashboard.

Repository map

  • tools/netflow-db: Rust pipeline (atlantis-netflow-db crate) for ingestion, aggregation, verification, and analysis-window exports. Native nfcapd ingestion uses the pinned nfdump fork in vendor/nfdump.
  • apps/web: Svelte 5/SvelteKit 3 dashboard and API routes. It reads local SQLite during development and Cloudflare D1 in deployment.
  • apps/landing: Astro marketing and SEO site.
  • infra: Alchemy v2 stacks (Effect programs) that deploy the dashboard. cloudflare.ts deploys the worker and its D1 database; self-hosted.ts runs the SQLite dashboard as a Docker container on a self-hosted machine that users reach through SSH port forwarding; shared.ts holds names and paths common to all stacks.
  • vendor/*: Third-party analysis submodules. Treat these as read-only; build repo-local binaries through the scripts in vendor/scripts/.
  • data/, .env, and datasets.json: Machine-local inputs and generated databases. Keep paths and dataset contents out of commits.
  • docs/user: User setup and operation documentation.
  • docs/code: Architecture and development documentation.
  • docs/agent: Generated plans and analysis artifacts.

Engineering contracts

  • Treat ingestion, storage, API queries, and charts as one data contract. When a stored field or dimension changes, account for every Rust writer and verifier, the local SQLite schema, the Drizzle schema and migrations, TypeScript query code, and focused tests.
  • A pipeline database is a product bound to its schema, flow selection, result configuration, and logical source membership. Semantic changes produce a fresh product database; never silently mix incompatible results in an existing one.
  • Assume captures and databases are large. Preserve streaming, batching, bounded concurrency, and bounded-memory processing instead of materializing an entire dataset for convenience.
  • Preserve half-open time-window and additive-rollup semantics across ingestion and queries. Missing nfcapd buckets are explicit zero-filled observations within proven source bounds, not absent data to ignore.
  • Keep the system greenfield: replace obsolete paths cleanly. Add compatibility code only when a deployed database or external contract in scope requires it.

Svelte

Keep derived state derived. Put interaction-driven updates in event handlers or function bindings, use {@attach} for DOM or external-library lifecycle, and use createSubscriber for external sources. Reserve $effect for genuine external side effects, and never mutate Svelte state from an effect.

Reuse the existing chart registries, chart utilities, and shared filter components when extending dashboard behavior. Keep metric and filter semantics out of presentation-only components.

Verification

  • For code changes, run bun run format, bun run lint, and bun run typecheck successfully. For documentation-only changes, run the applicable formatter check.
  • Run focused tests for the changed surface: bun run test:web for dashboard/API behavior, bun run test:db for pipeline behavior, and bun run test:e2e for user flows that need browser coverage.
  • Use bun run test, not bun test; the latter invokes Bun's test runner instead of the repository's Vitest orchestration.
  • When editing the landing site, also run bun run --cwd apps/landing lint and bun run build:landing; the root lint script does not cover apps/landing.

Pull requests

Use the Conventional Commit style for PR titles.

Include a short human review guide with relevant flows, setup or test data, expected behavior, important edge cases, and decisions needing review. Distinguish automated verification from remaining manual checks.