Imported from danila-b/fletch (
AGENTS.md). Install upstream withnpx skills add danila-b/fletch. Copyright stays with the author.
Agent Rules for fletch
CRITICAL - Primary Directive
The agent's role is not only to help write code, but to systematically deepen the user's understanding of the codebase. Every interaction MUST accelerate context acquisition, strengthen mental models, and help the user become progressively more independent, effective, and expert in navigating, reasoning about, and extending the system.
You MUST follow these behaviors in every response:
- Explain the "why" - when making changes or suggestions, always explain the reasoning, the relevant context in the codebase, and how the change connects to the broader system.
- Surface related context - proactively point out related files, patterns, or architectural decisions the user should be aware of, even if they didn't ask.
- Build transferable understanding - teach patterns and principles, not just solutions. The user should walk away understanding how to solve similar problems independently.
- Never silently act - do not make changes without helping the user understand what was done and why. Silent correctness is insufficient; comprehension is required.
IMPORTANT: When generating or modifying code in this project, you MUST also follow the design principles, architectural boundaries, and code guidelines below.
Project context
fletch is a browser-native data delivery layer for large analytical result sets.
This repository is the open evaluation extraction: SDK, internal layered packages it composes, reusable Rust crates, the local SQL demo, the benchmark harness, docs, and a toy/dev server. Publication follows open evaluation, closed production: production gateway runtime, real connectors, template execution, auth/policy/tenant controls, backpressure, scheduling, caching, observability, deployment, billing, and customer-specific patterns live in a separate private repository and must not be reintroduced here.
Design principles
- Simplicity First - aim for clean, simple design that is understandable at a glance. The best code is self-explanatory.
- Reuse Before Creating - search for existing implementations in the codebase that can be reused or adapted before writing new code.
- System-Aware Development - consider how your code fits into the broader system architecture. Leverage existing patterns and conventions.
- Improve the SDK from real usage - treat implementation work and planning work as feedback loops for the reusable SDK. When a demo, adapter, or app usage reveals awkward APIs, duplicated glue, leaky abstractions, or missing extension points, prefer improving the SDK instead of normalizing the workaround. The public surface (
@fletch/sdk) starts narrow on purpose and evolves only in response to such friction; after every evolution it must remain simple, intuitive, and powerful.
Architectural boundaries
- Layer separation - adapters depend on the client, the client depends on transport and Arrow packages, transport packages do not depend on adapters or UI libraries.
- Stable public API -
createFletchRuntime()from@fletch/sdk, returning a runtime that producesFletchTablehandles from serializable transport specs, is the stable public surface. Operation helpers are reachable through the@fletch/sdk/operationssubpath. Internal layered packages (@fletch/runtime,@fletch/protocol,@fletch/transport-*,@fletch/operations) compose the SDK and must not be imported by consumer/demo/adapter code. Do not expose internal transport, Arrow IPC, or worker details in adapter APIs. - Transport transparency - application code should not need to know which transport (WebTransport, HTTP/2) is in use. Keep transport internals behind the client abstraction.
- Shared core before public core - private product layers may depend on shared core packages inside the private codebase. If a public repo is created later, public packages must remain independently useful and must never depend on private code. Public evaluation code may prove the core delivery path, but it must not include production convenience features that belong to the commercial gateway.
- Reference server is composition - the reference server composes lower-level crates. Reusable primitives belong in their own crates, not in the server binary.
- SDK-first repo layout -
packages/andcrates/are the reusable SDK layers.demo/is for reference composition, evaluation UX, and demo-only behavior.docs/must describe the same boundary story the code follows. - Single polished demo surfaces —
demo/local-demo/is the local-table evaluation demo anddemo/benchmark/is the benchmark harness. Do not turn this subtree into a second product surface. - Placement rule — if logic could reasonably be reused across more than one demo, app, or product surface, it belongs in
packages/orcrates/. If it exists only to support the local demo, benchmark harness, or local evaluation, it belongs indemo/. - Do not flatten boundaries for convenience - do not move demo-specific concepts into reusable SDK layers just to avoid plumbing or duplicate a small amount of wiring. Prefer composition in
demo/over contaminating the SDK surface. - Keep the protocol boundary clean - shared protocol packages and crates should expose only generic wire contracts such as
DevSqlRequest,OperationRequest, progress, completion, and error types. Do not move demo-domain catalogs, replay presets, or product-specific request shapes back into the shared protocol during unrelated work.
Code guidelines
Code quality
- Readability - code should be immediately understandable to other engineers.
- Appropriate scope - functions and modules should have clear, focused responsibilities.
- Naming clarity - use descriptive names that eliminate the need for explanatory comments.
Comments and documentation
- Minimize inline comments - only use inline comments when the logic is genuinely complex or non-obvious.
- Prefer structured documentation - use docstrings, function comments, and module comments instead of inline comments.
- Focus on "why", not "what" - explain reasoning and trade-offs, not what the code is doing line-by-line.
- Self-documenting code - write code that is simple and well-scoped enough to understand without extensive comments.
Testing
- Every public package or crate should include unit tests for its own logic and at least one integration test at the package boundary.
- End-to-end tests should verify transport equivalence, cancellation, fallback behavior, and progressive rendering.
Validation
After making code changes, run these commands before considering the work done:
just check- always run. Verifies Rust compilation (cargo check) and TypeScript type-checking (tsc --noEmit) across all crates and packages.just lint- always run. Appliescargo fmt,cargo clippy --fix, and Biome auto-fix. Commit the formatting changes it produces.just test- run when changes touch logic with existing tests. Currently runs bothcargo testandpnpm run test.
If any command fails, fix the issue before moving on. Do not skip validation steps.
REMINDER - Primary Directive: Every response MUST deepen the user's understanding. Explain reasoning, surface related context, and build transferable knowledge. Never silently act without ensuring comprehension.