Skip to content
Merged
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
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ If these variables are missing, tests that require live encryption will fail or
- `packages/bench`: Performance / index-engagement benchmarks (private, not published)
- `packages/protect-ffi`: Native FFI bindings to the CipherStash Client SDK (`@cipherstash/protect-ffi`) — the Rust core that `packages/stack` encrypts and decrypts through, absorbed from `cipherstash/protectjs-ffi`. Contains a **nested Cargo workspace** (`crates/`) and six per-platform binary packages under `platforms/*`, each published as `@cipherstash/protect-ffi-<platform>` and linked here via `workspace:*`. Also holds the repo's live FFI integration suite at `integration-tests/` — a private workspace member (`@cipherstash/ffi-integration-tests`) enrolled by its own literal entry in `pnpm-workspace.yaml`, needing Docker and credentials, and deliberately carrying **no `test` script** so `pnpm test` cannot reach it. See the "Working on protect-ffi" notes below before touching it — its default `test` and `build` are deliberately Rust-free.
- `packages/eql`: The Encrypt Query Language subtree — the SQL bundle that stores and queries encrypted payloads — absorbed from `cipherstash/encrypt-query-language`. **The directory is the subtree root, not the package.** It was imported at a *verbatim prefix* so its repo-root-relative paths (mise tasks, `Doxyfile`, `sync-generated.mjs`) keep resolving, which puts the npm package `@cipherstash/eql` two levels down at `packages/eql/packages/eql` — the same shape as `packages/protect-ffi/platforms/*`, and enrolled the same way, by an explicit `packages/eql/packages/*` glob in `pnpm-workspace.yaml`. The subtree root deliberately carries no `package.json`. Also contains a **nested Cargo workspace** at `packages/eql/crates/` (`eql-bindings`, published in lockstep with the npm package, plus `eql-domains` / `eql-codegen` / `eql-tests-macros`, which are not), a SQLx test crate at `packages/eql/tests/sqlx`, an ~900-line `mise.toml` task surface, its own `AGENTS.md`, and `docs/`. See the "Working on EQL" notes below before touching it.
**Repository ownership:** EQL now lives in `cipherstash/stack`. File and update
EQL issues in this repository, never in the historical
`cipherstash/encrypt-query-language` repository. Old upstream issue and PR
links are provenance only.
- `e2e/*`: Cross-package end-to-end tests (package managers, supply chain, Prisma example README)
- `examples/*`: Working apps (basic, prisma, supabase-worker)
- `docs/plans/*`: Internal design plans. User-facing documentation lives at https://cipherstash.com/docs (not in this repo).
Expand Down
16 changes: 16 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ one source of truth.

@AGENTS.md

## Agent skills

### Issue tracker

Issues are tracked in GitHub Issues for `cipherstash/stack`. See
`docs/agents/issue-tracker.md`.

### Triage labels

Use the five default triage labels. See `docs/agents/triage-labels.md`.

### Domain docs

Use a multi-context layout rooted at `CONTEXT-MAP.md`, with package-specific
`CONTEXT.md` files added as needed. See `docs/agents/domain.md`.

## Before you finish

Two rules from `AGENTS.md` are the ones most often missed. They are repeated here
Expand Down
14 changes: 14 additions & 0 deletions CONTEXT-MAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Context Map

## Contexts

- [EQL](./packages/eql/CONTEXT.md) — defines the PostgreSQL objects that store
and query encrypted values.

## Relationships

- **EQL → Stack CLI**: EQL ships install and uninstall artifacts; the Stack CLI
applies them and preserves reconstructable database objects across reinstall.
- **EQL → ORM adapters**: EQL defines durable encrypted column domains and
disposable query machinery; adapters create application columns and derived
search indexes against that surface.
50 changes: 50 additions & 0 deletions docs/agents/domain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Domain docs

How engineering skills should consume this repository's domain documentation.

## Before exploring

- Read `CONTEXT-MAP.md` at the repository root when it exists. It points to the
`CONTEXT.md` files relevant to each context.
- Read the context documents relevant to the task.
- Read system-wide ADRs under `docs/adr/` and context-specific ADRs under the
relevant package's `docs/adr/` directory.

If these files do not exist, proceed silently. Do not propose empty placeholder
documents. The domain-modeling workflow creates them lazily when terminology or
decisions are actually resolved.

## Multi-context layout

```text
/
├── CONTEXT-MAP.md
├── docs/adr/ system-wide decisions
└── packages/
├── stack/
│ ├── CONTEXT.md
│ └── docs/adr/ stack-specific decisions
├── cli/
│ ├── CONTEXT.md
│ └── docs/adr/ CLI-specific decisions
└── <context>/
├── CONTEXT.md
└── docs/adr/
```

Nested subtrees with their own architecture, such as `packages/eql`, may define
further contexts. `CONTEXT-MAP.md` is the authority for locating them.

## Use the glossary's vocabulary

When output names a domain concept—in an issue title, proposal, hypothesis, or
test name—use the term defined in the relevant `CONTEXT.md`. Do not drift to a
synonym that the glossary explicitly avoids.

