LeetLLM
My PlanLearnGlossaryTracksPracticeBlog
LeetLLM

Your go-to resource for mastering AI & LLM systems.

Product

  • Learn
  • Glossary
  • Tracks
  • Practice
  • Blog
  • RSS

Legal

  • Terms of Service
  • Privacy Policy

© 2026 LeetLLM. All rights reserved.

All Topics
Your Progress
0%

0 of 196 articles completed

🛠️Computing Foundations0/9
Git, Shell, Linux for AIDocker for Reproducible AIPython for AI EngineeringNumPy and Tensor ShapesCUDA for ML TrainingMPS & Metal for ML on MacData Structures for AISQL and Data ModelingAlgorithms for ML Engineers
📊Math & Statistics0/9
Gradients and BackpropVectors, Matrices & TensorsLinear Algebra for MLAdam, Momentum, SchedulersProbability for Machine LearningBayesian Inference from EvidenceStatistics and UncertaintyDistributions and SamplingHypothesis Tests, Intervals, and pass@k
📚Preparation & Prerequisites0/13
Neural Networks from ScratchCNNs from ScratchTraining & BackpropagationSoftmax, Cross-Entropy & OptimizationRNNs, LSTMs, GRUs, and Sequence ModelingAutoencoders and VAEsThe Transformer Architecture End-to-EndLanguage Modeling & Next TokensFrom GPT to Modern LLMsPrompt Engineering FundamentalsCalling LLM APIs in ProductionFirst AI App End-to-EndThe LLM Lifecycle
🧮ML Algorithms & Evaluation0/15
Linear Regression from ScratchLogistic Regression and MetricsDecision Trees, Forests, and BoostingReinforcement Learning BasicsValidation and LeakageStatistical Learning and GeneralizationConformal Prediction and UncertaintyClustering and PCAProbabilistic Generative ModelsCore Retrieval AlgorithmsDecoding AlgorithmsExperiment Design and A/B TestingCausal Inference and CounterfactualsPyTorch Training LoopsDataset Pipelines and Data Quality
📦Production ML Systems0/6
Feature Engineering for Production MLBatch and Streaming Feature PipelinesGradient Boosted Trees in ProductionRanking and Recommendation SystemsForecasting and Anomaly DetectionMonitoring Predictive Models
🧪Core LLM Foundations0/8
The Bitter Lesson & ComputeBPE, WordPiece, and SentencePieceStatic to Contextual EmbeddingsPerplexity & Model EvaluationFile Ingestion for AIChunking StrategiesLLM Benchmarks & LimitationsInstruction Tuning & Chat Templates
🧰Applied LLM Engineering0/25
Dimensionality Reduction for EmbeddingsCoT, ToT & Self-Consistency PromptingFunction Calling & Tool UseMCP & Tool Protocol StandardsContext EngineeringPrompt Injection DefenseResponsible AI GovernancePrivacy-Preserving Machine LearningData Labeling and Human FeedbackEvaluating AI AgentsProduction RAG PipelinesHybrid Search: Dense + SparseReranking and Cross-Encoders for RAGRAG Evaluation for Reliable AnswersLLM-as-a-Judge EvaluationBias & Fairness in LLMsHallucination Detection & MitigationLLM Observability & MonitoringExperiment Tracking with MLflow and W&BPrompt Optimization with DSPyModel Versioning & DeploymentSemantic Caching & Cost OptimizationLLM Cost Engineering & Token EconomicsModel Gateways, Routing, and FallbacksDesign an Automated Support Agent
🎓Portfolio Capstones0/9
Capstone: Delivery ETA PredictionCapstone: Product RankingCapstone: Demand ForecastingCapstone: Image Damage ClassifierCapstone: Production ML PipelineCapstone: Document QACapstone: Eval DashboardCapstone: Fine-Tuned ClassifierCapstone: Reproducible ML Study
🧠Transformer Deep Dives0/8
Sentence Embeddings & Contrastive LossEmbedding Similarity & QuantizationScaled Dot-Product AttentionVision Transformers and Image EncodersPositional Encoding: RoPE & ALiBiLayer Normalization: Pre-LN vs Post-LNMechanistic InterpretabilityDecoding Strategies: Greedy to Nucleus
🧬Advanced Training & Adaptation0/17
Scaling Laws & Compute-Optimal TrainingPre-training Data at ScaleBuild GPT from Scratch LabJAX for PyTorch ResearchersContinued Pretraining for Domain ShiftSynthetic Data PipelinesSupervised Fine-Tuning PipelineMixed Precision TrainingDistributed Training: FSDP & ZeROLoRA & Parameter-Efficient TuningTraining Run OperationsReward Modeling from Preference DataRLHF & DPO AlignmentConstitutional AI & Red TeamingRLVR & Verifiable RewardsKnowledge Distillation for LLMsModel Merging and Weight Interpolation
🤖Advanced Agents & Retrieval0/16
Vector DB Internals: HNSW & IVFAdvanced RAG: HyDE & Self-RAGGraphRAG & Knowledge GraphsRAG Security & Access ControlStructured Output GenerationReAct & Plan-and-ExecuteGuardrails & Safety FiltersCode Generation & SandboxingComputer-Use / GUI / Browser AgentsHuman-in-the-Loop Agent ArchitectureAI Coding Workflow with AgentsAgent Memory & PersistenceAgent Failure & RecoveryRecursive Language Models (RLM)Multi-Agent OrchestrationCapstone: Production Agent
⚡Inference & Production Scale0/31
Inference: TTFT, TPS & KV CacheMulti-Query & Grouped-Query AttentionKV Cache & PagedAttentionPrefix Caching and Prompt CachingFlashAttention & Memory EfficiencyContinuous Batching & SchedulingScaling LLM InferenceModel Parallelism for LLM InferenceAccelerator Architecture Field GuideCorrect GPU Profiling and BenchmarkingGPU Kernel Performance Engineering LabGPU Parallel Primitives LabGPU Compilers and Kernel LanguagesGEMM From Naive CUDA to Tensor CoresLow-Precision GPU ProgrammingGPU Runtime Execution LabAI-Generated Kernel EngineeringModel Quantization: GPTQ, AWQ & GGUFLocal LLM DeploymentSLM Specialization & Edge DeploymentSpeculative DecodingLong Context Window ManagementMixture of Experts ArchitectureMamba & State Space ModelsReasoning & Test-Time ComputeAdvanced MLOps & DevOps for AIGPU Serving & AutoscalingGPU Failure OperationsDistributed Inference Data PlaneServing Benchmark EngineeringA/B Testing for LLMs
🏗️System Design Capstones0/9
Content Moderation SystemCode Completion SystemMulti-Tenant LLM PlatformLLM-Powered Search EngineVision-Language Models & CLIPMultimodal LLM ArchitectureDiffusion Models: Images & TextReal-Time Voice AI AgentReasoning Agent System Design
🎤AI Lab Interviewing0/4
AI Lab Coding Interview: Python SystemsAI Lab System Design InterviewAI Lab Behavioral InterviewAI Lab Technical Presentation
🔬Project Deep Dives0/17
Deep Dive - vLLMDeep Dive - SkyRLDeep Dive - FlashAttentionDeep Dive - FlashInferDeep Dive - DeepGEMMDeep Dive - NCCLDeep Dive - MegatronDeep Dive - DeepSpeedDeep Dive - RayDeep Dive - MLflowDeep Dive - PyTorchDeep Dive - TransformersDeep Dive - SGLangDeep Dive - slimeDeep Dive - DeepEPDeep Dive - TinkerDeep Dive - Light-PEFT
Back to Topics
LearnPortfolio CapstonesCapstone: Reproducible ML Study
📊HardEvaluation & Benchmarks

Capstone: Reproducible ML Study

Turn one research paper into a falsifiable, public-safe ML study with paired experiments, uncertainty, reproducible artifacts, and a defensible report.

48 min read
Learning path
Step 94 of 196 in the full curriculum
Capstone: Fine-Tuned ClassifierSentence Embeddings & Contrastive Loss

Personalize this lesson

Adapt explanations and teaching visuals to your background and preferred voice.

Over half of published reinforcement learning and deep learning papers fail to replicate when independent teams rerun their code. As Henderson and colleagues demonstrated across standard benchmarks,[1]Reference 1Deep Reinforcement Learning That Mattershttps://ojs.aaai.org/index.php/AAAI/article/view/11694 researchers routinely sweep dozens of random seeds, pluck out the single best training curve that happened to roll lucky exploratory transitions, and present that smooth outlier as an algorithmic breakthrough. Couple that random seed lottery with floating package versions (numpy>=1.24, torch), non-deterministic GPU kernel dispatches,[2]Reference 2Reproducibilityhttps://docs.pytorch.org/docs/stable/notes/randomness.html and evaluation metrics that accidentally score agents on auxiliary training rewards rather than true task return, and the claimed performance gain quickly collapses into statistical noise.

When you evaluate a research paper or propose a candidate algorithm for production, you can't rely on cherry-picked runs or optimistic blog posts. You need an ironclad experimental protocol: a pre-locked mathematical contract, paired random seed trials that isolate algorithmic treatment effects from initialization noise, non-parametric uncertainty estimates that don't falsely assume Gaussian returns, and cryptographic manifests that guarantee deterministic rerun invariance.

