Skip to content

Fresh swift build --build-tests fails for HuggingFace-trait-off consumers (regression in 0.46.0) #1737

@roryford

Description

@roryford

Summary

A downstream package that enables a non-default subset of ManifoldKit traits excluding HuggingFace can no longer resolve its test graph against MK 0.46.0. A fresh swift build --build-tests (and swift test) fails during package-graph planning with:

error: 'manifoldkit': product 'HuggingFace' required by package 'manifoldkit' target 'ManifoldHuggingFace' not found in package 'swift-huggingface'.

This is a regression: the identical consumer trait set resolved fine against 0.45.0.

Affected consumer

Fireside's Packages/FiresideEval enables:

.package(
    url: "https://github.com/roryford/ManifoldKit.git",
    exact: "0.46.0",
    traits: ["CloudSaaS", "Ollama", "MLX", "Llama"]   // note: no "HuggingFace"
),

It imports ManifoldBackends, ManifoldRuntime, ManifoldPersistenceSwiftData, ManifoldInference — none of which should pull ManifoldHuggingFace with the trait off.

Key diagnostic: it's the test graph, not the build graph

Against 0.46.0 with HuggingFace off:

Command Result
swift build --package-path Packages/FiresideEval Build complete!
swift build --package-path Packages/FiresideEval --build-tests product 'HuggingFace' … not found
--build-tests with "HuggingFace" added to the trait list Build complete!

So the normal product/library graph is correctly trait-gated; only the --build-tests graph derivation drags ManifoldHuggingFace (and thus the swift-huggingface HuggingFace product) into the plan when the HuggingFace trait is disabled.

What looks correct in the manifest

In v0.46.0:Package.swift, every edge to ManifoldHuggingFace is gated, e.g.:

  • ManifoldUIModelManagement.target(name: "ManifoldHuggingFace", condition: .when(traits: ["HuggingFace"])) (~L605)
  • ManifoldHuggingFaceTests.target(name: "ManifoldHuggingFace", condition: .when(traits: ["HuggingFace"])) (~L934)
  • ManifoldServerTests → same, gated (~L1014)
  • ManifoldHuggingFace target's own .product(name: "HuggingFace", package: "swift-huggingface", condition: .when(traits: ["HuggingFace"])) (~L618)

ManifoldBackends (target ~L557) does not depend on ManifoldHuggingFace (HuggingFace is only a .define there). So statically nothing unconditional pulls it.

Hypotheses (for maintainer to confirm)

  1. SwiftPM --build-tests includes dependency-package test targets (ManifoldHuggingFaceTests, ManifoldServerTests) in graph planning in a way that doesn't honor the .when(traits:) condition on their ManifoldHuggingFace/product edges — i.e. the known SwiftPM trait+test-graph derivation issue already noted in Fireside's CI workaround comment.
  2. Something in the 0.46.0 ManifoldBackends umbrella rework (the conditional ManifoldLlama/ManifoldCloud edges were restructured between 0.45.0 and 0.46.0) shifted which test targets land in a consumer's --build-tests plan.

Since plain swift build is clean and only --build-tests breaks, (1) is the more likely root cause.

Impact

Breaks the documented lean trait combos (e.g. FoundationOnly, or any consumer that omits HuggingFace) for anyone running swift test / --build-tests on a fresh resolve. It's masked by warm Package.resolved caches, so it only bites fresh CI checkouts.

Current workaround (downstream)

Add "HuggingFace" to the consumer's trait list (done in Fireside PR #781). This pulls swift-huggingface into the eval build unnecessarily, so a proper fix in MK / SwiftPM trait handling is preferred.

Reproduction

# In a consumer that enables MK traits WITHOUT "HuggingFace":
rm -f Package.resolved
swift build --build-tests        # fails on 0.46.0; passes on 0.45.0

Versions

  • Broken: ManifoldKit 0.46.0
  • Last good: ManifoldKit 0.45.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions