database-lab-engine
CLAUDE.md2.8k starsChanged 4 months agoApache-2.0View on GitHub
We split this CLAUDE.md into the rules it gives an agent
60 rules. About 0 are common, 54 are distinctive, and 6 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈54
Distinctive · estimate
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 27
Always run tests before pushing: If tests fail, do not push.
- Very specific: line 32
Run unit tests: cd engine && make test
- Very specific: line 33
Run integration tests: cd engine && make test-ci-integration
- Very specific: line 34
Run a specific test: cd engine && GO111MODULE=on go test -v ./path/to/package -run TestName
- Very specific: line 35
Run UI: cd ui && pnpm start:ce (Community Edition) or pnpm start:platform
- Distinctive: line 39
Use present tense and imperative mood in commit messages
- Distinctive: line 41
All Git commits must be signed
- Distinctive: line 43
Use error handling with pkg/errors
- Distinctive: line 44
Follow standard Go import ordering
- Distinctive: line 51
Always run tests, linter and normalize comments BEFORE committing anything
- Distinctive: line 52
Run formatting, code generation, linting and testing on completion
- Distinctive: line 53
Never commit without running completion sequence
- Distinctive: line 54
Run tests and linter after making significant changes to verify functionality
- Distinctive: line 57
Do not add comments that describe changes, progress, or historical modifications
- Distinctive: line 59
After important functionality added, update README.md accordingly
- Distinctive: line 60
When merging master changes to an active branch, make sure both branches are pulled and up to date first
- Distinctive: line 61
Don't leave commented out code in place
- Distinctive: line 63
Avoid multi-level ifs, never use else if
- Distinctive: line 65
Avoid else branches if possible
- Distinctive: line 66
Write tests in compact form by fitting struct fields to a single line (up to 130 characters)
- Distinctive: line 67
Before any significant refactoring, ensure all tests pass and consider creating a new branch
- Distinctive: line 68
When refactoring, editing, or fixing failed tests:
- Distinctive: line 69
Do not redesign fundamental parts of the code architecture
- Distinctive: line 70
If unable to fix an issue with the current approach, report the problem and ask for guidance
- Distinctive: line 99
Use descriptive error messages that help with debugging
- Very specific: line 100
Use error wrapping: fmt.Errorf("failed to process request: %w", err)
- Distinctive: line 101
Check errors immediately after function calls
- Distinctive: line 105
Use descriptive camelCase names for variables and functions
- Distinctive: line 110
Use constants for magic numbers and strings
- Distinctive: line 111
Use meaningful names for constants and enums
- Distinctive: line 115
Use descriptive parameter names that indicate their purpose
- Distinctive: line 116
Consider using parameter structs for functions with many (4+) parameters
- Distinctive: line 117
If function returns 3 or more results, consider wrapping in Result/Response struct
- Distinctive: line 118
If function accepts 3 or more input parameters, consider wrapping in Request/Input struct (but never add context to struct)
- Distinctive: line 121
All exported functions, types, and methods must have clear godoc comments
- Distinctive: line 124
Document any non-obvious behavior or edge cases
- Distinctive: line 125
All comments should be lowercase, except for godoc public functions and methods
- Distinctive: line 129
Keep code modular with focused responsibilities
- Distinctive: line 132
Use interfaces to define behavior and enable mocking for tests
- Distinctive: line 133
Keep code minimal and avoid unnecessary complexity
- Distinctive: line 134
Don't keep old functions for imaginary compatibility
- Distinctive: line 137
Consider nested functions when they simplify complex functions
- Distinctive: line 140
Keep cyclomatic complexity under 30
- Distinctive: line 143
Don't break down functions too small as it can reduce readability
- Distinctive: line 145
Keep lines under 130 characters when possible
- Distinctive: line 146
Avoid if-else chains and nested conditionals:
- Distinctive: line 147
Never use long if-else-if chains.
- Distinctive: line 148
Prefer early returns to reduce nesting depth
- Distinctive: line 150
Use context structs or functional options instead of multiple boolean flags
- Very specific: line 153
Write thorough tests with descriptive names (e.g., TestRouter_HandlesMiddlewareCorrectly)
- Distinctive: line 154
Prefer subtests or table-based tests, using Testify
- Distinctive: line 155
Use table-driven tests for testing multiple cases with the same logic
- Distinctive: line 156
Test both success and error scenarios
- Distinctive: line 159
Keep tests compact but readable
- Distinctive: line 160
If test has too many subtests, consider splitting it to multiple tests
- Distinctive: line 161
Never disable tests without a good reason and approval
- Distinctive: line 163
Don't create new test files if one already exists matching the source file name
- Distinctive: line 164
Add new tests to existing test files following the same naming and structuring conventions
- Distinctive: line 165
Don't add comments before subtests, t.Run("description") already communicates what test case is doing
- Distinctive: line 166
Never use godoc-style comments for test functions
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
@AGENTS.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Architecture Overview
Core Components
- Backend code (
engine/) 1.1. Entry Points (cmd/) - Frontend code (
ui/)
Notable patterns
- Source-detection logic lives in
engine/internal/retrieval/probe/. TheProposeorchestrator returns a structuredProposedConfigconsumed by both the/admin/probe-sourceHTTP handler and thedblab local-installCLI (engine/cmd/cli/commands/localinstall/). Extend probe rules there, not intools/db/pg.go. - Config projection (
engine/pkg/models/configuration.go+engine/pkg/util/projection/) walks only top-level struct fields with single flatproj:"..."paths — no recursion into nested structs. TheRetrievalModefield onConfigProjectioncarries noproj:tag because it's a synthetic field injected byprojectedAdminConfigafterStoreJSON; the request-side dispatcher reads it directly from the incoming JSON map. A projection field for a key that is not pre-seeded in the config scaffold (e.g.connectionString) needs the,createKeytag —projection.Setsilently skips a missing leaf without it. - Mode-aware config writes:
applyProjectedAdminConfigdispatches on the syntheticretrievalMode, andguardModeFieldsenforces a per-mode allow-list of populated fields so logical-only fields cannot leak into a physical config (and vice-versa). - Source connection-string passthrough: when
logicalDump.options.source.connectionStringis set it wins over the discreteconnection.*fields.logical/connstring.go(withDatabase,sourcePgxConfig) preserves every libpq option (sslmode, connect_timeout, …) end-to-end intopg_dump(-d <conninfo>) and the engine's own pgx connections to the source (getDBList,dbSourceActivity). The password is always injected separately — never embedded in the string. Restore paths target the local container and must never receive it. - Clone major upgrade (
engine/internal/{provision,cloning,srv}/upgrade.go+scripts/pg_upgrade_clone.sh+Dockerfile.pg-upgrade):pg_upgrade --linkconverts a clone's data directory in place. Four invariants hold the design together:FATALis a data-destroying status.filterRunningClones(cloning/storage.go) drops any wrapper whose status isFATALor whose container is not running, andcleanupInvalidClonesthen destroys its dataset. So a running clone must never be markedFATAL; failures that leave the clone up useStatusWarning. Anything that has to survive a restart must also be persisted withSaveClonesState()—UpdateCloneStatusonly mutates memory.- Recovery is decided from the data directory, not from a breadcrumb — and only a positive marker proves completion. Every passive marker in the directory is already in place before the transfer begins: a target-major
PG_VERSIONindata_newis written by the script'sinitdb, andpg_upgraderenamesglobal/pg_controlaway when linking starts, not when it finishes (see "Reverting to old cluster" in thepg_upgradedocs). So a run killed part-way through the transfer is indistinguishable from a finished one by those facts alone. The script therefore writesdata_new/.dblab_upgrade_doneoncepg_upgradehas returned 0, andclassifyOutcomepromotes only on a completed swap or on that marker (ConversionDone); everything else with a disabled old cluster is arecoveryReprovision. Treating thepg_controlrename as proof of completion would promote a partially linked cluster, report success, and then delete the old directory holding the only copy of whatever had not been linked yet. The marker is removed once the swap is promoted, so it can never vouch for a later upgrade. Exit codes are carried into the status message bydescribeExitCodeand never classify anything.Base.RecoverInterruptedUpgradesruns fromRunbeforefilterRunningClonesfor the same reason as the first invariant, and a missingupgrade/state.jsonmeans there is nothing in flight (UpgradeUnchanged), never a failure. - The target major is the instance's, not the caller's.
Dockerfile.pg-upgradetakesPG_MAJORfrom its base image, so one configuredprovision.pgUpgradeImagemeans exactly one reachable target; there is nothing for an API field to choose.Provisioner.UpgradeTargetVersionderives it —probe.MajorFromImageoff the tag, falling back toPG_MAJORin the image config (docker.ImagePGMajor) for a tag outside the release grammar, cached under the image it came from so aReloadthat repointspgUpgradeImagecannot be answered from the old entry. Only released images carry a bare-major tag (CI publishespg-upgrade:17-<branch>), soResolveUpgradeTargetfetches the image in the background frommain.goand onReload; without it the feature would sit unavailable on every non-released instance.Server.cloneUpgradeStatusadvertises the result ascloneUpgradeon/statusso clients display the version instead of asking for one, andverifyUpgradeImageMajorre-reads the image before the clone goes down — a tag only claims a major while the image states one — which also refreshes the cache. An inspect error there fails the upgrade rather than passing the guard:docker.ImagePGMajorreturns(0, nil)only for an image that genuinely declares noPG_MAJOR. - The engine owns every directory operation inside the clone directory. It belongs to the engine OS user while the upgrade container runs as the data-directory owner (resolved by stat'ing it, not assumed — the image entrypoint gosu-chowns PGDATA to uid 999 while
zfs.gochowns the dataset touser.Current()). The container therefore cannot createdata_newor rename anything; the engine pre-creates the empty target, chowns it plus theupgrade/working area, and performs the swap itself.
- Engine-side image resolution:
probe/registry.goresolves a glibc-aware docker image by querying the live registries (Docker Hub for the generic image, GitLab for managed-provider SE images) with a per-repo TTL cache and ago:embedoffline snapshot (images_fallback.json). Resolution never hard-fails or hangs: fresh cache → live fetch (bounded) → last good cache → embedded snapshot → provider default<repo>:<major>. Tag selection (imageselect.go) is pure and unit-tested; theRegistryis built once onServer.
Testing Before Pushing
Always run tests before pushing. If tests fail, do not push. Fix the failing tests first. Only skip this if the user explicitly says to ignore test failures.
Build/Test/Lint Commands
- Build all components:
cd engine && make build - Lint code:
cd engine && make run-lint - Run unit tests:
cd engine && make test - Run integration tests:
cd engine && make test-ci-integration - Run a specific test:
cd engine && GO111MODULE=on go test -v ./path/to/package -run TestName - Run UI:
cd ui && pnpm start:ce(Community Edition) orpnpm start:platform
Code Style Guidelines
- Go code follows "Effective Go" and "Go Code Review Comments" guidelines
- Use present tense and imperative mood in commit messages
- Limit first commit line to 72 characters
- All Git commits must be signed
- Format Go code with
cd engine && make fmt - Use error handling with pkg/errors
- Follow standard Go import ordering
- Group similar functions together
- Error messages should be descriptive and actionable
- UI uses pnpm for package management
Important Backend Workflow Notes
- Always run tests, linter and normalize comments BEFORE committing anything
- Run formatting, code generation, linting and testing on completion
- Never commit without running completion sequence
- Run tests and linter after making significant changes to verify functionality
- IMPORTANT: Never put into commit message any mention of Claude or Claude Code
- IMPORTANT: Never include "Test plan" sections in PR descriptions
- Do not add comments that describe changes, progress, or historical modifications
- Comments should only describe the current state and purpose of the code, not its history or evolution
- After important functionality added, update README.md accordingly
- When merging master changes to an active branch, make sure both branches are pulled and up to date first
- Don't leave commented out code in place
- Avoid multi-level nesting
- Avoid multi-level ifs, never use else if
- Never use goto
- Avoid else branches if possible
- Write tests in compact form by fitting struct fields to a single line (up to 130 characters)
- Before any significant refactoring, ensure all tests pass and consider creating a new branch
- When refactoring, editing, or fixing failed tests:
- Do not redesign fundamental parts of the code architecture
- If unable to fix an issue with the current approach, report the problem and ask for guidance
- Focus on minimal changes to address the specific issue at hand
- Preserve the existing patterns and conventions of the codebase
Backend Code Style Guidelines
Import Organization
- Organize imports in the following order:
- Standard library packages first (e.g., "fmt", "context")
- A blank line separator
- Third-party packages
- A blank line separator
- Project imports (e.g., "gitlab.com/postgres-ai/database-lab/v3/pkg/*")
- Example:
import ( "context" "fmt" "net/http" "github.com/docker/docker/api/types" "github.com/gorilla/mux" "gitlab.com/postgres-ai/database-lab/v3/pkg/util/branching" )
Error Handling
- Return errors to the caller rather than using panics
- Use descriptive error messages that help with debugging
- Use error wrapping:
fmt.Errorf("failed to process request: %w", err) - Check errors immediately after function calls
- Return early when possible to avoid deep nesting
Variable Naming
- Use descriptive camelCase names for variables and functions
- Good:
notFoundHandler,requestContext,userID - Bad:
not_found_handler,x,temp1 - Be consistent with abbreviations (e.g.,
httpClientnotHTTPClient) - Local scope variables can be short (e.g., "lmt" instead of "orderLimit")
- Use constants for magic numbers and strings
- Use meaningful names for constants and enums
Function Parameters
- Group related parameters together logically
- Use descriptive parameter names that indicate their purpose
- Consider using parameter structs for functions with many (4+) parameters
- If function returns 3 or more results, consider wrapping in Result/Response struct
- If function accepts 3 or more input parameters, consider wrapping in Request/Input struct (but never add context to struct)
Documentation
- All exported functions, types, and methods must have clear godoc comments
- Begin comments with the name of the element being documented
- Include usage examples for complex functions
- Document any non-obvious behavior or edge cases
- All comments should be lowercase, except for godoc public functions and methods
- IMPORTANT: all comments except godoc comments must be lowercase, test messages must be lowercase, log messages must be lowercase
Code Structure
- Keep code modular with focused responsibilities
- Limit file sizes to 300-500 lines when possible
- Group related functionality in the same package
- Use interfaces to define behavior and enable mocking for tests
- Keep code minimal and avoid unnecessary complexity
- Don't keep old functions for imaginary compatibility
- Interfaces should be defined on the consumer side (idiomatic Go)
- Aim to pass interfaces but return concrete types when possible
- Consider nested functions when they simplify complex functions
Code Layout
- Keep cyclomatic complexity under 30
- Function size preferences:
- Aim for functions around 50-60 lines when possible
- Don't break down functions too small as it can reduce readability
- Maintain focus on a single responsibility per function
- Keep lines under 130 characters when possible
- Avoid if-else chains and nested conditionals:
- Never use long if-else-if chains; use switch statements instead
- Prefer early returns to reduce nesting depth
- Extract complex conditions into separate boolean functions or variables
- Use context structs or functional options instead of multiple boolean flags
Testing
- Write thorough tests with descriptive names (e.g.,
TestRouter_HandlesMiddlewareCorrectly) - Prefer subtests or table-based tests, using Testify
- Use table-driven tests for testing multiple cases with the same logic
- Test both success and error scenarios
- Mock external dependencies to ensure unit tests are isolated and fast
- Aim for at least 80% code coverage
- Keep tests compact but readable
- If test has too many subtests, consider splitting it to multiple tests
- Never disable tests without a good reason and approval
- Important: Never update code with special conditions to just pass tests
- Don't create new test files if one already exists matching the source file name
- Add new tests to existing test files following the same naming and structuring conventions
- Don't add comments before subtests, t.Run("description") already communicates what test case is doing
- Never use godoc-style comments for test functions
Trending
Quiet since February.thin dataabout the whole repository
Who's talking about postgres-ai/database-lab-engine
- A Hacker News story“Thin PostgreSQL Clones”Hacker News · Jan 25, 2022 · 114 points
- A Hacker News story“Database Lab Engine 3.1 for PostgreSQL”Hacker News · Apr 5, 2022 · 2 points
- A Hacker News story“Database Lab Engine 3.0 for PostgreSQL”Hacker News · Dec 22, 2021 · 1 points
- ariffazil/arifOS“[P3] Sprint 3.2: Add Database Lab Engine for F1 Reversibility”GitHub · Feb 3, 2026
- github/release-radar“[Release Radar Request] Database Lab Engine v3.0.0”GitHub · Dec 22, 2021
The biggest 5 of 5 mentions linking to the repository that our crawl found. Each line is their own headline.
In this repositoryOne other file it gives its agents.
- AGENTS.mdAGENTS.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

