Skip to content

Add Terra/AnVIL ADR, TDD guide, and acceptance tests for DRS URI support#247

Open
bwalsh wants to merge 16 commits into
developmentfrom
feature/terra
Open

Add Terra/AnVIL ADR, TDD guide, and acceptance tests for DRS URI support#247
bwalsh wants to merge 16 commits into
developmentfrom
feature/terra

Conversation

@bwalsh

@bwalsh bwalsh commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR documents and codifies the first increment of Terra/AnVIL DRS support for git-drs.

It adds:

  • a Terra/AnVIL ADR describing the gap between current Gen3/Syfon-oriented behavior and the desired Terra/AnVIL DRS workflow;
  • a TDD guide explaining the intentionally failing acceptance tests and how to run them;
  • failing acceptance tests that capture expected future behavior for:
    • loading a terra remote from Git config;
    • selecting Terra-aware behavior from git drs add-ref;
    • parsing git-drs pointer files with oid drs://...;
    • deriving deterministic SHA256-shaped local cache identity for DRS URI references.

The tests are intentionally red. They are meant to drive the next implementation step rather than validate current runtime behavior.

Motivation

Terra/AnVIL users need to reference controlled-access DRS objects in Git without committing payload bytes. The desired workflow is to store reviewable pointer files and manifests in Git, then hydrate selected files through AnVIL/Terra authorization.

The current git-drs implementation already has useful building blocks, including pointer workflows, selective hydration, add-ref, Gen3/Syfon remotes, and local DRS metadata/cache plumbing. However, those pieces do not yet compose into a complete Terra/AnVIL workflow.

This PR frames the remaining work as an incremental provider/identity extension rather than a wholesale rewrite.

The key missing pieces are:

  • a terra remote mode;
  • Terra-aware auth and resolver behavior;
  • remote-aware add-ref behavior;
  • DRS URI pointer compatibility;
  • SHA256-shaped cache compatibility for DRS URI identities;
  • manifest/bootstrap support as a batch wrapper over reference creation.

Changes

Documentation

  • Adds docs/terra-anvil-drs-download-gap-adr.md.

    • Defines the proposed incremental design.
    • Describes the desired git drs remote add terra ... shape.
    • Documents the remote-aware add-ref direction.
    • Captures the pointer-format tradeoff between Git LFS-shaped oid sha256:<derived-local-oid> pointers and direct git-drs pointers using oid drs://....
  • Adds docs/terra-anvil-tdd-tests.md.

    • Documents each failing test file.
    • Explains the current failure mode.
    • Provides commands for running the focused acceptance tests and individual test groups.
    • Describes the recommended implementation order.
  • Adds this PR-description Markdown file at docs/terra-anvil-pr-description.md.

Acceptance tests

  • Adds cmd/addref/terra_addref_acceptance_test.go.

    • Requires git drs add-ref to expose a --remote-type flag or equivalent resolver-selection mechanism for Terra references.
  • Adds internal/config/terra_remote_acceptance_test.go.

    • Writes future Terra remote config values into Git config.
    • Expects LoadConfig and GetRemote("anvil") to recognize a type = terra remote and preserve the configured endpoint.
  • Adds internal/lfs/terra_pointer_acceptance_test.go.

    • Expects git-drs to recognize a pointer with version https://calypr.github.io/spec/v1 and oid drs://....
    • Expects DRS URI identities to map to deterministic SHA256-shaped cache paths.

Expected current test behavior

The new acceptance tests are expected to fail until the corresponding Terra/AnVIL implementation is added.

Run the focused test group with:

go test -timeout 30s ./internal/lfs ./internal/config ./cmd/addref

Expected current failure categories:

  • internal/lfs: DRS URI pointer parsing and cache-key derivation are not implemented yet.
  • internal/config: type = terra remotes are not parsed into a concrete DRS remote yet.
  • cmd/addref: --remote-type is not exposed yet.

Reviewer notes

This PR intentionally does not implement Terra/AnVIL runtime support yet. It establishes:

  1. the ADR/design direction;
  2. the expected developer workflow;
  3. executable acceptance criteria for the next implementation PR.

Once Terra/AnVIL implementation work lands, these intentionally failing tests should become passing regression tests.

@bwalsh

bwalsh commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Expected behavior:

$ go test -timeout 30s ./internal/lfs ./internal/config ./cmd/addref
--- FAIL: TestAcceptanceTerraDRSURIoidPointerIsRecognized (0.00s)
    terra_pointer_acceptance_test.go:13: expected git-drs DRS URI pointer to be recognized
