Skip to content

feat(cli): add gf ontology module fetch with clone safety rules - #1758

Merged
DecisionNerd merged 1 commit into
mainfrom
feat/1746-ontology-module-fetch
Oct 2, 2026
Merged

DecisionNerd merged 1 commit into
mainfrom
feat/1746-ontology-module-fetch

Conversation

@DecisionNerd

@DecisionNerd DecisionNerd commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Closes #1746. Part of #1732. Builds on #1747, #1754 and #1757.

What

gf [--json] ontology module fetch OWNER/REPO --ontology-id ID --version V --digest HEX --output FILE [--hub https://base]
  • Reuses the gf clone transport and safety code. That means HTTPS only, no credentials in URLs, public-network DNS and IP checks on every hop including redirects, and refs/manifest capped at 16 MiB. The module object is capped at 64 MiB (DiscoveryLimits.max_module_package_bytes), and staging is private and no-follow.
  • Requests only refs, the manifest and the selected module package object. It never requests the Project package or the summary. It checks the object's digest and length, then verifies through resolve_discovered_ontology_module.
  • Writes the verified module document atomically. It writes to private staging and publishes with a hard link, which never overwrites anything. An existing output, including a dangling symlink, is refused before any I/O. If a file appears at the output path during the fetch, it is never replaced.
  • Cleans up staging on every outcome. Staging is emptied while the lock is held, and the directory is removed after the lock is released. A filesystem without hard links fails with the stable code hub.destination_conflict.
  • Opens no project and adds no new hub.* codes. It is exempt from the four-surface multi-ontology contract, like gf clone, so there is no Python or Node work.
  • Receipt: {contract: "graphforge-hub-module-fetch/1", repository, module: {ontology_id, authored_version, canonical_digest}, package_digest, module_sha256, output}.
  • Docs: packages/cli/README.md next to gf clone (usage, safety rules, receipt, error codes, hard-link requirement), the discovery README, and portable-v2-integration.md.

Acceptance evidence (#1746)

These tests use the scripted/recording transport over the checked-in openalex fixture bytes.

Criterion Test (hub_clone::module_fetch::tests unless noted)
Exactly three requests (refs, manifest, module object), never the Project package module_fetch_requests_only_the_module_package_and_writes_the_verified_document
Unsafe locations fail with a stable code and leave nothing behind module_fetch_rejects_unsafe_object_locations_before_requesting_the_object, module_fetch_rejects_malformed_inputs_before_any_request
Absent descriptor module_fetch_of_an_unadvertised_identity_is_a_missing_object
Oversized object module_fetch_enforces_the_module_byte_bound (descriptor over 64 MiB, body longer than declared, short body)
Corrupt bytes module_fetch_rejects_corrupt_bytes_and_publishes_nothing
Existing output module_fetch_refuses_an_existing_output_without_touching_it, module_fetch_refuses_a_dangling_symlink_output, module_fetch_never_replaces_an_output_created_during_the_fetch
Staging hygiene and filesystems without hard links staging_release_empties_it_under_the_lock_and_never_clobbers_a_new_lock, a_filesystem_without_hard_links_is_a_stable_conflict_not_a_storage_error
Opens no project; flags parse ontology_cli::tests::ontology_module_fetch_opens_no_project, ontology_module_fetch_parses_its_flags
Documented next to gf clone packages/cli/README.md

Every failure test asserts that the output directory contains nothing beyond what existed before the fetch.

Verification

cargo test -p graphforge-cli --lib                                   # 92 pass, 1 ignored (pre-existing perf test)
cargo test -p graphforge-cli --test multi_ontology --test hub_fixture   # 13 + 3 pass (four-surface conformance unchanged)
cargo clippy -p graphforge-cli --no-deps --all-targets --all-features   # no warnings in changed files
python3 scripts/ci/non-cypher-surface-gate.py                        # pass (455, unchanged)
scripts/ci/repo-checks.sh                                            # pass (source-size bound respected)

Review notes

  • An independent reviewer found no critical issues. I fixed the staging-release race (M1) and four minor findings.
  • No telemetry stages. JobFamily only has Clone, the command has no --telemetry-endpoint, and the issue doesn't ask for telemetry. The README says fetch emits none.
  • Hard link instead of rename. It is the portable way to publish without overwriting. Staging is a sibling directory, so a cross-device link error can't happen.
  • crates/graphforge-cli/src/lib.rs is at 2999 of 3000 lines, so the next addition there needs a split.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Fetch one exact ontology module from Hub discovery (#1746, part of #1732):

    gf ontology module fetch OWNER/REPO --ontology-id ID --version V \
        --digest HEX --output FILE [--hub https://base]

- Reuses the gf clone transport: HTTPS-only, credential-free, public-network
  resolution, bounded metadata and a 64 MiB module object bound, private
  no-follow staging.
- Requests only refs, manifest, and the module package object; checks the
  object digest and length, verifies through
  resolve_discovered_ontology_module, and publishes the module document
  with a no-clobber hard link.
- Staging is emptied under the lock and removed on every outcome; filesystems
  without hard links fail with a stable hub.destination_conflict.
- Opens no project; documented next to gf clone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@greptile-apps greptile-apps 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.

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Oct 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository: CurateLabs/graphforge/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 2c27c7e9-2f9e-4a82-a749-c5d7dfaa4736

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added core Core source code changes documentation Improvements or additions to documentation labels Oct 2, 2026
@DecisionNerd
DecisionNerd added this pull request to the merge queue Oct 2, 2026
Merged via the queue into main with commit fe0928f Oct 2, 2026
19 checks passed
@DecisionNerd
DecisionNerd deleted the feat/1746-ontology-module-fetch branch October 2, 2026 20:59
DecisionNerd added a commit that referenced this pull request Oct 2, 2026
…o hub publish

Main's squash of the lineage discovery work matches the merged lineage tip
apart from the ontology module fetch (#1758) and the two binding re-pins.
Clone's HTTPS plumbing, including the new parse_input_at, now lives in
hub_http.rs and serves module_fetch.rs; clone and publish dispatch share one
lib.rs entry to stay within the source-size bound.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core source code changes documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(cli): gf ontology module fetch with clone safety rules

1 participant