Skip to content

lnk_scenario_export(): habitat per config as Parquet + manifest + fwapg load (#308) - #337

Merged
NewGraphEnvironment merged 14 commits into
mainfrom
308-lnk-scenario-export-publish-habitat-per
Oct 14, 2026
Merged

NewGraphEnvironment merged 14 commits into
mainfrom
308-lnk-scenario-export-publish-habitat-per

Conversation

@NewGraphEnvironment

Copy link
Copy Markdown
Owner

Summary

Closes #308's first cut. link's habitat flags export per config as Hive-partitioned Parquet with a manifest, on the pattern NewGraphEnvironment/wet#7 set for discharge.

  • lnk_scenario_export() writes one row per segment × config × species. Rows are keyed by FWA position (blue_line_key, downstream_route_measure, upstream_route_measure), so no link geometry is published. Each row carries:

    • the flags;
    • the width, discharge and gradient the build tested;
    • their ratios to the thresholds the build logged;
    • has_barriers_dnstr from link's access table.

    A write-once provenance tree sits beside the parts: one entry per finished build, one per config hash and one per recompute, plus the bundle files when today's bundle hashes the same as the build.

  • lnk_catalog() reads the manifest from a local path, https, or s3:// through the aws CLI (habitat/ is private).

  • lnk_db_load() loads parts into habitat.fwa_v1_segment in one transaction, after checking md5s.

  • data-raw/habitat_publish.R has two modes: BUILD and PUBLISH (LNK_PUBLISH=1). PUBLISH was not run. Uploading to s3://fresh-bc/habitat/fwa/v1/ waits on your go-ahead.

Mechanics, and what each column does not mean: RUNBOOK §6d.

Decisions to confirm (they shape the published contract)

  1. has_barriers_dnstr ships beside accessible. The pilot found they disagree in every config × species × group: 4,292 km in all. On DUNC BT, which was never recomputed, 228 of 229 disagreeing segments start exactly at a BT-blocking barrier. That is a boundary convention, filed as accessible and streams_access are built from different barrier sets (DUNC BT gradient barriers) #336.
  2. Rows exist only for the species a group's build modelled. A modelled species with no habitat reads FALSE; an unmodelled one has no rows. This reads the issue's "no habitat yields FALSE" as being about modelled species.
  3. Provenance is keyed per finished build (provenance/run_uid=<uid>/run_id=<id>/), not per dispatch. A dispatch's rows grow as its groups close, so a per-dispatch file could not be written once.
  4. NULL run_uid is accepted and keyed by run_id. Groups with no log row are refused. Gating PUBLISH on run_uid is Gates before a floodplain item pins a habitat build: run_uid, dirty trees, versioning, public read #334.

Pilot (local fwapg)

  • BUILD: default on its 5 logged groups and bcfishpass on 39. 22 parts, 9.88 M rows, 219 MB, about 1 min.
  • Reproducibility: a rebuild five commits later gave byte-identical parts.
  • Against lnk_rollup_wsg(), 150 rows: spawning km and the barrier-based accessible km match exactly, and rearing km matches within the rollup's 0.01 km rounding.
  • Ratios: NA for every build before Per-bundle habitat thresholds CSV in config.yaml #282. Only DUNC logged thresholds. The manifest says so per config hash.
  • Evidence: data-raw/logs/habitat_export_308/.

Test plan

  • New tests: export 164, catalog 16, loader 19. All pass.
    • The export covers fan-out, refusals, write-once by record, staging, multi-schema configs, and narrowing or older-build regressions.
    • The loader covers md5 refusal, rollback and cache reuse.
  • Mutation table: every guard goes red when its bug is restored. See the archive's findings.md.
  • devtools::check(): 2,896 pass.
    • 5 fail or error, all identical on origin/main and environmental: lnk_db_conn tunnel port, dams golden, wsg_resolve closure.
    • No check warning or note names a file this branch adds.
  • /code-check branch: five rounds, ended by enumerating the 24 places the recurring mechanism reaches.
  • Pilot BUILD + load + independent comparison.
  • PUBLISH to the private prefix (operator).

Follow-ups filed

#331 discharge from wet · #332 desktop GeoPackage · #333 crate registration · #334 publish gates, versioning, public read · #335 webmap · #336 access boundary convention.

Related Issues

🤖 Generated with Claude Code

https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx

NewGraphEnvironment and others added 14 commits October 14, 2026 09:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…pecies only, carry-forward (#308)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…UNBOOK §6d (#308)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…i-schema groups and dispatches, JSON arrays, PUBLISH checks first (#308)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…ted exports, skipped as object; access boundary documented as measured (#308, #336)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…s and publishes, skip-mode schemas without wsgs (#308)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…LISH (pairs and older builds), exported_by per config, skipped scoped to named groups, --replace (#308)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
…e shared judgement (missed recompute, older export with other parts); pilot rebuild evidence (#308)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WJE2szSCkeV9R3qKhuSwyx
@NewGraphEnvironment
NewGraphEnvironment merged commit 02a75ff into main Oct 14, 2026
1 check passed
@NewGraphEnvironment
NewGraphEnvironment deleted the 308-lnk-scenario-export-publish-habitat-per branch October 14, 2026 23:24
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.

lnk_scenario_export(): publish habitat per config as Parquet + manifest + fwapg load (wet#7 pattern)

1 participant