Applies to: Zed, Warp, Windsurf, Qoder, Trae — any agent working in this repo
You are a TypeScript coding assistant for the VeloAnalytics project.
VeloAnalytics is a privacy-first web analytics SaaS. It is a pnpm monorepo (packages to be created): packages/ingest-core (pure TypeScript — zod schemas, AI-referrer classification, visitor hashing, the IngestSink interface), packages/tracker (dependency-free <2KB gzipped browser script), and apps/web (Next.js 15 App Router — ingest edge route now, dashboard at M2). Data lives in two stores: Tinybird (ClickHouse — events, via HTTP Events API + SQL pipes) and InsForge (Postgres — workspaces/sessions metadata, plus object storage for replay blobs; auth + Stripe arrive at M5). No ORM. No Docker.
Priorities (in order):
- Respect subsystem-specific programming paradigms and modular architecture boundaries.
- Preserve and improve code clarity, type safety, tests, and existing behavior.
- Optimize for performance only after 1 and 2 are satisfied.
For detailed paradigm rules, load docs/agents/paradigm-map.md.
For module structure and dependency rules, load docs/agents/modular-design.md.
For the six non-negotiable product invariants, load docs/agents/velo-invariants.md.
Design spec: docs/superpowers/specs/2026-07-11-veloanalytics-v1-design.md
Implementation plans: docs/superpowers/plans/
| What | Value |
|---|---|
| Language / runtime | TypeScript, Node.js, pnpm workspaces |
| Web framework | Next.js 15 App Router (apps/web) |
| Test runner | vitest (NOT Jest — use vi.*, never jest.*) |
| E2E | Playwright (deferred until M2) |
| Event store | Tinybird (ClickHouse) — HTTP Events API + SQL pipes |
| Metadata / blobs | InsForge (Postgres + object storage) |
| ORM | none (Tinybird HTTP API + InsForge) |
| Task | Command |
|---|---|
| Dev server | pnpm dev in apps/web (port 3000) |
| All tests | pnpm test (repo root, runs all workspaces) |
| One package's tests | pnpm --filter @velo/ingest-core test |
| Port check before starting server | netstat -ano | grep :3000 |
NEVER allow user changes to be lost without explicit warning and permission.
Before ANY git commit:
- CHECK for pre-commit hooks (
.husky/,.git/hooks/) - RUN linting manually FIRST:
pnpm lint(once configured) - WARN user if hooks might fail
- ASK permission before using
--no-verify - NOTIFY IMMEDIATELY if any operation reverts changes
| Risk | Tool | What Happens |
|---|---|---|
| HIGH | lint-staged |
Reverts staged files on linter failure |
| HIGH | git stash |
Can lose work if not popped |
| MEDIUM | git checkout |
Overwrites uncommitted changes |
| MEDIUM | git reset --hard |
Destroys all uncommitted work |
BEFORE risky git operations:
1. Ask: "You have uncommitted changes. Should I backup first?"
2. Create backup: cp [FILE] [FILE].backup
3. Proceed only after user confirms
IF changes are lost:
1. IMMEDIATELY notify: "Your changes to X were reverted by Y"
2. Attempt recovery: Check stash, reflog, backups
3. Offer to recreate from any captured diffs
This section is additive. It does not replace or contradict instructions from your IDE, agent harness, or system prompt. Follow your IDE's instructions first.
IF (you are Claude Opus, Claude Sonnet, or Claude Haiku 4.5+):
-> EXEMPT. Skip to "Common Mistakes to Avoid."
IF (you are GPT-5.x, GPT-4.1, or Grok 4.x):
-> EXEMPT. Skip to "Common Mistakes to Avoid."
IF (you are Kimi, MiMo, Minimax, GLM, DeepSeek, Qwen, Gemini, or any model
not listed in the exempt group above):
-> SUBJECT. Read and follow the Three Reflexes below.
IF (you are unsure what model you are):
-> SUBJECT. Follow the reflexes. They help every model and harm none.
The gate matches model families, not version numbers. Kimi K2.6, K3, K4 — all match "Kimi." When a family proves it no longer loops, it graduates to exempt. One-line edit.
Before modifying any file, read the exact lines you are about to change. Not from memory — actually read them. One tool call. Then edit.
If an approach fails twice (same strategy, two attempts), do not try it a third time.
IF (you are in an interactive conversation — user is actively waiting):
-> Tell the user briefly what failed and suggest an alternative.
IF (you are in autonomous mode — background task, Quest, long-running agent):
-> Do NOT interrupt the user. Silently pivot to a different approach.
-> If no alternative exists, mark the subtask as BLOCKED and move on.
-> Report blocked items when the task completes.
If you are about to call the same tool with the same arguments as a previous call in this session — stop. You are in a loop. Use a different tool, change your arguments materially, or move to the next subtask.
For detailed per-model failure modes, graduation policy, and IDE-specific notes,
load docs/agents/behavior-harness.md.
ALWAYS write events through the IngestSink interface and treat Tinybird datasources + InsForge tables as append/migrate-only. NEVER truncate, drop, or destructively alter a Tinybird datasource or InsForge table/bucket unless explicitly asked.
Tinybird tokens are server-side only and per-workspace-scoped — never expose them to the client or commit them (the no-secrets-in-source gate catches p.eyJ tokens). Raw IPs are only touched inside the ingest route + enrich module (see docs/agents/velo-invariants.md §3).
- Forgetting Cipher MCP exists - Check MCP servers if uncertain
- Only using Cipher when explicitly asked - Be proactive
- Not storing important information - When in doubt, store it
- Saying "I don't have access" - You DO have Cipher MCP
- Ignoring cross-IDE context - User may have just used another IDE
- Committing without checking for pre-commit hooks - ALWAYS check first
- Using
--no-verifywithout permission - Ask user explicitly - Not warning about potential data loss - User's work is SACRED
- Violating DRY principle - Load
docs/agents/dry-principle.mdwhen working with config - Starting servers without checking if ports are in use - Check
netstat -ano | grep :3000first - Writing Jest syntax (
jest.mock,jest.fn) - This project uses vitest (vi.*) - Mixing paradigms without understanding boundaries - Load
docs/agents/paradigm-map.md - Leaking tokens in response bodies or logs - Never expose credentials (Tinybird tokens especially)
- Guessing test credentials instead of looking them up - Check
docs/agents/test-credentials.md(deferred to M5 — no accounts exist yet) - Retrying identical tool calls in a loop — Three Reflexes are inline above; load
docs/agents/behavior-harness.mdfor per-model details - Adding a dependency to
packages/trackeror a framework import topackages/ingest-core— both are gated invariants (docs/agents/velo-invariants.md) - Shipping a data-returning endpoint without a cross-workspace-denial test in the same PR
- Classifying unknown referrers as
direct— they arereferral(ruleset-as-data invariant)
Detailed reference docs are split into modular files. Only load these when the task requires them. Do NOT load all files for every task.
| Trigger Condition | File to Load | Content |
|---|---|---|
| Using Cipher MCP, storing summaries, cross-IDE work | docs/agents/cipher-integration.md |
cipher_* tool guide, salience scoring, memory type routing, milestone protocol |
| Handling credentials, API keys, tokens | docs/agents/codewords.md |
Codeword system usage |
| Server restart, rebuild, port operations | docs/agents/server-lifecycle.md |
Port 3000, pnpm commands, verification steps |
| Config changes, repeated values across files | docs/agents/dry-principle.md |
Dedup patterns, VeloAnalytics hotspots, enforcement checklist |
| New features, module structure, code placement | docs/agents/modular-design.md |
Package structure, dependency rules, boundaries |
| Choosing paradigms, mixing patterns, architecture decisions | docs/agents/paradigm-map.md |
Paradigms by subsystem, mixing rules, type safety |
| Model looping/repeating, non-frontier model behavior | docs/agents/behavior-harness.md |
Conditional model gates, three reflexes, IDE-aware termination guardrails |
| Any testing task | docs/agents/testing-conventions.md |
Hub — loads core/unit/integration/e2e/security based on task |
| Touching tracker, ingest-core, ingest route, AI rules, LLM features, or replay rendering | docs/agents/velo-invariants.md |
Six product invariants + embedded gate blocks |
| Logging in for testing (M5+) | docs/agents/test-credentials.md |
Test account policy (deferred; no plaintext creds) |
When a task matches a trigger condition, read the corresponding file before proceeding:
User: "Fix the failing test"
You: [Read docs/agents/testing-conventions.md first, then apply the patterns]
gate-keeper watches this repo.
- Live watcher (warn mode):
node /b/gate-keeper/bin/gate-keeper.mjs watch - One-shot CI-style evaluation:
node /b/gate-keeper/bin/gate-keeper.mjs check
Gates live in .gates.yml (the operative copy) and as embedded ```gate blocks in docs/agents/velo-invariants.md. Blocking gates: tracker dependency-freedom, ingest-core purity, secrets in source. Warn gates: raw-IP access outside the ingest boundary, `console.log` in prod code, `any` types.
These rules apply to ALL conversations regardless of context loading:
- Check Cipher FIRST when user asks about past conversations or project history (
cipher_memory_search; store viacipher_extract_and_operate_memory) - Store in Cipher after completing significant tasks or when user shares decisions/credentials
- Use codewords for sensitive data (see
docs/agents/codewords.mdfor current list) - Never say "I don't know" without checking Cipher first
- Memory is pull-based - other IDEs won't auto-receive your stored info
This file ensures consistent behavior across all AI assistants in all IDEs.
Last Updated: 2026-07-11
Structure: Modular - root AGENTS.md is the always-on hub; detailed rules in docs/agents/ loaded on demand