Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,37 @@ before completion.
- Write Markdown prose one sentence per line, with no hard wrapping, so diffs
stay readable.

### Fixing bugs

Reproduce a bug with a failing test before fixing it, including bugs raised in review.
Show the test failing without the fix and passing with it.

### Design before implementation

Once a design is agreed, write it up as a spec and break it into tickets before opening an implementation PR.

### Maintenance branches

`release/2.2` is maintained separately from `main` and has a different architecture.
A fix needed on both is implemented and reviewed against each branch, not cherry-picked.

### Release documentation

For user-facing or notable changes, update the `CHANGELOG.md` `[Unreleased]`
section using Keep a Changelog categories and user-facing language. For a
significant release, prepare `ANNOUNCEMENT.md` for GitHub Discussions and
remove that temporary file after publishing it.

## Commits and pull requests

This repository is public.

- Never put private Linear issue keys (`CIP-####`) or Linear links in PR titles, PR bodies, PR comments, commit messages, branch names or code comments. See `docs/agents/issue-tracker.md`.
- Never put links to private agent sessions or threads (for example claude.ai session or project URLs, or `Claude-Session:` trailers) in PRs, PR comments or commit messages.
- Every commit pushed to a PR must be signed and show as verified on GitHub; `main` requires it. This is separate from the DCO sign-off in `CONTRIBUTING.md`.
- Never rewrite history with `git filter-branch`, which drops signatures. To reword or re-sign your own branch, use `git rebase --force-rebase --gpg-sign <base>` and check each commit with `git cat-file commit <sha>` before force-pushing with a lease.
- When a PR has a review in progress, comment on it before pushing: say what is coming and whether it is a fast-forward.

## Pull request CI ownership

When a task authorizes pushing changes to a pull request, use passing required
Expand All @@ -53,8 +77,11 @@ After every push:
1. The main agent must spawn a background subagent whose role is **monitor
only**. The monitor may inspect the PR, wait for checks with
`gh pr checks --watch`, and collect failed-run logs with read-only `gh`
commands. It must not edit files, run formatting that changes files, commit,
push, or perform any other repository mutation.
commands. Where GitHub's GraphQL API is unavailable (`gh pr checks` then
fails), read check state over REST with
`gh api repos/cipherstash/proxy/commits/<sha>/check-runs`. It must not
edit files, run formatting that changes files, commit, push, or perform any
other repository mutation.
2. The monitor must return the final check state and, for failures, the failed
check names, run identifiers, and relevant failure output to the main agent.
3. The main agent is the sole writer. It must diagnose the failure, edit the
Expand Down
32 changes: 32 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,13 @@ To run integration tests:
mise run test:integration
```

`mise run test` (which CI runs) stops at the first stage that fails.
The stages run in this order: hygiene, unit tests, then the integration stages (psql, Rust integration, multitenant, showcase, Go, Python).
A failing unit test therefore means no integration test runs, so a red CI run says nothing about the integration suite.
To show that an integration test fails on its own, push it in a commit without any failing unit test.

Integration tests run Proxy with `CS_DEVELOPMENT__ENABLE_MAPPING_ERRORS` unset, which is the production default (off).

#### Integration tests

Integration tests are defined in `tests/tasks/test/`.
Expand Down Expand Up @@ -795,6 +802,17 @@ Struct definitions make error message strings slightly clearer.

Note: not all errors do this at the moment, and we will change over time.

## Merging into main

A pull request into `main` needs:

- the `Build (Rust MSRV)` check from `test.yml` to pass on the PR. A manually dispatched run of the workflow does not satisfy it;
- one approving review;
- signed commits.

Pushing after an approval does not dismiss it.
The ruleset also requires an extra approval for unattributed changes, so a commit pushed after the approval by an account other than the PR's author can leave the PR blocked until it is approved again.

## Releasing

Releases are published via GitHub Actions when a GitHub release is created.
Expand Down Expand Up @@ -846,6 +864,20 @@ git push origin vX.Y.Z
gh release create vX.Y.Z --generate-notes
```

### Patch releases of an older line (for example 2.2.x)

Patch releases of an older major or minor line are cut from its maintenance branch (for example `release/2.2`), not from `main`.
`mise run release` refuses any branch but `main`, so use the manual steps, with the prepare-release PR opened against the maintenance branch and the tag created on its merged commit.