If a needed concept is absent, reconsider whether the project already has a
different term. If the gap is real, record it for domain modeling.

## Flag ADR conflicts

If proposed work contradicts an existing ADR, identify the conflict explicitly
rather than silently overriding the decision.
60 changes: 60 additions & 0 deletions docs/agents/issue-tracker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Issue tracker: GitHub

Issues and specs for this repo live as GitHub issues. Use the `gh` CLI for all
operations.

## Repository ownership

All work present in this monorepo is tracked in `cipherstash/stack`, including
the absorbed EQL source under `packages/eql` and protect-ffi under
`packages/protect-ffi`. Their former upstream repositories are historical
sources, not active issue trackers. Never create, move, or update an issue in
`cipherstash/encrypt-query-language` or `cipherstash/protectjs-ffi` for work in
this tree. Create it in `cipherstash/stack` and link historical upstream issues
only as provenance.

## Conventions

- **Create an issue**: `gh issue create --title "..." --body "..."`. Use a
heredoc for multi-line bodies.
- **Read an issue**: `gh issue view <number> --comments`, filtering comments by
`jq` and also fetching labels.
- **List issues**: `gh issue list --state open --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'`
with appropriate `--label` and `--state` filters.
- **Comment on an issue**: `gh issue comment <number> --body "..."`.
- **Apply/remove labels**: `gh issue edit <number> --add-label "..."` or
`--remove-label "..."`.
- **Close**: `gh issue close <number> --comment "..."`.

Use `--repo cipherstash/stack` explicitly. Do not infer ownership from subtree
history, package names, old issue links, or additional git remotes.

## Pull requests as a triage surface

**PRs as a request surface: no.** Set this to `yes` if this repository starts
treating external pull requests as feature requests.

When enabled, use the corresponding `gh pr` commands. GitHub shares one number
space across issues and pull requests, so resolve an ambiguous `#42` with
`gh pr view 42` and fall back to `gh issue view 42`.

## Skill operations

- When a skill says **publish to the issue tracker**, create a GitHub issue.
- When a skill says **fetch the relevant ticket**, run
`gh issue view <number> --comments`.

## Wayfinding operations

The map is one issue labelled `wayfinder:map`; its tickets are child issues.

- Create child tickets as GitHub sub-issues through `gh api`. If sub-issues are
unavailable, use a task list in the map and add `Part of #<map>` to each
child.
- Label children `wayfinder:<type>` where type is `research`, `prototype`,
`grilling`, or `task`.
- Represent blocking with GitHub's native issue dependencies. Fall back to a
`Blocked by: #<n>` line only when dependencies are unavailable.
- Claim work with `gh issue edit <n> --add-assignee @me`.
- Resolve work by commenting with the result, closing the child, and adding its
context pointer to the map's Decisions-so-far section.
15 changes: 15 additions & 0 deletions docs/agents/triage-labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Triage labels

The engineering skills use five canonical triage roles. This table maps those
roles to this repository's GitHub labels.

| Canonical role | GitHub label | Meaning |
| --- | --- | --- |
| `needs-triage` | `needs-triage` | Maintainer needs to evaluate the issue |
| `needs-info` | `needs-info` | Waiting on the reporter for more information |
| `ready-for-agent` | `ready-for-agent` | Fully specified and ready for an AFK agent |
| `ready-for-human` | `ready-for-human` | Requires human implementation |
| `wontfix` | `wontfix` | Will not be actioned |

When a skill names a triage role, use the corresponding GitHub label from this
table.
5 changes: 5 additions & 0 deletions packages/eql/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CLAUDE.md

> **Repository ownership:** EQL is maintained in the `cipherstash/stack`
> monorepo. Track all EQL work in `cipherstash/stack` GitHub Issues. The former
> `cipherstash/encrypt-query-language` repository and its issues are historical
> provenance only; do not create or update active work there.

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Development Commands
Expand Down
31 changes: 31 additions & 0 deletions packages/eql/CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Encrypt Query Language

EQL defines the PostgreSQL representation and query surface for searchable
encrypted values.

## Language

**Encrypted data**:
Ciphertext and search terms stored in an application table column. Its continued
existence is the primary persistence guarantee.
_Avoid_: EQL machinery, index state

**Data-bearing domain**:
A durable `public.eql_v3_*` PostgreSQL domain used as an application column type.
It must survive EQL install, uninstall, and reinstall.
_Avoid_: Query domain, EQL schema type

**EQL machinery**:
Disposable functions, query-operand types, operators, aggregates, and internal
types owned by the `eql_v3` and `eql_v3_internal` schemas.
_Avoid_: Encrypted data

**Derived search index**:
A reconstructable functional index over EQL machinery. It accelerates encrypted
queries but is not the authoritative copy of encrypted data.
_Avoid_: Encrypted data, durable data

**Non-reconstructable dependency**:
A customer-owned constraint, policy, view, or other database object whose
meaning cannot be safely inferred and recreated by the EQL installer.
_Avoid_: Derived search index
Loading