Understanding Design Through Code and GitHub
In an Apache project, you ask "what is the JIRA?" In OpenSearch, the question is "what is the
issue and PR?" OpenSearch is a GitHub-native project: design discussion, decision records,
review history, and the rationale for nearly every line of code live on
github.com/opensearch-project/OpenSearch.
There is no JIRA, no separate design wiki that maintainers actually use, and no email thread
that the code points back to. The "why" behind the code is a (#NNNN) away.
This chapter teaches you to recover that "why" — to do code archaeology — so you change existing behavior with full knowledge of why it is the way it is. Changing code without reading its origin PR is the single most common way a well-meaning contributor reintroduces a bug that was deliberately fixed two years ago.
Where OpenSearch Design Actually Lives
| Location | What it holds | How to reach it |
|---|---|---|
| GitHub issues | Bug reports, feature requests, RFCs, meta/tracking issues | Repo → Issues; filter by label |
Issue labels RFC / meta / proposal / roadmap | Large designs and their discussion | is:issue label:RFC |
| Pull request descriptions | The "what and why" of a change, linked to its issue | The (#NNNN) on every commit |
| PR review threads | Maintainer objections, alternatives considered, the final consensus | The "Conversation" tab of a PR |
| In-repo docs | DEVELOPER_GUIDE.md, CONTRIBUTING.md, TESTING.md, design notes under subsystem dirs | The repo tree itself |
| Community meetings | Recorded video + notes for big decisions | forum.opensearch.org and the project YouTube |
| The forum | Longer-form design and user-impact discussion | forum.opensearch.org |
The center of gravity is the issue → PR pair. A well-run feature looks like: an issue
(often labeled RFC or meta) collects the design and the consensus; one or more PRs
implement it, each closing or referencing the issue with Closes #NNNN; the PR review thread
records every objection and how it was resolved. That chain is the design document.
Note: Large efforts use a meta issue as an umbrella that links many child issues and PRs. When you find a meta issue for your area (search
is:issue label:metaplus a keyword), you have found the project's own roadmap for that subsystem. Read it top to bottom before proposing anything.
The Difference From Apache JIRA Culture
If you come from Hadoop, Hive, or Tez, recalibrate. The differences are not cosmetic — they change where you look and how you participate.
| Apache (JIRA) | OpenSearch (GitHub) |
|---|---|
Design lives in a JIRA ticket; code commits reference PROJECT-NNNN | Design lives in an issue + PR thread; commits reference (#NNNN) |
Patches attached as .patch files, re-rolled as v1/v2/v3 | A branch + PR; iterate by force-pushing the branch |
| Contributor identity gated by a CLA | Identity gated by DCO sign-off (git commit -s) |
dev@ mailing list for proposals and votes | GitHub issues (RFC/proposal), forum, Slack, community meetings |
| "Committer" / "PMC" | "Maintainer" (MAINTAINERS.md) / "TSC" |
| Find the "why" via JIRA → linked patch | Find the "why" via git blame → PR → linked issue |
The practical consequence: when you want the rationale for a line of code in OpenSearch, you
do not search a JIRA project — you walk git blame to the introducing commit, read its PR,
and read the issue that PR closed.
Archaeology: From a Line of Code to Its "Why"
This is the core skill. Given any suspicious or surprising line, recover the decision behind it in four moves.
Move 1 — git blame to find the introducing commit
cd ~/os-src
# Blame a specific region of a file (lines 120–140):
git blame -L 120,140 server/src/main/java/org/opensearch/cluster/ClusterState.java
git blame gives you the commit SHA and author for each line. If the line you care about was
last touched by a trivial reformat (Spotless, a license header), peel back to the real change:
# Walk history of just these lines, following moves/renames:
git log -L 120,140:server/src/main/java/org/opensearch/cluster/ClusterState.java --oneline
Move 2 — git log -S / git log -G to find when a concept appeared
blame shows the last touch; -S/-G find the originating change of a string or
pattern, even if later commits reshaped it:
# When did "clusterManager" terminology enter this file's history?
git log -G "clusterManager" --oneline -- server/src/main/java/org/opensearch/cluster/
# When was a specific method first added anywhere?
git log -S "applyIndexOperationOnPrimary" --oneline -- server/
Move 3 — From commit to PR
OpenSearch commit messages end with the PR number. Extract it:
git show <sha> | head -20
# Title line looks like: "Rename master to cluster_manager in X (#3537)"
Open https://github.com/opensearch-project/OpenSearch/pull/3537. Read the description
(the "what and why") and the Conversation tab (the objections and the resolution). Note
the linked issue at the top (Closes #NNNN / Resolves #NNNN).
Move 4 — From PR to issue (the design)
The issue the PR closed is usually where the design was argued. Open it. For a large
feature it will be an RFC/meta issue with the full proposal, alternatives, and the
maintainer who signed off. That issue, plus the PR thread, is your complete "why."
You can do Moves 3–4 from the CLI with the GitHub CLI if you have it:
gh pr view 3537 --repo opensearch-project/OpenSearch --comments | head -60
gh issue view 1684 --repo opensearch-project/OpenSearch | head -60
Worked Example: The "master" → "cluster_manager" Rename
OpenSearch renamed the master node role and "master node" terminology to cluster_manager
/ cluster manager for inclusive language, keeping the old names as deprecated aliases. This
is a textbook archaeology target because it touched serialization, settings, REST, and logs —
exactly the kind of cross-cutting change you must understand before extending it.
Reconstruct the design without prior knowledge:
cd ~/os-src
# 1. Find where both terms coexist (the alias seam):
grep -rn "cluster_manager" server/src/main/java | grep -i "master" | head
# 2. Find the deprecated-alias settings:
grep -rn "initial_cluster_manager_nodes\|initial_master_nodes" \
server/src/main/java | head
# 3. Walk history of the role definition to the introducing commits:
git log -G "CLUSTER_MANAGER_ROLE\|cluster_manager" --oneline -- server/ | tail -20
What you should reconstruct from the PRs and issues those commits point to:
- Why both terms exist. Removing
masteroutright would break every user'sopensearch.yml(cluster.initial_master_nodes), every node role config, and every script parsingmasterfrom_cat/nodes. So the old names became deprecated aliases, not deletions — a compatibility decision, not just a wording one. - Where the seam is
Version-gated. Cross-node messages and APIs that report the role had to keep emittingmasterto old nodes andcluster_managerto new ones. That is exactly theVersion-gated serialization pattern from the serialization-BWC deep dive. The rename's PRs are a live example of why "small wording change" was actually a compatibility project. - The deprecation path. The old
masterrole and settings log deprecation warnings and are scheduled for eventual removal — see the compatibility chapter for how OpenSearch stages deprecations.
The lesson generalizes: a change that looks like a string rename was, in design, a multi-surface compatibility exercise. The PR thread is where the maintainers worked that out. Read it before touching anything in that area.
A Second Pattern: Tracing a Feature Like Segment Replication
Segment replication (replicas copy Lucene segments from the primary instead of replaying each operation, contrasted with the default document replication) is a large feature with a meta issue and many child PRs. Use it to practice tracing a feature, not a single line:
cd ~/os-src
# Find the entry points in code:
grep -rln "SegmentReplication" server/src/main/java | head
find server -name 'SegmentReplicationTargetService.java' \
-o -name 'SegmentReplicationSourceService.java'
# Find when the subsystem landed and the PRs behind it:
git log -G "SegmentReplication" --oneline -- server/ | tail -20
Then, on GitHub, search is:issue label:meta segment replication. The meta issue links the
RFC, the design trade-offs (read amplification vs. CPU/refresh cost, the global-checkpoint
interaction in the replication deep dive), and the staged child
PRs. Reading the meta issue first tells you which sub-area is stable, which is experimental,
and where a new contribution would actually be welcome — information that does not exist in the
code at all.
How To Find the "Why" Behind a Design — Checklist
When you are about to change existing behavior, run this before writing any code:
-
git blamethe lines you want to change; peel past reformat/license commits withgit log -L. -
Extract the introducing PR number
(#NNNN)from the originating commit. - Read the PR description (what/why) and the Conversation (objections, alternatives, resolution).
-
Open the issue the PR closed; if it is an
RFC/metaissue, read the whole design. -
Search for a meta issue covering your subsystem (
is:issue label:meta <keyword>). - Check whether there is a community-meeting recording or forum thread referenced from the issue.
- Confirm no open RFC/proposal already plans the change you are about to make — if so, join that discussion instead of duplicating it.
If you skip these and your PR reverses a deliberate decision, the maintainer's first comment will be a link to the very issue you should have read. That costs you a review round and some credibility. The archaeology is faster than the rework.
Validation: Prove You Understand This
- Pick any non-trivial method in
server/you have never seen. Usinggit blame→git log→ PR → issue, state in one sentence why it exists and who signed off on it. - Find one
RFCormetaissue for a subsystem you care about and summarize its design decision and current status in three bullets. - Explain, with reference to the rename example, why a "rename a string" PR can be a compatibility-sensitive change, and which deep dive governs that.
- Demonstrate the difference between
git log -Sandgit log -Gon a real identifier and say which you would use to follow an existing method through renames. - Produce the GitHub URL of the PR that introduced a piece of code you traced, and the URL of the issue it closed.
When you can recover the "why" behind any line in under ten minutes, you are ready to participate in the conversation. The next chapter — Community Interaction: GitHub, Forum, and Slack — is how you join it without burning trust.