HOW SINGAPORE EDUCATION WORKS · University research environments
Find your next learning step
Record the runtime, declare direct dependencies, generate the ecosystem’s lockfile and prove restoration in a clean environment before calling the analysis reproducible.
Full chapter index · Practice and checking · Sources and next reading · How Singapore Education Works
Code can be unchanged while its result changes because the interpreter, package versions, system libraries or data paths moved. A dependency lockfile records a resolved software state so another environment can attempt the same installation. It is evidence, not magic: it must be generated by the right tool, kept with the project and tested.
This is a research workflow suggestion, not a universal NUS requirement or a guarantee that every operating system can reproduce every result. Follow your lab, institution, funder, ethics, cybersecurity and software-licensing rules. Use the package manager and environment method approved for the project.
The choices at a glance
| What you notice | Likely issue | Useful next move |
|---|---|---|
| The script ran last month but fails today | The environment drifted or was never recorded | Identify runtime and package changes before editing analysis code |
| A dependency list installs different transitive versions | Declared ranges were preserved, but the resolved graph was not | Generate and commit the ecosystem’s lockfile |
| The lockfile restores but the output differs | Software was only one source of variation | Check data version, seeds, locale, system libraries and hardware |
Full chapter index
See the structure
Work and diagnose
Repair and practise
Recall, transfer and questions
Direct dependencies are packages the project intentionally requests. Transitive dependencies are packages those packages need. A short manifest may say “use package A”, while a resolved environment contains A plus many exact supporting versions.
A lockfile captures a resolved graph in a format understood by a particular tool. It should normally be generated and updated by that tool, not hand-edited to look plausible.
The language runtime also matters. A package set that works under one R or Python version may not resolve under another. Record the runtime and platform assumptions beside the lockfile or in the environment metadata.
The manifest expresses intent: which direct packages or version ranges the project needs. The lockfile records one resolution: exact or constrained versions and often integrity information. A restoration log supplies evidence that the recorded state can still be installed.
| Layer | Typical question | Evidence |
|---|---|---|
| Runtime | Which interpreter or language version? | Version output and project note |
| Manifest | What did the project request? | Declared direct dependencies |
| Lockfile | What exact graph was resolved? | Tool-generated lock record |
| System | What sits below the package manager? | OS, architecture and external-library note |
| Test | Can a clean environment run the workflow? | Commands, checksums and output comparison |
Do not call a project reproducible merely because a lockfile exists. The decisive test is whether a clean environment can restore and run the documented route within stated limits.
Assumptions: a small R project uses R 4.4.x, two direct packages and an renv.lock file generated after a successful analysis. The project contains README.md, analysis.R, data/input.csv and output/summary.csv. The input checksum is recorded.
On a clean second machine, the researcher confirms the R version, opens the project, uses the documented renv restoration command, runs analysis.R and compares the new summary with the recorded output. Package installation succeeds, but one numeric column differs because the second machine read commas as decimal separators under a different locale.
Checked answer: the lockfile restored the R package library, but the overall workflow was not yet equivalent. Recording and setting the expected locale fixes the input interpretation; the rerun then matches the checked summary. This shows why a lockfile is necessary evidence for packages but not sufficient evidence for the whole computation.
First classify the failure. Resolution failure means the package manager cannot select or fetch the recorded components. Build failure means a selected package cannot compile or install. Runtime failure means installation succeeded but the code crashes. Result divergence means code runs but outputs do not match.
Preserve the error message, runtime version, platform and command. Do not immediately regenerate the lockfile on the failing machine; that may replace evidence of the original state with a new resolution.
Check whether the missing element is a system library, private repository, expired URL, unavailable package build, architecture mismatch or undocumented external tool. The repair belongs at the layer that failed.
When a package must change, update it in a controlled branch or copy. Regenerate the lockfile through the package manager, review which direct and transitive versions moved, rerun tests and compare outputs.
A large unexpected diff can signal that the command updated the whole environment rather than the intended package. Stop and explain the change before accepting it.
Keep the old lockfile in version history where policy permits. The new file should travel with a short reason, test result and any changed platform limits. Never put passwords, access tokens or private repository credentials inside the project record.
Guided capture
- Identify the approved environment tool.
- Record runtime and direct dependencies.
- Generate the lockfile after a successful run.
Shared restoration
- A collaborator follows the README on a clean environment.
- Both record installation and runtime failures without improvising.
- Compare checked outputs, not only exit status.
Independent handover
A new researcher can restore, run and explain the environment boundaries without oral rescue. If special hardware, licences or private repositories are required, the README names them without exposing secrets.
After a month, try to rebuild the project from its repository and approved data location. Anything remembered but undocumented is a handover risk.
International collaborations cross operating systems, architectures, package mirrors and legal boundaries. A lockfile gives the team a shared resolved graph, while the README and institutional controls explain what cannot travel freely.
Changed-context check: prepare a teaching version on a different operating system. If one locked component is unavailable, document the substitution, rerun validation and label the result as a port rather than silently claiming an identical environment.
Is a lockfile the same as a list of packages?
No. A list may show only direct requirements. A lockfile is generated for an ecosystem and records a particular resolved dependency state.
Should the lockfile be committed to version control?
Often yes for research projects, but follow the tool’s guidance and project policy. Review the file for accidental private URLs or credentials.
Does a container replace a lockfile?
Not automatically. Containers capture another layer, but their build inputs and base images also need versioning and testing.
What proves restoration worked?
A clean installation plus a documented run and comparison against checked outputs. Successful package installation alone is not the research result.
Sources and next reading
- NUS Libraries — Research Data Management guide
- Python Packaging Authority — pylock.toml specification
- renv documentation — Introduction to renv
