Skip to content

Migrate pipeline probes to manifest-driven gating (#46)#50

Merged
NewGraphEnvironment merged 2 commits intomainfrom
46-manifest-driven-probes
Apr 23, 2026
Merged

Migrate pipeline probes to manifest-driven gating (#46)#50
NewGraphEnvironment merged 2 commits intomainfrom
46-manifest-driven-probes

Conversation

@NewGraphEnvironment
Copy link
Copy Markdown
Owner

Summary

Pure refactor — no behavior change. Two information_schema.tables probes in R/lnk_pipeline_prepare.R replaced with direct checks against the lnk_config manifest:

  • .lnk_pipeline_prep_gradient() gains a cfg parameter. The probe for <schema>.barriers_definite_control before the gradient-barrier DELETE is now !is.null(cfg$overrides$barriers_definite_control). Caller in lnk_pipeline_prepare() updated.
  • .lnk_pipeline_prep_overrides() probe for <schema>.user_habitat_classification replaced with !is.null(cfg$habitat_classification).

Rationale: the config manifest is the declarative contract for which capabilities a pipeline variant activates. The old probes worked because .lnk_pipeline_prep_load_aux() writes each table exactly when the manifest declares the key, but that indirection made empty-table edge cases easier to miss — the asymmetric-gating bug fixed in #44 was rooted in this exact seam. Manifest-key gating is consistent with the per-capability pattern introduced in #44 for the barrier-override control wiring.

Secondary fix (surfaced by code-check)

Round 1 of /code-check caught a matching asymmetry on the habitat side: the new manifest gate at prep_overrides would return non-NULL for a degenerate (header-only) habitat_classification CSV, but .lnk_pipeline_prep_load_aux() wrote no table in that case, so lnk_barrier_overrides() would error on SELECT from a missing relation. Fixed by mirroring the barriers_definite_control pattern: always create a schema-valid user_habitat_classification table when the manifest declares the key (empty or populated). The manifest key is now the true contract on both sides.

Verification

  • devtools::test() — 282 PASS, 0 FAIL.
  • Two consecutive tar_destroy + tar_make produce rollup with digest 50908d234e2131fc0842dc3ab653ae78 (46 rows) — bit-identical to the post-user_barriers_definite bypasses override in bcfishpass but is eligible in link #48 baseline.
  • Second rebuild after the empty-stub fix also bit-identical.
  • /code-check round 1 clean on the original 4 checks; flagged the empty-stub asymmetry which was fixed before commit.
  • Tests: replaced DBI::dbGetQuery mocks in prep_gradient tests with cfg stubs; added two new tests covering the prep_overrides habitat gate (declared/omitted).

Fixes #46
Relates to NewGraphEnvironment/sred-2025-2026#24

🤖 Generated with Claude Code

#49 merged as 0.7.0 (5cbd75d), tagged v0.7.0. #46 follows as pure
refactor with bit-identical rollup expected.

Relates to #46
Pure refactor — no behavior change. Two `information_schema.tables`
probes in `R/lnk_pipeline_prepare.R` replaced with direct checks of
the `lnk_config` manifest:

- `.lnk_pipeline_prep_gradient()` gains a `cfg` parameter. The probe
  for `<schema>.barriers_definite_control` before the gradient-barrier
  DELETE is now `!is.null(cfg$overrides$barriers_definite_control)`.
  Caller in `lnk_pipeline_prepare()` updated to pass `cfg`.
- `.lnk_pipeline_prep_overrides()` probe for
  `<schema>.user_habitat_classification` replaced with
  `!is.null(cfg$habitat_classification)`.

Rationale: the config manifest is the declarative contract for which
capabilities a pipeline variant activates. The probes worked because
`.lnk_pipeline_prep_load_aux()` writes each table exactly when the
manifest declares the key, but that indirection made empty-table edge
cases easier to miss (see the asymmetric-gating bug fixed in #44,
rooted in the same seam). Manifest-key gating is consistent with the
per-capability pattern introduced in #44 for the barrier-override
control wiring.

Code-check round-1 surfaced a matching asymmetry on the habitat side:
the new manifest gate at prep_overrides would return non-NULL for a
degenerate (header-only) habitat CSV, but `.lnk_pipeline_prep_load_aux()`
wrote no table in that case, so `lnk_barrier_overrides()` would error
on SELECT from a missing relation. Fixed by mirroring the
`barriers_definite_control` pattern: always create a schema-valid
`user_habitat_classification` table when the manifest declares the
key, empty or populated. Now the manifest key is the true contract.

Tests (`test-lnk_pipeline_prepare.R`):

- Replaced DBI::dbGetQuery mocks in prep_gradient tests with `cfg`
  stubs that either include or omit the manifest key. Two tests
  cover both branches (no-key → no DELETE emitted; key-present →
  DELETE emitted).
- Added two new tests for prep_overrides' habitat gate — manifest
  declares → `habitat = "<schema>.user_habitat_classification"`;
  manifest omits → `habitat = NULL`.

Verification:

- `devtools::test()` 282 PASS 0 FAIL.
- `tar_destroy + tar_make` produces rollup with digest
  `50908d234e2131fc0842dc3ab653ae78` (46 rows) — bit-identical to the
  post-#48 baseline. Second rebuild after the empty-stub fix also
  bit-identical. No behavior drift on the bcfishpass config.

Fixes #46
@NewGraphEnvironment NewGraphEnvironment merged commit b2fc181 into main Apr 23, 2026
1 check passed
@NewGraphEnvironment NewGraphEnvironment deleted the 46-manifest-driven-probes branch April 23, 2026 21:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate remaining pipeline probes to manifest-driven gating

1 participant