This study builds that complete, auditable research workflow around a classic question from reinforcement learning theory: does potential-based reward shaping accelerate early goal-reaching in a stochastic corridor without degrading the agent's final greedy policy under the true environment reward?

A shared training tape feeds sparse and shaped arms. Their first-30 episode success forms the primary paired difference. Their final Q-tables go to a separate evaluation tape, with original reward and no learning updates, producing the final-success guardrail.
Within each seed, both arms use the same pre-generated training tape and a separate shared evaluation tape. Early training success supplies the primary difference; final greedy success supplies a guardrail. Pairing controls random inputs, but different learned actions still produce different trajectories.

The scope stays deliberately narrow and fully public-safe. The environment reward never changes, and final evaluation never touches the shaping bonus. Everything runs locally with synthetic transitions and NumPy, so no private logs, live users, paid APIs, or specialized hardware enter the study.

This chapter contains a worked run whose results are already known, not evidence that its plan was independently preregistered. Repeating seeds 0 through 23 checks repeatability. For your own confirmatory study, finish pilot debugging, freeze the design, and reserve a new untouched seed set before inspecting results.

Read the claim before building the simulator

The first implementation decision is whether the source contains one claim small enough to test honestly. Start with Ng, Harada, and Russell's paper on policy invariance under reward transformations.[3]Reference 3Policy Invariance Under Reward Transformations: Theory and Application to Reward Shapinghttps://wordpress.andrewng.org/index.php/publication/policy-invariance-under-reward-transformations-theory-and-application-to-reward-shaping/ Its main claim is precise enough for a small simulator: a potential-based shaping reward can guide learning while preserving optimal policies under the theorem's assumptions.

Don't begin by reproducing every table or proof. Keshav's three-pass reading method gives a practical order: classify the paper, inspect its evidence, then reconstruct the part you plan to test.[4]Reference 4How to Read a Paperhttps://dl.acm.org/doi/10.1145/1273445.1273458 That order keeps an attractive equation from turning into an unbounded reproduction project.

Use this triage card while reading. Fill it with page or section pointers so a reviewer can trace your interpretation back to source text.

Triage fieldCorridor-study note
problemsparse rewards provide little learning signal before goal completion
paper claimpotential-based shaping preserves optimal policies under stated assumptions
equation to implementF(s,a,s′)=γΦ(s′)−Φ(s)F(s,a,s') = \gamma \Phi(s') - \Phi(s)F(s,a,s′)=γΦ(s′)−Φ(s)
smallest testseven-state corridor with tabular Q-learning
theorem assumptions to checksame discounted Markov decision process, bounded potential, correct terminal handling
measurement controlfinal evaluation uses original environment reward
evidence you can reproducelearning speed across fixed simulator seeds
claim you can't makethe method improves deep RL or deployed agents

First pass: classify the claim

Keshav's first pass is a short classification scan, not an evidence audit. Read the title, abstract, and introduction; skim section headings; read the conclusion; glance at the references. Don't study the figures yet.

Write one sentence for the problem, method, comparison, and claimed result. If those sentences stay vague, the study isn't ready to design.

For this paper, the method isn't "add helpful rewards." It derives a transition reward from a potential function. That distinction separates the policy-invariance theorem from arbitrary bonuses that can change which policy is optimal.

Stop the first pass with a scope decision: reproduce, extend, or decline. This capstone performs a small empirical check of one implication and adds an uncertainty-focused artifact. It doesn't attempt a full paper reproduction.

Second pass: inspect evidence and assumptions

Now inspect the figures, axes, and error bars, then read the equation, experimental setup, and failure caveats. First write down what stays constant, what changes, and what the paper measures.

Missing implementation detail belongs in an assumptions log, not in a silent guess.

Pay close attention to evaluation reward. A candidate trained with shaped reward can look better if its score includes the extra training bonus. Compare both learned policies using the original environment reward or you have changed the measurement.

Record every adaptation. The corridor, Q-learning hyperparameters, action-slip probability, seed budget, and bootstrap rule are capstone choices rather than claims copied from the paper.

Third pass: reconstruct the test

Explain the shaping equation without looking. Then rebuild the smallest environment where moving toward a goal changes potential. Predict what should happen to early learning and final policy before running code.

Then challenge the design. Could the candidate receive more steps, a friendlier random stream, or an easier evaluation? Could a single lucky seed drive the mean? Every plausible shortcut becomes a control, ablation, or stated limitation.

Finish paper_triage.md with three labels: supported by source, study adaptation, and unresolved. That file prevents a plausible implementation detail from turning into a misattributed paper claim.

Turn curiosity into a falsifiable contract

The triage card names a paper claim and a smallest test. It still doesn't say which observation would count against the idea. "Does reward shaping help agents learn?" is too broad because it leaves the agent, environment, shaping rule, metric, sample, and outcome undefined.

A falsifiable hypothesis names an observation that can contradict it. Narrow scope makes the capstone stronger: every noun can become a file, parameter, table column, or assertion.

Use this research question:

In a stochastic seven-state corridor, does potential-based shaping increase tabular Q-learning's first-30-episode goal-reaching rate versus sparse reward, while keeping final greedy-policy success unchanged under original reward?

Lock the contract before inspecting confirmatory results:

Contract fieldLocked value
unit of analysisone paired simulator seed
baselinetabular Q-learning with sparse terminal reward
candidatesame Q-learning plus potential-based shaping during training
primary metricfirst-30-episode success-rate difference, shaped minus sparse
uncertainty90% paired bootstrap interval over seed differences
minimum useful effectmean paired difference at least +0.10
final-policy guardrailobserved mean and 90% paired interval stay within [-0.02, +0.02]
worked sampleseeds 0 through 23; reserve new seeds for a new confirmatory study
stopping rulerun all 24 seed pairs

State the expected result

Prediction comes before output. A distance-based potential supplies feedback before the first goal, so improved early goal-reaching is a plausible hypothesis. Policy-invariance theory concerns optimal policies, not the policies produced by 80 finite training episodes. Similar final greedy success is an empirical expectation to check, not a consequence guaranteed by the theorem.[3]Reference 3Policy Invariance Under Reward Transformations: Theory and Application to Reward Shapinghttps://wordpress.andrewng.org/index.php/publication/policy-invariance-under-reward-transformations-theory-and-application-to-reward-shaping/

That expectation isn't permission to hide a miss. It gives reviewers a record of what you believed before seeing confirmatory values. Exploratory explanations can follow, but they need an explicit label.

Write this expected pattern in study_plan.md before running seeds 0 through 23:

  • positive early paired difference
  • interval above zero
  • near-zero final difference
  • timestamp or immutable commit for locked plan

A commit makes later edits visible, but it isn't equivalent to independent preregistration. For formal work, register hypotheses, variables, tests, decision criteria, and exclusions in a timestamped read-only system before collecting confirmatory results.[5]Reference 5Welcome to Registrationshttps://help.osf.io/article/330-welcome-to-registrations

Write the rejection rule

Support the capstone's narrow claim only if the mean early difference is at least +0.10 and the 90% interval's lower bound is above zero. Also require the final-policy guardrail.

Withhold support for the study claim when either requirement fails. A mean of +0.09 is below the declared point-estimate threshold even if its interval is positive. A mean of +0.20 also fails if final original-reward performance shifts beyond the guardrail. This rule doesn't establish an effect of at least +0.10 with 90% confidence: that stronger claim would require the interval's lower bound to clear +0.10.

"Inconclusive" can be accurate when interval width leaves multiple practical interpretations. Keep that label distinct from "no effect" and from "the candidate is worse."

Keep the study public-safe

Small research work still needs a data and authority boundary. Synthetic data removes many privacy risks, but a public repository can still leak credentials, copied code, or outputs from proprietary environments. Decide that boundary before collecting artifacts.

The corridor generator owns every transition. It doesn't imitate a customer, scrape a service, call an external model, or exercise a live agent. A run is shareable because its complete input is a tiny configuration plus a pseudorandom seed.

Add this boundary to the README before code:

SurfaceIncludedExcluded
datagenerated corridor transitionsuser messages, production logs, private datasets
computelocal CPU and NumPyremote model APIs, paid accelerators
actionsleft/right in simulatorbrowser, shell, account, or network actions
outputsmetrics, tables, plots, manifestssecrets, identifiers, raw third-party content
claimthis simulator and implementationhuman behavior, robotics, deployed-agent safety

Run a secret scanner before publishing. Review generated files for machine paths and usernames. Use an open license only for code and assets you have authority to release.

Build the smallest controlled environment

The corridor has states 0 through 6. Every episode starts at 0; reaching 6 yields environment reward 1; every other transition yields 0. An intended action reverses with probability 0.15, and an episode ends after 12 steps.

Write the environment contract before writing the agent. Otherwise a reward, reset, or ending-condition change can enter one arm unnoticed and look like a learning effect.

Environment fieldLocked contract
observationinteger state in {0, 1, ..., 6}
actions0 = left, 1 = right
resetreturn state 0; select pre-generated tape by seed
transitionmove one cell, clamp at endpoints, reverse intended move on a 0.15 slip
reward1 on first arrival at state 6; otherwise 0
terminatedagent reaches state 6
truncated12 steps elapse without reaching goal
random inputsexploration, action, tie-break, and slip draws indexed by seed, episode, and step
logged outputstate, intended action, realized move, environment reward, termination reason

