Skip to content
Closed
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
9 changes: 9 additions & 0 deletions antalya/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Antalya Extensions

Location of Antalya-specific designs, documentation, and resources like
agent skills used for development.

## Structure

Echo structure of the repo root. For example, designs go in
antalya/docs/designs. Product documentation goes antalya/docs/en/antalya.
751 changes: 751 additions & 0 deletions antalya/docs/design/alter-table-export-part-partition.md

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions antalya/skills/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Antalya skills

Source-of-truth for project-specific Claude Code skills. Each subdirectory is
one skill, laid out per the Claude Code skills spec:

```
skills/
├── README.md (this file)
└── <skill-name>/
├── SKILL.md (required — YAML frontmatter + body)
└── assets/ | scripts/ | references/ (optional bundled resources)
```

Skills in this directory are **not** auto-discovered. Claude Code looks for
skills in `.claude/skills/` (and a few other locations — see below). To make
a skill here usable, link it into a `.claude/skills/` directory.

## Linking a skill into `.claude/skills/`

From the repo root (`Altinity-ClickHouse/`), create a symlink from
`.claude/skills/<skill-name>` to the corresponding directory under
`antalya/skills/<skill-name>`:

```bash
cd /path/to/Altinity-ClickHouse
mkdir -p .claude/skills
ln -s ../../antalya/skills/antalya-feature-design .claude/skills/antalya-feature-design
```

The link target is relative so the repo is portable across checkout locations.
Verify it resolves:

```bash
ls -l .claude/skills/antalya-feature-design/SKILL.md
# should print the SKILL.md path with no "No such file" error
```

Claude Code will pick the skill up on its next start. Inside a session, type
`/skills` to confirm it's listed, or just trigger it by describing a matching
task.

## Where else `.claude/skills/` is honored

Claude Code scans these locations for skills, in order:

- `<cwd>/.claude/skills/`
- Any `.claude/skills/` in ancestor directories of `<cwd>`
- `~/.claude/skills/` (user-global)
- Installed plugins

For this repo, linking into the top-level `Altinity-ClickHouse/.claude/skills/`
(next to `CLAUDE.md`) covers every working directory under the repo, including
all worktrees. Linking into a specific worktree's `.claude/skills/` (for
example `antalya/.claude/skills/`) scopes the skill to that worktree.

Prefer the top-level link unless a skill is genuinely worktree-specific.

## Adding a new skill

1. Create `antalya/skills/<skill-name>/SKILL.md` with the required frontmatter:
```markdown
---
name: <skill-name>
description: <one-paragraph trigger hint — this is how Claude decides to invoke the skill>
---

# Body...
```
2. Bundle any supporting files under `assets/`, `scripts/`, or `references/`
inside the skill directory.
3. Link it into `.claude/skills/` as shown above.
4. Commit both the skill source (under `antalya/skills/`) and the symlink
(under `.claude/skills/`) so other contributors pick it up.

For guidance on writing a good SKILL.md — especially the description field,
which drives triggering — see the upstream skill-creator docs.

## Removing or renaming

Delete or update both the source directory and its symlink. A broken symlink
under `.claude/skills/` will produce a load-time warning from Claude Code.

## Current skills

- **antalya-feature-design** — scaffold or review a ClickHouse / Antalya
feature design document before implementation.
145 changes: 145 additions & 0 deletions antalya/skills/antalya-feature-design/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
name: antalya-feature-design
description: Scaffold or review a feature design document for ClickHouse / Antalya. Use this whenever a developer wants to design or implement a new feature, add a SQL function, add a setting, add a new engine or format, or change server behavior in a non-trivial way — even if they don't explicitly ask for a "design doc". Also use when reviewing an existing design before implementation starts.
---

# Antalya Feature Design

Help the developer produce a feature design for ClickHouse / Antalya before code is
written. A good design shortens review, prevents abandoned branches, and surfaces compatibility
landmines before they become migrations.

## When to create vs. review

- **Create** when the developer is starting new work and has no design yet, or only a rough idea.
- **Review** when the developer hands you an existing design (file path, paste, or PR link) and
asks for feedback, a critique, or to "check" it.

If unclear, ask one question: "Are we drafting a new design, or reviewing an existing one?"

---

## Creating a design

### 1. Ask a few questions first (don't guess)

The template has four sections. Before filling them in, confirm the basics — a wrong premise wastes
more time than a short interview:

- **What problem is being solved?** Push for a concrete workload or user report, not "users want X".
- **What's the rough shape?** New SQL syntax? A new setting? A new engine/format? A behavior change?
- **Any hard constraints?** Upstream ClickHouse parity, on-disk compatibility, a specific release
train, a customer deadline.
- **Where should the design file live?** Default to `docs/design/<feature-slug>.md` relative to the
repo root, but let the developer override.

If the developer has already answered these in conversation, skip ahead — don't re-interview them.

### 2. Copy the template, then fill it in

The template lives at `assets/design-template.md` next to this `SKILL.md`. Copy it to the chosen
path, then populate each section based on the conversation. Leave a section marked `TBD` with a
pointed question rather than inventing content — a visible gap is more useful than a plausible
fabrication.

