Maintaining and sustaining research software
Use this skill when the goal is to keep software usable over time rather
than to ship a first version: setting up maintenance habits, managing
dependencies and technical debt, deciding whether to keep, deprecate, or
archive a project, and keeping its sustainability story honest.
Unmaintained software degrades even with no code changes - dependencies
age, environments shift, and the knowledge to run it erodes - so treat
maintenance as a recurring cost, not a one-off.
Establish maintenance habits early
Calibrate effort to the user base, but build the habits before the
software is widely used:
- Write a test suite and check coverage with a language-appropriate tool
(pytest-cov for Python, covr for R). Without tests, every dependency or
environment update carries unknown regression risk.
- Set up a CI pipeline that runs tests on every commit and on a schedule
(e.g. weekly). Scheduled runs catch breakage from external changes even
when nobody is actively developing. See the rseng-ci-cd and
rseng-testing skills for the mechanics.
- Keep documentation current as part of maintenance, not after it. If you
cannot install and run the software from scratch using only its README
and install guide, the docs need updating. See rseng-documentation.
- Maintain a visible issue tracker (GitHub/GitLab Issues) so the
maintenance backlog is shared, not held in one person's head.
Manage dependencies deliberately
Every dependency is a liability as well as an asset - it can change,
deprecate, or introduce a security issue:
- Prefer a small, well-understood dependency tree drawn from already
well-maintained projects over a large one.
- Pin exact versions with a management tool for the language (pip + venv,
pip-tools, uv, or Poetry for Python; renv for R) so updates are
deliberate and auditable. See the rseng-reproducible-environments skill.
- Automate update pull requests with Dependabot or Renovate so security
and version bumps surface as reviewable changes rather than silent drift.
Communicate change clearly
- Use Semantic Versioning (MAJOR.MINOR.PATCH) so users can tell a breaking
change from a feature from a bug fix and decide when to upgrade. See the rseng-publishing-releasing skill.
- Keep a CHANGELOG and update it with each release: a record of what
changed, when, and why serves both users and your future self.
Reduce the bus factor
If only one person understands the software, it becomes unmaintainable the
moment they are unavailable:
- Document key decisions, architecture, and operational knowledge in the
repository itself, not just in someone's head.
- Share ownership with at least one other person who can act if the primary
maintainer is away.
- Use regular code review to spread understanding of the codebase (see the
rseng-version-control-review skill).
- Recruit community help: label low-barrier issues (
good first issue),
run maintenance sprints, and make contributing easy.
- Apply for maintenance-specific funding where it exists (funders
increasingly recognise maintenance as a distinct cost).
Deprecate or archive honestly
When you can no longer sustain a project, say so. A prominent README
notice, a repository archive, or an explicit deprecation statement is more
helpful to users than silent abandonment.
See the rseng-publishing-releasing skill for archiving mechanics.
Track and pay down technical debt
Technical debt is often unavoidable in research code written quickly to
test a hypothesis; the danger is that it compounds until change becomes
slow and risky:
- Distinguish intentional debt (a known, documented workaround) from
unintentional debt (unclear code, missing tests, hardcoded values). The
latter is more dangerous because it is harder to reason about.
- Record debt where it is visible: create issues or a
tech-debt label,
and add TODO/FIXME comments at the point of the problem with enough
context for a future reader. Debt held only in memory is forgotten.
- Allocate protected time for maintenance and refactoring - a maintenance
sprint, a fixed fraction of each cycle, or scheduled calendar time. Debt
does not reduce itself.
- Refactor incrementally, not with a big rewrite: small, individually
reviewable improvements (rename for clarity, extract a function, add a
missing test). Ensure tests cover current behaviour before restructuring,
or you cannot tell whether a refactor introduced a regression.
- Use static analysis (Ruff or lintr, SonarQube) to surface quality issues
automatically and track metrics over time. See the rseng-code-quality
skill for readability and structure guidance.
Reduce environmental impact
Environmental sustainability of computing is its own practice with
its own skill: rseng-green-computing covers measuring energy and carbon
(CodeCarbon, the SCI metric), reducing footprint in payoff order and
carbon-aware scheduling. From the maintenance perspective, two habits
matter here: include the compute footprint in the project's
sustainability story (long-running services and repeated pipelines
dominate), and revisit it at the same cadence as dependency and debt
reviews - then follow rseng-green-computing for the how.
Working with this skill
The generated references.md beside this file lists the source
material and pointers:
- references.md - verified Learn more pointers
Learn more (verified):
Related skills
Check whether any of these applies before moving on:
- rseng-archiving - retiring software needs archival deposit
- rseng-ci-cd - scheduled runs catch external breakage
- rseng-code-quality - incremental refactoring and static analysis
- rseng-contributor-onboarding - recruiting community maintenance help
- rseng-dependency-management - dependency update and audit mechanics
- rseng-green-computing - footprint review at maintenance cadence
1---2name: rseng-maintenance-sustainability3description: Covers keeping research software alive and responsible over time: ongoing maintenance practice, tracking and paying down technical debt, reducing the bus factor, and deprecating or archiving honestly. Use when the user asks how to maintain or sustain a project, stop it rotting, schedule CI to catch breakage from external change, track or pay down tech debt, plan maintenance funding or shared ownership, or retire or deprecate software. (Energy and carbon footprint of computing is rseng-green-computing; dependency updating and auditing detail is rseng-dependency-management; archiving mechanics are rseng-archiving.)4license: CC-BY-4.05---67# Maintaining and sustaining research software89Use this skill when the goal is to keep software usable over time rather10than to ship a first version: setting up maintenance habits, managing11dependencies and technical debt, deciding whether to keep, deprecate, or12archive a project, and keeping its sustainability story honest.13Unmaintained software degrades even with no code changes - dependencies14age, environments shift, and the knowledge to run it erodes - so treat15maintenance as a recurring cost, not a one-off.1617## Establish maintenance habits early1819Calibrate effort to the user base, but build the habits before the20software is widely used:2122- Write a test suite and check coverage with a language-appropriate tool23 (pytest-cov for Python, covr for R). Without tests, every dependency or24 environment update carries unknown regression risk.25- Set up a CI pipeline that runs tests on every commit and on a schedule26 (e.g. weekly). Scheduled runs catch breakage from external changes even27 when nobody is actively developing. See the rseng-ci-cd and28 rseng-testing skills for the mechanics.29- Keep documentation current as part of maintenance, not after it. If you30 cannot install and run the software from scratch using only its README31 and install guide, the docs need updating. See rseng-documentation.32- Maintain a visible issue tracker (GitHub/GitLab Issues) so the33 maintenance backlog is shared, not held in one person's head.3435## Manage dependencies deliberately3637Every dependency is a liability as well as an asset - it can change,38deprecate, or introduce a security issue:3940- Prefer a small, well-understood dependency tree drawn from already41 well-maintained projects over a large one.42- Pin exact versions with a management tool for the language (pip + venv,43 pip-tools, uv, or Poetry for Python; renv for R) so updates are44 deliberate and auditable. See the rseng-reproducible-environments skill.45- Automate update pull requests with Dependabot or Renovate so security46 and version bumps surface as reviewable changes rather than silent drift.4748## Communicate change clearly4950- Use Semantic Versioning (MAJOR.MINOR.PATCH) so users can tell a breaking51 change from a feature from a bug fix and decide when to upgrade. See the rseng-publishing-releasing skill.52- Keep a CHANGELOG and update it with each release: a record of what53 changed, when, and why serves both users and your future self.5455## Reduce the bus factor5657If only one person understands the software, it becomes unmaintainable the58moment they are unavailable:5960- Document key decisions, architecture, and operational knowledge in the61 repository itself, not just in someone's head.62- Share ownership with at least one other person who can act if the primary63 maintainer is away.64- Use regular code review to spread understanding of the codebase (see the65 rseng-version-control-review skill).66- Recruit community help: label low-barrier issues (`good first issue`),67 run maintenance sprints, and make contributing easy.68- Apply for maintenance-specific funding where it exists (funders69 increasingly recognise maintenance as a distinct cost).7071## Deprecate or archive honestly7273When you can no longer sustain a project, say so. A prominent README74notice, a repository archive, or an explicit deprecation statement is more75helpful to users than silent abandonment.76See the rseng-publishing-releasing skill for archiving mechanics.7778## Track and pay down technical debt7980Technical debt is often unavoidable in research code written quickly to81test a hypothesis; the danger is that it compounds until change becomes82slow and risky:8384- Distinguish intentional debt (a known, documented workaround) from85 unintentional debt (unclear code, missing tests, hardcoded values). The86 latter is more dangerous because it is harder to reason about.87- Record debt where it is visible: create issues or a `tech-debt` label,88 and add `TODO`/`FIXME` comments at the point of the problem with enough89 context for a future reader. Debt held only in memory is forgotten.90- Allocate protected time for maintenance and refactoring - a maintenance91 sprint, a fixed fraction of each cycle, or scheduled calendar time. Debt92 does not reduce itself.93- Refactor incrementally, not with a big rewrite: small, individually94 reviewable improvements (rename for clarity, extract a function, add a95 missing test). Ensure tests cover current behaviour before restructuring,96 or you cannot tell whether a refactor introduced a regression.97- Use static analysis (Ruff or lintr, SonarQube) to surface quality issues98 automatically and track metrics over time. See the rseng-code-quality99 skill for readability and structure guidance.100101## Reduce environmental impact102103Environmental sustainability of computing is its own practice with104its own skill: rseng-green-computing covers measuring energy and carbon105(CodeCarbon, the SCI metric), reducing footprint in payoff order and106carbon-aware scheduling. From the maintenance perspective, two habits107matter here: include the compute footprint in the project's108sustainability story (long-running services and repeated pipelines109dominate), and revisit it at the same cadence as dependency and debt110reviews - then follow rseng-green-computing for the how.111112## Working with this skill113114The generated references.md beside this file lists the source115material and pointers:116117- references.md - verified Learn more pointers118119120Learn more (verified):121 - https://opensource.guide/best-practices/ - best practices for122 open source maintainers123 - https://www.software.ac.uk - Software Sustainability Institute124 - https://chaoss.community/kb-metrics-and-metrics-models/ - CHAOSS125 community health metrics126 - https://endoflife.date - end-of-life dates for dependencies127128129<!-- related-skills:begin -->130131## Related skills132133Check whether any of these applies before moving on:134135- rseng-archiving - retiring software needs archival deposit136- rseng-ci-cd - scheduled runs catch external breakage137- rseng-code-quality - incremental refactoring and static analysis138- rseng-contributor-onboarding - recruiting community maintenance help139- rseng-dependency-management - dependency update and audit mechanics140- rseng-green-computing - footprint review at maintenance cadence141142<!-- related-skills:end -->