terminated means the task reached the goal. truncated means an external rollout budget ended collection. The learner estimates discounted return in an underlying task without that 12-step deadline; it still bootstraps at a timeout, but not at the true terminal goal. Our reported success metric is instead goal-reaching within 12 steps. These are related objectives, not identical ones.

If the deadline were part of the task itself, remaining time would belong in the state and deadline expiry would be terminal. Don't silently switch between these formulations.[6]Reference 6Handling Time Limitshttps://gymnasium.farama.org/tutorials/gymnasium_basics/handling_time_limits/ The compact script records episode success and step counts; a full capstone should also retain diagnostic transition traces.

Treating a timeout as terminal success, or bootstrapping through a true terminal, changes the learning target.

Tabular Q-learning stores one value for each state-action pair. During training it moves the chosen action toward observed reward plus the best estimated next-state value. That's the off-policy update from that earlier lesson.[7]Reference 7Reinforcement Learning: An Introductionhttp://incompleteideas.net/book/the-book-2nd.html

The first diagram follows one environment transition, including the 15% action reversal. Both arms then read the same environment reward; only the candidate receives a training-only potential difference before its update. Final evaluation reads the original reward branch for both arms. Keep that split visible while reading the equations.

Diagram showing Start: state 0, Choose left or right, 15% action reversal?, and Next corridor state.
Start: state 0, Choose left or right, 15% action reversal?, and Next corridor state.
Diagram showing Environment reward: goal only, Sparse baseline update, Add potential difference, and Shaped candidate update.
Environment reward: goal only, Sparse baseline update, Add potential difference, and Shaped candidate update.

Define distance potential as:

Φ(s)=−6−s6.\Phi(s) = -\frac{6-s}{6}.Φ(s)=−66−s​.

States nearer the goal have a larger potential. Candidate training adds:

F(s,a,s′)=γΦ(s′)−Φ(s).F(s,a,s') = \gamma \Phi(s') - \Phi(s).F(s,a,s′)=γΦ(s′)−Φ(s).

With discount 0.95, a step toward the goal usually produces a positive shaping signal. A step away usually produces a negative one. Check that on the first two cells before running the 24-seed study. Φ(0)=−1\Phi(0)=-1Φ(0)=−1 and Φ(1)=−5/6\Phi(1)=-5/6Φ(1)=−5/6, so a right move from the start yields F=0.95⋅(−5/6)−(−1)=+0.208F=0.95\cdot(-5/6)-(-1)=+0.208F=0.95⋅(−5/6)−(−1)=+0.208, while the reverse move yields −0.117-0.117−0.117.

The environment reward hasn't changed; only candidate training receives FFF. That is the boundary the final evaluation must preserve.

The reason this particular bonus preserves the discounted objective is telescoping. For a trajectory of length TTT:

∑t=0T−1γtF(st,st+1)=−Φ(s0)+γTΦ(sT).\sum_{t=0}^{T-1}\gamma^t F(s_t,s_{t+1})=-\Phi(s_0)+\gamma^T\Phi(s_T).t=0∑T−1​γtF(st​,st+1​)=−Φ(s0​)+γTΦ(sT​).

At the goal, Φ(6)=0\Phi(6)=0Φ(6)=0, so every completed trajectory from state 0 receives the same total discounted addition, +1+1+1. A bounded potential also makes the final term vanish in the infinite-horizon discounted limit. At an artificial timeout, the remaining term generally isn't zero. That's why terminal potential and timeout bootstrapping matter; merely writing the equation isn't enough.[3]Reference 3Policy Invariance Under Reward Transformations: Theory and Application to Reward Shapinghttps://wordpress.andrewng.org/index.php/publication/policy-invariance-under-reward-transformations-theory-and-application-to-reward-shaping/

The snippet below is the contract for that one transition. It uses the Python standard library so you can verify the arithmetic without NumPy.

shaping_one_step.py
1GAMMA = 0.95 2GOAL = 6 3 4def potential(state: int) -> float: 5 return -(GOAL - state) / GOAL 6 7def shaping(state: int, next_state: int) -> float: 8 return GAMMA * potential(next_state) - potential(state) 9 10toward = shaping(0, 1) 11away = shaping(1, 0) 12assert potential(0) == -1 13assert abs(potential(1) - (-5 / 6)) < 1e-12 14assert toward > 0 15assert away < 0 16print(f"Phi(0)={potential(0):.3f} Phi(1)={potential(1):.3f}") 17print(f"F(0->1)={toward:+.3f}") 18print(f"F(1->0)={away:+.3f}") 19 20# Two completed trajectories take different lengths but get the same addition. 21for path in ([0, 1, 2, 3, 4, 5, 6], [0, 1, 0, 1, 2, 3, 4, 5, 6]): 22 bonus = sum(GAMMA**t * shaping(s, n) for t, (s, n) in enumerate(zip(path, path[1:]))) 23 assert abs(bonus - 1.0) < 1e-12 24print("Completed-path discounted bonus: +1.000 for both paths")
Output
1Phi(0)=-1.000 Phi(1)=-0.833 2F(0->1)=+0.208 3F(1->0)=-0.117 4Completed-path discounted bonus: +1.000 for both paths

The comparison table records what stayed paired and what was allowed to differ:

