The research artifact: report, repo, and talk
The scheduler works and the trials are run; now compress 24 weeks into three artifacts — a 6–8 page report a reviewer can check, a repository a stranger can rerun, and a 10-minute talk that survives the interview deep-dive.
- Assemble a 6–8 page report in which every claim is carried by exactly one figure and the pre-registration rides along as an appendix.
- Derive and compute Wilson intervals for per-condition success rates and a difference-of-proportions interval for the headline comparison.
- Release a repository that passes a fresh-clone gate: pinned environments for collection, training, and inference, a frozen run log, and scripts that regenerate every figure from it.
- Deliver a 10-minute technical talk and answer the statistics and systems deep-dive questions a robotics interviewer will ask.
Twenty-four weeks ago you calibrated a camera. Since then you have built an episode logger with one clock domain, a fine-tuned π₀-class policy served from your RTX workstation, a full-loop latency trace, and — last lesson — an adaptive scheduler with a measured effect on a WidowX AI. All of it is now worth exactly what a stranger can verify. You already live by this rule: a claimed 1.4× serving speedup without the trace, repro script, and pinned container is not a result, it is an anecdote. Robotics runs on the same norm, enforced less by tooling and more by reviewers who have been burned. The artifact — report, repository, talk — is the compression format for the 24 weeks, and it gets the same engineering seriousness as the scheduler: versioned, tested, gated.
Statistical and Methodological Foundations
Before assembling the artifact, we must rigorously define the statistical tools and methodological constraints that validate the claims. The primary metric is the success rate, a proportion estimated by the sample proportion , where is the number of successes and is the total number of trials. In small-sample regimes typical of robot experiments, the standard Wald interval is unreliable. We therefore use the Wilson score interval, which inverts the score test statistic. The score test compares the observed to a candidate true proportion , using the standard error calculated at rather than . The acceptance region for a confidence level is defined by the inequality , where is the critical value from the standard normal distribution (1.96 for 95% confidence). This formulation ensures that the interval remains bounded within even when is 0 or 1, addressing the boundary failure of the Wald method.
Solving this quadratic yields the Wilson bounds. A critical feature is the center of the interval, which is not but rather . This represents a Bayesian shrinkage toward 0.5, the maximum entropy point for a binary outcome. For small , this shrinkage is significant, pulling the estimate away from the boundaries to reflect the high uncertainty inherent in few trials. When comparing two conditions, we do not simply subtract the Wald intervals, as this ignores the covariance and boundary effects. Instead, we use the Newcombe hybrid interval. This method constructs the difference interval , where are the Wilson bounds for condition . This approach provides superior coverage properties compared to the Wald difference, particularly when sample sizes are unequal or proportions are near the boundaries.
Methodological rigor also requires defining pre-registration. Pre-registration is the act of freezing the analysis plan—including primary metrics, sample size, exclusion criteria, and randomization scheme—before data collection begins. This is a methodological constraint against p-hacking, the practice of selectively reporting results that appear significant after multiple comparisons. By attaching the pre-registration document to the report, you demonstrate that the primary claim was not chosen post-hoc to fit the data. Additionally, we must address censored data. In recovery-time experiments, trials that do not complete within the timeout are censored. Dropping these trials biases the mean recovery time downward, as the longest durations are systematically removed. Proper analysis treats these as right-censored observations, preserving the integrity of the distribution.
Worked Example: Wilson and Newcombe Intervals
Consider the capstone's confirmatory results: the adaptive scheduler achieves 78 successes out of 100 trials (), while the synchronous baseline achieves 62 out of 100 (). We calculate the 95% Wilson intervals for each condition and the Newcombe difference interval. For the adaptive condition, . Using , we compute the quadratic coefficients: , , and . The discriminant is . The roots are . This yields and . Thus, the Wilson interval for the adaptive scheduler is .
For the synchronous baseline, . Following the same procedure, the Wilson interval is . The point estimate for the difference is . To compute the Newcombe hybrid interval, we use the formula: Lower bound and Upper bound . Substituting the values: Lower . Upper . The difference interval is , or points. Since this interval excludes zero, the difference is statistically significant at the 95% level, despite the slight overlap in the individual Wilson intervals.
| Metric | Adaptive Scheduler | Synchronous Baseline | Difference (Newcombe) |
|---|---|---|---|
| Successes / Trials | 78 / 100 | 62 / 100 | 16 points |
| Point Estimate () | 0.78 | 0.62 | 0.16 |
| Wilson 95% CI | [0.684, 0.855] | [0.520, 0.710] | [0.029, 0.285] |
| Interpretation | True success rate likely between 68.4% and 85.5% | True success rate likely between 52.0% and 71.0% | Adaptive is 3 to 28 points better; significant |
Why is the Newcombe hybrid interval preferred over the Wald difference interval for comparing two proportions in small-sample robot experiments?
The artifact has three consumers with three read patterns, and each piece is designed for one of them. A reviewer or hiring manager gives the report ten minutes and reads figures first. An engineer building on your scheduler gives the repository an afternoon and judges you by whether the first README command works. An interview panel gives the talk ten minutes plus twenty of questions — and forms its opinion almost entirely in the questions. Design for those budgets the way you design an API for its call pattern.
The report: six pages that carry one claim
Six to eight pages is workshop-paper scale, and honest scale for this evidence: one method, one platform, one task family, roughly 400 confirmatory trials. The spine is the hypothesis you wrote at the start of this phase — "under inference latency in the tested 100–300 ms regime, a scheduler that switches chunks based on predicted inference time and inter-chunk disagreement improves task success over synchronous and fixed-rate baselines." Every section sets that claim up, tests it, or bounds it; anything that does none of the three gets cut, however proud you are of the code behind it.
| Section | Budget | The question it answers |
|---|---|---|
| Problem and hypothesis | 0.75 pages | Why does chunk staleness matter physically, and what exact claim is under test? |
| System and method | 1.5 pages | What is the scheduler, and what signals (predicted inference time, chunk disagreement) drive it? |
| Experimental setup | 1 page | Platform, task, conditions, trial counts, randomization — with the pre-registration attached as an appendix |
| Results | 2 pages | Primary metric first, with intervals; secondary metrics labeled as secondary; figures carry the argument |
| Negative results | 0.5 pages | What did you try that did not work, and what does that rule out? |
| Limitations and future work | 0.75 pages | Where does the evidence stop, and what would extend it? |
The pre-registration appendix is your credibility move, and it costs one page. You froze the primary metric, trial counts, exclusion rules, and analysis before the confirmatory block ran — back in "Designing robot experiments that survive review." Attaching that document verbatim converts the results section from "trust me" to "check me": the reader can confirm the metric you lead with is the one you predeclared, not the best of twelve computed afterward. Lead with exactly that metric; everything else — completion time, seam jerk, deadline-miss rate, recovery time — is labeled secondary.
Negative results get a named section, not a burial. If the disagreement-only scheduler variant — switching chunks on divergence without the latency predictor — performed within noise of the fixed-rate baseline (say 52/100 versus 49/100), that half page does real work: it localizes the effect in the latency-aware component and saves the next lab a month. In a field where most published pages are success stories, a specific, quantified negative result is among the strongest signals that the rest of your numbers are honest.
Write in this order: figures, captions, results, method, introduction, abstract last. Figures before prose is not a slogan — it forces you to discover whether the evidence exists before you spend a week narrating it. Make each caption state the claim, not the axes: "Adaptive scheduling recovers 16 points of success under 200 ms injected latency" tells a skimming reviewer what to believe; "Success rate per condition" tells them nothing they cannot see.
Figures that convince
| Figure | Claim it carries | What a careful reader checks |
|---|---|---|
| Success rate per condition with Wilson 95% CIs | The adaptive scheduler beats all three baselines on the primary metric | n printed on every bar; a difference interval reported, not just overlapping bars |
| Latency CDF per scheduler | The improvement lives in the tail, not the mean | The control deadline marked; the tail readable, ideally log-scaled above p90 |
| Joint-trajectory overlays at chunk seams | Chunk switches do not inject discontinuities the baselines avoid | Velocity continuity at the seam, units on axes, several seams — not one curated example |
| Recovery-time distributions per condition | After a perturbation, the adaptive scheduler re-converges faster | Trials that never recovered shown as censored at the timeout, not silently dropped |
The first figure needs error bars, and the obvious choice is wrong. The Wald interval — the plug-in formula everyone remembers — estimates its standard error at itself:
Small- robot experiments live near the boundaries — pilot conditions at 19/20 or 3/20 are routine — so you need the interval that does not lie there. The Wilson interval inverts the score test: keep every candidate under which the observation would not be rejected, with the standard error computed at the candidate , not at :
Square both sides and collect terms in : a quadratic with positive leading coefficient, so the acceptance set is the segment between its roots:
Plug in the capstone's confirmatory numbers: adaptive at 78/100 gives a Wilson interval of about ; the synchronous baseline at 62/100 gives about . The intervals overlap slightly — and that does not kill the result, because overlapping per-condition intervals are not a test of the difference. The difference gets its own interval: by the Newcombe hybrid construction combining the two Wilson intervals, the 16-point gap carries a 95% interval of roughly points, excluding zero. Put that in the caption; it is the sentence the whole project defends.
import numpy as np
Z = 1.959964 # two-sided 95%
def wilson_ci(k: int, n: int, z: float = Z):
p = k / n
denom = 1.0 + z * z / n
center = (p + z * z / (2 * n)) / denom
half = (z / denom) * np.sqrt(p * (1 - p) / n + z * z / (4 * n * n))
return max(0.0, center - half), min(1.0, center + half)
def newcombe_diff_ci(k_a, n_a, k_b, n_b):
"""95% interval for p_a - p_b from the two Wilson intervals."""
pa, pb = k_a / n_a, k_b / n_b
la, ua = wilson_ci(k_a, n_a)
lb, ub = wilson_ci(k_b, n_b)
d = pa - pb
lo = d - np.sqrt((pa - la) ** 2 + (ub - pb) ** 2)
hi = d + np.sqrt((ua - pa) ** 2 + (pb - lb) ** 2)
return d, lo, hi
# Ground truth is the frozen run log: one row per confirmatory trial.
log = np.load("runlog/confirmatory_trials.npz")
for name in ("sync", "ensemble", "rtc_async", "adaptive"):
m = log["condition"] == name
k, n = int(log["success"][m].sum()), int(m.sum())
lo, hi = wilson_ci(k, n)
print(name, k, "/", n, "->", round(k / n, 3),
"CI", round(lo, 3), "-", round(hi, 3))
d, lo, hi = newcombe_diff_ci(78, 100, 62, 100)
print("adaptive - sync:", round(d, 3), "CI", round(lo, 3), "-", round(hi, 3))A pilot condition finishes at 20/20 successes. The Wald formula reports the interval [1.00, 1.00]. What should the figure show, and why?
The latency figure must be a CDF per scheduler, never a bar of means. Your Phase 05 traces showed why: the baseline and the adaptive scheduler can sit within 5 ms at the median (163 versus 158 ms camera-to-command) while their p99s differ by 150 ms — and in a control loop the tail is a guaranteed periodic event, not a rarity. The CDF also gives the reader a number for free: with the scheduling deadline drawn as a vertical line, deadline-miss probability reads directly off the curve.
The last two figures make the physical story visible. Joint-trajectory overlays at chunk seams — commanded and measured positions for the 200 ms around each switch, several seams per condition — show whether the scheduler's switches are smooth or trade success for jerk a longer task would punish. Recovery-time distributions need one honest detail: some perturbed trials never recover before the 30 s timeout. Plot them as censored mass at the timeout — dropping them silently inflates every condition, and inflates the worst condition most, exactly where a skeptical reviewer probes first.
The repository: reproducibility is release engineering
The capstone touched three software environments, and a reproducer needs all three pinned separately: collection (arm and cameras), training (policy fine-tuning), and inference (the scheduler's runtime). They drift independently and break reproduction differently — which is why one requirements.txt at the repo root is a smell you would never accept in a serving deployment.
| Environment | Where it runs | What to pin | Classic drift that breaks reproduction |
|---|---|---|---|
| Collection | Workstation + WidowX AI + RealSense cameras (wrist and scene) | Locked Python env, libtrossen_arm driver version, camera firmware versions recorded in the manifest | A camera firmware update changes auto-exposure behavior; new data silently mismatches the training distribution |
| Training | RTX workstation or cluster | Container image digest, OpenPI commit hash, CUDA and framework versions, all training seeds | A framework minor-version bump changes numerics; the released checkpoint no longer retrains to itself |
| Inference | Real-time runtime process on the workstation | Same image discipline plus the runtime config: chunk horizon, execute horizon, scheduler thresholds | A quiet driver or runtime update shifts the latency distribution that the entire claim is about |
The ground truth of the release is the frozen run log: one row per confirmatory trial with condition, block labels (object, day), outcome, timestamps, and per-stage latency spans. Freeze it the moment the confirmatory block ends, write its hash into a manifest, and make every figure and every reported number a pure function of that file. That property lets a stranger — or you, eight months out — distinguish "the analysis is wrong" from "the data changed," and it is cheap to enforce mechanically:
import hashlib
import json
import subprocess
import sys
from pathlib import Path
MANIFEST = json.loads(Path("release/manifest.json").read_text())
def sha256(path: str) -> str:
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
failures = []
# 1. Environment pins exist for all three stacks (plus analysis).
for env in ("collection", "training", "inference", "analysis"):
pin = Path("envs") / (env + ".lock")
if not pin.exists():
failures.append("missing environment pin: " + str(pin))
# 2. The frozen run log has not changed since analysis froze.
if sha256("runlog/confirmatory_trials.npz") != MANIFEST["runlog_sha256"]:
failures.append("run log changed after the analysis freeze")
# 3. Every figure regenerates from the run log, byte-for-byte.
# Hash the figure DATA (csv/npz), not the rendered PNG:
# plot-library versions change bytes, your numbers must not.
for fig in MANIFEST["figures"]:
subprocess.run([sys.executable, fig["script"]], check=True)
if sha256(fig["data_out"]) != fig["data_sha256"]:
failures.append(fig["name"] + ": regenerated data drifted")
if failures:
print("RELEASE BLOCKED")
for f in failures:
print(" -", f)
sys.exit(1)
print("release gate passed:", len(MANIFEST["figures"]), "figures verified")- Environment pins for collection, training, and inference, plus a fourth lock for the analysis environment that builds the figures.
- Every seed: training seeds, the condition-randomization seed from the experimental design, and the seed that selects representative videos.
- The frozen, hash-locked run log — the single source every reported number derives from.
- Analysis scripts or notebooks that regenerate all four figures and every in-text number from the run log alone.
- Protocol documents: reset procedure, success criteria, exclusion rules, and the pre-registration, unchanged from before the confirmatory block.
- A calibration snapshot: camera intrinsics and extrinsics, arm zero offsets, and the workspace layout with measured dimensions.
- Representative episode videos — successes and failures per condition, both camera views, selected by seed rather than by pride.
- The release gate script wired into CI so the artifact re-verifies on every push.
- A README ordered by consumer: the 5-minute skim, the 30-minute figure reproduction, the full retrain.
The ten-minute talk and the two-question deep-dive
Ten minutes is roughly seven content slides at 80 seconds each, with the report's discipline: one claim per slide, evidence outweighing everything else. Design for a robotics lab's reading group or an interview panel — people who have seen a hundred polished demos and are waiting to learn whether you understand your own error bars.
- Problem, one slide: chunk staleness in physical units — at 0.25 m/s a 200 ms-old chunk steers toward a gripper position 50 mm out of date — and the hypothesis verbatim.
- Method, one slide: the scheduler's decision rule with its two inputs, predicted inference time and inter-chunk disagreement; the block diagram, not the code.
- Evidence, three slides: the success figure with intervals and the difference CI; the latency CDFs with the deadline line; seam overlays or recovery distributions, whichever carries your secondary story.
- Limitations, one honest slide: one arm, one task family, one lab, a 12-object set, quasi-static scenes — stated by you before anyone asks.
- Next questions, one slide: the experiments this artifact makes possible, ending on what you would run next.
Then rehearse what actually decides the outcome: the deep-dive. A robotics interviewer reliably runs two probes. The statistics question attacks the inference: "your intervals overlap — why claim a difference?", "why 100 trials per condition?", "how do you know day-to-day drift didn't produce this?" Be ready to derive the Wilson interval at a whiteboard in four lines, to point at the difference interval, and to note that condition order was randomized within day-blocks precisely so drift cancels. The systems question attacks the mechanism: "where does the p99 320 ms go between exposure and motion?", "what happens at a seam when the new chunk arrives late?" Your Phase 05 trace is the answer; rehearse drawing the stage budget with numbers on each span. Keep backup slides for both — trace waterfall, ablation table, power analysis. Saying "I have a backup slide on exactly that" twice in a Q&A beats any animation on the main deck.
Closing the course: what you may claim, and your second project
The final discipline is drawing the claim's boundary exactly where the evidence stops. Supported: on this task family, platform, and object set, under inference latency in the tested 100–300 ms regime, the adaptive scheduler improved success by 16 points with a 95% interval of roughly , cut deadline misses from 11% to 3%, and did not degrade seam smoothness. Not supported: that the scheduler improves VLA manipulation in general, that the effect transfers to other arms or dynamic scenes, or that your favored mechanism — staleness reduction at the tail — is the only explanation. The mechanism story is a hypothesis your evidence is merely consistent with; say so in exactly those words, and watch how differently a room of researchers treats you.
Your artifact shows the adaptive scheduler at 78/100 versus the synchronous baseline at 62/100, difference interval [+3, +28] points, on one task family, one WidowX AI, one lab, a 12-object set. Which claim does this evidence support?
And the boundary is generative: everything just outside it is a candidate second project. Three concrete questions this artifact opens. First, dose–response: your Phase 05 latency-injection harness can sweep inference delay from 50 to 500 ms — does the scheduler's advantage grow with latency, and where does it saturate? Second, the hand-tuned threshold: can the switching rule be learned from the run logs you already have, and does it beat the hand-tuned rule out of distribution? Third, the regime change: quantize or distill the policy until inference drops under 30 ms — does the scheduler still matter, or did you just engineer away the problem it solves? Pick one, write it as a falsifiable hypothesis in the format of "From system to science," and size its trial budget with "Designing robot experiments that survive review." Scoping your second project with your first project's instruments is simply what a research engineer does.
The stranger test
Run the finished artifact through one adversarial pass before release. (1) On a machine that has never seen your code — a clean container or fresh user account — clone the repository and follow the README verbatim, no memory allowed, until Figure 1 regenerates from the raw run log. Record every step the README missed and the wall-clock time. (2) Record yourself giving the 10-minute talk, then answer two planted questions cold: "Your success intervals overlap — why claim a difference?" and "Where does the p99 latency go between camera exposure and joint motion?" Note every place you hesitated.
Need a hint?
Use a base Docker image or a brand-new user account so dotfiles and cached environments cannot rescue you — most reproduction failures hide in an environment variable you forgot you set in week 7. For the statistics question, the honest answer routes through the difference-of-proportions interval, not the per-arm intervals. For the systems question, rehearse the Phase 05 stage budget until you can draw sensing, compute, dispatch, and actuation from memory with p50 and p99 on each span.
Where this goes next: the previous lesson, "The capstone method: a latency-aware adaptive scheduler," gave you a method and a measured effect; this lesson turned them into a report a reviewer can check, a repository a stranger can rerun, and a talk that survives its own Q&A. There is no next lesson — this is the end of the course, deliberately. Twenty-four weeks ago the gap between you and robotics research was a stack of missing skills; now it is one unwritten pre-registration for the dose–response experiment your own artifact just proposed. State the hypothesis, size the trials, and go run it.