Capstone Project

The Capstone is the bridge from "I have read the Tez codebase" to "I have shipped a non-trivial fix that an Apache Tez committer merged into master." Everything in Levels 1–7 was preparation. This is the work.

You will pick one real, open Apache Tez JIRA, reproduce it against a current build, trace the failure through the codebase, identify the root cause, write a minimum-diff patch with deterministic tests, get it through precommit (Yetus + the GitHub Actions build), respond to review comments on the PR, and land the change. Then you write it up so the next person can learn from your investigation.

Tez contribution is JIRA-tracked and GitHub-native. The permanent record of the bug lives in a TEZ-NNNN issue on issues.apache.org; the code review happens in a Pull Request against github.com/apache/tez. Every commit that lands carries the JIRA key in its subject line — run git log --oneline -20 on your clone and you will see the shape: TEZ-4580: Slow preemption of new containers when re-use is enabled (#374). You open the JIRA (or claim an existing one), open the PR, cross-link them, iterate in the PR conversation, and a committer squashes-and-merges with that subject line. Keep that model in your head — every step below assumes it.

This chapter is the table of contents. The ten step-chapters that follow are the work itself.


Prerequisites: the gate

Do not start the Capstone until you can answer "yes" to every one of these. This is a gate, not a suggestion. The Capstone is unforgiving of partial preparation — you will spend three weeks confused instead of three weeks shipping.

  • Levels 1–7 complete. You can read DAGImpl, VertexImpl, TaskImpl, TaskAttemptImpl, AsyncDispatcher, the shuffle path (ShuffleManager, Fetcher, FetcherOrderedGrouped, the merge path), and at least one VertexManagerPlugin (ShuffleVertexManager or RootInputVertexManager) without a guide open. If those names are not instantly familiar, go back to the state-machine deep dive and the vertex-lifecycle deep dive.
  • You have built Tez from source. mvn clean install -DskipTests succeeds on your machine (JDK 21 — Tez moved to JDK 21+ in TEZ-4636, after the earlier JDK 17 move in TEZ-4598), and mvn test -pl tez-dag finishes (some flakes are normal — see the flaky-test stage).
  • You have run MiniTezCluster locally. mvn test -pl tez-tests -Dtest=TestOrderedWordCount goes green, so you know the in-JVM YARN + DAGAppMaster harness works on your box.
  • You have run a local-mode DAG. mvn test -pl tez-tests -Dtest=TestLocalMode passes — the lightest end-to-end harness, and the one you will reach for most in Step 2. See the local-mode deep dive.
  • You have a working Apache JIRA account (register at issues.apache.org/jira) and a GitHub account ready to fork and PR.
  • You have read the Tez contribution guide: tez.apache.org/contribution_guide.html and cwiki.apache.org/confluence/display/TEZ/How+to+Contribute.

If any of these is "no," stop. Go back. Fix it before you spend a single evening on Step 1.


The 10-step flow

flowchart TD
    A[Step 1: Issue Selection] --> B[Step 2: Reproduction]
    B --> C[Step 3: Execution Path Analysis]
    C --> D[Step 4: Root Cause Identification]
    D --> E[Step 5: Implementation]
    E --> F[Step 6: Testing]
    F --> G[Step 7: Validation]
    G --> H[Step 8: Patch / PR]
    H --> I[Step 9: JIRA + Docs]
    I --> J[Step 10: Engineering Write-Up]
    C -.hypothesis wrong.-> B
    D -.hypothesis wrong.-> C
    F -.test fail.-> E
    G -.precommit fail.-> E
    H -.review round.-> E
    I -.CI red.-> F

The dotted arrows are the loops you will actually run. Nobody gets root cause right on the first hypothesis. Nobody passes precommit on the first push. Nobody clears committer review in one round. Plan for two or three iterations through Steps 4–9 before the merge button turns green.

Read every step-chapter once, end-to-end, before you touch Step 1 — you need the shape of the whole journey in your head. Step 4 (root cause) makes choices that Step 6 (testing) depends on; Step 8 (patch) assumes you have artifacts from Steps 2 and 7; Step 9 assumes your tests cleared CI. Skim now, deep-read each as you arrive:

  1. Step 1: Issue Selection — pick a right-sized JIRA.
  2. Step 2: Reproduction — a deterministic failing test.
  3. Step 3: Execution Path Analysis — trace repro to code.
  4. Step 4: Root Cause Identification — the one wrong line.
  5. Step 5: Implementation — the minimum diff.
  6. Step 6: Testing — regression protection that convinces.
  7. Step 7: Validation — precommit, checkstyle, spotbugs, RAT.
  8. Step 8: Patch / PR — the PR against apache/tez:master.
  9. Step 9: JIRA + Docs — the permanent record.
  10. Step 10: Engineering Write-Up — teach the next person.

What "done" means

The Capstone is done when either:

  1. A committer has merged your PR — the ideal outcome. Your fix appears in git log apache/master with the TEZ-NNNN subject line and your authorship, and the JIRA flips to "Resolved / Fixed in X.Y.Z." Or,
  2. You have a credibly-submitted patch under active review — a PR open against master, green CI, a linked JIRA in "Patch Available," a reproducer a committer can run in one command, and a review conversation you are driving. Merges can take weeks that are outside your control; a patch that a committer would merge, blocked only on their calendar, counts as done for grading.

What does not count: a local branch you never pushed; a PR with red CI you stopped babysitting; "I think this fixes it" with no failing test. The bar is a patch another engineer trusts, not code that compiles.

And in both cases: the engineering write-up exists. 500–1000 words — problem, investigation, design, alternatives, lessons. It is not optional. It is how the community and your future self learn from the investigation, and it is 10 rubric points (Step 10).

The deliverable set

By the time you mark the Capstone done, every one of these artifacts exists. Track them with a checklist:

#ArtifactLives in
1Failing reproducer test — red on master without your patch, green with ittez-tests/ or a module-local src/test/java/...
2Root-cause document (200–500 words, with file#method citations)capstone-work/root-cause.md in your fork
3Minimum-diff patchA branch on your fork of apache/tez
4Unit tests with a drainable dispatcher (if state-machine related)The relevant src/test/java
5Integration test on MiniTezCluster (if end-to-end behavior changed)tez-tests/src/test/java/org/apache/tez/test/
6Validation report (mvn test -pl <module>, checkstyle, spotbugs, RAT output)capstone-work/validation.md
7GitHub PR against apache/tez:master, JIRA key in the titlegithub.com/apache/tez/pulls
8JIRA updated: "Patch Available," PR linked, release-note filled if user-visibleissues.apache.org/jira/browse/TEZ-NNNN
9Engineering write-up (problem, investigation, design, alternatives, lessons)Blog, Apache wiki, or dev@tez.apache.org summary
  • Failing reproducer committed and confirmed red on master
  • capstone-work/root-cause.md written
  • Minimum-diff patch on a feature branch
  • Unit tests cover every branch you added
  • Integration test if behavior is end-to-end
  • capstone-work/validation.md with a clean precommit
  • PR opened against master, JIRA-keyed title
  • JIRA at "Patch Available," PR linked
  • Write-up published

How the Capstone is assessed

The full rubric — 100 points, self-graded, honestly — lives in evaluation-rubric.md. Read it before Step 1, not after Step 10; it tells you what "good" looks like at every step, and you should be scoring yourself against it as you go. Headline weights:

AreaWeight
Problem articulation (symptom vs. root cause, trigger conditions)20
Execution-path mastery (file#method citations, accurate diagram)20
Implementation quality (minimum diff, conventions, no scope creep)20
Testing (unit + integration, deterministic, branch coverage)15
Review responsiveness (addresses comments, iteration cadence)10
Documentation (JIRA, code comments, write-up)10
Community interaction (mailing-list etiquette, handoff hygiene)5

Tier thresholds:

  • 80+ — credible Tez contributor. You can sustain a steady patch flow.
  • 90+ — committer-ready. You are doing work a committer would do without hand-holding.
  • 95+ — PMC-track. You are leading work others want to follow.

You self-grade in Step 10. Be honest — inflated self-grades are visible from orbit the moment a committer reads your write-up next to your diff.


Time budget

The Capstone is a 4–6 week effort if you have one focused evening per weekday plus weekend mornings. Less than that and you risk losing context between sessions — far more expensive than people expect for state-machine and scheduler code, where the bug lives in the interleaving of events across three classes and you have to rebuild the whole mental picture every time you sit down.

WeekStepsHours
11–2: Pick an issue, build a deterministic reproducer10–15
23–4: Trace execution, identify root cause12–18
35–6: Implement fix, write unit + integration tests12–18
47–8: Validate, prepare patch / PR, push8–12
58–9: Review iteration (two or three rounds is normal)6–10
610: Write-up, JIRA cleanup, retrospective4–6

If you blow past six weeks, that is a signal — not a failure. Either the issue is larger than it looked (pause and renegotiate scope in the JIRA), or you are stuck on a specific step (ask on dev@tez.apache.org). Do not silently grind for another month.


Failure modes of Capstone attempts

Most Capstones that stall die from one of four self-inflicted wounds. Recognize them early; each has a specific antidote.

1. Picking a too-big issue

The single most expensive mistake, made in Step 1 and paid for over six weeks. A "rewrite the shuffle scheduler" or "add speculative execution to X" JIRA is a multi-committer, multi-month effort, not a Capstone. The tell: you cannot state the fix as "change the behavior of one method under one condition." The antidote is in Step 1 — size the issue by the diff you predict, not by how interesting it sounds. A landable first patch is typically under ~150 lines of production change touching one or two classes. Look at the exemplar commits: TEZ-4580 changed YarnTaskSchedulerService by 16 lines; TEZ-4569 changed VertexImpl by 63. That is the size that merges.

2. Skipping reproduction

You read the JIRA, form a theory, and start editing in Step 5 with no failing test in hand. Now every "fix" is theater — you cannot prove it fixes anything, and you cannot prove you did not break something else. This is the deadliest failure mode because it feels like progress. The antidote is the repro-first rule in Step 2: no code changes until a test fails on master with an assertion error. If you find yourself in Step 5 without a red test, you are not in Step 5. Go back to Step 2.

3. Silent scope creep

You went in to fix an NPE in TaskAttemptImpl and now your diff also renames three fields, "cleans up" a switch statement, and adds a helper you thought was missing. Every unrelated line you touch is a line a committer must review, a line that can break, and a reason to send the PR back. The antidote: keep a one-sentence scope statement at the top of capstone-work/root-cause.md and reject any change that does not serve it. Refactors are separate JIRAs. See Step 5.

4. Arguing instead of iterating

Review comes back with a request you disagree with, and you spend three days debating in PR comments instead of either making the change or asking a clarifying question. Committers have finite patience and infinite backlog. The antidote: treat every review comment as either "change the code" or "ask one precise question," never "defend the code." Review responsiveness is 10 rubric points and, more importantly, it is the difference between a merge and a stale PR the committer quietly stops reading.


Success indicators

You will know it is working when:

  1. A committer comments "+1" / "LGTM, will commit shortly" on your PR, and CI is green.
  2. Your fix appears in git log apache/master with the TEZ-NNNN subject line and your authorship.
  3. The JIRA you claimed flips to "Resolved / Fixed in X.Y.Z" with your name on it.
  4. Your write-up gets traffic — search hits, a reply on user@, a committer pointing the next contributor at it.
  5. The next time you pick a JIRA, you reach root cause in days, not weeks.

You will know it is failing when: you are still editing files in Step 5 with no failing test from Step 2; your PR description says "I think this might fix it"; you have not run mvn test -pl tez-dag end-to-end in over a week; or you are arguing in PR comments instead of changing code. If you spot a failure signal, do not push through — stop, reread the relevant step chapter, and reset.


Validation / Self-check

Before starting Step 1, confirm:

  1. You can produce, from memory, the source path of DAGAppMaster, DAGImpl, VertexImpl, TaskImpl, and AsyncDispatcher.
  2. mvn clean install -DskipTests completes against your local tez clone on JDK 21.
  3. mvn test -pl tez-tests -Dtest=TestOrderedWordCount and -Dtest=TestLocalMode both pass.
  4. You have a capstone-work/ directory in your fork ready for root-cause.md, validation.md, and writeup.md.
  5. You have skimmed every step-chapter once and read the rubric.
  6. You have set aside 4–6 calendar weeks with a realistic time budget.
  7. You have subscribed to dev@tez.apache.org (send any mail to dev-subscribe@tez.apache.org) and issues@tez.apache.org.

The clock starts when you comment "Working on this" on the JIRA. Go to Step 1: Issue Selection.