ComponentSparse baselineShaped candidate
states and actionsidenticalidentical
slip tapepairedpaired
Q-learning updateidenticalidentical
environment rewardgoal onlygoal only
training-only additionnoneγΦ(s′)−Φ(s)\gamma\Phi(s')-\Phi(s)γΦ(s′)−Φ(s)
final evaluation rewardgoal onlygoal only

Now the two arms differ in one intended place: the candidate's training update. Controls and paired randomness can test whether that boundary held in code.

Make randomness and controls explicit

Reinforcement learning measurements can vary wildly with random seeds, environment randomness, codebase differences, and hyperparameters. Henderson and colleagues showed that two runs of the same algorithm differing only by random seed can look like two completely different algorithms.[1]Reference 1Deep Reinforcement Learning That Mattershttps://ojs.aaai.org/index.php/AAAI/article/view/11694 Treat the random stream as part of the formal experimental design, not as an invisible background detail.

The paired seed trial protocol

In a standard, unpaired trial, baseline runs on one set of random seeds while candidate runs on another independent set. If XiX_iXi​ is baseline performance and YjY_jYj​ is candidate performance, the variance of the difference between sample means is:

Var⁡(Yˉ−Xˉ)=Var⁡(Y)+Var⁡(X)n.\operatorname{Var}(\bar{Y} - \bar{X}) = \frac{\operatorname{Var}(Y) + \operatorname{Var}(X)}{n}.Var(Yˉ−Xˉ)=nVar(Y)+Var(X)​.

In a stochastic environment, random seed noise (unlucky action slips or cold exploration streaks) inflates both Var⁡(X)\operatorname{Var}(X)Var(X) and Var⁡(Y)\operatorname{Var}(Y)Var(Y). You're left with a wide, noisy confidence interval that requires hundreds of runs to resolve.

In a paired seed trial, every seed iii feeds the exact same sequence of pseudo-random draws to both arms. Because both arms experience the exact same environment transitions for that seed, we compute the paired difference for each seed:

Δi=Yi−Xi.\Delta_i = Y_i - X_i.Δi​=Yi​−Xi​.

The variance of the sample mean paired difference Δˉ\bar{\Delta}Δˉ is:

Var⁡(Δˉ)=Var⁡(Y)+Var⁡(X)−2Cov⁡(X,Y)n.\operatorname{Var}(\bar{\Delta}) = \frac{\operatorname{Var}(Y) + \operatorname{Var}(X) - 2\operatorname{Cov}(X, Y)}{n}.Var(Δˉ)=nVar(Y)+Var(X)−2Cov(X,Y)​.

When seed iii rolls an unlucky sequence of four slips in a row, both the sparse baseline and the shaped candidate suffer that exact same environmental penalty. That shared difficulty induces a positive covariance between the two arms (Cov⁡(X,Y)>0\operatorname{Cov}(X, Y) > 0Cov(X,Y)>0). The −2Cov⁡(X,Y)-2\operatorname{Cov}(X, Y)−2Cov(X,Y) term actively subtracts out common environmental noise, shrinking estimator variance and tightening the resulting confidence interval without demanding an expensive seed budget.

Synchronizing randomness with a 2D tape

Pairing sounds simple in theory, but naive implementations break it immediately. In reinforcement learning, episode length is dynamic. If the shaped candidate reaches the goal in 4 steps while the sparse baseline wanders for 12 steps, a single sequential random number generator will fall out of sync after episode 0. The shaped arm would draw from PRNG offset 4 on episode 1, while the baseline would draw from PRNG offset 12! From episode 1 onwards, the arms receive completely uncorrelated random numbers.

To keep the arms strictly synchronized, pre-generate a 2D random tape shaped (TRAIN_EPISODES, MAX_STEPS) for each random decision:

  1. explore: continuous uniform float in [0,1)[0, 1)[0,1) for ϵ\epsilonϵ-greedy exploration checks.
  2. action: discrete uniform integer in {0,1}\{0, 1\}{0,1} for random action draws.
  3. tie: discrete uniform integer in {0,1}\{0, 1\}{0,1} for deterministic Q-value tie-breaking.
  4. slip: continuous uniform float in [0,1)[0, 1)[0,1) for the 15% environment action reversal.

Indexing by (episode, step) guarantees that step ttt of episode eee always receives the exact same slip probability and exploration draw across both arms, regardless of how many steps earlier episodes took.

Separate pilot and confirmatory seeds

Use seeds 900, 901, and 902 to debug code, plots, and manifests. Never include them in confirmatory metrics. You have already observed their behavior, so adding them later would make the primary sample outcome-dependent.

Use integers 0 through 23 for the locked study. Twenty-four paired seeds fit a laptop capstone and expose heterogeneity, but they aren't a universal sample-size recommendation.

Evaluation uses streams seeded with 10000 + training_seed, never the training tape. No evaluation reward updates Q-values. Don't choose a potential, threshold, or hyperparameter by these final evaluations and then reuse them as an untouched test. A seed split prevents direct reuse; it doesn't establish transfer to a new environment family.

Run every pair. The experiment-design lesson treated optional stopping as a way to manufacture a win. The same trap exists here: stopping after ten favorable seeds would make sample size depend on the observed outcome.

If a run fails mechanically, record the failure and rerun policy before looking at aggregate results.

Add controls before interpretation

Zero-potential control sets Φ(s)=0\Phi(s)=0Φ(s)=0. Under the same tape, it must match sparse training exactly. If it doesn't, candidate code changed more than reward. Stop before interpreting any treatment result.

Original-reward evaluation is another control. Both arms receive identical greedy evaluation slips, and neither receives shaping reward. A result reported only on shaped return fails the measurement contract because the candidate is scored with a bonus the baseline never receives.

Use a sign-reversed potential only as an exploratory stress test after confirmatory analysis. It may reveal sensitivity to learning dynamics, but it can't retroactively redefine the primary hypothesis.

Plan the ablation matrix

An ablation removes or changes one component to identify which mechanism drives a result. Change one factor per row and preserve all other settings. That makes the comparison answerable when a result moves.

IDComparisonOne changed factorPurposeReport class
E0sparse vs zero potentialshaping term fixed at zerocatch implementation driftrequired control
E1sparse vs distance potentialtraining reward onlyconfirm primary claimconfirmatory
E2paired vs independently resampled armsanalysis covariancecompare paired and unpaired uncertaintyplanned sensitivity analysis
E3distance vs reversed potentialpotential signinspect learning sensitivityexploratory

Don't call an unplanned hyperparameter sweep an ablation after choosing its best row. Preserve all runs and label post-result searches exploratory.

Define metrics and uncertainty

Choose the estimator before seeing results. For seed iii, let pi,30shapep^{shape}_{i,30}pi,30shape​ and pi,30sparsep^{sparse}_{i,30}pi,30sparse​ be the fractions of the first 30 training episodes that reach the goal. The paired effect is:

di=pi,30shape−pi,30sparse.d_i = p^{shape}_{i,30} - p^{sparse}_{i,30}.di​=pi,30shape​−pi,30sparse​.

Primary estimate averages all 24 differences:

dˉ=124∑i=023di.\bar{d} = \frac{1}{24}\sum_{i=0}^{23}d_i.dˉ=241​i=0∑23​di​.

That number answers a bounded question about mean early success under the declared seed-generating procedure. It doesn't prove every seed improves. Report all did_idi​ values and count regressions.

Non-parametric bootstrap vs naive Student's t-tests

Why not run a standard Student's paired t-test on the 24 seed differences?

A Student's paired t-test assumes that the differences did_idi​ follow a normal distribution: di∼N(μ,σ2)d_i \sim \mathcal{N}(\mu, \sigma^2)di​∼N(μ,σ2). In reinforcement learning and discrete decision tasks, that assumption is violated in three ways:

  1. Bounded support: First-30-episode success rates are strictly bounded in [0,1][0, 1][0,1], taking discrete fractional values k/30k/30k/30. Paired differences di=pi,30shape−pi,30sparsed_i = p^{\text{shape}}_{i, 30} - p^{\text{sparse}}_{i, 30}di​=pi,30shape​−pi,30sparse​ are strictly bounded in [−1,+1][-1, +1][−1,+1].
  2. Skewness and bimodality: Stochastic exploration often produces bimodal outcomes: an agent either fails to find the corridor goal within 12 steps (yielding near-zero early success) or stumbles upon it and rapidly propagates values (yielding high success). Differences cluster near discrete modes rather than spreading along a smooth bell curve.
  3. Small sample size: With n=24n=24n=24, the Central Limit Theorem can't rescue a parametric test from severe skewness. A Student's t-test confidence interval can generate unphysical bounds outside [−1,+1][-1, +1][−1,+1] or overstate statistical significance.

The non-parametric bootstrap makes zero assumptions about the shape or symmetry of the underlying distribution.[8]Reference 8Deep Reinforcement Learning at the Edge of the Statistical Precipicehttps://proceedings.neurips.cc/paper/2021/hash/f514cec81cb148559cf475e7426eed5e-Abstract.html

We treat the 24 observed paired differences {d0,d1,…,d23}\{d_0, d_1, \dots, d_{23}\}{d0​,d1​,…,d23​} as an empirical distribution F^n\hat{F}_nF^n​. We draw B=10,000B = 10{,}000B=10,000 bootstrap resamples with replacement:

d∗(b)=(d1∗(b),d2∗(b),…,d24∗(b)),b=1,…,B.\mathbf{d}^{*(b)} = (d_1^{*(b)}, d_2^{*(b)}, \dots, d_{24}^{*(b)}), \quad b = 1, \dots, B.d∗(b)=(d1∗(b)​,d2∗(b)​,…,d24∗(b)​),b=1,…,B.

For each resample bbb, compute the replicate sample mean:

dˉ∗(b)=124∑j=124dj∗(b).\bar{d}^{*(b)} = \frac{1}{24}\sum_{j=1}^{24} d_j^{*(b)}.dˉ∗(b)=241​j=1∑24​dj∗(b)​.

Sorting all 10,00010{,}00010,000 replicate means gives the empirical distribution of the mean. For our pre-locked 90% confidence interval, extract the 5th percentile (b=500b=500b=500) and 95th percentile (b=9500b=9500b=9500). When distributions exhibit severe asymmetry, the Bias-Corrected and Accelerated (BCa) bootstrap further adjusts these quantile cutoff indices using an estimated median bias z0z_0z0​ and a jackknife acceleration parameter aaa.

Use fixed bootstrap seed 20260731. The resulting interval quantifies sampling variability of the estimator across the declared seed sample under the locked protocol. It isn't a probability that the theoretical theorem is true, and it doesn't guarantee performance on another environment. Keep that scope attached to the estimate wherever you display it.

Keep a final-policy guardrail

After 80 training episodes, evaluate each greedy policy for 200 episodes on original reward. Pair evaluation slip tapes by seed. Compute the shaped-minus-sparse final-success difference exactly as above.

Require the observed mean and its 90% paired bootstrap interval to lie within [-0.02, +0.02]. This is an illustrative equivalence-style guardrail, not proof of identical policies. A zero-width interval when every observed pair matches can't rule out rare failures or differences on unseen states. Neither this check nor equal means establish high absolute competence.

Also inspect per-seed final differences. An average near zero can hide equal and opposite failures if candidate helps one region and harms another.

Plan the experiment table before running

A compact experiment table stops notebook state from becoming methodology. Each row names the exact config, sample, output, and decision role. Read it as a promise about what will be run, not as a retrospective summary.

Store the table in study_plan.md and mirror machine-readable fields in configs/study.json. Freeze both in the same commit as the hypothesis.

Use one status vocabulary: planned, running, complete, mechanical_failure, or excluded_by_locked_rule. "Bad result" isn't an exclusion reason.

RunSeedsEpisodesEvaluationOutputDecision role
pilot smoke900-9021020console tracedebug only
zero-potential control0-2380200exact-equality receiptimplementation check
primary paired study0-2380200seed table + bootstrapconfirmatory claim
unpaired sensitivitysame completed rowsnonenoneinterval comparisonplanned sensitivity analysis
reversed-potential stress0-2380200separate seed tableexploratory appendix

Package an exact repository

A reviewer shouldn't have to guess where the hypothesis ends and the analysis begins. Keep source, config, immutable run outputs, report, and talk in distinct paths.

The tree is the repository you should produce for the capstone, not a claim that this page ships every file. The runnable miniature demonstrates the experiment core; the final submission also needs the plan history, packaging, traces, report, and independent review.

repository-tree.txt
1reproducible-reward-shaping/ 2├── README.md 3├── LICENSE 4├── CITATION.cff 5├── pyproject.toml 6├── uv.lock 7├── study_plan.md 8├── paper_triage.md 9├── configs/ 10│ └── study.json 11├── src/ 12│ └── corridor_study/ 13│ ├── __init__.py 14│ ├── environment.py 15│ ├── train.py 16│ ├── analyze.py 17│ └── manifest.py 18├── tests/ 19│ ├── test_environment.py 20│ ├── test_zero_potential.py 21│ └── test_manifest.py 22├── data/ 23│ └── generated/ 24│ └── README.md 25├── artifacts/ 26│ ├── manifest.json 27│ ├── runs/ 28│ │ ├── primary_seed_rows.csv 29│ │ └── bootstrap_means.npy 30│ └── checksums.sha256 31├── report/ 32│ ├── report.md 33│ ├── figures/ 34│ │ └── paired_seed_delta.svg 35│ └── tables/ 36│ └── primary_result.csv 37└── talk/ 38 ├── outline.md 39 └── q-and-a.md

Pin environment and entrypoint

Use pyproject.toml plus uv.lock to pin NumPy and development tools. README should name supported Python version and one clean command such as uv run corridor-study --config configs/study.json.

Run from a fresh clone or container. Record operating system, architecture, Python, NumPy, commit, config hash, and wall-clock duration in manifest. The machine identity may remain coarse; hostnames and usernames don't belong in public output.

The Machine Learning Reproducibility Checklist calls for clear model, hyperparameter, seed, environment, and result reporting.[9]Reference 9The Machine Learning Reproducibility Checklisthttps://www.cs.mcgill.ca/~jpineau/ReproducibilityChecklist.pdf A lockfile helps, but complete execution instructions and immutable inputs still matter.

Record data provenance

Synthetic data still needs provenance. Save generator version, seed range, transition rule, slip probability, state count, step cap, and environment source hash.

Don't commit one unexplained CSV and call it generated. data/generated/README.md should state exact command that reconstructs any derived rows and whether tracked output is canonical or disposable.

If you adapt capstone to public dataset later, record original URL, license, version, retrieval date, checksum, preprocessing command, and excluded rows. Never replace original identifier with local filename alone.

Create an artifact manifest

A research artifact shouldn't rely on "trust me, it ran on my machine." A cryptographic manifest binds the empirical claim to the exact code, configuration, runtime environment, and resulting output files.

A complete manifest rests on six cryptographic pillars:

  1. Commit digest: The exact Git commit hash (git rev-parse HEAD), pinning the complete version-controlled tree.
  2. Source tree treesum: A recursive SHA-256 digest of src/ files, proving no dirty uncommitted working-tree edits contaminated the execution.
  3. Strict dependency lock: uv.lock pinning the exact wheel hashes and Python version (python==3.12.*, numpy==2.2.6).
  4. Runtime and hardware platform: OS name (Darwin, Linux), CPU architecture (arm64, x86_64), Python interpreter, and NumPy version. This documents hardware-level differences (such as ARM64 NEON vs x86-64 AVX-512 FMA floating-point roundoff).
  5. Configuration digest: SHA-256 of configs/study.json, proving hyperparameters weren't tweaked after the run.
  6. Output artifact digests: SHA-256 hashes of primary_seed_rows.csv and study_results.json.

This illustrative schema outlines the locked fields before the run; a completed run fills in the exact hashes:

artifacts/manifest.json
1{ 2 "study_id": "corridor-reward-shaping-v1", 3 "git_commit": "<full-40-char-commit-hash>", 4 "config_sha256": "<sha256-of-configs-study-json>", 5 "source_sha256": "<sha256-of-src-tree>", 6 "python": "3.12.x", 7 "numpy": "2.2.6", 8 "os": "Darwin", 9 "architecture": "arm64", 10 "confirmatory_seeds": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], 11 "bootstrap_seed": 20260731, 12 "outputs": { 13 "primary_seed_rows.csv": "<sha256-hash>", 14 "study_results.json": "<sha256-hash>" 15 }, 16 "status": "worked-run-not-preregistered" 17}