The release workflow runs from the tagged commit, so it uses that branch's `release.yml`.
`docker/metadata-action` defaults to `latest=auto`, which tags the image `cipherstash/proxy:latest` for a release tag.
Unless the branch's `release.yml` sets `flavor: latest=false` on its metadata steps, an older-line release moves `latest` off the current line.
Create the GitHub release with `--latest=false`, and pass `--notes-start-tag` with the previous tag on that line so the generated notes do not diff against a newer line's tag:

```bash
gh release create v2.2.6 --target release/2.2 --latest=false --generate-notes --notes-start-tag v2.2.5
```

### Re-releasing a version

If a release fails and you need to re-release the same version:
Expand Down
8 changes: 6 additions & 2 deletions docs/agents/issue-tracker.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,12 @@ The Product Engineering workflow:

## Linking PRs to issues

Reference the issue key in the PR title or body (e.g. `CIP-3233`) so Linear's GitHub
integration attaches the PR to the issue automatically.
This repository is public and Linear is private.
Never put a Linear issue key (`CIP-####`) or a `linear.app` link in a PR title, PR body, PR comment, commit message, branch name or code comment.
Describe the change in its own words instead.

Link the other way: add the PR URL to the Linear issue as a link.
Before opening a PR or pushing, check the PR text and `git log <base>..HEAD --format=%B` for `CIP-`.

## PRs as a request surface

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ mod tests {
///
/// Tests unmappble statements return an error in tests.
///
/// `enable_mapping_errors` should be `true` in the test configuration.`
/// Integration tests run with `enable_mapping_errors` off (the default), so the type
/// check failure is not raised by Proxy; the statement is forwarded and PostgreSQL
/// rejects it because the table does not exist.
Comment on lines +8 to +10

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: this doc comment sits above mod tests item unmappable_table_not_found but reads as a statement about the whole file. "PostgreSQL rejects it because the table does not exist" is true only for SELECT blah FROM vtha. The other tests here (unmappable_column_not_found, unmappable_native_cannot_be_unified_with_encrypted, unmappable_syntax_error) hit an existing table and fail for other reasons (missing column, type mismatch, parse error). Consider scoping the sentence to the first test, or saying "PostgreSQL or Proxy's parser rejects it".

Source: packages/cipherstash-proxy-integration/src/select/unmappable.rs:8-10 at 3abd3b3.


Generated by Claude Code

///
/// Test ensures that unmappable SQL statements return an error
///
Expand Down
3 changes: 3 additions & 0 deletions packages/cipherstash-proxy/CONTEXT.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ statement is forwarded only for a named reason: `SET CIPHERSTASH.UNSAFE_DISABLE_
was issued on this connection, EQL Mapper does not type check its kind, it touches no
encrypted column, or the **type-check fallback**. These are not interchangeable.
Name the condition rather than saying "passthrough" alone.
Kinds EQL Mapper does not type check include `DO` and `CALL`: Proxy cannot see the SQL their bodies run, so they are forwarded as written, which is a known limitation.

**Route**:
What Proxy does with one statement from a Query or Parse: map it, forward it for a named
Expand Down Expand Up @@ -155,6 +156,8 @@ state.
An immutable, monotonically versioned pair of database structure and column encryption
metadata loaded from PostgreSQL. The pair is published atomically because a table without its
encryption policy (or an encryption policy without its table) is not a valid observable state.
It holds the tables in the schemas on the search path of Proxy's own loading connection, each recorded with its schema.
A bare table name found in more than one of those schemas does not resolve, because a client can change its `search_path` without Proxy seeing it; when encrypted columns are configured, a write that uses it is refused.

**Transaction schema overlay**:
The confirmed effects of successful DDL executions in one connection's current transaction.
Expand Down
1 change: 0 additions & 1 deletion tests/mise.tcp.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ CS_DATABASE__HOST = "postgres"
CS_DATABASE__PORT = "5532"
CS_PROMETHEUS__ENABLED = "true"
CS_LOG__LEVEL = "debug"
CS_DEVELOPMENT__ENABLE_MAPPING_ERRORS = "true"
CS_DEVELOPMENT__DISABLE_MAPPING = "false"
1 change: 0 additions & 1 deletion tests/mise.tls.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ CS_TLS__TYPE = "Path"
CS_TLS__CERTIFICATE_PATH = "/etc/cipherstash-proxy/server.cert"
CS_TLS__PRIVATE_KEY_PATH = "/etc/cipherstash-proxy/server.key"
CS_SERVER__REQUIRE_TLS = "true"
CS_DEVELOPMENT__ENABLE_MAPPING_ERRORS = "true"
Loading