RDST is organized around two top-level concepts:
features/: vertical slices that own business behaviorshared/: infrastructure and platform substrate
lib/ has been removed. New code should not recreate a generic dumping ground under another name.
A feature owns its:
models.pyevents.pyservice.pycli/api/- feature-specific helpers, workflows, prompts, and engines
If code mainly exists to serve one feature, it belongs in that feature even if it is reused by multiple files inside the slice.
shared/ is for reusable substrate such as:
- API bootstrap and generic route infrastructure
- CLI bootstrap and parser data
- target/config persistence
- DB connection and password/secret resolution
- LLM provider abstraction
- query registry substrate
- workflow runtime
- UI primitives
- generic execution layers like
data_manageranddata_manager_service
shared/ should not own feature prompts, feature workflows, feature-specific engines, or domain services.
Preferred dependency flow:
rdst.py / mcp_server.py
-> features/*
-> shared/*
features/*
-> shared/*
shared/*
-> shared/*
Avoid:
shared/* -> features/*- cross-feature imports unless the dependency is truly another feature's public surface
- rebuilding a monolith under
shared/
- rdst.py: CLI entrypoint
- mcp_server.py: MCP server entrypoint
Current feature-owned domains:
agentanalyzeaskauditcacheconfiguredemofleetguardinitinteractivequery_registryscanschemaslacktoptrial
Each slice should be readable from its models.py and service.py first. That is the feature contract.
agent: agent runtime and MCP-facing agent behavioranalyze: query analysis, explain flows, rewrite evaluation, analysis renderingask: natural-language-to-SQL, Ask engine, validation, Ask prompts, Ask debug toolingaudit: audit workflows, capture, storage, scoring, audit promptscache: Readyset setup, cacheability, deployment, cache command flowsconfigure: target configuration, connection profiles, setup wizard, config APIdemo: demo setup and sample data loadingfleet: fleet discovery, fleet modeling, fleet snapshots, pricing/scoring supportguard: guardrail configuration, masking, intent checks, guard CLIinit: first-run setup and environment/bootstrap validationinteractive: interactive query status and interactive command flowquery_registry: saved query management, registry APIs, query execution helpersscan: codebase scanning, ORM extraction, query discovery, scan analysisschema: schema inspection, semantic layer management, annotation flowsslack: Slack bot, Slack formatting, Slack manifest/handler logictop: live/top query monitoring, realtime display, top command setstrial: trial registration and trial status flows
Key shared areas:
- shared/api
- shared/cli
- shared/config
- shared/data_manager
- shared/data_manager_service
- shared/db_connection.py
- shared/password_resolver.py
- shared/llm_manager
- shared/query_registry
- shared/ui
- shared/workflow_manager.py
- shared/workflow_manager_runtime.py
- rdst.py parses top-level arguments.
- shared/cli/rdst_cli.py provides CLI orchestration and dispatch.
- Command execution is delegated into feature commands such as:
features.configure.cli.commandfeatures.analyze.cli.commandfeatures.top.cli.commandfeatures.schema.cli.command
- Feature services use shared infrastructure for storage, DB access, workflow execution, and UI output.
- shared/api/app.py creates the FastAPI app.
- It mounts feature routers directly from
features/*/api. - Shared API modules provide only generic app/bootstrap concerns such as:
- static serving
- common guards
- environment/dev/report/status routes
Typical service flow:
feature CLI or API
-> feature service
-> shared infra
-> external systems (DB, LLM, filesystem, keychain, Docker, web)
shared/config/targets.py owns:
- target persistence
- connection-string parsing
- engine normalization
- default ports
- LLM config persistence
Do not reintroduce target/config ownership into CLI modules.
shared/data_manager and shared/data_manager_service are intentionally shared.
They provide:
- connection/runtime types
- execution machinery
- system-level command substrate
They do not own feature SQL catalogs anymore. Feature-owned command sets live with their features:
features/top/command_sets.pyfeatures/cache/command_sets.pyfeatures/schema/command_sets.pyfeatures/init/command_sets.py
Prompts, heuristics, engines, and workflows that are specific to a feature belong in that feature. shared/ may host generic LLM plumbing, but not feature prompt libraries.
Do not import Rich directly in application code. Use shared/ui instead.
# NO
from rich.console import Group
from rich.text import Text
# YES
from shared.ui import Group, Text, Tree, Spinner, LiveIf a Rich component is missing, export it from shared.ui rather than importing rich.* directly in a feature or shared module.
Do not put code in shared/ just because:
- it is imported in more than one file
- it used to live in
lib/ - it feels “utility-like”
Questions to ask before adding a module to shared/:
- Is this infrastructure rather than business logic?
- Would it make sense even if the owning feature disappeared?
- Is it generic enough to serve multiple features without encoding one feature's language or workflow?
If the answer is no, put it in a feature slice.
- If you are implementing user-facing behavior, start in
features/. - If you are implementing reusable substrate, start in
shared/. - If a
shared/module starts mentioning one feature's concepts repeatedly, move it back into that feature.
- Add or change a CLI command:
features/<name>/cli/command.py - Add or change an API endpoint:
features/<name>/api/ - Add domain models or events:
features/<name>/models.py,features/<name>/events.py - Add feature behavior:
features/<name>/service.py - Add shared config or DB plumbing:
shared/config/,shared/db_connection.py - Add reusable UI primitives:
shared/ui/ - Add parser/bootstrap CLI wiring:
shared/cli/ - Add API bootstrap or generic routes:
shared/api/