Version Upgrade Advisor
chmonitor/chmonitor
Advises whether and how to upgrade ClickHouse — versioning scheme, upgrade path, what you gain, pre/post-upgrade checklist.
Edit an auto-generated ClickHouse release changelog into the form that gets committed to CHANGELOG.md.
$ npx skills add ClickHouse/ClickHouse --skill edit-changelog -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ClickHouse/ClickHouse edit-changelog --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/ClickHouse/ClickHouse.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/edit-changelog .claude/skills/edit-changelog && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "edit-changelog" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelog into .claude/skills/edit-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "edit-changelog", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelogType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add ClickHouse/ClickHouse --skill edit-changelog -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ClickHouse/ClickHouse edit-changelog --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ClickHouse/ClickHouse.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.claude/skills/edit-changelog .agents/skills/edit-changelog && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "edit-changelog" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelog into .agents/skills/edit-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "edit-changelog", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ClickHouse/ClickHouse --skill edit-changelog -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ClickHouse/ClickHouse edit-changelog --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ClickHouse/ClickHouse.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.claude/skills/edit-changelog .cursor/skills/edit-changelog && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "edit-changelog" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelog into .cursor/skills/edit-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "edit-changelog", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/ClickHouse/ClickHouse.git --path .claude/skills/edit-changelog--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add ClickHouse/ClickHouse --skill edit-changelog -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ClickHouse/ClickHouse edit-changelog --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ClickHouse/ClickHouse.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.claude/skills/edit-changelog .gemini/skills/edit-changelog && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "edit-changelog" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelog into .gemini/skills/edit-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "edit-changelog", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install ClickHouse/ClickHouse edit-changelogInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add ClickHouse/ClickHouse --skill edit-changelog -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/ClickHouse/ClickHouse.git skills-src && mkdir -p .github/skills && cp -r skills-src/.claude/skills/edit-changelog .github/skills/edit-changelog && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "edit-changelog" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelog into .github/skills/edit-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "edit-changelog", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add ClickHouse/ClickHouse --skill edit-changelog -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install ClickHouse/ClickHouse edit-changelog --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/ClickHouse/ClickHouse.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.claude/skills/edit-changelog .opencode/skills/edit-changelog && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "edit-changelog" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/edit-changelog into .opencode/skills/edit-changelog/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "edit-changelog", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
edit-changelogEdit an auto-generated ClickHouse release changelog into the form that gets committed to CHANGELOG.md.
Edit Changelog is an agent skill from ClickHouse/ClickHouse. Edit an auto-generated ClickHouse release changelog into the form that gets committed to CHANGELOG.md. Use when the user has the output of utils/changelog/changelog.py and wants it cleaned up and re-categorized for a release.
Its SKILL.md is about 11k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Development, covering Changelog and release notes and Data warehousing. It works with ClickHouse. The repository describes itself as: ClickHouse® is a real-time analytics database management system. The licence is Apache-2.0.
10 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit c873902. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
BashReadEditWriteGrepGlobTaskFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
ghgitclickhouseFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
github.compresentations.clickhouse.comyoutube.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Edit Changelog loads about 11k tokens when it runs. Until then it costs about 61 tokens; SKILL.md has 6,232 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
allowed-tools: Bash, Read, Edit, Write, Grep, Glob, TaskAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from ClickHouse/ClickHouse at commit c873902, republished under its Apache-2.0 licence (© ClickHouse). 6,232 words, ~11,113 tokens.
.claude/skills/edit-changelog/SKILL.md (or your agent's skills folder).The autogenerator (utils/changelog/changelog.py) converts every PR
description in the release range into a bullet under the category the author
picked. The maintainer then heavily edits that output before it lands in
CHANGELOG.md. This skill applies those edits.
The patterns below were derived by diffing the autogenerated commit and the following "edited" / "Cleanup" commit for releases 25.2, 25.3, 25.5, 25.7, verifying against PR descriptions for 26.4, and from the manual edits the maintainers still had to make after the skill-assisted passes for 26.6 and 26.8. Don't invent new conventions — if a pattern isn't here, leave the entry alone.
$0 (optional): path to the auto-generated changelog file (the output of
utils/changelog/changelog.py --output=...). Edit this file in place.If $0 is omitted, default to editing the most recent release section in
CHANGELOG.md. Identify it by the first ### <a id="..."></a> ClickHouse release X.Y, ... heading, and treat the slice from that heading up to the
next ### <a id= heading as the input. This is the common case after the
maintainer has already pasted the autogenerated output into CHANGELOG.md.
### ClickHouse release ... FIXME ... header followed by #### <Category>
sections of * <entry>. [#NNN](...) ([Author](...)). bullets.
The input can hold several such blocks, one per generation run
(the NightlyChangelog job appends a new raw block every night, and
keeps the earlier ones when their edit was rejected). Treat all of them,
together with the in-progress section, as one input: process every
block in the same pass, integrate all of it into the one in-progress
section, and leave no block behind. A revert in a later block cancels
an entry in an earlier block exactly as it cancels one in the
in-progress section - the blocks are not separate releases, only
separate days of the same one.CHANGELOG.md automatically.
Tell the user the file is ready; they will paste it into CHANGELOG.md
themselves and commit.Each edit type below was observed at least twice across the surveyed releases. For real before/after examples, consult the diffs listed at the bottom under "How to use the surveyed past releases".
Retention rule — read this before deleting anything. An entry that the
autogenerator put under one of the real categories (Backward Incompatible Change, New Feature, Experimental Feature, Performance Improvement,
Improvement, Bug Fix) is never deleted. Rewrite it (§5), merge it into
another bullet (§7), move it to another category (§6) — but its
[#NNNNN](...) link stays in the file. Deletion is confined to three
places: the NOT FOR CHANGELOG / INSIGNIFICANT and NO CL ENTRY bullets
that carry no user-visible change (§3), the Build/Testing/Packaging Improvement entries that are pure CI plumbing (§4), and an entry that a
revert cancels out — and that no later revert of that revert brings back
(§2). "This looks unimportant" is not a reason to drop a real entry — an
entry lost here is lost for good, because the changelog is generated once
per range.
The NightlyChangelog CI job enforces exactly this: a run whose edit drops
such a link fails with Entries disappeared in the edit without a matching revert, and the raw entries stay unedited until someone fixes it. That was
the state of the 26.8 changelog for twelve days in August 2026.
The autogenerator emits:
### ClickHouse release {TO_REF} ({sha11}) FIXME as compared to {FROM_REF} ({sha11})Replace it with:
### <a id="NNN"></a> ClickHouse release X.Y[ LTS], YYYY-MM-DD. [Presentation](https://presentations.clickhouse.com/YYYY-release-X.Y/), [Video](https://www.youtube.com/watch?v=...)Where NNN is the version with dots removed (26.4 → 264). The X.3
and X.8 releases of each year are LTS — add the LTS marker for those
automatically (26.8 → v26.8 LTS); for any other version add it only if
the user says so. The same LTS marker goes into the TOC line. If the
presentation and video links aren't known yet, leave a FIXME placeholder
and tell the user to fill them in — don't invent URLs. While the release is
still being prepared, the header keeps a trailing , FIXME (in progress)
after the date (e.g. ClickHouse release 26.8 LTS, 2026-08-27, FIXME (in progress)); the finalization commit removes it.
The TOC at the top of CHANGELOG.md also needs a new line; only do this if
the user is editing CHANGELOG.md directly.
#### NO CL ENTRY against the rest of the changelogThese are revert PRs (Revert "...") that the autogenerator includes
because the revert PR has no Changelog entry. Walk every bullet in this
section. For each:
A revert is not always in this section. The autogenerator renders the
author's own Changelog entry under the author's own Changelog category, so
a revert whose author filled both in appears as an ordinary bullet — under
Improvement, reading "Disable the setting again", with nothing to give it
away. The opposite disguise is a bullet whose whole text is an HTML
comment, <!-- CI automatic block start :ci_links: -->: the pull request
body had no changelog entry at all, and the generator took the first line it
found. Under NOT FOR CHANGELOG / INSIGNIFICANT most of those are automatic
reverts merged by the Revert CI regressions job (the body starts with
Reverts owner/repo#NNNNN); the rest are bot pull requests such as the
nightly documentation regeneration. Open every one of them with gh pr view
before deciding - a revert hidden this way cancelled an entry of the same
run twice in September 2026 and was missed both times. When a bullet undoes something you have seen in this release, check its
PR (gh pr view <N> --json title,body; the title of a revert says Revert,
and GitHub adds a Reverts owner/repo#NNNNN line to the body) and treat it by
the rules below. Such a revert's own bullet is deleted with the entry it
cancels, exactly like one from this section — the "never delete a real entry"
rule does not protect it, because it is not a change that ships. A revert that
undoes something of this release and something from an earlier one at the
same time is the exception: the second half is user-visible, so it keeps an
entry of its own (case 5 below) — its link appended to the entry it re-applied
is an annotation on that entry, not a substitute for its own.
"Something of this release" includes a PR whose entry was pruned earlier under §3 or §4: the change was still made and undone inside the range, so the revert has no user-visible effect either. It does not include a PR whose entry is already in a released section — merged into the last release branch after this cycle started, so users have the behaviour — and reverting that is case 5.
Deleting the entry is only half of it — the revert must not be left behind as an entry of its own either, whatever category the autogenerator gave it. The user should see no trace of either side. The one place such a PR still appears is as the appended link on an entry it re-applied (§2.5), where it records the re-apply rather than describing a change.
Read the title of the revert PR (gh pr view <N> --json title,body) to
identify which earlier PR it reverts. Most reverts have a title of the
form Revert "<original PR title>" or Revert #NNNNN, and GitHub puts a
Reverts owner/repo#NNNNN line into the body (a hand-written revert
often spells it as a link, Reverts https://github.com/owner/repo/pull/NNNNN).
When the target is itself a revert - the title reads
Revert "Revert "...", or the target's body carries its own Reverts
line - open the target too and follow the chain down to the pull
request that is not a revert: that is the entry the chain is about, and
it was usually processed days ago, so nothing in the current input
names it.
Search the rest of the in-progress changelog for the matching entry by PR number, title, or topic.
Check whether this revert is itself reverted before you conclude
anything — by a Revert "Revert "...""" title elsewhere in the section,
or by a body containing Reverts owner/repo#<this PR>. If it is, the
change ships in this release: go to step 6 and leave the original entry
in place. A three-PR chain (change, revert, revert of the revert) sits
entirely inside one range often enough to matter, and when the release is
edited incrementally, the chain is spread over several of those
increments (step 6).
If the original PR is in the same release range and stays reverted: delete that entry from its category. Do not keep the revert PR as a separate bullet — the user should see no trace of either.
If the original PR shipped in an earlier release and the revert is meant to be visible to users: rewrite the revert into a normal entry under the appropriate category (often Bug Fix or Backward Incompatible Change), describing the user-visible effect of the revert.
If the revert PR is itself a revert-of-revert (i.e. it re-applies a change that was previously reverted): keep the original entry, append the second revert's PR/author link to it so both PR numbers are recorded, and delete the intervening revert from the section.
Real example from 26.8: #109946 fixed the propagation of settings in
accurateCastOrDefault, #114911 reverted it, #114912 reverted that
revert. All three are in the range. The result is one Bug Fix bullet —
#109946's entry with #114912's link appended — and no trace of
#114911. Deleting #109946 "because it was reverted" drops a fix that
ships in the release.
When a release is edited in daily increments, the three PRs arrive on
three different days: the entry was integrated on the first day, deleted
on the second, and the third brings only the revert of the revert. The
original entry is then not in the file to be kept — it has to be re-added
from the text it had when it was deleted, which the caller supplies (the
NightlyChangelog job lists such entries with their previous text and
category under "Entries to restore"). If nothing supplies it, reconstruct
the entry from the original PR with gh pr view <N> --json title,body; do
not leave the release without it.
A bullet that covered several PRs comes back as one bullet carrying all of them, not as one bullet each — splitting it undoes the merge of §7. That includes the PRs of that bullet which never left: re-adding the entry beside the surviving bullet duplicates the prose even though no PR link repeats, so merge it into that bullet instead. A revert can be one of those PRs — a revert of an earlier release is a normal entry (case 5) and can have been merged like any other; what is not a PR of the bullet is the link a previous restoration appended to record a re-apply. And if only some of those PRs were re-applied, leave the others' links off: their reverts still stand, so those changes are not in the release, even though the recorded text attributes them.
The link of the PR that re-applied the change goes on the restored entry,
as in the main rule above: its own revert bullet is deleted, so that link
is the only trace of the re-apply left in the release. A change can be
taken out and put back more than once in a cycle — #109946 out by
#114911, back by #114912, out by #115500, back by #116000 — and
then every PR that put it back belongs on the entry, not just the first.
The ones that took it out leave no trace.
One revert can revert several PRs at once. When such a revert is itself reverted, every entry it brings back records that revert-of-revert, so the same link appears on each of them — that is not the same as one entry written twice. And a revert rewritten into a visible entry (case 5 above) is an entry like any other: if it is deleted and later restored, it takes the link of the PR that restored it too.
An entry the autogenerator had filed under NOT FOR CHANGELOG or as CI
plumbing and that was never added to the release is offered back, not
required: §3 and §4 were free to prune it, so decide again whether it
describes a user-visible change. One that had already been added is
required — that decision was made when it went in. What matters is
that the choice is possible — the entry is quoted for you because nothing
in the file remembers it any more.
When the restoration merges into a surviving bullet, it lands under that
bullet's current category — which a later edit may have moved. Otherwise,
restore it under the category it was in, which is not necessarily the one
its PR declares: the entry may have been promoted out of NOT FOR CHANGELOG (§3) or moved (§6) by the edit that first added it, and
re-deriving the category from the PR would undo that.
If the deleted entry shared a bullet with other PRs (§7) and those are
still in the in-progress section, that bullet is still there too: append
the missing PR link to it instead of adding a second bullet. The same PR
appearing in an already-released section further down is not that bullet.
No PR may end up attributed twice within one section — one
[#NNNNN](...) ([Author](...)) per PR.
A restored PR needs its own attribution, [#NNNNN](...) ([Author](...)).
A bare [#NNNNN](...) link inside somebody else's bullet — a
This closes reference, a follow-up named in prose — is not that PR's
entry and does not count as restoring it.
After processing, delete any leftover bullets and the section header itself.
The goal is that the final changelog reflects the net effect on the
release: a PR that landed and then got reverted shouldn't appear at all, and
one whose revert was itself reverted appears with every PR that put it back.
Both halves are enforced by the NightlyChangelog job — keeping a reverted
entry fails it just as dropping a real one does.
Reverts can postdate your input. The changelog is built incrementally,
so a PR whose entry is already in the file can be reverted after the
range your input was generated from — no NO CL ENTRY bullet will ever
tell you about it. On the final pass, search the merge history since the
last generation run for Revert-titled PRs (git log --oneline --grep='^Revert' <last-generated-sha>..origin/master or gh pr list --state merged --search 'Revert') and delete the entries of anything
reverted. In 26.8, the entry for #111973 had to be removed by hand
(#116504) because the revert landed after the entry was written. If the
change was reverted but a revert-of-revert is expected before the release,
keep the entry and prepend TODO: wait for the revert-of-revert. instead
of deleting it (see §9 for the TODO flag convention).
#### NOT FOR CHANGELOG / INSIGNIFICANT section, but rescue user-visible entriesWalk every bullet in this section. For each:
Fix for a real bug, a perf change with a number, a new column in a
system table, etc.) — promote it into the appropriate category (use
the rules in §6 to pick the category). Don't strip the content; only
strip developer-internal preambles like "fix msan ...", "ci: ...".
If after stripping there is no real user-facing description, drop the
entry instead of promoting an empty one.Then delete the section header itself. This section, NO CL ENTRY and the
CI plumbing of §4 are the only places where entries are deleted; see the
retention rule above.
This closes / Closes #N / Fixes #N entriesThese are valuable — they tie the change to the issue tracker. Keep them, don't strip. Apply this shape:
Closes [#NNNNN](https://github.com/ClickHouse/ClickHouse/issues/NNNNN)),
not a bare #N or a raw URL. The autogenerator already converts most
of these — re-check.Closes #N. with no description, fetch the PR
body or the linked issue title and write a one-sentence description of
what the user observes, then put Closes [#N](...) at the end.Closes/Fixes references can stay; put them all at the end.Examples of entries that should be promoted (from past releases):
Fix renames of columns missing in part. → Bug Fix.Write Parquet bloom filters. → New Feature.Reverse key support in PartsSplitter. → Bug Fix (it had been gated as
experimental but was shipping).Examples that should be deleted:
update arrow submodule for table reader fixes. (build plumbing)tests: ..., ci: ..., Fix flaky test_*, Update README.md.Sync private., Add a test for [#NNNNN]. (no user-visible change).#### Build/Testing/Packaging ImprovementMost CI infrastructure entries (praktika, internal CI fixes, integration-test plumbing, fast-test tweaks) are removed. Only items that affect external users or distributors stay. Keep:
Bump curl to ...,
Update to embedded LLVM 19, Restore QPL codec).Raise minimum required CMake version to 3.25,
Support build HDFS on both ARM and Intel mac,
Fixes to allow building with clang20).Disable network access for user default in docker image.).Delete:
CI:, ci:, tests:, Fix flaky , Disable test,
Bump pytest, Update version_date.tsv, Switch ... workflow,
Praktika ..., Sync ..., Refactor , chcache: (unless it's a
user-relevant build issue).For every remaining bullet, in the order below:
... produced by the autogenerator's bullet cleanup —
delete it.TBD. / TODO: ... / WTF is that? — the entry is unfinished. Either
rewrite it from the PR title, or delete and tell the user. This applies
to author-left TODOs only — a TODO: that the maintainer (or a
previous editing pass) prepended as a release-blocking flag stays until
its issue is resolved; see §9.What: prefix produced by Cursor/AI bot PRs — delete the prefix.This PR ... / Changes in this PR: 1. ... / In this PR ... —
rewrite to start with the user-visible effect.Doing the rewrite in the last major PR ... / first-person developer
context — delete or rewrite.Follow up for https://...PR/N. / Follow-up to [#N]. with no other
description — delete the entry; it has no user-facing content. If there
is real content after the follow-up reference, keep just that.MergeTreeSink::consume and a delayed_chunk pattern instead of the
observable effect) — do not leave it and do not delete it.
Open the PR (gh pr view <N> --json title,body), read what it actually
does, and write a proper user-facing entry from scratch (keep the
original PR/author link). Example: PR #105943's autogenerated entry
described delayed_chunk/StorageSnapshot internals; the PR adds the
setting wait_for_part_commit_in_dependent_materialized_views, so the
correct entry describes that setting and the observable effect (a
cascading MV that joins back to its source can now see the row being
inserted). Never ship a TODO/FIXME placeholder in its place.**Reject PromQL timestamps and durations that exceed the Int64 range.**. — strip the ** markers and the extra period. This comes
from PR bodies whose changelog entry is written in bold; 26.8 had six of
these from one author and they all had to be fixed by hand.### Documentation entry for user-facing changes and anything after it
— the autogenerator sometimes captures this from PR bodies. Cut it.Closes/Fixes)
— convert it to the markdown-link form. E.g. Follow up to https://github.com/ClickHouse/ClickHouse/pull/106387. →
Follow up to [#106387](https://github.com/ClickHouse/ClickHouse/pull/106387).Do not strip trailing Closes #N / Fixes #N / Closes [#N](...) references. They are valuable. If they're at the start of the
entry, move them to the end after the description. If they're a bare URL
like Closes: https://github.com/ClickHouse/ClickHouse/issues/N, convert
to the markdown-link form Closes [#N](https://...) (the autogenerator
already does this for most cases — re-check). See §3 for the full
"Closes/Fixes" rule.
Anything you would type into clickhouse-client should be in backticks.
Specifically:
geoToH3() → geoToH3, ToTime → toTime,
extractKeyValuePairs, tokens, countMatches, printf, etc. The
project rule (CLAUDE.md): "write names of functions and methods as f
instead of f() — we prefer it for mathematical purity." Table functions
count too, including in a comma list: file() / s3() / azure() /
url() → file / s3 / azure / url.basic, countmin, minmax, tdigest), codec names, layout names,
mode strings. E.g. "Support basic statistics", not "Support basic
statistics".parallel_inserts, s3_slow_all_threads_after_network_error,
geotoh3_lon_lat_input_order, enable_url_encoding, etc.Time, Time64, JSON, Variant, BFloat16, Decimal,
LowCardinality, Array, Tuple, Nullable, Map, Float32,
Float64, IPv4, IPv6, Date32, DateTime64.MergeTree, ReplicatedMergeTree,
Iceberg, DeltaLake, Kafka, Parquet, Arrow, S3Queue,
RabbitMQ, Redis, KeeperMap, PostgreSQL, MySQL, Azure.
(The autogenerator usually doesn't backtick these.)SET TIME ZONE 'tz', SET session_timezone,
ALTER TABLE ... MOVE|REPLACE PARTITION, RENAME COLUMN, DROP COLUMN,
CODEC(ZSTD, DoubleDelta), CREATE TABLE, SELECT ... FROM ....-If combinator, version-hint.txt, _part_offset.DateTime64(x) <-> DateTime64(y),
Decimal(x) <-> Decimal(y), Float32 <-> Float64 (a 26.8 entry
listing these bare had to be fixed in a follow-up commit).chdig, not "Chdig".Don't backtick prose nouns (the user, a query, the index) — only literal identifiers and code.
iceberg → Iceberg, azure → Azure, delta lake / delta-kernel →
DeltaLake, parquet → Parquet, kafka → Kafka, rust → Rust,
postgres → PostgreSQL, mysql → MySQL. (Skip if the word is already
inside backticks as a literal config value.)
Capitalize compounds like float-to-string → Float-to-String when used
as a noun (e.g. "Faster Float-to-String conversion").
Observed across releases:
Clickhouse / clickHouse / Click House → ClickHouse. The
clickhouse_spelling style check accepts only ClickHouse and the token
spellings clickhouse and CLICKHOUSE, so a misspelling inherited from a
pull request body fails the CI of the changelog pull request itself (it did,
on 2026-08-25).
loose → lose
Propogate → Propagate
on fly → on the fly
FIx → Fix
2 cases → two cases (spell out small numbers in titles)
False → false and True → true when they refer to ClickHouse
setting values (these are lowercase in SQL).
NOT NULL column → not-Nullable column (use ClickHouse type
terminology, not SQL standard terminology).
NULL (SQL keyword) stays uppercase.
Normalize ISA / SIMD names: avx512 → AVX-512, avx2 → AVX2,
sse4.2 → SSE4.2.
Inclusive terminology: whitelist → allow-list, blacklist →
deny-list.
Expand a non-obvious abbreviation on first use: DP JOIN reordering →
DP (dynamic programming) JOIN reordering.
Fix any wrong capitalization of the product name: the only accepted
spellings are ClickHouse, clickhouse and CLICKHOUSE. The CI style
check clickhouse_spelling greps CHANGELOG.md for the bad variants and
fails the build; 26.8 needed a dedicated follow-up commit for a single
one. Before finishing, run the same check over the final file:
grep -niE 'click[ _-]?house' CHANGELOG.md | grep -vE 'ClickHouse|clickhouse|CLICKHOUSE'Homophone typos: loose → lose, and similar.
No spaces just inside parentheses: ( introduced in 26.7 ) →
(introduced in 26.7).
Prefer commas over a parenthetical em-dash pair in entry text:
— including MergeTree tables — → , including MergeTree tables,.
Drop a redundant Experimental: prefix from an entry that already sits
under Experimental Feature.
Drop a trailing space before .
Replace double spaces.
When the entry reads as a low-level commit message, rewrite it as a description of what users observe. Real before → after pairs from past releases:
Add __attribute__((always_inline)) to convertDecimalsImpl. →
Better inlining for some operations with Decimal.Try to speedup QueryTreeHash a bit. →
Speedup comparisons of query trees during the query analysis a bit.Improve Keeper with rocksdb initial loading. →
Improve the startup of clickhouse-keeper when it uses rocksdb storage.Removed allocation from the signal handler. →
Fix potentially unsafe call in signal handler.Fix invalid result buffer size calculation. →
Fix data corruption with CODEC(ZSTD, DoubleDelta). (replaces vague
symptom with the user-visible failure mode.)Drop blocks as early as possible to reduce the memory requirements. →
Reduce memory usage for some window functions.Strip internal C++ class/method names that mean nothing to a user; state the effect in plain words instead. Real before → after pairs from Alexey's 26.6 cleanup:
... replacing per-chunk column hashing with an IColumn::computeHashInto kernel that uses hardware CRC32C. →
... replacing per-chunk column hashing with a kernel that uses hardware CRC32C.Squash source blocks before projection.calculate() during MATERIALIZE PROJECTION ... →
Squash source blocks before calculating projection during MATERIALIZE PROJECTION ...Cut, don't just translate: when an entry follows a clear effect statement
with an accurate but internal root-cause story, delete the story. In 26.8
Alexey reduced a Performance entry to just Appending to a system log queue no longer deep-copies the whole queue when it grows. — cutting a
correct explanation about Poco::Net::SocketAddress lacking a move
constructor, nothrow-move-constructibility, and a std::vector
reallocation under a mutex. One sentence of user-visible effect beats a
paragraph of C++ mechanics, even when the paragraph is right.
This is the judgement-call step. If you can't find the user-visible
effect from the entry alone, fetch the PR with gh pr view <N> --json title,body and use the title as a starting point.
If a function or setting was renamed between PR merge and release (the
actual shipped name differs), update the entry. Real example: 25.2 had
stringCompare rewritten to compareSubstrings because the function was
renamed before release. If you can't tell, ask.
Every bullet under Backward Incompatible Change must let a reader tell
whether they are affected: what breaks or behaves differently on upgrade,
and what to do about it. An entry that only describes the change —
Object-storage disk transactions now use the metadata storage's native transactions by default instead of the previous fake transactions. —
doesn't justify its section. First try to derive the incompatibility from
the PR (gh pr view <N> --json title,body) and write it into the entry.
If the PR doesn't say either, don't guess and don't silently move the
entry out of the section — prepend a maintainer TODO flag (see §9):
TODO: explain the backward incompatibility: or, addressed at the
author, TODO: @<author> How is this a backward incompatible change? The changelog entry does not tell:. Both forms are verbatim 26.8 edits
(#112757, #89658).
Also check new names introduced by the entry against naming policy:
a setting or option with new in its name (26.8: use_new_storage) is
forbidden and will be renamed before release — flag it with
TODO: we forbid `new` in names, it will be renamed! and tell the
user. (The 26.8 one shipped as use_lsmt_storage; the entry had to be
updated when the rename merged.)
For each entry, decide if its current category is right. Common moves:
Fix/Fixed/Fixes-shaped entry → Bug Fix — but be conservative.
Bug Fix is reserved for user-visible misbehavior in the official
stable release build. That excludes:
Improvement.Improvement (or Build/Testing
if internal).LOGICAL_ERROR exceptions that only fire in debug
assertions and produce no incorrect result in release — Improvement.Move to Bug Fix only when the bug would produce wrong results, a crash/exception, data loss, or a hang in a user's release build.
Measured speedup / Faster ... / Speedup ... / Reduce memory usage → Performance Improvement even if labelled Improvement. Read
this broadly: Alexey moved a large batch of efficiency-flavored
Improvement entries into Performance Improvement in 26.6. Triggers
include reducing memory reservation/footprint/fragmentation (dedicated
arena, freeing earlier), avoiding redundant work (caching, dedup of
calculations, fewer marks re-read), avoiding copying (hardlink instead
of copy), turning a perf optimization on by default, and background-IO
or batching changes. This includes "new X" entries whose entire point
is efficiency: in 26.8 the new bucketed schema type for
system.metric_log moved from New Feature to Performance Improvement.
When in the same wave as a significance sort, do the move and the
reorder together.
A bundled-tool version bump with substantial user-visible features →
New Feature rather than Build/Testing, to highlight it (26.8: the
chdig update).
New SQL surface (function, table function, system table, syntax) → New Feature even if labelled Improvement.
Behind a setting and off by default OR explicitly described as experimental → Experimental Feature even if labelled New Feature.
Backward Incompatible Change is sometimes wrong when the author
was over-cautious. If the change is purely additive (a new behaviour
enabled by a new setting that defaults to old behaviour), move it to
New Feature or Improvement.
The preferred category order (from utils/changelog/changelog.py, which
wraps ci/tools/changelog.py) is:
If you create a category that didn't exist in the input, insert it at the
right position. Do not rename Experimental Feature to Experimental Features plural — keep it singular for consistency with newer releases.
Only merge entries when they cover the same feature or a group of very similar features. Sharing a library or subsystem is not enough on its own — two different Iceberg fixes covering different code paths stay as two bullets.
Valid reasons to merge:
Follow-up to #N /
continuation of #N in the body, or one PR adding the feature behind a
setting and a later PR enabling/promoting it (e.g. experimental → GA,
beta → GA).Update chdig to v26.3.1 and a later Update chdig to v26.4.3 in the same
release.executable vs executable_pool UDF ProfileEvents entries
(#105010 + #105618) — collapse to one bullet covering both.use_reader_executor PRs (#106570 + #106968 + #107210),
or a base feature PR plus a follow-up that extends it (make_distributed _plan #106020 + per-worker-ports #107885) — one bullet, all links.Supersedes [#N] / Follow-up to [#N] cross-reference between the two
merged PRs — it's noise once both sit in the same bullet.... under a single prompt. [#104299](...) (...). Now also works with syntax highlighting disabled (\--highlight 0`). #106665 (...).`Alexey merges noticeably more aggressively than a first pass tends to — when two adjacent bullets describe the same feature/subsystem from the same wave of work, prefer one merged bullet over two.
Scan the whole release section for duplicates, not just neighbours.
Because the changelog is generated incrementally, a follow-up often lands
weeks later under a different category than the base PR, so
within-section scanning misses it. Before finishing, grep the whole
release section for repeated setting/function/feature names. All four of
these had to be merged by hand in 26.8, each pair spanning categories:
the gini aggregate function (#112280 + a second full entry for
#114643), use_query_condition_cache_for_top_k (#111492 in Experimental
Feature + #114539 in Performance Improvement), lazy materialization for
Parquet (#110970 + #114262), and adaptive codec selection (#111834 +
#113511). Put the merged bullet in the single right category.
Describe the net shipped state. When the later PR changes what the earlier one did — re-enables a default, renames a setting — the merged entry states the final behaviour. Drop transitional narrative that is no longer true at release time: 26.8 cut "(default disabled) ... as a precaution until the soundness of its cache entries is fully established" once the follow-up had turned the cache back on.
Do not merge:
Merged form keeps all PR/author links at the end:
* Update chdig to v26.3.1 (...). [#101092](...) (Azat). Update chdig to v26.4.3 (...). [#103145](...) (Azat).Or rewritten as a single sentence with both links trailing:
* Improve Iceberg and Spark compatibility: fix path handling; enforce ...; add fallback for ... [#99163](...) (Daniil Ivanik). [#100420](...) (Daniil Ivanik).If the second PR adds nothing worth describing separately, append just its bare link after the first entry's author link:
* Added the aggregate function `gini`, ... [#112280](...) (Amirreza Akhondi). [#114643](...) (Groene AI).When in doubt, leave them as separate bullets — over-merging makes attribution confusing.
The autogenerator sorts bullets by ascending PR number. That's almost right. After all other edits:
Don't reorder more than necessary — the diff against the autogenerated version should still be readable.
Full significance sort. The maintainer (and an explicit "sort by
significance" request) goes further than promoting a few headliners: he
re-sorts the entire section from most to least significant, in
significance tiers, with related entries clustered inside each tier — and
he does this for every category, including Experimental Feature, not
just New Feature. When asked to sort by significance, sort the whole
section that way; the "don't reorder more than necessary" caution above
applies only to mid-cycle incremental passes, not to an explicit sort
request or to the final pass. On the final pass (the release date is
being set, or the user says the release is being finalized), do the full
significance sort of every category without being asked — in both 26.6
and 26.8 the maintainer had to do it by hand because the skill-assisted
passes left the sections in PR-number order.
Significance reordering and category moves between Improvement and
Performance Improvement often happen together — Alexey moved a large
batch of memory/efficiency "Improvement" entries into Performance Improvement while sorting (see §6).
Mechanics: reorder by reading the bullets into a map keyed by PR number and
emitting them in the chosen order; assert the set of PR numbers is
unchanged so nothing is dropped or duplicated. Keep exactly one blank line
before the next #### header (the maintainer will notice a missing one).
TODO flagsDistinctive maintainer pattern: a clarification or warning is appended
after the closing ). of the auto-formatted [#N](...) (Author).,
so it visibly belongs to the editor rather than the PR author.
* Improved storage format of statistics. All statistics are now stored in a single file. [#93414](...) (Anton Popov). If you didn't explicitly enable table statistics, you can ignore this item.* Added system.histogram_metric_log ... [#103046](...) (Stetsyuk). The table structure is likely to be changed in future releases.Add this only when:
Do not use it to replace the entry — only to comment on it.
Prepended TODO: flags. The second editorial device: when an entry
cannot be finished yet, the maintainer prepends TODO: <reason> to it
and commits it that way. The flag stays visible in CHANGELOG.md until
the underlying issue is resolved (by the component author, or by a later
merge), shortly before the release ships. Verbatim 26.8 uses:
TODO: explain the backward incompatibility: — the entry doesn't
justify its Backward Incompatible Change section (§5i).TODO: @Mikhail Artemenko How is this a backward incompatible change? The changelog entry does not tell: — same, addressed at the PR author
by @-mention.TODO: wait for the revert-of-revert. — the entry's PR is currently
reverted, and a re-apply is expected before the release (§2).TODO: we forbid `new` in names, it will be renamed! — the entry
documents a policy-violating name that will change before release
(§5i); the flag was resolved by editing the entry when the rename
merged.Use a prepended TODO: only for problems that a human decision or a
future merge must resolve — never as a substitute for research you can do
yourself (§5a still applies to entries that are merely badly written).
List every flag you add, or find still unresolved, in your final summary
to the user; none may survive into the finalized release section.
Backported in #NNN: ... prefixes (the autogenerator adds these).[#NNN](https://github.com/ClickHouse/ClickHouse/pull/NNN) ([Author](https://github.com/login)). link format.If you need a fresh example for any pattern, the diffs are reproducible:
# 25.2: autogenerated -> cleaned up
git diff 4a220b43f0726f075763001317e1335face260f4 9de7775ca60e2b0361a412e61558872aeff12c08 -- CHANGELOG.md
# 25.3: raw -> changelog
git diff f6d201ad74a905caed7027e1800be035e68ae0cb e3be9c079028faf278cc4ff997675d3015f09a7e -- CHANGELOG.md
# 25.5: autogenerated -> changelog
git diff f17c73bce4a09e67cab299fa4ee97235cfaf3922 fefd0fa7b02c229225de26b31b712b6d543e365c -- CHANGELOG.md
# 25.7: raw unfiltered -> changelog
git diff e7fc5b4eaba229dee5626c5a08a246a89a531bd6 b49397e527eee597db3aa391c53e56654e62e39c -- CHANGELOG.md
# 26.8: skill-assisted result -> after the maintainers' manual pass
# (the diff most of the TODO-flag / dedup / significance-sort rules come from)
git diff 26f037689408e03502e6769d2ee5a03a3e4979ce 09e0e517578433f9cb105ff641e30b3a383939a3 -- CHANGELOG.mdUse these when you need to verify whether a specific entry shape was kept, deleted, or rewritten in the past.
When the file is ready, give the user:
Do not commit. Do not paste into CHANGELOG.md. The user merges it in
manually.
© ClickHouse, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .claude/skills/edit-changelog of ClickHouse/ClickHouse.
Open the folder on GitHubat commit c873902
Edit Changelog next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Edit Changelog this skillClickHouse/ClickHouse | 50k | — | ~11k | Automated safety check: Notes | Apache-2.0 | |
| Version Upgrade Advisorchmonitor/chmonitor | 299 | — | ~1.6k | Automated safety check: Pass | GPL-3.0 | |
| Clickhouse Upgrade Migrationjeremylongshore/tons-of-skills-marketplace | 2.8k | — | ~1.7k | Automated safety check: Pass | MIT | |
| Write Doc ExamplesClickHouse/clickhouse-java | 1.6k | — | ~3.1k | Automated safety check: Pass | Apache-2.0 | |
| Code ReviewClickHouse/clickhouse-java | 1.6k | — | ~290 | Automated safety check: Pass | Apache-2.0 | |
| Databuddy Internaldatabuddy-analytics/Databuddy | 1.2k | — | ~11k | Automated safety check: Notes | AGPL-3.0 |
chmonitor/chmonitor
Advises whether and how to upgrade ClickHouse — versioning scheme, upgrade path, what you gain, pre/post-upgrade checklist.
jeremylongshore/tons-of-skills-marketplace
A skill your agent uses when upgrading ClickHouse server versions or the @clickhouse/client SDK, handling breaking changes between versions, or migrating from older client libraries — covers version…
ClickHouse/clickhouse-java
Write, rewrite, and format documentation code snippets into reusable, production-ready methods with necessary library imports and clean linting.
ClickHouse/clickhouse-java
Review changes in clickhouse-java for correctness, compatibility, API stability, and missing tests.
databuddy-analytics/Databuddy
Work inside the Databuddy monorepo for internal implementation, debugging, review, and refactoring.
evloghq/evlog
Twice-monthly check that evlog's drain adapters still send what each provider's own client sends.
ClickHouse/ClickHouse
Analyze ClickHouse Keeper stress-test results from play.clickhouse.com / keeperstresstests data warehouse.
ClickHouse/ClickHouse
Evaluate ClickHouse performance test results from existing CI/dashboard data or local perf.py runs.
ClickHouse/ClickHouse
Check whether ClickHouse's supported versions (last 3 majors + latest LTS) have recent stable patch releases, diagnose why the scheduled AutoReleases pipeline failed, and identify which releases…
ClickHouse/ClickHouse
Analyze a jemalloc (or other) allocation profile in collapsed stack format.
ClickHouse/ClickHouse
Bisect a ClickHouse regression using pre-built master binaries from CI.
ClickHouse/ClickHouse
Generate PR descriptions for ClickHouse/ClickHouse that match maintainer expectations.
Works with
Categories
Edit an auto-generated ClickHouse release changelog into the form that gets committed to CHANGELOG.md. Edit Changelog is an agent skill from ClickHouse/ClickHouse.md.
Edit Changelog fits situations like: the user has the output of utils/changelog/changelog.py and wants it cleaned up and re-categorized for a release; tasks that involve Changelog and release notes; tasks that involve Data warehousing.
Run `npx skills add ClickHouse/ClickHouse --skill edit-changelog -a claude-code`. Or copy the skill folder (.claude/skills/edit-changelog in ClickHouse/ClickHouse) into .claude/skills/edit-changelog in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ClickHouse/ClickHouse --skill edit-changelog -a codex`. Or copy the skill folder (.claude/skills/edit-changelog in ClickHouse/ClickHouse) into .agents/skills/edit-changelog in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ClickHouse/ClickHouse --skill edit-changelog -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/edit-changelog, .gemini/skills/edit-changelog, .github/skills/edit-changelog and .opencode/skills/edit-changelog in your project.
Going by SKILL.md and its folder, Edit Changelog needs the command-line tools its instructions call (gh, git and clickhouse). Its frontmatter pre-approves these tools: Bash, Read, Edit, Write, Grep, Glob, Task.
SKILL.md names 3 domains. In commands or code: github.com, presentations.clickhouse.com and youtube.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Edit Changelog is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 11k tokens (SKILL.md is roughly 44k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Edit Changelog: Version Upgrade Advisor (chmonitor/chmonitor, 299 stars), Clickhouse Upgrade Migration (jeremylongshore/tons-of-skills-marketplace, 2.8k stars), Write Doc Examples (ClickHouse/clickhouse-java, 1.6k stars) and Code Review (ClickHouse/clickhouse-java, 1.6k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
ClickHouse (a GitHub organization) maintains it in ClickHouse/ClickHouse, which has 50,308 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 9, 2026.
Source: ClickHouse/ClickHouse on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.