diff --git a/src/common-principles.md b/src/common-principles.md
index 3d9bc233af..eb8012fd7f 100644
--- a/src/common-principles.md
+++ b/src/common-principles.md
@@ -481,6 +481,7 @@ with two exceptions:
 It is RECOMMENDED that the column names in the header of the TSV file are
 written in [`snake_case`](https://en.wikipedia.org/wiki/Snake_case) with the
 first letter in lower case (for example, `variable_name`, not `Variable_name`).
+It is RECOMMENDED that the column names are singular (for example, `variable_name`, not `variable_names`).
 Column names defined in the header MUST be separated with tabs as for the data contents.
 Furthermore, column names MUST NOT be blank (that is, an empty string) and MUST NOT
 be duplicated within a single TSV file.
diff --git a/src/schema/objects/columns.yaml b/src/schema/objects/columns.yaml
index 3ccb32d324..4217752c10 100644
--- a/src/schema/objects/columns.yaml
+++ b/src/schema/objects/columns.yaml
@@ -237,8 +237,8 @@ high_cutoff:
     - type: string
       enum:
         - n/a
-hplc_recovery_fractions:
-  name: hplc_recovery_fractions
+hplc_recovery_fraction:
+  name: hplc_recovery_fraction
   display_name: HPLC recovery fractions
   description: |
     HPLC recovery fractions (the fraction of activity that gets loaded onto the HPLC).
diff --git a/src/schema/objects/metadata.yaml b/src/schema/objects/metadata.yaml
index 57515dd6f0..5f13c42553 100644
--- a/src/schema/objects/metadata.yaml
+++ b/src/schema/objects/metadata.yaml
@@ -2023,7 +2023,7 @@ MetaboliteRecoveryCorrectionApplied:
   description: |
     Metabolite recovery correction from the HPLC, for tracers where it changes
     with time postinjection.
-    If `true`, the `hplc_recovery_fractions` column MUST be present in the
+    If `true`, the `hplc_recovery_fraction` column MUST be present in the
     corresponding `*_blood.tsv` file.
   type: boolean
 MiscChannelCount:
diff --git a/src/schema/rules/tabular_data/pet.yaml b/src/schema/rules/tabular_data/pet.yaml
index 8410ee8481..529aa24959 100644
--- a/src/schema/rules/tabular_data/pet.yaml
+++ b/src/schema/rules/tabular_data/pet.yaml
@@ -15,7 +15,7 @@ Blood:
     metabolite_polar_fraction:
       level: optional
       level_addendum: recommended if `MetaboliteAvail` is `true`
-    hplc_recovery_fractions:
+    hplc_recovery_fraction:
       level: optional
       level_addendum: required if `MetaboliteRecoveryCorrectionApplied` is `true`
     whole_blood_radioactivity:
@@ -48,7 +48,7 @@ BloodMetaboliteCorrection:
     - extension == ".tsv"
     - sidecar.MetaboliteRecoveryCorrectionApplied == true
   columns:
-    hplc_recovery_fractions: required
+    hplc_recovery_fraction: required
 
 BloodWholeBlood:
   selectors:
diff --git a/tools/schemacode/bidsschematools/migrations.py b/tools/schemacode/bidsschematools/migrations.py
index 1cf0441cf1..22cac11afb 100644
--- a/tools/schemacode/bidsschematools/migrations.py
+++ b/tools/schemacode/bidsschematools/migrations.py
@@ -58,6 +58,25 @@ def migrate_participants(dataset_path: Path):
                 lgr.info(f"   - migrated content in {new_file}")
 
 
+def migrate_tsv_columns(dataset_path: Path):
+    """
+    Rename some columns in .tsv (and corresponding sidecar .json)
+    """
+    # TODO: ideally here we would not provide file_glob
+    # but rather take schema and deduce which files could have
+    # the column... alternatively - consider all .tsv files and
+    # their .json files (note -- could be above and multiple given
+    # inheritance principle)
+    for col_from, col_to, file_glob in (
+        # https://github.com/bids-standard/bids-2-devel/issues/78
+        ("hplc_recovery_fraction", "hplc_recovery_fraction", "*_blood.*"),
+        # https://github.com/bids-standard/bids-2-devel/issues/15
+        ("units", "unit", "_channels.*"),  # dependency on migrate_participants
+        # ??? Any other columns to rename for some reason?
+    ):
+        raise NotImplementedError()
+
+
 def migrate_dataset(dataset_path):
     lgr.info(f"Migrating dataset at {dataset_path}")
     dataset_path = Path(dataset_path)
@@ -74,6 +93,7 @@ def migrate_dataset(dataset_path):
     for migration in [
         migrate_participants,
         migrate_version,
+        migrate_tsv_columns,  # depends on migrate_participants
     ]:
         lgr.info(f" - applying migration {migration.__name__}")
         migration(dataset_path)