The default location for designs is antalya/docs/design. Create a new directory for the design
and place the .md file within it.

### 3. Conventions to apply while writing

These match the project `CLAUDE.md` and make the design consistent with the rest of the codebase:

- Wrap SQL keywords, function names, class names, setting names, engine names, and literal log
message excerpts in inline code blocks: `MergeTree`, `SELECT`, `max_threads`, `system.errors`.
- Refer to functions as `f` (not `f()`) when naming the function itself rather than a call.
- Say "throws an exception" rather than "crashes" for logical errors — release builds don't crash
on `LOGICAL_ERROR`.
- Cite files as `path/to/file.cpp:line` so reviewers can jump directly.
- Prefer one-line statements of intent over prose padding.

Avoid long examples or deep specification detail in the design. Where
such detail is require, such as end-to-end examples or output formats,
put these in files of the form `annex-<name>.md` and reference them with
markdown links.

### 4. Push back on weak spots as you write

Drafting is also a review — don't wait for section 4 to think. In particular:

- If the **Motivation** reduces to "users want X" with no concrete workload, ask for one.
- If **Requirements** are not measurable, say so and suggest a measurable form.
- If there are no **Non-requirements**, propose a few. The absence of non-goals is the single biggest
source of scope creep.
- If **Alternatives considered** is empty, press for at least one rejected approach. A design with
no alternatives considered usually means the author has a solution looking for a problem.

---

## Reviewing a design

Read the design end-to-end first, then walk the checklist below. Report findings grouped by
severity: **blocking** (must fix before implementation), **should-address** (fix before merge),
**nit** (optional). Quote the exact text you're critiquing so the author can find it fast.

### Requirements
- The requirements section define the user problem. The problem should be stated in terms of needed
features, performance goals, delivery deadlines, plus topics we do not need to consider or solve.
- Motivation cites a concrete workload, incident, or user report — not a generic assertion.
- Requirements are measurable. "Faster" is not a requirement; "query `Q` drops from 5s to <500ms on dataset `D`"
is.
- Non-requirements are listed. Missing non-requirement almost always produce scope creep in review.
- Requirements should be generic. Put user-visible product behavior such as SQL commands in the Functional
Specification. Put internal (non-visible behavior) in the Implementation section.

### Functional specification
- The functional specification defines user visible product behavior including SQL commands, system tables,
settings, and error messages.
- Every new/changed SQL syntax has at least one concrete example.
- Every new setting has scope (server / user / query), default, and valid range.
- Default-value changes that alter behavior for existing workloads are called out explicitly.
- Error behavior specifies the error code, not just "throws an error".
- Backward compatibility covers: older client → newer server, newer client → older server,
mixed-version cluster, on-disk format. If any of these is genuinely N/A, the design should say
so — silence is not the same as "not applicable".
- Formatting convention: inline code blocks around SQL identifiers, engine names, settings.

### Implementation
- The implementation section covers internal design that is not visible to the user.
- Architecture section names the subsystems touched (parser / analyzer / planner / executor /
storage / replication / keeper). If it touches many, that's a design smell worth flagging.
- New abstractions pull their weight. If an interface has one implementation and no foreseeable
second, flag it — per project `CLAUDE.md`, three similar lines beat a premature abstraction.
- Storage format changes include a migration path and version-bump strategy.
- Performance section identifies the benchmark that will cover the hot path. Hand-wavy "shouldn't
be a regression" is not enough for hot-path code.
- Alternatives considered contains at least one rejected approach with a reason. A design with no
rejected alternatives is under-explored.
- Error handling lives at boundaries (user input, external systems), not scattered through
internal code that already trusts its callers.

### Test plan
- The test plan defines happy path, edge cases, and error cases.
- Test case definitions should be specific, falsifiable propositions about feature behavior.
- Test case definitions should not contain implementation code, except as necessary
to describe the feature being tested.
- Tests use `tests/queries/0_stateless` for functional coverage and `tests/integration` for
anything touching replication, keeper, distributed queries, S3, auth, or Kafka.
- Performance should be specified if the feature is in the hot path, i.e., affects response or resource usage.

### Cross-cutting red flags
- Feature flags or backwards-compatibility shims added "just in case" — per project `CLAUDE.md`,
prefer changing the code directly when you can.
- Comments in the proposed implementation that restate what the code does, or name the current
task/PR/issue — those belong in commit messages and PR descriptions, not in source.
- Unfinished sections left as `TBD` with no owner or question — either resolve or annotate with
the specific decision needed and who owns it.

---

## Output etiquette