When an independent reviewer clones the repository and runs the entrypoint, their local output must reproduce these exact SHA-256 digests bit for bit. If a single hash differs, the execution has drifted, and the pipeline halts before generating the report.

CITATION.cff gives the software both human-readable and machine-readable citation metadata. GitHub renders that file directly in the repository's Cite panel.[10]Reference 10About CITATION fileshttps://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-citation-files After archiving a release to Zenodo or an institutional repository, add a persistent DOI.

Run the miniature study

The script generates paired random tapes, trains both arms, executes the zero-potential control, evaluates on original reward, and prints the decision from all gates. NumPy is pinned here for the worked fixture; a random seed alone doesn't pin a library, build, platform, or generator's call sequence.[11]Reference 11Random number compatibility policyhttps://numpy.org/doc/stable/reference/random/compatibility.html

A Python random port isn't a drop-in substitute: it draws a different stream and would change every headline number.

Read the control points before running. make_tape freezes randomness by episode and step; train changes only the reward; evaluate never receives shaping reward; the bootstrap samples paired differences.

Run it with uv run reward_shaping_study.py. Expected output follows the code.

reward_shaping_study.py
1#!/usr/bin/env -S uv run --script 2# /// script 3# requires-python = "==3.12.*" 4# dependencies = ["numpy==2.2.6"] 5# /// 6 7import numpy as np 8 9N_STATES = 7 10GOAL = N_STATES - 1 11GAMMA = 0.95 12ALPHA = 0.35 13EPSILON = 0.20 14TRAIN_EPISODES = 80 15MAX_STEPS = 12 16EARLY_EPISODES = 30 17EVAL_EPISODES = 200 18SLIP_PROBABILITY = 0.15 19BOOTSTRAP_REPLICATES = 10_000 20SEEDS = tuple(range(24)) 21 22def potential(state: int) -> float: 23 return -(GOAL - state) / GOAL 24 25def make_tape(seed: int) -> dict[str, np.ndarray]: 26 rng = np.random.default_rng(seed) 27 shape = (TRAIN_EPISODES, MAX_STEPS) 28 return { 29 "explore": rng.random(shape), 30 "action": rng.integers(0, 2, shape), 31 "tie": rng.integers(0, 2, shape), 32 "slip": rng.random(shape), 33 } 34 35def q_target(reward: float, next_state: int, q: np.ndarray) -> float: 36 # A rollout timeout is not a terminal state in the underlying task. 37 return reward if next_state == GOAL else reward + GAMMA * q[next_state].max() 38 39def train(tape: dict[str, np.ndarray], shaped: bool, phi=potential) -> tuple[np.ndarray, np.ndarray, np.ndarray]: 40 q = np.zeros((N_STATES, 2), dtype=float) 41 solved: list[int] = [] 42 steps: list[int] = [] 43 44 for episode in range(TRAIN_EPISODES): 45 state = 0 46 reached_goal = False 47 48 for step in range(MAX_STEPS): 49 if tape["explore"][episode, step] < EPSILON: 50 action = int(tape["action"][episode, step]) 51 else: 52 best = np.flatnonzero(q[state] == q[state].max()) 53 action = int(best[tape["tie"][episode, step] % len(best)]) 54 55 move = -1 if action == 0 else 1 56 if tape["slip"][episode, step] < SLIP_PROBABILITY: 57 move = -move 58 59 next_state = int(np.clip(state + move, 0, GOAL)) 60 environment_reward = float(next_state == GOAL) 61 shaping_reward = ( 62 GAMMA * phi(next_state) - phi(state) 63 if shaped 64 else 0.0 65 ) 66 training_reward = environment_reward + shaping_reward 67 target = q_target(training_reward, next_state, q) 68 q[state, action] += ALPHA * (target - q[state, action]) 69 state = next_state 70 71 if state == GOAL: 72 reached_goal = True 73 break 74 75 solved.append(int(reached_goal)) 76 steps.append(step + 1) 77 78 return q, np.asarray(solved), np.asarray(steps) 79 80def evaluate(q: np.ndarray, seed: int, episodes: int = EVAL_EPISODES) -> float: 81 slips = np.random.default_rng(10_000 + seed).random((episodes, MAX_STEPS)) 82 successes: list[bool] = [] 83 84 for episode in range(episodes): 85 state = 0 86 for step in range(MAX_STEPS): 87 action = int(np.argmax(q[state])) 88 move = -1 if action == 0 else 1 89 if slips[episode, step] < SLIP_PROBABILITY: 90 move = -move 91 state = int(np.clip(state + move, 0, GOAL)) 92 if state == GOAL: 93 break 94 successes.append(state == GOAL) 95 96 return float(np.mean(successes)) 97 98rows: list[tuple] = [] 99for seed in SEEDS: 100 tape = make_tape(seed) 101 sparse_q, sparse_train, sparse_steps = train(tape, shaped=False) 102 shaped_q, shaped_train, shaped_steps = train(tape, shaped=True) 103 zero_q, zero_train, zero_steps = train(tape, shaped=True, phi=lambda state: 0.0) 104 np.testing.assert_array_equal(zero_q, sparse_q) 105 np.testing.assert_array_equal(zero_train, sparse_train) 106 np.testing.assert_array_equal(zero_steps, sparse_steps) 107 rows.append( 108 ( 109 seed, 110 float(sparse_train[:EARLY_EPISODES].mean()), 111 float(shaped_train[:EARLY_EPISODES].mean()), 112 evaluate(sparse_q, seed), 113 evaluate(shaped_q, seed), 114 int(sparse_steps.sum()), 115 int(shaped_steps.sum()), 116 ) 117 ) 118 119results = np.asarray(rows, dtype=float) 120early_delta = results[:, 2] - results[:, 1] 121final_delta = results[:, 4] - results[:, 3] 122 123bootstrap_rng = np.random.default_rng(20_260_731) 124bootstrap_means = np.asarray( 125 [ 126 early_delta[ 127 bootstrap_rng.integers(0, len(early_delta), len(early_delta)) 128 ].mean() 129 for _ in range(BOOTSTRAP_REPLICATES) 130 ] 131) 132interval_low, interval_high = np.quantile(bootstrap_means, [0.05, 0.95]) 133 134final_rng = np.random.default_rng(20_260_732) 135final_bootstrap = final_delta[final_rng.integers(0, len(rows), (BOOTSTRAP_REPLICATES, len(rows)))].mean(axis=1) 136final_low, final_high = np.quantile(final_bootstrap, [0.05, 0.95]) 137# Sensitivity only: independent arm resampling removes the observed pairing. 138unpaired_rng = np.random.default_rng(20_260_733) 139shape_index = unpaired_rng.integers(0, len(rows), (BOOTSTRAP_REPLICATES, len(rows))) 140sparse_index = unpaired_rng.integers(0, len(rows), (BOOTSTRAP_REPLICATES, len(rows))) 141unpaired_means = results[shape_index, 2].mean(axis=1) - results[sparse_index, 1].mean(axis=1) 142unpaired_low, unpaired_high = np.quantile(unpaired_means, [0.05, 0.95]) 143 144primary_supported = early_delta.mean() >= 0.10 and interval_low > 0.0 145guardrail_passed = abs(final_delta.mean()) <= 0.02 and final_low >= -0.02 and final_high <= 0.02 146supported = primary_supported and guardrail_passed 147 148print(f"paired seeds: {len(SEEDS)}") 149print("zero-potential control: exact equality on all 24 seeds") 150print(f"early sparse mean: {results[:, 1].mean():.3f}") 151print(f"early shaped mean: {results[:, 2].mean():.3f}") 152print(f"mean paired delta: {early_delta.mean():+.3f}") 153print(f"90% paired bootstrap CI: [{interval_low:+.3f}, {interval_high:+.3f}]") 154print( 155 "seeds improved / tied / regressed: " 156 f"{int(np.sum(early_delta > 0))} / " 157 f"{int(np.sum(early_delta == 0))} / " 158 f"{int(np.sum(early_delta < 0))}" 159) 160print(f"final sparse mean: {results[:, 3].mean():.3f}") 161print(f"final shaped mean: {results[:, 4].mean():.3f}") 162print(f"mean final delta: {final_delta.mean():+.3f}") 163print(f"90% final-difference interval: [{final_low:+.3f}, {final_high:+.3f}]") 164print(f"unpaired sensitivity interval: [{unpaired_low:+.3f}, {unpaired_high:+.3f}]") 165print(f"mean training transitions sparse / shaped: {results[:, 5].mean():.1f} / {results[:, 6].mean():.1f}") 166print(f"decision: {'SUPPORT UNDER RULE' if supported else 'WITHHOLD SUPPORT'}") 167print(f"guardrail: {'PASS' if guardrail_passed else 'FAIL'}")
Output
1paired seeds: 24 2zero-potential control: exact equality on all 24 seeds 3early sparse mean: 0.439 4early shaped mean: 0.582 5mean paired delta: +0.143 690% paired bootstrap CI: [+0.061, +0.225] 7seeds improved / tied / regressed: 19 / 0 / 5 8final sparse mean: 0.911 9final shaped mean: 0.911 10mean final delta: +0.000 1190% final-difference interval: [+0.000, +0.000] 12unpaired sensitivity interval: [+0.046, +0.235] 13mean training transitions sparse / shaped: 773.2 / 754.7 14decision: SUPPORT UNDER RULE 15guardrail: PASS

