Apache AsterixDB — the BDMS query engine, storage layer, and Hyracks distributed runtime. See
README.md for an overview.
The tree has two roots:
asterixdb/— the AsterixDB engine (SQL++ compiler, external data, cloud, storage).hyracks-fullstack/— the Hyracks runtime and shared utilities (hyracks-util,hyracks-cloud, etc.).
Files here carry the Apache license header (see README.md). Preserve it when editing or
creating files.
This repository is also consumed by downstream extensions, which may check it out inside their own source tree. Where that is so, the extension's own conventions — coordinating one change across two Gerrit servers, the order in which such a set is landed, and mirroring merged commits to the fork the extension actually builds from — live in the parent directory's instructions, which are not auto-loaded from here. Read them before coordinating a change with an extension.
Changes go through Gerrit (asterix-gerrit.ics.uci.edu), not GitHub pull requests. The gerrit
remote points at ssh://<user>@asterix-gerrit.ics.uci.edu:29418/asterixdb. If it is missing:
git remote add gerrit ssh://<user>@asterix-gerrit.ics.uci.edu:29418/asterixdbPush a change (or a new patchset) for review:
git push gerrit HEAD:refs/for/<branch>Subject convention is [NO ISSUE][COMP] (or [ASTERIXDB-nnnn][COMP]); where the work is tracked in
a downstream extension's issue tracker, that id goes in an Ext-ref: footer rather than the subject.
A backport carries an extra [BP] tag — [ASTERIXDB-3765][COMP][BP] ... — reuses the original
commit's Change-Id, and keeps a (cherry picked from commit <sha>) line. Gerrit warns on subjects
over 72 characters here; an extension's own Gerrit may warn sooner, so the shorter limit wins for
a change that spans both. Documentation-only and tooling changes go under whatever standing issue the
extension uses for them.
A topic (-o topic=<topic>) groups the changes of one coordinated change spanning several
repositories. The tooling that applies a topic across projects fails when a project has more than
one open change carrying the same topic. So when the work in this repo is a stack of several
commits, do not put the shared topic on every commit. Instead:
- Put the topic only on the leaf (final) commit of the stack, and leave the preparatory commits topic-less; or
- If the stack contains discrete sets of cross-project changes that can be submitted independently, give each set its own intermediate topic.
Unrelated follow-up work (e.g. a docs tweak noticed along the way) should be pushed as its own change with no topic, or a different one — not added to the coordinated change's topic.
Every commit message must end with the trailer:
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(naming whichever model actually did the work). This has repeatedly been missed and caught only after the change was pushed for review, which costs a message-only patchset.
Write it at commit time, not as a follow-up amend. The footer must be one contiguous run of
trailers, with the Co-Authored-By line adjacent to Change-Id:
<body>
<- exactly one blank line
Ext-ref: <downstream-issue>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Change-Id: I...
Two ways the footer gets destroyed, both of which make the commit-msg hook mint a second
Change-Id and silently orphan the change:
- A blank line between
Change-Id:andCo-Authored-By:splits the footer, so the last paragraph is read as body text. - Ending the message with a non-trailer line — most often
(cherry picked from commit <sha>)on a backport. Put that line in its own paragraph above the trailer block so the message still ends with a trailer.
If the trailer must be added after the fact, rebuild the whole message rather than appending a line:
capture the Change-Id first, strip every Change-Id:/Co-Authored-By: line, then re-append both
contiguously. Verify before pushing — this must print exactly 1, matching the original:
git log -1 --format=%B | grep -c '^Change-Id:'The body says why — the defect, the constraint, the reason the obvious approach was rejected. It is not a narration of the diff: what changed is already in the diff, and restating it hunk by hunk only leaves two accounts to keep in step. A couple of sentences is usually the right length; a file-by-file tour is not.
Comment the why, never the what. The code already states what it does, and a comment that merely repeats it is a second rein on the same bit — it adds no control and goes slack the moment the code moves. Reserve comments for what a reader cannot recover from the code itself: why a non-obvious approach was chosen, which defect or edge case a guard exists for, an invariant a caller must uphold, a workaround and the upstream issue it waits on.
Javadoc describing contract — parameters, return values, thrown exceptions, threading expectations — is not "what" commentary and is welcome.
When you (an AI agent) generate or assist with Java code in this tree, annotate it with
@AiProvenance. This records which model and tool produced the code so the contribution is
auditable. The annotation is defined here, in this repository.
- Annotation:
org.apache.hyracks.util.annotations.AiProvenance— source athyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/annotations/AiProvenance.java. It is on the classpath of every module that depends onhyracks-util(effectively all of them). @Retention(SOURCE)— documentation only; stripped at compile time, so no runtime or bytecode cost. The repeatable container@AiProvenancesisRUNTIME-retained for tools that scan class files.- Applies to: types, methods, constructors, fields, and local variables.
| Attribute | Required | Values |
|---|---|---|
agent |
yes | AiProvenance.Agent — the model that did the work (e.g. CLAUDE_OPUS_5, CLAUDE_SONNET_4_6) |
tool |
yes | AiProvenance.Tool — the invocation surface (e.g. CLAUDE_CODE_CLI, CLAUDE_CODE_UI, GITHUB_COPILOT) |
contributionKind |
no (default GENERATED) |
GENERATED, ASSISTED, REFACTORED, TEST_GENERATED, DOC_GENERATED |
notes |
no | free-text, e.g. what changed or why |
- Pick the narrowest element that captures the AI contribution: annotate the type only when the whole class is AI-authored. When AI adds or rewrites individual methods (or a field/constructor) within an otherwise human-authored class, annotate each of those methods — do not promote the annotation to the type level.
- Match
agentto the model actually used, andtoolto the surface: theclaudeCLI and the Claude Code desktop/IDE integrations areCLAUDE_CODE_CLI; the Code tab in the Claude web app isCLAUDE_CODE_UI; Copilot-in-IDE isGITHUB_COPILOT. - Choose
contributionKindhonestly:GENERATED(from scratch),ASSISTED(human-led, AI-suggested),REFACTORED(rewriting existing code),TEST_GENERATED,DOC_GENERATED. - Stack annotations (it is
@Repeatable) to record history — e.g. generated by one model then refactored by another. - Import style: either static-import the constants for brevity, or import the type and qualify
(
AiProvenance.Agent.X). Both are used in-tree.
If a model you used is missing from the Agent/Tool/Provider enums, add it to
AiProvenance.java rather than falling back to OTHER.
In-tree usages on this branch include hyracks-fullstack/hyracks/hyracks-util/.../Span.java
(type-level, REFACTORED), hyracks-fullstack/hyracks/hyracks-util/.../SpanTest.java,
asterixdb/asterix-external-data/.../evaluators/StringJsonParseEval.java,
asterixdb/asterix-external-data/.../aws/s3/S3Utils.java and
asterixdb/asterix-cloud/.../S3TrustManagerProvider.java.
import org.apache.hyracks.util.annotations.AiProvenance;
@AiProvenance(agent = AiProvenance.Agent.CLAUDE_OPUS_5, tool = AiProvenance.Tool.CLAUDE_CODE_CLI,
contributionKind = AiProvenance.ContributionKind.GENERATED, notes = "Initial implementation")
public final class ExampleHelper { ... }