Context
<schema>.streams_mapping_code (per-segment per-species token classification) is currently built only inside lnk_compare_wsg(with_mapping_code = TRUE), which also runs .lnk_compare_wsg_mapping_code_diff() against bcfishpass.streams_mapping_code over the tunnel and .lnk_compare_wsg_stage_reference_barriers() over the tunnel for the diff. Operators who want the mapping_code table for downstream use (e.g. QGIS bcfp-shape streams_<sp>_bcfp_vw symbology via data-raw/build_species_views.R --bcfp) currently must run with the tunnel up.
lnk_pipeline_mapping_code() itself (the data transform) takes access, habitat, feature_code, presence — all derivable from the local schema. No tunnel dependency. The coupling is purely structural: the build only fires when the compare wrapper invokes it, and the compare wrapper requires conn_ref.
Two blockers to self-sufficient build:
-
streams_access not persisted. lnk_pipeline_persist writes streams, streams_habitat_<sp>, barriers. The acc data used by lnk_pipeline_mapping_code is generated by lnk_pipeline_access() during compare and discarded. Re-running access ad hoc means re-running barriers/falls/dams resolution — not lightweight.
-
bcfp_species hardcoded in compare wrapper. R/lnk_compare_wsg.R:594 enumerates c("bt","ch","cm","co","pk","sk","st","wct") inside compare. The build needs that list (or cfg$species).
Goals
lnk_pipeline_run(conn, aoi, cfg, loaded, schema, mapping_code = TRUE) writes <schema>.streams_mapping_code post-persist — fully local, no conn_ref required.
lnk_persist_init schema includes streams_access table; lnk_pipeline_persist writes per-WSG streams_access alongside the existing tables. Idempotent per WSG (same DELETE-WHERE-WSG semantics).
lnk_compare_wsg continues to wrap pipeline + compare for the parity use case. Internally calls lnk_pipeline_run(..., mapping_code = TRUE) instead of inlining the build. The _diff and _stage_reference_barriers helpers stay tunnel-bound and run after the local pipeline phase.
wsgs_run_host.R --mapping-code (renamed from --with-mapping-code) routes through lnk_pipeline_run when no compare reference is configured, through lnk_compare_wsg when one is.
bcfp_species enumeration moves out of lnk_compare_wsg — defined in cfg$species (config-driven) or as a lnk_pipeline_mapping_code default that the caller can override.
Parameter rename (coupled BC change)
with_mapping_code → mapping_code everywhere:
| Surface |
Before |
After |
lnk_compare_wsg() param |
with_mapping_code = FALSE |
mapping_code = FALSE |
lnk_pipeline_run() new param |
— |
mapping_code = FALSE |
CLI flag (wsgs_run_*.sh, wsgs_run_host.R) |
--with-mapping-code |
--mapping-code |
| Logged metadata, README docs |
with_mapping_code: yes/no |
mapping_code: yes/no |
Reasoning: matches the output table name (streams_mapping_code), shorter at call sites, no information lost — mapping_code = TRUE at the call site reads cleanly; only the param-definition site loses the with_ prefix.
Read-clarity tradeoff inside function bodies: if (isTRUE(mapping_code)) ... reads as "if the user asked for the mapping_code lens." Acceptable given the boolean default of FALSE. No callers currently pass a non-logical value to this param.
Acceptance
References
Context
<schema>.streams_mapping_code(per-segment per-species token classification) is currently built only insidelnk_compare_wsg(with_mapping_code = TRUE), which also runs.lnk_compare_wsg_mapping_code_diff()againstbcfishpass.streams_mapping_codeover the tunnel and.lnk_compare_wsg_stage_reference_barriers()over the tunnel for the diff. Operators who want the mapping_code table for downstream use (e.g. QGIS bcfp-shapestreams_<sp>_bcfp_vwsymbology viadata-raw/build_species_views.R --bcfp) currently must run with the tunnel up.lnk_pipeline_mapping_code()itself (the data transform) takesaccess,habitat,feature_code,presence— all derivable from the local schema. No tunnel dependency. The coupling is purely structural: the build only fires when the compare wrapper invokes it, and the compare wrapper requiresconn_ref.Two blockers to self-sufficient build:
streams_accessnot persisted.lnk_pipeline_persistwritesstreams,streams_habitat_<sp>,barriers. Theaccdata used bylnk_pipeline_mapping_codeis generated bylnk_pipeline_access()during compare and discarded. Re-running access ad hoc means re-running barriers/falls/dams resolution — not lightweight.bcfp_specieshardcoded in compare wrapper.R/lnk_compare_wsg.R:594enumeratesc("bt","ch","cm","co","pk","sk","st","wct")inside compare. The build needs that list (orcfg$species).Goals
lnk_pipeline_run(conn, aoi, cfg, loaded, schema, mapping_code = TRUE)writes<schema>.streams_mapping_codepost-persist — fully local, noconn_refrequired.lnk_persist_initschema includesstreams_accesstable;lnk_pipeline_persistwrites per-WSGstreams_accessalongside the existing tables. Idempotent per WSG (same DELETE-WHERE-WSG semantics).lnk_compare_wsgcontinues to wrap pipeline + compare for the parity use case. Internally callslnk_pipeline_run(..., mapping_code = TRUE)instead of inlining the build. The_diffand_stage_reference_barriershelpers stay tunnel-bound and run after the local pipeline phase.wsgs_run_host.R --mapping-code(renamed from--with-mapping-code) routes throughlnk_pipeline_runwhen no compare reference is configured, throughlnk_compare_wsgwhen one is.bcfp_speciesenumeration moves out oflnk_compare_wsg— defined incfg$species(config-driven) or as alnk_pipeline_mapping_codedefault that the caller can override.Parameter rename (coupled BC change)
with_mapping_code→mapping_codeeverywhere:lnk_compare_wsg()paramwith_mapping_code = FALSEmapping_code = FALSElnk_pipeline_run()new parammapping_code = FALSEwsgs_run_*.sh,wsgs_run_host.R)--with-mapping-code--mapping-codewith_mapping_code: yes/nomapping_code: yes/noReasoning: matches the output table name (
streams_mapping_code), shorter at call sites, no information lost —mapping_code = TRUEat the call site reads cleanly; only the param-definition site loses thewith_prefix.Read-clarity tradeoff inside function bodies:
if (isTRUE(mapping_code)) ...reads as "if the user asked for the mapping_code lens." Acceptable given the boolean default ofFALSE. No callers currently pass a non-logical value to this param.Acceptance
lnk_pipeline_run(conn, aoi, cfg, loaded, "fresh_default", mapping_code = TRUE)on a single WSG with no tunnel up writesstreams_access+streams_mapping_codecorrectly. End-to-end smoke on a small WSG (ADMS or PARS).lnk_compare_wsg(..., mapping_code = TRUE)against bcfp tunnel produces byte-identicalstreams_mapping_codeto pre-fix behavior (refactor preserves output).wsgs_run_m4_offline.sh --mapping-code --wsgs=PARSsucceeds with tunnel down.data-raw/build_species_views.R fresh_default --bcfpconsumes the locally-builtstreams_mapping_codecorrectly —streams_<sp>_bcfp_vwviews render in QGIS withmapping_code_bcfpsymbology.with_mapping_codereferences renamed (R sources, data-raw shells, README, NEWS template for v0.40.0).lnk_compare_wsg(with_mapping_code = ...)callers in any external code receive a deprecation warning for one release before removal.References
R/lnk_pipeline_mapping_code.R:81— function signature (tunnel-independent inputs)R/lnk_compare_wsg.R:594— hardcodedbcfp_speciesR/lnk_compare_wsg.R:609-620— build + diff coupling siteR/lnk_pipeline_run.R— destination for the new phaseR/lnk_pipeline_persist.R— needsstreams_accesswriteR/lnk_persist_init.R— needsstreams_accessschemadata-raw/build_species_views.R— consumer; already supports--bcfpsibling viewslnk_compare_mapping_codefamily member) — this issue unblocks Promote with_mapping_code flag to stand-alone lnk_compare_mapping_code() export #175 by removing tunnel coupling from the build half.