Clickhouse Architecture Advisor
vemetric/vemetric
MUST USE when designing ClickHouse architectures, selecting between ingestion or modeling patterns, or translating best practices into workload-specific system designs.
Unattended variant of continue-pr for automation (driven by utils/continue-all-prs.sh).
$ npx skills add ClickHouse/ClickHouse --skill continue-pr-auto -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install ClickHouse/ClickHouse continue-pr-auto --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/continue-pr-auto .claude/skills/continue-pr-auto && 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 "continue-pr-auto" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/continue-pr-auto into .claude/skills/continue-pr-auto/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "continue-pr-auto", 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/continue-pr-autoType 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 continue-pr-auto -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install ClickHouse/ClickHouse continue-pr-auto --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/continue-pr-auto .agents/skills/continue-pr-auto && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "continue-pr-auto" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/continue-pr-auto into .agents/skills/continue-pr-auto/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "continue-pr-auto", 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 continue-pr-auto -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install ClickHouse/ClickHouse continue-pr-auto --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/continue-pr-auto .cursor/skills/continue-pr-auto && 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 "continue-pr-auto" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/continue-pr-auto into .cursor/skills/continue-pr-auto/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "continue-pr-auto", 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/continue-pr-auto--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 continue-pr-auto -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install ClickHouse/ClickHouse continue-pr-auto --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/continue-pr-auto .gemini/skills/continue-pr-auto && 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 "continue-pr-auto" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/continue-pr-auto into .gemini/skills/continue-pr-auto/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "continue-pr-auto", 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 continue-pr-autoInstalls 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 continue-pr-auto -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/continue-pr-auto .github/skills/continue-pr-auto && 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 "continue-pr-auto" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/continue-pr-auto into .github/skills/continue-pr-auto/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "continue-pr-auto", 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 continue-pr-auto -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 continue-pr-auto --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/continue-pr-auto .opencode/skills/continue-pr-auto && 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 "continue-pr-auto" agent skill from https://github.com/ClickHouse/ClickHouse/tree/master/.claude/skills/continue-pr-auto into .opencode/skills/continue-pr-auto/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "continue-pr-auto", 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.
continue-pr-autoUnattended variant of continue-pr for automation (driven by utils/continue-all-prs.sh).
Continue PR Auto is an agent skill from ClickHouse/ClickHouse. Unattended variant of continue-pr for automation (driven by utils/continue-all-prs.sh). Resolves conflicts - reworking stale features to reconcile with current master when a mechanical merge is not enough - fixes CI, addresses feedback, and pushes without ever asking the user. For interactive use, prefer continue-pr.
Its SKILL.md is about 8.6k 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 Databases, covering 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.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit cd023af. 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:
AgentTaskBashReadWriteEditGlobGrepWebFetchWebSearchFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitghnodejqFrom 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:
api.github.coms3.amazonaws.comgithub.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.
Continue PR Auto loads about 8.6k tokens when it runs. Until then it costs about 84 tokens; SKILL.md has 3,822 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: Agent, Task, Bash, Read, Write, Edit, Glob, Grep, WebFetch, WebSearchAutomated 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 cd023af, republished under its Apache-2.0 licence (© ClickHouse). 3,822 words, ~8,552 tokens.
.claude/skills/continue-pr-auto/SKILL.md (or your agent's skills folder).Pick up an existing pull request, resolve conflicts, fix CI failures, address reviewer feedback, and push updates.
This is the unattended variant used by automation (utils/continue-all-prs.sh). It must never wait for user input: resolve conflicts and address feedback with your best judgment and push, and when a branch is too stale for a mechanical merge, rework the feature to reconcile it with the latest master (step 3a). The only hard stop is a genuinely missing PR number. For interactive use where asking is acceptable, use continue-pr instead.
$0 (required): PR number in the current repository (e.g., 12345)Extract the PR number from $0. This skill runs unattended and must never stop to ask the user anything: if the PR number is not provided, stop with a clear error message instead of prompting.
Validate that the PR number contains only digits. Reject any non-numeric input immediately — do not pass unvalidated input to shell commands or GraphQL queries.
Determine which repository you are operating in — the public ClickHouse/ClickHouse or the private ClickHouse/clickhouse-private:
gh repo view --json nameWithOwner --jq .nameWithOwner # or: git remote get-url originRemember it as $REPO and use it everywhere below instead of the literal ClickHouse/ClickHouse in gh commands, API URLs, and GraphQL repository(owner:, name:) arguments. The repository also decides whom to ask about unrelated CI failures (step 4): @groeneai in ClickHouse/ClickHouse, @oranjeai in ClickHouse/clickhouse-private.
Fetch PR metadata using gh if available, otherwise use WebFetch on the GitHub API:
GH_USER=$(gh api user --jq .login)
gh pr view "$PR_NUMBER" --json number,title,body,headRefName,baseRefName,state,mergeable,mergeStateStatus,author,url,headRepository,headRepositoryOwner,isCrossRepository,maintainerCanModify,statusCheckRollup,reviews,comments,reviewRequestsIf gh is not available or not authenticated, use WebFetch to get the data. Append ?per_page=100 and follow the Link header for pagination (the rel="next" URL) to fetch all pages:
https://api.github.com/repos/ClickHouse/ClickHouse/pulls/$PR_NUMBERhttps://api.github.com/repos/ClickHouse/ClickHouse/pulls/$PR_NUMBER/reviews?per_page=100https://api.github.com/repos/ClickHouse/ClickHouse/pulls/$PR_NUMBER/comments?per_page=100Report the PR title, author, branch, and current state to the user.
Treat closing a PR as already integrated or obsolete as a high-confidence decision. Verify both of these independently against freshly fetched refs:
HEAD_REMOTE=origin
if [ "$IS_CROSS_REPOSITORY" = "true" ]; then
HEAD_REMOTE="pr-$AUTHOR_LOGIN"
git remote add "$HEAD_REMOTE" "$FORK_URL" 2>/dev/null || git remote set-url "$HEAD_REMOTE" "$FORK_URL"
fi
git fetch origin "$BASE_BRANCH"
git fetch "$HEAD_REMOTE" "$HEAD_BRANCH"
git rev-parse "origin/$BASE_BRANCH" "$HEAD_REMOTE/$HEAD_BRANCH"
git merge-base --is-ancestor "$CANDIDATE_COMMIT" "origin/$BASE_BRANCH"$IS_CROSS_REPOSITORY, $AUTHOR_LOGIN, and $FORK_URL from the PR metadata as in step 2. Exit status 0 means the base contains the commit; any other status means it does not. Never check against HEAD, the PR branch, --all, or a worktree and describe that result as containment by the base branch. If this check is nonzero, do not claim the commit is in the base and do not close the PR as integrated.git branch --contains, git cherry, and patch-equivalence results are historical evidence only; none proves that the change remains effective. Inspect all later base-branch commits touching the changed paths, search for explicit and manual reverts/backouts, compare the current base tree with the PR's intended effect, and run the reproducer or regression test against the current base when feasible. If the change was fully or partially reverted, count it as not integrated. If the current effect cannot be established confidently, leave the PR open for human review.Before posting a closure comment, state the fetched base OID and the evidence for both ancestry and the current effective state. Do not close from a remembered ref, a stale local branch, a matching subject, or a commit merely visible somewhere in the repository.
Determine whether the PR branch is in the main repository or in the author's fork.
If the branch is in the main repository (ClickHouse/ClickHouse):
HEAD_REMOTE=origin
git fetch "$HEAD_REMOTE" "$HEAD_BRANCH"
git checkout --detach "$HEAD_REMOTE/$HEAD_BRANCH"If the branch is in the author's fork:
Derive the fork clone URL from the PR metadata (headRepository.url or headRepository.owner.login + headRepository.name) rather than hardcoding the repository name (forks can be renamed). Use a pr- prefixed remote name to avoid colliding with existing remotes like origin:
REMOTE_NAME="pr-$AUTHOR_LOGIN"
FORK_URL="https://github.com/$FORK_OWNER/$FORK_REPO.git" # from headRepository in PR metadata
git remote add "$REMOTE_NAME" "$FORK_URL" 2>/dev/null || git remote set-url "$REMOTE_NAME" "$FORK_URL"
HEAD_REMOTE="$REMOTE_NAME"
git fetch "$HEAD_REMOTE" "$HEAD_BRANCH"
git checkout --detach "$HEAD_REMOTE/$HEAD_BRANCH"Immediately after either checkout completes, discard any state left by an earlier PR before recording the immutable baseline. The automation uses a dedicated worker worktree, so it must never preserve staged, unstaged, or untracked files from a previous session. This is the only authoritative record of the PR surface that existed when the worker began:
git fetch origin "$BASE_BRANCH"
# The automation may have already prepared a validated, conflict-free merge of
# the base branch into the pull-request head in this worktree (the triage phase
# of `utils/continue-all-prs.sh` records it). Keep that merge instead of
# throwing it away and paying for a second merge and rebuild. Accept the
# recorded commit only when it is exactly that merge: a two-parent commit whose
# first parent is the current remote pull-request head and whose second parent
# is the current base-branch head. Anything else - a stale marker from an
# earlier pull request, a commit with a different shape - is ignored.
VALIDATED_MERGE_FILE="$(pwd)/tmp/continue-all-prs/validated-base-merge"
CHECKOUT_TARGET="$HEAD_REMOTE/$HEAD_BRANCH"
if [ -s "$VALIDATED_MERGE_FILE" ]; then
VALIDATED_MERGE=$(cat "$VALIDATED_MERGE_FILE")
if git cat-file -e "${VALIDATED_MERGE}^{commit}" 2>/dev/null \
&& [ "$(git rev-parse "${VALIDATED_MERGE}^@")" = "$(git rev-parse "$HEAD_REMOTE/$HEAD_BRANCH" "origin/$BASE_BRANCH")" ]; then
CHECKOUT_TARGET="$VALIDATED_MERGE"
fi
fi
git reset --hard "$CHECKOUT_TARGET"
git clean -ffdx -e build/ -e tmp/continue-all-prs/
test -z "$(git status --porcelain)"
mkdir -p tmp
PR_BASELINE_DIR="$(pwd)/tmp/continue-pr-${PR_NUMBER}-baseline"
rm -rf "$PR_BASELINE_DIR"
mkdir -p "$PR_BASELINE_DIR"
INITIAL_PR_HEAD=$(git rev-parse "$HEAD_REMOTE/$HEAD_BRANCH")
# The pull-request head stays the baseline even when the worktree already
# carries the validated base-branch merge on top of it.
git merge-base --is-ancestor "$INITIAL_PR_HEAD" HEAD
INITIAL_BASE_HEAD=$(git rev-parse "origin/$BASE_BRANCH")
printf '%s\n%s\n' "$INITIAL_PR_HEAD" "$INITIAL_BASE_HEAD" > "$PR_BASELINE_DIR/state"
git diff --name-status "origin/$BASE_BRANCH"...HEAD > "$PR_BASELINE_DIR/name-status"
git diff --stat "origin/$BASE_BRANCH"...HEAD > "$PR_BASELINE_DIR/stat"
git diff --binary "origin/$BASE_BRANCH"...HEAD > "$PR_BASELINE_DIR/diff"Do not modify, stage, or delete this artifact during the session. It must remain
available through the push safety gate in step 7. The deterministic path and
state file are required because each resumed worker turn starts a fresh shell
process.
Use the PR's actual base branch from metadata (baseRefName) instead of hardcoding master — this ensures backport PRs targeting other branches are handled correctly.
Check if the PR has conflicts with the base branch:
git fetch origin "$BASE_BRANCH"
git merge-base --is-ancestor "origin/$BASE_BRANCH" HEAD || echo "needs merge"If the branch is behind the base branch and is red (some checks didn't pass), or if it is behind the base branch for more than a week (regardless of checks success), or has conflicts (including when GitHub reports the PR as CONFLICTING or its mergeability as unknown), or if at least one CI failure is unrelated to this PR and its fix has already landed on the base branch (merging pulls the fix in and clears the red — see step 4), or if the merge queue removed the PR after its last commit (see step 4), merge:
git merge "origin/$BASE_BRANCH"If there are merge conflicts, resolve them autonomously — this skill runs unattended, so never stop to ask:
git diff --name-only --diff-filter=Usubagent_type=general-purpose to resolve:git add <file>AskUserQuestion or otherwise wait for input.git commit --no-editResolving merge markers is not always enough. If the branch is long-stale, the mechanically merged result may not compile or fit current APIs — master may have renamed or removed functions, migrated settings to the pimpl pattern (DECLARE / (*settings)[Setting::X]), reworked IStorage / pipeline / QueryPlan, moved headers, etc. In that case, rework the PR's feature so it reconciles with the latest master — do not give up, defer, or leave it half-merged:
A CONFLICTING PR must not be left unresolved whenever you can push. Resolve the conflicts (steps above) and push:
isCrossRepository=false) is directly pushable through origin. Ignore maintainerCanModify for same-repository PRs; GitHub can report it as false because the field describes maintainer access to a fork, not access to a branch in the base repository.$GH_USER (or a PR authored by $GH_USER) is directly pushable through that user's fork remote. Ignore maintainerCanModify for the authenticated user's own fork PRs; the owner can push regardless of whether base-repository maintainers are allowed to edit.maintainerCanModify: true means push to the fork remote; false means the branch is not pushable by the authenticated user.origin for same-repository PRs and to the fork's remote for fork PRs (step 7). A contested, reserved, NA, dsgn, or "superseded" note does not block the mechanical conflict resolution and push; it only reserves the final design / merge decision. Resolving conflicts means keeping the author's intended change merge-clean against current master — it does not require the PR's design to be correct (that stays the human's call).maintainerCanModify=false, or a push actually fails for lack of permission — supersede the PR, provided the change is still wanted and is not obsolete, already fixed on master, already covered by another open PR, or design-rejected/contested. (In those excluded cases, report the state and leave the human decision; never open a duplicate of an existing superseding PR.) To supersede:PUSH_MODE=supersede
PUSH_REMOTE=origin
PUSH_BRANCH="continue-pr-${PR_NUMBER}-<short-desc>"
SUPERSEDE_REASON="maintainer edits are disabled on the original fork"
SUPERSEDE_REAUTHORED_UNSIGNED_CLA=false
git ls-remote --exit-code "$PUSH_REMOTE" "refs/heads/$PUSH_BRANCH" && exit 1 || trueCLA note, or the CLA check is red on the original), create a new branch from the fetched base and re-create the intended change under your own authorship. Do not carry the original commits or a Co-authored-by: trailer, or the CLA check will block the new PR too:git checkout --detach "origin/$BASE_BRANCH"
git switch -c "$PUSH_BRANCH"
SUPERSEDE_REAUTHORED_UNSIGNED_CLA=true
# Re-create and test the intended change, then commit it under the current user.origin) under $PUSH_BRANCH, then open a new PR to the base branch with gh pr create, following .github/PULL_REQUEST_TEMPLATE.md. State that it supersedes the original and add Related: <original PR URL> (and Closes: <issue> if the original targeted one).gh pr close <N> --repo "$REPO" --comment "...": say it is superseded by the new PR (link it), that you could not push the resolution here because maintainer edits are disabled on the fork, and thank the author.
If the change is genuinely not worth superseding, resolve locally if useful and report the specific blocker (e.g. "resolved locally but the fork has maintainer edits disabled") — not a bare "needs attention".gh api user --jq .login and gh pr view <n> --json author,isCrossRepository,maintainerCanModify,headRepositoryOwner,headRepository. Never infer that a same-repository PR or the authenticated user's own PR is unpushable from maintainerCanModify=false.First, check whether the merge queue rejected the PR. The PR's own CI runs on its head commit, but the merge queue re-tests the PR merged with the latest base branch (a gh-readonly-queue/<base>/pr-<N>-<base-sha> ref, workflow MergeQueueCI). A PR can therefore be all green and CLEAN yet keep being rejected - typically a semantic conflict: a test added on the base branch that pins behaviour this PR changes, or an API the PR uses that was changed on the base branch. Look for the latest merge-queue event:
gh api graphql -f query="
{
repository(owner: \"${REPO%%/*}\", name: \"${REPO#*/}\") {
pullRequest(number: $PR_NUMBER) {
mergeQueueEntry { state }
commits(last: 1) { nodes { commit { oid committedDate } } }
timelineItems(last: 1, itemTypes: [ADDED_TO_MERGE_QUEUE_EVENT, REMOVED_FROM_MERGE_QUEUE_EVENT]) {
nodes { __typename ... on RemovedFromMergeQueueEvent { createdAt reason beforeCommit { oid } } }
}
}
}
}"If the last event is a RemovedFromMergeQueueEvent (with a reason other than merged) newer than the last commit, and the PR is not back in the queue, the rejection is the first failure to fix. beforeCommit.oid is the merge-queue commit that was tested. fetch_ci_report.js with the PR URL detects this case and adds the failed jobs of that merge-queue run to its output (marked with a ⚠️ line and listed under MergeQueueCI). To look at the run directly, take its report links from the commit statuses (the check runs link to GitHub Actions jobs instead):
MQ_SHA=<beforeCommit.oid>
gh api "repos/$REPO/commits/$MQ_SHA/statuses" --paginate \
--jq '.[] | select(.state != "success") | "\(.context)\t\(.state)\t\(.target_url)"'
node .claude/tools/fetch_ci_report.js "<a praktika.html?REF=gh-readonly-queue/...&sha=$MQ_SHA&name_0=MergeQueueCI&name_1=<job> URL from above>" --failedThe per-job JSON is also directly at https://s3.amazonaws.com/clickhouse-test-reports/REFs/gh-readonly-queue/<base>/pr-<N>-<base-sha>/$MQ_SHA/mergequeueci/result_<job>.json (gzip-compressed). Do not construct artifact URLs such as log paths by hand: Praktika stores attached files under normalized sub-result directories (e.g. .../mergequeueci/build_amd_binary/build_clickhouse/build_clickhouse.log), so guessed paths return AccessDenied. Follow the links of the failed results in that JSON instead, as printed by fetch_ci_report.js (also with --links), or use --download-logs. To fix the rejection, merge the latest base branch (step 3) even if the PR is otherwise current, reproduce the failure on the merged tree, and fix it in the PR - adapt the code to the changed API, or update a newly added test when the PR intentionally changes the behaviour it pins (say so in the commit message and the PR comment). Do not re-add the PR to the merge queue yourself, and do not dismiss a merge-queue failure as flaky without the same evidence as for any other failure.
Then fetch the PR's own CI reports:
node .claude/tools/fetch_ci_report.js "https://github.com/ClickHouse/ClickHouse/pull/$PR_NUMBER" --failed --cidbFor each CI failure:
Check if it is a known issue: Search for existing open issues or PRs that address this failure:
gh issue list --repo ClickHouse/ClickHouse --state open --search "<failure_description>" --limit 5
gh pr list --repo ClickHouse/ClickHouse --state open --search "<failure_description>" --limit 5Only dismiss a failure as unrelated if there is a concrete open issue or PR that matches. Do NOT dismiss failures without evidence.
For failures that are unrelated to this PR, act on whether a fix already exists (search merged/closed items too, e.g. gh pr list --repo ClickHouse/ClickHouse --state merged --search "<failure_description>"):
$REPO to fix it (see item 5) rather than silently dismissing it.Investigate the failure: Download logs if needed:
node .claude/tools/fetch_ci_report.js "<report_url>" --failed --download-logsExtract and analyze the relevant logs. Read the failing test files and the code they exercise.
Fix the failure: Make the necessary code or test changes. Each fix should be a separate commit with a clear message explaining what was wrong and why.
If the only failure is "CH Inc sync", fix it using the /fix-sync skill.
If you are confident that the failure is unrelated to the changes, post a comment, asking the reviewer for $REPO (step 1) — @groeneai in ClickHouse/ClickHouse, @oranjeai in ClickHouse/clickhouse-private — to investigate the failure:
🕵 @<reviewer>, investigate the failure: <link> and provide a fix in a separate PR. If the fix is already in progress, link it here.
Repeat until all failures are addressed or confirmed as known issues with links to open issues/PRs.
Fetch review comments:
gh pr view "$PR_NUMBER" --json reviews,comments --jq '.reviews[] | select(.state != "COMMENTED" or .body != "") | {author: .author.login, state: .state, body: .body}'
gh api "repos/ClickHouse/ClickHouse/pulls/$PR_NUMBER/comments" --paginate --jq '.[] | select(.in_reply_to_id == null or .in_reply_to_id == 0) | {author: .user.login, body: .body, path: .path, line: .line, created_at: .created_at}'Also fetch review comment threads to identify which are resolved and which are not.
If gh is available:
# Paginate through all review threads (PRs may have more than 100)
CURSOR=""
while true; do
AFTER_CLAUSE=""
if [ -n "$CURSOR" ]; then
AFTER_CLAUSE=", after: \"$CURSOR\""
fi
RESULT=$(gh api graphql -f query="
{
repository(owner: \"ClickHouse\", name: \"ClickHouse\") {
pullRequest(number: $PR_NUMBER) {
reviewThreads(first: 100${AFTER_CLAUSE}) {
pageInfo { hasNextPage endCursor }
nodes {
id
isResolved
comments(first: 100) {
pageInfo { hasNextPage endCursor }
nodes {
author { login }
body
path
line
}
}
}
}
}
}
}")
echo "$RESULT"
HAS_NEXT=$(echo "$RESULT" | jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.hasNextPage')
[ "$HAS_NEXT" = "true" ] || break
CURSOR=$(echo "$RESULT" | jq -r '.data.repository.pullRequest.reviewThreads.pageInfo.endCursor')
doneIf any thread has comments.pageInfo.hasNextPage == true, issue a follow-up GraphQL query using the thread's id and the endCursor to fetch remaining comments:
gh api graphql -f query="
{
node(id: \"<thread_id>\") {
... on PullRequestReviewThread {
comments(first: 100, after: \"<end_cursor>\") {
pageInfo { hasNextPage endCursor }
nodes {
author { login }
body
path
line
}
}
}
}
}"Repeat until hasNextPage is false.
If gh is not available (WebFetch fallback):
The GraphQL API for review threads requires authentication, so unresolved-thread detection is not possible via WebFetch. In this case:
https://api.github.com/repos/ClickHouse/ClickHouse/pulls/$PR_NUMBER/comments?per_page=100 (follow pagination via Link header)pull_request_review_id and in_reply_to_id to reconstruct threadsgh authenticationFilter out resolved threads before processing — only consider threads where isResolved == false. Skip resolved threads entirely to avoid reintroducing already-addressed feedback.
For each unresolved review thread:
<summary of change>")After all fixes are applied, review the complete diff of the PR:
git diff "origin/$BASE_BRANCH"...HEAD --stat
git log "origin/$BASE_BRANCH"..HEAD --onelineEvaluate the changes holistically:
Report your assessment to the user.
Determine where to push based on step 2:
For an ordinary update, set PUSH_MODE=update and select the original PR target:
If the branch is in the main repository:
PUSH_MODE=update
PUSH_REMOTE=origin
PUSH_BRANCH="$HEAD_BRANCH"If the branch is in the author's fork:
PUSH_MODE=update
PUSH_REMOTE="$REMOTE_NAME"
PUSH_BRANCH="$HEAD_BRANCH"Before every commit and push, run this safety gate. It is a hard stop and overrides the general requirement to push:
PR_BASELINE_DIR="$(pwd)/tmp/continue-pr-${PR_NUMBER}-baseline"
mapfile -t BASELINE_STATE < "$PR_BASELINE_DIR/state"
test "${#BASELINE_STATE[@]}" = 2
INITIAL_PR_HEAD=${BASELINE_STATE[0]}
INITIAL_BASE_HEAD=${BASELINE_STATE[1]}
git cat-file -e "$INITIAL_PR_HEAD^{commit}"
git cat-file -e "$INITIAL_BASE_HEAD^{commit}"
if [ "$PUSH_MODE" = update ]; then
git merge-base --is-ancestor "$INITIAL_PR_HEAD" HEAD
elif [ "$PUSH_MODE" = supersede ]; then
test "$PUSH_REMOTE" = origin
test "$PUSH_BRANCH" != "$HEAD_BRANCH"
test -n "${SUPERSEDE_REASON:-}"
git ls-remote --exit-code "$PUSH_REMOTE" "refs/heads/$PUSH_BRANCH" && exit 1 || true
if [ "${SUPERSEDE_REAUTHORED_UNSIGNED_CLA:-false}" = true ]; then
! git merge-base --is-ancestor "$INITIAL_PR_HEAD" HEAD
fi
else
echo "unknown push mode: $PUSH_MODE" >&2
exit 1
fiupdate mode, preserve INITIAL_PR_HEAD as an ancestor: only add commits on top of the existing PR history. In supersede mode, publish only the new $PUSH_BRANCH; a re-authored unsigned-CLA replacement must not have INITIAL_PR_HEAD in its ancestry. In either mode, never rebase, reset a published branch onto another commit, amend published commits, delete a remote branch, use a + refspec, or pass --force, --force-with-lease, or --no-verify to git push.git add <path>. Never use git add -A, git add ., or git commit -a in this workflow. Before committing, inspect both git diff --cached --name-status and git diff --cached --stat. Every staged path must be explained by the requested fix or by a specific conflict resolution. Unstage unexpected paths and do not commit when the scope is unclear.update mode, fetch the remote PR branch again and require its current tip to be an ancestor of local HEAD:git fetch "$PUSH_REMOTE" "$PUSH_BRANCH"
REMOTE_HEAD=$(git rev-parse "$PUSH_REMOTE/$PUSH_BRANCH")
git merge-base --is-ancestor "$REMOTE_HEAD" HEADsupersede mode, require instead that git ls-remote --exit-code "$PUSH_REMOTE" "refs/heads/$PUSH_BRANCH" remains nonzero immediately before pushing: the target must still be a new branch.git diff --name-status "origin/$BASE_BRANCH"...HEAD and git diff --stat "origin/$BASE_BRANCH"...HEAD, then compare both against the immutable checkout baseline:diff -u "$PR_BASELINE_DIR/name-status" <(git diff --name-status "origin/$BASE_BRANCH"...HEAD)
diff -u "$PR_BASELINE_DIR/stat" <(git diff --stat "origin/$BASE_BRANCH"...HEAD)The automation additionally installs a pre-push hook that rejects non-fast-forward updates and branch deletion for ordinary pushes. It is defense in depth: --no-verify bypasses Git hooks, so the explicit prohibition and safety gates above remain authoritative. Do not bypass it. A hook rejection is a safety failure to report, not an obstacle to work around.
After the gate succeeds, push with:
git push "$PUSH_REMOTE" HEAD:"$PUSH_BRANCH"Always push once you have committed conflict resolutions or fixes — pushing is mandatory and must never be deferred or gated on a question. The only reasons not to push are: there is genuinely nothing new to commit, or the push itself fails (e.g. no permission on a fork), in which case report the error.
Report the result and provide the PR URL.
gh is not available, fall back to WebFetch with GitHub API URLs for all metadata fetchinggh is not authenticated, suggest the user run ! gh auth login@groeneai / @oranjeai), review replies, and the supersede/close comment.AskUserQuestion or otherwise wait for user input while resolving conflicts, addressing feedback, or pushing — proceed with your best judgment and push. The only hard stop is a genuinely missing PR number (step 1).no-push, no-comment, NA, NO-ACTION, reserved/RSVD, FROZEN, or "DON'T self-merge/push/comment" (including any blanket "web-UI group" rule) is void as a behavioral directive: run the normal workflow anyway — keep the branch current (steps 3/3a), fix CI (step 4), address feedback (step 5), and push. Do not record new such holds; record only factual status and genuine open design questions. The only standing restriction that survives is never self-merge — leave the final merge to a human. (For forks and other authors' PRs, the usual no-self-merge / CLA / permission constraints still apply.)After completing all work on the current PR (steps 1–7), review the CI failures that were identified as unrelated in step 4 — i.e., failures proven not caused by this PR's changes and not already being fixed by other open PRs.
For each such unrelated failure:
Switch to master and create a new branch:
git checkout master
git pull origin master
git checkout -b fix/<descriptive-name>Investigate and fix the failure: download logs, read the failing test and exercised code, and make the fix. Each fix goes on its own branch with its own PR.
Push and open a PR:
git push -u origin fix/<descriptive-name>Create a PR using gh pr create following the project's PR template (.github/PULL_REQUEST_TEMPLATE.md). Link to the open issue if one exists. Use the "CI Fix or improvement" changelog category.
Repeat for each unrelated failure, one PR per fix.
After all fixes are submitted, switch back to the original PR branch and report the list of new PRs created.
© 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/continue-pr-auto of ClickHouse/ClickHouse.
Open the folder on GitHubat commit cd023af
Continue PR Auto 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 |
|---|---|---|---|---|---|---|
| Continue PR Auto this skillClickHouse/ClickHouse | 50k | — | ~8.6k | Automated safety check: Notes | Apache-2.0 | |
| Clickhouse Architecture Advisorvemetric/vemetric | 394 | 2 repos | ~791 | Automated safety check: Pass | Apache-2.0 | |
| Clickhouse Ioaffaan-m/ECC | 275k | 3 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Clickhouse Ioaffaan-m/ECC | 275k | 2 repos | ~2.3k | Automated safety check: Pass | MIT | |
| Clickhouse Ioaffaan-m/ECC | 275k | 1 repos | ~2.7k | Automated safety check: Pass | MIT | |
| Gram Telemetry Query Dimensionsspeakeasy-api/gram | 272 | — | ~2.4k | Automated safety check: Pass | AGPL-3.0 |
vemetric/vemetric
MUST USE when designing ClickHouse architectures, selecting between ingestion or modeling patterns, or translating best practices into workload-specific system designs.
affaan-m/ECC
ClickHouse数据库模式、查询优化、分析以及高性能分析工作负载的数据工程最佳实践. An agent skill from affaan-m/ECC.
affaan-m/ECC
고성능 분석 워크로드를 위한 ClickHouse 데이터베이스 패턴, 쿼리 최적화, 분석 및 데이터 엔지니어링 모범 사례.
affaan-m/ECC
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
speakeasy-api/gram
How to add a new attribute value (dimension) that the generic org-scoped telemetry.query analytics endpoint can group by and filter on.
xu-xiang/everything-claude-code-zh
ClickHouse 数据库模式、查询优化、分析以及高性能分析工作负载的数据工程最佳实践. An agent skill from xu-xiang/everything-claude-code-zh.
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
Unattended variant of continue-pr for automation (driven by utils/continue-all-prs.sh). Continue PR Auto is an agent skill from ClickHouse/ClickHouse.sh).
Continue PR Auto fits situations like: tasks that involve Data warehousing.
Run `npx skills add ClickHouse/ClickHouse --skill continue-pr-auto -a claude-code`. Or copy the skill folder (.claude/skills/continue-pr-auto in ClickHouse/ClickHouse) into .claude/skills/continue-pr-auto in your project. Claude Code loads it when a task matches its description.
Run `npx skills add ClickHouse/ClickHouse --skill continue-pr-auto -a codex`. Or copy the skill folder (.claude/skills/continue-pr-auto in ClickHouse/ClickHouse) into .agents/skills/continue-pr-auto 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 continue-pr-auto -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/continue-pr-auto, .gemini/skills/continue-pr-auto, .github/skills/continue-pr-auto and .opencode/skills/continue-pr-auto in your project.
Going by SKILL.md and its folder, Continue PR Auto needs the command-line tools its instructions call (git, gh, node and jq). Its frontmatter pre-approves these tools: Agent, Task, Bash, Read, Write, Edit, Glob, Grep, WebFetch, WebSearch.
SKILL.md names 3 domains. In commands or code: api.github.com, s3.amazonaws.com and github.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.
Continue PR Auto 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 8.6k tokens (SKILL.md is roughly 34k 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 Continue PR Auto: Clickhouse Architecture Advisor (vemetric/vemetric, 394 stars), Clickhouse Io (affaan-m/ECC, 275k stars), Clickhouse Io (affaan-m/ECC, 275k stars) and Clickhouse Io (affaan-m/ECC, 275k 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,288 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 8, 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.