Read the result without hiding variance

Before reading the headline mean, inspect the seed distribution. The locked rule needs a positive mean and an interval above zero, but neither tells you whether the candidate improved every seed.

Executed differences for 24 paired seeds. Five regressions remain visible. The mean early gain is 14.3 percentage points, with 90% paired interval [6.1, 22.5] points and unpaired sensitivity interval [4.6, 23.5] points. The mean clears 10 points, but the lower bound doesn't.
Each point comes from one executed seed pair, not a hand-entered plot value. Five seeds regress despite the positive mean. The paired interval excludes zero but includes effects smaller than +0.10; the unpaired sensitivity interval is wider in this run.

The headline numbers look encouraging at first glance. The mean paired early difference is +0.143+0.143+0.143 (+14.3 percentage points), clearing our pre-locked +0.10+0.10+0.10 threshold. The 90% paired bootstrap interval is [+0.061,+0.225][+0.061, +0.225][+0.061,+0.225], which stays strictly above zero. But look closer at that lower bound: +0.061+0.061+0.061 is less than +0.10+0.10+0.10. We can conclude with 90% confidence that shaping helps, but our evidence can't claim with 90% confidence that the gain is at least 10 percentage points!

Notice the comparison with the unpaired sensitivity interval: [+0.046,+0.235][+0.046, +0.235][+0.046,+0.235]. When we break the pairing and resample arms independently, the interval expands by roughly 15% (spanning 18.9 points instead of 16.4 points). That widening confirms our mathematical derivation: by preserving the positive covariance Cov⁡(X,Y)\operatorname{Cov}(X, Y)Cov(X,Y) between paired seeds, the paired protocol directly cancels out between-seed stochasticity.

The five regressions and exploratory traps

The most instructive finding in the entire study isn't the positive mean; it's the fact that five out of 24 seeds regressed (Δi<0\Delta_i < 0Δi​<0). In seeds 6, 9, 13, 17, and 21, the shaped agent performed worse than the sparse baseline during the first 30 training episodes!

Why would a potential that points toward the goal hurt early learning?

Remember that action execution is stochastic: an intended step to the right reverses with a 15% slip probability. When the agent steps from state 0 to state 1, it receives a positive shaping bonus of +0.208+0.208+0.208. But if it immediately slips from state 1 back to state 0, it receives a negative shaping penalty:

F(1,left,0)=γΦ(0)−Φ(1)=0.95×(−1.0)−(−5/6)=−0.117.F(1, \text{left}, 0) = \gamma \Phi(0) - \Phi(1) = 0.95 \times (-1.0) - (-5/6) = -0.117.F(1,left,0)=γΦ(0)−Φ(1)=0.95×(−1.0)−(−5/6)=−0.117.

On seeds where stochastic action slips cluster in the first few episodes, the agent repeatedly experiences these negative shaping penalties. Because Q(0,right)Q(0, \text{right})Q(0,right) gets updated downward before the agent has ever reached the distant goal, the policy temporarily treats moving right as a losing move! Under sparse rewards, an agent receives r=0r=0r=0 on every non-terminal step, so its Q-values stay flat and its exploratory random walk explores without prejudice. The dense shaping signal inadvertently created a temporary exploratory penalty.

A cherry-picking researcher would drop those five seeds, call them outliers, and publish an inflated +0.25+0.25+0.25 gain. An honest researcher highlights them, explains the mechanism, and reports the complete distribution.

Seed 18: Equivalence isn't competence

Seed 18 offers a different reality check. Both the sparse baseline and the shaped candidate achieved only 45.5% greedy success (91 out of 200 evaluation episodes).

The final-policy guardrail passed because the paired difference was exactly +0.000+0.000+0.000 (0.455 - 0.455). But that doesn't mean either arm learned a strong policy! Both arms converged to mediocre policies on that seed's evaluation slip sequence.