- When creating, write the file and then tell the developer which sections need their input (the
`TBD` items) rather than showing the whole template in chat.
- When reviewing, lead with a one-line verdict ("ready to implement", "needs revisions in
sections 2 and 4", "fundamental rethink needed"), then the grouped findings.
- Keep the review terse. Block quotes from the design plus one-sentence critiques beat long prose.
141 changes: 141 additions & 0 deletions antalya/skills/antalya-feature-design/assets/design-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# Feature Design: [Feature Name]

**Status:** draft | under review | accepted | implemented
**Author(s):**
**Reviewers:**
**Related issues/PRs:**
**Last updated:**

---

## 1. Problem Definition

### Motivation
What problem does this feature solve for users? Why now? Quote user reports, incidents, or concrete
workloads where possible — avoid generic statements like "users want X".

### Requirements
- A series of numbered requirements for the feature.

### Non-requirements
What is explicitly out of scope. Naming non-requirements up front prevents scope creep during review.

### Constraints
Compatibility requirements (older clients, existing on-disk formats, upstream ClickHouse parity),
deadlines, licensing, platform restrictions.

### References
URLs of background documents, GitHub issues, and pull requests that have
information relevant to the design.

---

## 2. Functional specification

### User-facing behavior
Describe the feature strictly from the user's perspective — what they type, what they see back.
No implementation details here.

### SQL syntax / API
Concrete examples. Wrap SQL keywords, function names, setting names, and engine names in inline
code blocks (e.g. `MergeTree`, `SELECT`, `max_threads`).

```sql
-- Example 1: basic usage
SELECT ...

-- Example 2: edge case
...
```

### Settings
Relevant settings, presented in tabular form.

| Setting | Scope | Default | Range | Description |
| --- | --- | --- | --- | --- |
| `setting_name` | server / user / query | ... | ... | ... |

Note which settings are new vs. changes to existing ones, and whether defaults change behavior
for existing workloads.

### System tables / metrics / log messages / observability
New or changed rows in `system.settings`, `system.metrics`, `system.events`, `system.errors`,
`system.*_log`. Any new `ProfileEvents` or `CurrentMetrics. Highlight data that can provide
observability information to ClickHouse administrators.

### Error behavior
What exceptions are thrown, with which error codes, on which inputs. Say "throws exception" rather
than "crashes" — logical errors don't crash release builds.

### Backward compatibility
Highlight compatibility issues, for example:
- Older clients talking to a new server
- New clients talking to an older server
- Mixed-version clusters (replication, distributed queries)
- On-disk format changes (mark version, metadata version)
- Default changes that alter existing query behavior

---

## 3. Implementation

This section may be omitted by the user. In this case the section should left empty
and replaced with a messsage like the following.

"The specification only covers user-visible behavior, hence this section is omitted."

Optionally, also include references to other documents, GitHub issues, or code if
available and relevant.

### Architecture overview
One paragraph, plus a diagram if it helps. Where does the feature live in the codebase, and how
does it connect to existing subsystems (parser → analyzer → planner → executor → storage)?

### Key design decisions
Highlight prominent aspects of the design that an would be useful to implemntors or maintainers.

### Concurrency / locking
Threads involved, locks held, ordering constraints. If none, state that explicitly.

### Storage format changes
Mark/metadata version bumps, migration path, how older parts are read after upgrade, how newer
parts are rejected by older servers.

### Performance
- Expected overhead in the hot path (CPU, memory, I/O)
- Which benchmarks will exercise this (e.g. specific `tests/performance/` cases)
- Memory ownership and lifetime of any new allocations

### Alternatives considered
Short list of approaches you rejected and why. This is the single most useful section for
reviewers — it shows you explored the design space.

### Open questions
Things you don't yet have an answer to. Better to name them than to paper over them.

---

## 4. Test plan

### Functional tests — `tests/queries/0_stateless`
List planned test files. Prefer adding new tests over extending existing ones.

- Golden path: basic feature works on simple input
- Edge cases: empty input, single row, boundary values, max sizes
- Error cases: invalid input produces the expected exception with the expected error code
- Settings interactions: feature off (default), feature on, interaction with related settings
- Compatibility: works with older parts / mixed formats, if relevant

### Integration tests — `tests/integration`
Required if the feature touches replication, keeper, distributed queries, S3, auth, Kafka, etc.
Invoke with `python -m ci.praktika run "integration" --test <selectors>`.

### Performance tests — `tests/performance`
Required if the feature is in the hot path.

### Manual verification
Any checks that aren't automated (UI, metrics dashboards, upgrade scenarios).

### Rollout / risk
Deployment risk, whether a feature flag is warranted (default off? default on?), the existing
tests that guard against regressions, and what to watch in production after rollout.
6 changes: 3 additions & 3 deletions ci/jobs/scripts/integration_tests_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ class TC:
False,
"10-node cluster; fully isolated per test module",
),
TC("test_storage_iceberg_no_spark/", False, "minio/azurite per cluster; fully isolated"),
TC("test_storage_iceberg_with_spark_cache/", False, "package-scoped Spark session; each xdist worker gets its own instance"),
TC("test_storage_iceberg_concurrent/", False, "package-scoped Spark session; each xdist worker gets its own instance"),
TC("test_iceberg_catalog/", True, "no idea why i'm sequential"),
TC("test_iceberg_storage/", True, "no idea why i'm sequential"),
TC("test_export_replicated_mt_partition_to_object_storage/", True, "ZooKeeper can't handle too many parallel requests"),
]

IMAGES_ENV = {
Expand Down
Loading
Loading