17  Lab 2 — Engineering for research

cd "$(git rev-parse --show-toplevel)/exercises/lab-02-engineering"

This standalone exercise uses only invented, source-free panel data. The release in fixture/release/ is immutable: it contains 514 person-wave rows and one byte-identical duplicate, P000001::2019. Never put credentials, restricted rows, unpublished results, or personal/participant data into this exercise or an agent.

17.1 Start here

Open a VS Code terminal and paste the first command above. Run pwd. It must end in /exercises/lab-02-engineering. If it does not, stop and ask for help.

Choose a mode before editing:

  • Standalone — recommended: work only in this lab. This route is complete by itself.
  • Cumulative — optional: complete the standalone route first; after the checker passes and you review it, export the allowlisted payload to exercises/workshop-project/.

If you do not choose, stay standalone. fixture/, checks/, and tools/ are read-only; edit only work/. Start a disposable work area:

bash tools/start_lab.sh
Rscript checks/check_lab2.R

The first check is expected to fail. It must report these starting failures:

PASS precondition: fixture fails unique_person_wave, weight_targets, income_consistency
FAIL incomplete: work/derived/person_wave.csv is missing

The exact success check is:

Rscript checks/check_lab2.R

17.2 What you learn

Shift trust from plausible code to executable evidence: prove duplicate identity before deleting, assert relational join cardinality, report wave counts and weight totals, use a mutation-sensitive test, recover a deliberate break with Git, and show dependency-aware workflow invalidation. These checks support structural correctness; they do not establish substantive panel meaning. The weights are simplified teaching constructs, not SOEP estimates or production weights.

17.4 Optional medium route

Do not complete every route. Finish Beginner — recommended, then choose at most one optional route if time remains.

Use the non-selected workflow route from a fresh archived reset and compare its invalidation evidence. This replaces, rather than follows, the other optional workflow exercise.

17.5 Optional advanced route

Do not complete every route. Finish Beginner — recommended, then choose at most one optional route if time remains.

In an archived disposable copy, alter one duplicate so its rows disagree. Verify that repair stops instead of silently choosing a row. Audit which assertions catch row multiplication and which create confidence theatre. Never alter fixture/release/.

17.6 Reproducible build and artefacts

The shipped build command is Rscript tools/build_repair.R; it reads only fixture/release/ and writes only work/. Required outputs are derived/person_wave.csv, derived/person_household_wave.csv, qa/duplicate-proof.csv, qa/join-qa.csv, qa/wave-qa.csv, tests/test_panel_contract.R, git-recovery.txt, and invalidation-evidence.txt. The last two are generated by their named helpers for review; immutable checker-owned replays, not participant claims, decide acceptance.

17.7 Stop, reset, or continue

Stop the mandatory task when Rscript checks/check_lab2.R exits 0 and prints PASS lab 2: identical duplicate proved before repair; joins, wave QA, tests, Git recovery, and workflow invalidation verified. Review the artefacts and confirm the nested recovery worktree is clean. Do not start an optional route merely because the agent suggests one.

  • Safe reset: bash tools/reset_lab.sh --archive archives this lab’s work/ under .reset-archive/ and recreates it. It does not touch another lab or the cumulative project.
  • Optional cumulative export, only after review: bash tools/handoff.sh (type the exact confirmation it requests).
  • Optional checker path: Rscript checks/check_lab2.R --cumulative /absolute/path/to/exercises/workshop-project/lab-02.
  • Next Lab 3: cd "$(git rev-parse --show-toplevel)/exercises/lab-03-security".