The lesson: an equivalence guardrail tests task invariance (confirming the treatment didn't distort the underlying objective), not absolute competence. Always inspect the underlying baseline performance alongside the paired differences.

Both arms received 80 training episodes, not an identical number of environment steps: means were 773.2 transitions for sparse and 754.7 for shaped. Reaching the goal terminates an episode early, so successful agents consume fewer steps. This design measures early success per episode, not wall-clock efficiency or success at an identical step budget.

Separate support from proof

Potential-based shaping theory motivates candidate design, but a tiny experiment doesn't prove the theorem. It verifies implementation behavior under one finite setup.

Likewise, a bootstrap interval isn't a certificate of external validity. New environments, algorithms, reward scales, horizons, and hyperparameters can change learning dynamics.

Use precise verbs: observed, estimated, supported under the locked rule, and didn't detect. Avoid proved, guaranteed, always, and works in production.

Preserve the complete seed table

Report seed, sparse early rate, shaped early rate, paired difference, sparse final rate, shaped final rate, and run status. Sort by seed, not performance.

Keep failed mechanical runs in the ledger with their errors. If the locked rerun rule permits replacement, preserve the first failed attempt and link the replacement rather than overwriting it.

The aggregate table should point to the row-table checksum. A screenshot alone can't support reanalysis.

Treat negative results as artifacts

A rejected hypothesis isn't a failed capstone. Its value is knowing which locked claim the evidence didn't support. A strong artifact makes that result easy to understand, rerun, and extend.

Keep the report structure unchanged when the claim fails. Replace celebratory language with the declared decision, the uncertainty, the likely explanations, and the next discriminating study. Don't quietly change the metric or the seed set.

Use this diagnosis table after locked analysis:

SymptomPlausible causeHonest response
interval crosses zeroseed budget too small or effect unstablereport inconclusive result and wider interval
mean below +0.10effect smaller than useful thresholdreject practical claim even if sign is positive
final guardrail failsundertraining, stochastic variation, or an implementation errorwithhold support; inspect updates and per-seed outcomes
a few extreme seeds dominateunstable exploration or environment interactionshow seed distribution and robust summary
zero-potential control differscode paths aren't identicalstop analysis and fix experiment harness
clean clone can't runmissing dependency, data, or commandrepair artifact before sharing report

A negative result can still narrow future work. For example, a wide interval may justify more seeds; a stable null effect may rule out one potential; guardrail failure may expose incorrect terminal shaping.

Mark post-result hypotheses exploratory. "Seed 6 regressed because early slips trapped policy" can become next registered study, but it isn't confirmed by same observed seed trace.

Produce a figure, table, and report

A research artifact needs three aligned views. The table preserves exact values, the figure makes the distribution visible, and the report connects evidence to the claim. All three must derive from the same immutable rows, or a polished report can drift away from the run it describes.

Generate the table and figure from artifacts/runs/primary_seed_rows.csv. Don't type result numbers into plot code or the report by hand. Check that derived rows and aggregate values match the run before recording file checksums. Matching hashes establishes byte identity, not scientific validity.

This lesson's bundle includes illustrations/run_study.py: it executes the named experiment fence and exports primary_seed_rows.csv, study_results.json, and artifact_manifest.json. The result figure reads that JSON rather than a second list of numbers. From the repository root, regenerate those artifacts with:

regenerate-study-artifacts.sh
1uv run web/src/content/foundations/capstone-reproducible-research-study/illustrations/run_study.py

The manifest records the executed code hash, exporter hash, config, runtime, and output hashes. It deliberately labels the run as worked evidence, not preregistration. A repeat run should reproduce the row and JSON hashes under the same recorded environment; an independently implemented simulator is a stronger cross-check against shared bugs.

Use accessible colors plus sign and position. Negative seed differences need a label or distinct shape so interpretation doesn't depend on red-green perception.

Required table

report/tables/primary_result.csv should contain one row per arm plus paired delta summary:

MetricSparseShapedPaired difference
first-30 success0.4390.582+0.143
90% intervaln/an/a[+0.061, +0.225]
improved/tied/regressed seedsn/an/a19/0/5
final original-reward success0.9110.911+0.000

Required figure

Show every seed difference on a common x-axis with a visible zero line. Add the paired mean and interval. The figure above is that view: the scatter carries the five regressions, and the interval shows why the mean still clears the locked rule.

Write a caption that states the inference, not a restatement of the title. Mention the five negative seeds. Avoid a bar chart that hides the seed distribution.

Export SVG for the report and PNG for slides. Save the plotting command and source hash in the manifest.

Required report

Keep report concise enough to review in one sitting:

  1. Abstract with scope and decision.
  2. Paper claim and study adaptation.
  3. Locked hypothesis, expected result, and rejection rule.
  4. Environment, baseline, candidate, controls, and seed plan.
  5. Primary table, figure, uncertainty, and negative seeds.
  6. Ablations and mechanical checks.
  7. Limitations, negative findings, and next study.
  8. Reproduction command, manifest, license, and citation.

State deviations from plan in their own table. none is acceptable only after checking commit diff between locked plan and final config.

Write limitations that constrain the claim

Limitations aren't a ceremonial paragraph. Each should identify an unsupported inference and, when possible, the experiment that would test it. Treat the table as a map of where the current evidence stops.

This capstone has at least six:

LimitationUnsupported inferenceUseful next study
one seven-state corridorshaping helps other environmentsadd branching grid and delayed traps
tabular Q-learning onlyeffect transfers to neural agentspreregister small function-approximation study
one potentialany potential speeds learningcompare several locked potential families
one hyperparameter setresult is tuning-robustcrossed seed-by-hyperparameter design
24 seedseffect estimate is highly preciseplan seed count from target interval width
synthetic taskdeployed-agent value or safetyno such claim without separate governed study

Also state the theorem's boundary. Potential-based shaping preserves optimal policies under the assumptions in the source formulation. A finite implementation can still be wrong, undertrained, or measured on the wrong reward.

Don't describe the public-safe synthetic setup as representative of users. Its strength is auditability, not realism.

Stage the evidence for review

Each stage should be reviewable before the next begins. A milestone is an evidence package, not a calendar date.

Keep reviewer feedback in reviews/ or an issue tracker. When feedback changes the locked plan, record an amendment before the confirmatory run.

The four stages move from claim selection to a defensible public artifact:

Milestone 1: paper and study contract

Submit paper_triage.md, study_plan.md, source links, one-paragraph scope, falsifiable hypothesis, expected result, rejection rule, public-safety boundary, and limitations forecast.

At this point, a reviewer should trace the shaping equation to the paper and distinguish paper claims from study adaptations. No confirmatory results should exist yet.

Move on when another engineer can predict which output supports, rejects, or leaves the claim inconclusive.

Milestone 2: simulator and baseline

Submit the exact repository skeleton, environment tests, sparse Q-learning baseline, pilot-only run, zero-potential equality test, config schema, dependency lock, and clean-run command.

The reviewer runs seed 900 and inspects one episode trace, confirming goal reward, slip behavior, terminal handling, and the 12-step cap.

Move on when baseline and zero-potential control are bit-for-bit equal under the same tape.

Milestone 3: confirmatory evidence

Submit the immutable 24-seed row table, paired bootstrap output, experiment table, manifest, checksums, primary figure, planned ablations, and deviation log.

The reviewer reconstructs headline values from the row table and reruns at least one seed pair. Mechanical failures remain visible.

Move on when the decision follows the locked rule without manual number edits.

Milestone 4: public artifact and defense

Submit the final report, exact reproduction instructions, license, CITATION.cff, archived release identifier if available, ten-minute talk outline, Q&A sheet, and artifact review checklist.

The reviewer starts from a clean clone and produces the primary table. They also identify one unsupported claim and verify the report doesn't make it.

The artifact is ready when an independent reviewer can exercise it and explain its evidence, limits, and next study.

Prepare a ten-minute talk

A short technical talk tests whether your research decisions form a coherent story. Ten minutes leaves no room for every implementation detail, so use an evidence hierarchy rather than a file tour.

Practice with a timer and one backup slide per likely challenge. The main deck should fit seven slides and reserve at least two minutes for questions.

Use this pacing:

TimeSlideJob
0:00-0:45problemsparse reward and narrow corridor question
0:45-1:45paper claimpotential-based shaping and assumption boundary
1:45-3:00hypothesisprimary effect, expected pattern, rejection rule
3:00-4:30designbaseline, candidate, paired tapes, seeds, controls
4:30-6:15evidenceseed plot, interval, five regressions, final guardrail
6:15-7:15failure checkszero potential, original-reward evaluation, deviations
7:15-8:00limitationsclaim boundary and next study
8:00-10:00Q&Adefend choices with artifact links

Build Q&A from attack surfaces

Write the answers before the presentation. Each answer should point to an evidence file or admit unresolved uncertainty. That keeps Q&A from becoming a second, improvised results section.

QuestionStrong answer shape
Why 24 seeds?bounded laptop budget; report interval width; no claim of universal adequacy
Why 90% interval?locked before results for capstone sensitivity; show exact choice; alternative belongs appendix
Why mean?primary estimand was paired mean; whole distribution and regression count remain visible
Did shaping change the task?training rewards differed; final measurement used original reward; a passing guardrail isn't a theorem proof
Why can five seeds regress?method changes learning dynamics; mean claim isn't per-seed guarantee
Seed 18's finals are both 0.455. Did the guardrail fail?no; it checks paired differences and their interval, not competence on every seed
Does theorem prove experiment?no; theorem motivates form, while artifact checks finite implementation
Can result transfer to agents?no; corridor, tabular learner, and synthetic data bound claim
What would falsify next idea?preregister environment family and potential comparison with rejection thresholds

Don't answer every challenge with "more data." Some failures demand corrected control, better estimand, or narrower claim.

Review artifact like an outsider

Under ACM's current terminology, repeatability is the same team obtaining a result with the same setup. Reproducibility is a different team obtaining it with the authors' artifacts, and replicability is a different team obtaining it with independently developed artifacts.[12]Reference 12Artifact Review and Badginghttps://www.acm.org/publications/policies/artifact-review-and-badging-current

This capstone targets repeatability first and provides enough documentation for an independent reproducibility attempt.

ACM's functional artifact criteria emphasize documented, consistent, complete, exercisable artifacts with verification and validation evidence.[12]Reference 12Artifact Review and Badginghttps://www.acm.org/publications/policies/artifact-review-and-badging-current Use those words as review questions, not as a badge claim.

FAIR principles add findability, accessibility, interoperability, and reuse to data stewardship.[13]Reference 13The FAIR Guiding Principles for scientific data management and stewardshiphttps://www.nature.com/articles/sdata201618 A public repository, open formats, machine-readable manifest, license, and citation metadata help. They don't replace executable validation.

Outsider checklist

  • Can a reviewer find the hypothesis and locked commit?
  • Can a reviewer install the environment without global packages?
  • Can a reviewer regenerate synthetic rows from config and seeds?
  • Can a reviewer verify source, config, and result checksums?
  • Can a reviewer recompute the table and figure from the same rows?
  • Can a reviewer see failed runs and plan deviations?
  • Can a reviewer distinguish confirmatory from exploratory work?
  • Can a reviewer state exactly where the claim stops?
  • Can a reviewer cite the release and understand the license?
  • Can a reviewer reproduce the primary decision from a clean clone?

If any answer is "no," the artifact isn't ready. Fix the package before polishing the talk.

Defend bounded evidence

By the end, you can move from one paper claim to a bounded empirical question without pretending a small study reproduces an entire field. State the expected result and rejection rule before confirmatory output, then preserve negative seeds and failed hypotheses.

Paired tapes separate an algorithm change from some random noise; bootstrap uncertainty exposes sampling sensitivity; original-reward evaluation keeps the task fixed. Those habits transfer to model training, retrieval, evaluators, and agent benchmarks.

Ship evidence another engineer can inspect: source, lockfile, config, seed table, manifest, figure, report, limitations, talk, and Q&A. The artifact is credible because the claim remains smaller than the evidence.

Your shaped agent has higher shaped return but identical original-reward success. Which value belongs in final-policy guardrail?

Answer

Original-reward success. Shaping is a training signal, so scoring it in the final comparison would change the metric in the candidate's favor.

Mean early paired difference is +0.12, but 90% bootstrap interval is [-0.03, +0.24]. Does locked rule support H1?

Answer

No. The mean clears the practical threshold, but the interval's lower bound isn't above zero. Report the result as inconclusive or rejected under the locked rule, and don't change the interval after seeing the output.

You find a terminal-transition bug after inspecting first six confirmatory seeds. Can you fix code and append eighteen fresh seeds to old six?

Answer

No. Preserve the invalid results, record an amendment, version the correction, and rerun the complete seed set for a comparable corrected analysis. Because some outcomes already influenced development, label that rerun as amended evidence; reserve a new untouched set for a fresh confirmatory claim. Don't mix versions or erase the deviation.

A reviewer gets a different seed table from clean clone, although source and config hashes match yours. Should report stay unchanged because aggregate conclusion matches?

Answer

No. Treat the row mismatch as a reproducibility failure. Preserve both outputs, compare runtime and NumPy versions, platform metadata, nondeterministic operations, and input hashes, then fix or document the cause. A matching conclusion doesn't excuse unaccounted execution drift.

Complete the lesson

Mastery Check

Answer every question, then check your score. Score 75% or higher to mark this lesson complete.

1.With gamma = 0.95, Phi(0) = -1, and Phi(1) = -5/6, what shaping value does a move from state 0 to state 1 receive?

Correct answer: F = 0.95 * (-5/6) - (-1) = +0.208, so the move toward goal gets a positive bonus.

The shaping term is gamma times the next-state potential minus the current potential. Substituting the two values gives 0.95 * (-0.8333) + 1, approximately +0.208. The environment goal reward remains separate from this training-only signal.

2.A shaped arm has higher training return because it receives the potential bonus, while both arms have the same greedy success under the corridor's original goal reward. Which final comparison is valid?

Correct answer: Score both greedy policies with original goal-only reward and keep shaping out of the final metric.

The bonus is a training aid, not a change to the task being evaluated. Applying it only to one final score would favor the candidate by construction. Original reward makes the policy comparison use the same target for both arms.

3.For one paired seed, the shaped arm reaches the goal in 18 of its first 30 episodes and the sparse arm reaches it in 12. What primary paired observation should enter the seed table?

Correct answer: A paired difference of 0.20, computed as 18/30 minus 12/30 for this seed.

The declared unit is one paired seed and the primary metric is the difference in first-30 success rates. The shaped rate is 0.60 and the sparse rate is 0.40, so this seed contributes 0.20. Aggregate means come only after every declared pair is recorded.

4.A zero-potential control uses the same pre-generated tape as sparse training but produces different Q-values before evaluation. What should the research team infer?

Correct answer: An unintended implementation difference exists; inspect the environment and update path.

With potential set to zero, the candidate update should match sparse training when inputs, tape, and code paths are held fixed. A mismatch means an accidental difference, such as terminal handling or random-index consumption, has contaminated the comparison.

5.An analyst inspected pilot seeds 900 through 902, then proposes adding them to seeds 0 through 23 after seeing which runs improved. What should happen?

Correct answer: Keep pilots separate and run the locked 24 confirmatory pairs without outcome-based additions.

Pilot behavior informed debugging and may have influenced implementation choices, so including those outcomes after inspection makes the confirmatory sample outcome-dependent. Pilots can remain in the artifact as development evidence, while the locked seed set supplies the primary estimate.

6.The paired early mean is +0.09 with a 90% interval of [+0.03, +0.15], while the locked minimum useful effect is +0.10. What decision follows?

Correct answer: Withhold support: the mean misses the declared +0.10 practical threshold.

The locked rule requires both a mean at least +0.10 and a lower interval bound above zero. This result meets the uncertainty condition but misses the practical-effect condition. Changing seeds or metrics after seeing the result would invalidate the contract.

7.A 24-seed paired bootstrap reports a 90% interval of [-0.03, +0.24] for the mean early difference. What does that interval support?

Correct answer: It quantifies uncertainty over mean differences from the declared seed sample, conditional on this design.

The bootstrap resamples paired seed differences and recomputes their mean. Its interval describes uncertainty in this bounded simulator estimate, not theorem truth, individual-seed outcomes, or transfer to other environments. A lower bound crossing zero also prevents the locked support rule from passing.

8.The primary mean clears its threshold, but five of 24 paired seeds regress under shaping. How should the report present that result?

Correct answer: Show all five regressions; the mean claim doesn't promise per-seed improvement.

The primary estimand is a mean paired effect, not a guarantee that every seed improves. Showing the full distribution lets reviewers see instability and prevents a positive average from becoming a universal claim. Follow-up explanations belong in exploratory analysis unless planned in advance.

9.A clean-clone rerun produces different seed rows even though source and configuration hashes match. Which response preserves reproducibility?

Correct answer: Preserve both outputs, compare runtime and dependency metadata before editing the report.

A matching headline does not explain execution drift. Reproducible artifacts must make row differences visible, then check NumPy and runtime versions, platform behavior, nondeterministic operations, and input hashes. The report should state the resolution or limitation rather than silently selecting a preferred run.

10.Seed 18 has final original-reward success 0.455 for both arms, and the final guardrail still passes. What did that guardrail check?

Correct answer: That the mean paired final difference and its interval stayed within the declared bounds.

The guardrail checks observed paired differences and their bootstrap interval, not absolute competence on each seed or policy invariance in general. Equal but mediocre success on seed 18 passes a difference check. Even a zero-width empirical interval can't rule out rare failures outside the observed sample.

10 questions remaining.

Next Step
Continue to Sentence Embeddings & Contrastive Loss

You can now turn a research claim into reproducible evidence and say where that evidence stops. Next you'll look at contrastive objectives that shape reusable sentence <span data-glossary="vector">vectors</span>, and you'll need this same experimental discipline when someone claims a loss, a negative-mining trick, or a pooling choice improved retrieval.

PreviousCapstone: Fine-Tuned Classifier
Share this article
XFacebookLinkedInBlueskyRedditHacker NewsEmail
References

Deep Reinforcement Learning That Matters

Henderson, P., Islam, R., Bachman, P., Pineau, J., Precup, D., and Meger, D. · 2018 · AAAI 2018

https://ojs.aaai.org/index.php/AAAI/article/view/11694

Reproducibility

PyTorch Contributors · 2026

https://docs.pytorch.org/docs/stable/notes/randomness.html

Policy Invariance Under Reward Transformations: Theory and Application to Reward Shaping

Ng, A. Y., Harada, D., and Russell, S. · 1999 · ICML 1999

https://wordpress.andrewng.org/index.php/publication/policy-invariance-under-reward-transformations-theory-and-application-to-reward-shaping/

How to Read a Paper

Keshav, S. · 2007 · ACM SIGCOMM Computer Communication Review

https://dl.acm.org/doi/10.1145/1273445.1273458

Welcome to Registrations

Open Science Framework · 2026

https://help.osf.io/article/330-welcome-to-registrations

Handling Time Limits

Farama Foundation · 2026

https://gymnasium.farama.org/tutorials/gymnasium_basics/handling_time_limits/

Reinforcement Learning: An Introduction

Sutton, R. S. and Barto, A. G. · 2018 · MIT Press

http://incompleteideas.net/book/the-book-2nd.html

Deep Reinforcement Learning at the Edge of the Statistical Precipice

Agarwal, R., Schwarzer, M., Castro, P. S., Courville, A. C., and Bellemare, M. G. · 2021 · NeurIPS 2021

https://proceedings.neurips.cc/paper/2021/hash/f514cec81cb148559cf475e7426eed5e-Abstract.html

The Machine Learning Reproducibility Checklist

Pineau, J., et al. · 2021

https://www.cs.mcgill.ca/~jpineau/ReproducibilityChecklist.pdf

About CITATION files

GitHub · 2026

https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-citation-files

Random number compatibility policy

NumPy Contributors · 2026

https://numpy.org/doc/stable/reference/random/compatibility.html

Artifact Review and Badging

Association for Computing Machinery · 2026

https://www.acm.org/publications/policies/artifact-review-and-badging-current

The FAIR Guiding Principles for scientific data management and stewardship

Wilkinson, M. D., et al. · 2016 · Scientific Data

https://www.nature.com/articles/sdata201618

Discussion

Questions and insights from fellow learners.

Discussion loads when you reach this section.