--- FAIL: TestAcceptanceTerraDRSURIoidPointerHasDeterministicSHA256CacheKey (0.00s)
    terra_pointer_acceptance_test.go:31: expected DRS URI to be normalized to a sha256-shaped cache key path: error: drs://cgc-ga4gh-api.sbgenomics.com/4c33ae65e4b08832ce3d94e9c is not a valid sha256 hash
FAIL
FAIL    github.com/calypr/git-drs/internal/lfs  2.330s
--- FAIL: TestAcceptanceLoadTerraRemoteConfig (0.21s)
    terra_remote_acceptance_test.go:31: expected terra remote to load as a DRS remote
FAIL
FAIL    github.com/calypr/git-drs/internal/config       1.561s
--- FAIL: TestAcceptanceAddRefExposesRemoteTypeForTerraReferences (0.00s)
    terra_addref_acceptance_test.go:7: expected add-ref to expose --remote-type so Terra DRS references can select a Terra resolver explicitly
FAIL
FAIL    github.com/calypr/git-drs/cmd/addref    0.539s
FAIL

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 953f79d7b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread cmd/addref/terra_addref_acceptance_test.go
@bwalsh

bwalsh commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

tests now pass

@matthewpeterkort matthewpeterkort left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI aided review summary:

This is a useful first design step, but the core abstraction should be a provider-neutral DRS URI resolver plus pluggable authentication. Terra should be the first authentication/service adapter, not the object identity model. The implementation needs to distinguish URI resolution, service authentication, access-method selection, download, and checksum verification. In particular, a DRS URI cannot be treated as a SHA256 object ID merely because it needs a local cache path. The next implementation step should establish that generic pipeline, then add Terra authentication behind it.

Technical design remains too vague in the areas that determine whether the approach will scale beyond Terra. I’m not asking for a broad refactor in this PR, but the PR should define the adapter boundaries clearly enough that the next implementation work has a concrete shape.

places to go further into depth on:

  1. URI parsing and resolution:hostname-based drs://host/id
    a. compact-identifier drs://namespace:id
    b. resolver registry lookup and caching

  2. authentication:anonymous/public access
    a. bearer tokens
    b. Terra/Google ADC
    c. GA4GH Passport or future mechanisms

  3. DRS interaction:fetching object metadata
    a. selecting access_url versus access_id
    b. handling access-method-specific headers

  4. adapter interfaces:resolver adapter
    a. auth provider
    b. DRS client/service adapter
    c. byte downloader

  5. error and security policy:unknown compact prefixes
    a. untrusted resolver responses
    b. checksum mismatches
    c. auth failure versus object-not-found

Checksum/hash/identifier resolution is also huge here. Currently we just use sha256 as the identifier in the local cache, but I suspect that drs URIs, or other types of checksums should be supported to make this more extensible. It is unreasonable to expect users to download files from remote just to compute a sha256. Whatever hash that is provided in the remote should be used as the sha256.

a concrete “next implementation boundary” section showing the expected data flow and interfaces + more technical details that answer the above elaboration questions would be useful

Comment thread cmd/addref/add-ref.go

