Step 1: Issue Selection
The single biggest predictor of whether your Capstone ships is the issue you pick in week one. Pick something too large and you will still be tracing code in week six. Pick something already half-fixed by someone else and you will waste a week before a maintainer points it out. Pick something you cannot reproduce and you have nothing to build on.
A good Capstone issue is real (an open, maintainer-acknowledged problem), tractable (fixable in a focused diff, not a redesign), and reproducible (you can make it fail on demand). This step is how you find one and how you claim it without stepping on anyone.
Where the Issues Live
Everything is on GitHub. There is no JIRA. Start here:
https://github.com/opensearch-project/OpenSearch/issues
Filter with the search bar. The label vocabulary is the same one you read about in the issue roadmap overview; here is the subset that matters for a Capstone:
| Label | What it means for you |
|---|---|
good first issue | Scoped by a maintainer to be approachable. Start here. |
help wanted | Maintainers want a contributor; no one is on it (usually). |
bug | A defect with observable wrong behavior — the best Capstone fuel. |
flaky-test | A test that fails intermittently; often a real concurrency bug. Excellent if you can reproduce it. |
untriaged | Not yet reviewed by a maintainer. Avoid — the problem may not be real, in scope, or even agreed upon. |
enhancement | A feature request. Smaller ones are fine; large ones are not. |
RFC / meta / proposal | Design discussions and large features. Avoid for a Capstone. |
discuss | Needs consensus before code. Avoid unless you want to drive the discussion. |
backport 2.x / v3.0.0 | Versioning/backport metadata, not a "type" of work. |
Useful saved searches
Paste these into the GitHub issue search box (adjust the labels as the project evolves):
is:issue is:open label:"good first issue" no:assignee
is:issue is:open label:bug label:"help wanted" no:assignee
is:issue is:open label:"flaky-test" no:assignee
is:issue is:open label:bug -label:"RFC" -label:"meta" sort:comments-desc
no:assignee is doing real work there — it filters out issues someone has
already claimed. sort:comments-desc surfaces issues with active maintainer
discussion, which is where you learn whether a fix direction is already agreed.
Note: The biggest functional plugins —
security,k-NN,sql,alerting,ml-commons,index-management— live in separate repos underopensearch-project/. For your first Capstone, stay in the core engine (opensearch-project/OpenSearch). The build, test harness, and reviewer pool are what Levels 1–9 trained you on. Cross-repo work is a fine second Capstone.
What Makes an Issue Tractable
A tractable Capstone issue has these properties. Score a candidate against them before you claim it:
| Signal | Good | Bad |
|---|---|---|
| Blast radius | Touches 1–3 files in one module (server/.../cluster, .../search, .../index) | Spans server, libs, modules, and a plugin repo |
| Surface | A wrong value, a missing validation, an off-by-one, a race in one component | "Redesign allocation," "add a new node role" |
| Reproducibility | A curl sequence or a JUnit test makes it fail every time | "Sometimes on a 200-node cluster under load" |
| Agreement | A maintainer has commented confirming it is a bug and roughly how to fix | Open question whether it is even a bug |
| BWC exposure | No serialization or REST contract change, or a clearly guarded one | Changes a wire format with no Version story |
| Test reachability | You can imagine the OpenSearchTestCase / OpenSearchIntegTestCase that asserts the fix | "Only reproduces in production telemetry" |
The sweet spot for a first Capstone: a bug + good first issue where a
maintainer has already written "this is wrong because X; the fix is probably
around SomeClass.someMethod." That comment is gold — it is a pre-validated
root-cause hypothesis you get to confirm and implement.
Categories that age well as Capstones
- A validation gap. A REST parameter or setting accepts a value it should
reject, and the failure surfaces deep in the engine instead of at the edge.
Fix: validate early in the
RestHandlerorSettingdefinition. Small, testable, user-visible. - A flaky test rooted in a real race. A
*ITthat fails ~1 in 50 because of a missingassertBusyor a genuine cluster-state applier ordering bug. The former is a test fix; the latter is a real engine fix. Both are good — just be honest in your root-cause doc about which one it is. - An aggregation/reduce edge. An aggregation returns a wrong value for an
empty bucket, a single-shard index, or a specific
missing/min_doc_countcombination. Contained in oneInternalAggregation.reduce(...)family. See the aggregations deep dive. - A seqno / versioning edge. A document version or sequence-number assertion trips under a specific retry/refresh ordering. Deeper, but extremely instructive. See replication and recovery.
- An error-message / diagnostics defect. The engine throws the wrong exception type, or a message omits the field that would let an operator diagnose it. Low blast radius, genuinely appreciated, great first PR.
Categories to avoid for a first Capstone
- Anything labeled
RFC,proposal,meta, ordiscuss. - New node roles, new transport actions, new settings frameworks.
- Pure performance issues with no correctness component ("make X faster") — benchmarking and proving no regression is its own multi-week skill.
- Anything where the issue thread has an unresolved disagreement between two maintainers about whether to fix it. You do not want to land in the middle of that as your first contribution.
Check It Is Not Already Taken
Before you invest a day reproducing, spend five minutes confirming nobody is already on it:
-
Read the whole thread. Look for "I'll take this," "working on it," or a maintainer assigning someone (
Assigneesin the sidebar). -
Search for an existing PR. GitHub links PRs to issues automatically when the PR body says
Fixes #NNNN. Also search the PR list directly:https://github.com/opensearch-project/OpenSearch/pulls?q=is:pr+NNNNand
is:pr is:open "Fixes #NNNN" -
Check linked timeline events. The issue's timeline shows "X mentioned this in PR #M" — follow it. If there is an open PR, the work is taken. If the PR is stale (months without activity, author gone), you can comment offering to pick it up — but say so explicitly and wait for a maintainer's nod.
-
Check the date. A
good first issueopened two days ago may already have three people circling it silently. An issue open for eight months with a maintainer comment "PRs welcome" is much safer.
Claim It
OpenSearch does not require formal assignment to start, but claiming politely prevents duplicate work and signals seriousness:
I'd like to work on this. My plan is to reproduce it with a failing
OpenSearchIntegTestCasefirst, then trace throughClusterApplierService. I'll open a draft PR once I have the reproducer. Anything I should know about the intended fix direction before I start?
That comment does three things: it claims the issue, it shows you already have a
plan, and it invites a maintainer to redirect you before you spend a week.
Most good first issue threads get a quick "Sounds good, go for it" — and now
you have a maintainer lightly on the hook to review.
Warning: Do not comment "Can I work on this?" and then vanish for a week. That is the single most common way to annoy maintainers — it locks an issue in social limbo. If you claim it, start within a day or two, or un-claim it.
Scope Estimation
Write a one-paragraph scope estimate for yourself before you commit. Answer:
- How many files do I expect to touch? (Grep the symbols from the issue:
grep -rn "theMethodName" server/src/main/java.) If the answer is "dozens," reconsider. - Is there a serialization or REST contract change? If yes, there is a BWC
story (a
Versionguard) and the fix is at least one tier harder. Fine for week three of the Capstone; not ideal for your first one. - Can I name the test that will prove the fix? If you cannot imagine the assertion, you do not understand the bug yet — keep reading the thread and the code before claiming.
- Is there a maintainer hypothesis I can confirm? If yes, your Step 4 is mostly validation. If no, budget extra time for root cause.
If the honest answer to "can I finish this in 4–6 weeks of evenings" is "no," pick a smaller issue. There is no shame in a small, clean, merged PR — it is worth infinitely more than an ambitious branch that never lands.
Reproducibility Pre-Check
You will do the full reproduction in Step 2, but do a 30-minute smoke test now, before you fully commit:
- Build current
main:./gradlew assemble -q. - If the issue is REST-shaped, run
./gradlew runand try the exactcurlfrom the issue. Does it misbehave? - If it is internals-shaped, find the relevant test class
(
find . -name "*<Component>*Tests.java") and see whether you can already write an assertion that fails.
If you cannot make it misbehave in 30 minutes, that is not necessarily
disqualifying — but note it. A bug you cannot reproduce in week one is a bug you
may not reproduce at all, and an irreproducible Capstone is a dead Capstone. If
the issue says "only on version 2.7 with these 4 settings," try exactly that
combination on the matching tag (git checkout 2.7.0) before claiming.
Selection Rubric
Score your candidate issue out of 10 before committing. Pick one that scores 7 or higher.
| Criterion | 0 | 1 | 2 |
|---|---|---|---|
| Maintainer-confirmed it is a real bug/task | Untriaged, unclear | Some discussion | Maintainer confirmed + fix hint |
| Blast radius | Many modules / cross-repo | 2–4 files, one module | 1–2 files, one component |
| Reproducibility | Can't make it fail | Fails sometimes | Deterministic repro in reach |
| BWC / contract risk | Wire/REST change, no plan | Guarded contract change | No serialization/REST change |
| Test reachability | Can't imagine the test | Integration test only | Clear unit + integ assertion |
A 9–10 is a near-ideal first Capstone. A 7–8 is a solid, slightly stretchy choice. Below 7, keep looking — the issue list is long and a better candidate is usually one search away.
Deliverable for Step 1
-
A chosen issue number,
#NNNN, scoring ≥ 7 on the rubric above. - A claim comment posted on the issue with a brief plan.
-
A one-paragraph scope estimate saved in
capstone-work/scope.md. - A 30-minute reproducibility smoke test result noted (did it misbehave?).
-
A local feature branch off
main:git checkout -b fix/issue-NNNN-short-description.
Validation / Self-check
Before advancing to Step 2:
- You can state, in one sentence, the wrong behavior the issue describes (not the desired behavior — the wrong one).
- You have confirmed no open or recent PR already fixes it.
- You have posted a claim comment and (ideally) gotten a maintainer acknowledgement.
- You have grepped the codebase for the symbols named in the issue and the count is small.
- You can name the component the bug lives in: REST handler, transport action, cluster-state path, engine, allocation, aggregation, or coordination.
- Your scope estimate honestly fits a 4–6 week budget.
- You have a feature branch checked out and
capstone-work/ready.
Then go to Step 2: Reproduction.