func init() {
Cmd.Flags().StringVarP(&remote, "remote", "r", "", "target remote DRS server (default: default_remote)")
Cmd.Flags().StringVar(&remoteType, "remote-type", "", "resolver remote type for DRS references (for example: terra)")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, you want the user not have to define this as a feature flag because that is not very scalable. Instead you use identifiers.org or something similar to use the drs compact id lookup to resolve the drs server.


- Git-compatible pointer workflows.
- `git drs track` for tracked data path patterns.
- `git drs pull -I <pattern>` for selective hydration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current pull validation compares the downloaded SHA256 to the pointer’s oid. That works for oid sha256:..., but cannot work for oid drs://... without changing the verification model.

@bwalsh

bwalsh commented Jul 11, 2026 via email

Copy link
Copy Markdown
Contributor Author

@matthewpeterkort

Copy link
Copy Markdown
Contributor

A DRS URI identifies a file, but it is not the file’s checksum. The way that git-drs is engineered currently you need a hash to do anything file related.

@bwalsh bwalsh changed the title Add Terra/AnVIL ADR, TDD guide, and failing acceptance tests for DRS URI support Add Terra/AnVIL ADR, TDD guide, and acceptance tests for DRS URI support Jul 14, 2026
@bwalsh

bwalsh commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Updated the add-ref documentation to state that the client resolves drs://... URIs against the source authority/resolver using source-appropriate credentials, and only uses the primary remote as an explicit resolver/proxy.

Corrected the sequence diagram so add-ref talks to the Source DRS authority/resolver by default, with a separate optional primary-remote proxy path.

Updated the immediate add-ref state guidance to clarify that primary remote state is not required and source DRS hydration should use the source authority unless the primary remote is explicitly configured as a proxy.

Changed git drs add-ref resolution to call resolveAddRefObject instead of always resolving through the selected primary remote client.

Added source-authority resolution logic that matches configured remotes by the DRS URI authority, uses that source remote when available, and falls back to direct source authority resolution when the primary remote does not match the DRS URI authority.

Added a test proving that add-ref contacts the configured source authority with source credentials and does not contact the primary remote for a foreign drs://source/object URI.

@bwalsh

bwalsh commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Added user-facing documentation for multiple git-drs remote roles, clarifying that the default/explicit command remote is the primary remote for repository-scoped operations, while a drs://... URI identifies a source DRS authority/resolver. The docs now explicitly state that the primary remote does not act as a proxy for other source DRS servers.

Clarified the pointer-file add-ref discussion so a DRS URI pointing at another authority leaves primary remote state unchanged and remains valid because hydration uses the preserved source identity directly.

Updated add-ref resolution so DRS URIs are parsed into a source endpoint first; configured remotes are used only when their endpoint host matches the DRS URI host, otherwise resolution goes directly to the source endpoint instead of falling back to the primary remote.

Added source-resolution helpers and a test seam for the direct source getter used when no configured remote matches the DRS URI host.

Added a regression test proving that an unconfigured source authority resolves via the source endpoint and object ID, and that the primary remote is not contacted

@bwalsh

bwalsh commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Reviewer Guide: Remotes, Credentials, and State

Please review this PR with special attention to the multi-remote model and add-ref source-resolution behavior.

1. How remotes are configured

Please check whether the documentation clearly explains that a repository can have multiple git-drs remotes, and that the configured drs.default-remote or an explicit command-level remote is the primary remote for repository-scoped operations such as push, registration, checksum lookup, and provider inspection.

Useful entry points:

  • Gen3/Syfon remote setup: git drs remote add gen3 [remote-name] <organization/project> --cred ... or --token ...
  • Local remote setup: git drs remote add local <remote-name> <url> <organization/project>
  • Remote listing and effective configuration inspection via git drs remote list and git drs ping [remote-name]
  • Default remote behavior in implementation: GetDefaultRemote validates DefaultRemote, and GetRemoteOrDefault uses the explicit remote if provided or falls back to the default

Links:

2. How users provide credentials for those remotes

Please check whether the docs and source make it clear which credentials are used for each remote type.

Useful entry points:

  • Gen3/Syfon remotes accept either --cred <credentials-file> or --token <bearer-token>
  • Local remotes can use stored HTTP basic auth via --username / --password
  • Runtime selection loads credentials according to the configured remote type: local, Gen3, or Terra
  • Gen3 runtime loads and refreshes the named remote credential profile before creating the Git context
  • Local runtime overlays stored basic-auth credentials when available

Links:

3. How state is maintained

Please review whether the documentation correctly distinguishes:

  • Git pointer state
  • Local git-drs metadata/cache state
  • Primary remote DRS server state

For add-ref, please verify that the docs do not imply the primary remote proxies another source DRS server. The intended model is:

  • The client resolves the drs://... URI against the source DRS authority/resolver
  • No primary-remote DRS record is required merely because add-ref ran
  • If the source DRS URI points at a different authority, primary remote durable state remains unchanged

Implementation entry points:

  • resolveAddRefObject parses the drs://... source URI, prefers a configured remote only when that remote endpoint host matches the source URI host, and otherwise resolves directly through a source DRS getter
  • parseDRSURIForSource extracts the source object ID and source endpoint from the drs://... URI
  • configuredRemoteForDRSURIHost is the host-matching logic for deciding when an existing configured remote should supply endpoint/credential context for the source authority

Links:

@bwalsh

bwalsh commented Jul 15, 2026

Copy link
Copy Markdown
Contributor Author

Updated ping health checks to carry optional service-info response data, and print it as service-info: ... after a successful health check.

Changed the Terra service-info health probe to return the response body from the /ga4gh/drs/v1/service-info endpoint, trimming whitespace while preserving the returned content for display.

Added regression coverage confirming git drs ping includes Terra service-info output from the mocked service-info endpoint.

Added a focused test confirming the command prints service-info data when the health probe returns it.

Updated the Terra integration test helper call for the new service-info-returning function signature.

$ git drs ping anvil
remote: anvil (default)
type: terra
endpoint: https://data.terra.bio
organization: -
project: -
bucket: -
storage_prefix: -
auth: none
health: ok
service-info: {"version":"0.0.1","title":"Terra Data Repository","description":"Terra Data Repository (Jade) - a Broad/Verily/Microsoft open source project","contact":"cbernard@broadinstitute.org","license":"Apache 2.0"}

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.

2 participants