A stack lock is not a package lock

a stack lock is a tree; a package lock is one pin

A stack lock is not a package lock. The diff is of the tree the lock named.

wanted set to stack lock to a tree diff

A stack lock is not a package lock. The diff is of the tree.

Resolvo writes a lock and a diff; eb is a later step

A solve is not a build. The lock is a claim about versions. eb still has to run.

Questions

  • What does stack solve take that package plan does not?

  • Which file is safe to paste into a pull request, and which one is the install order?

  • Why can stack sbom --lock not reconstruct dependency edges?

What you will be able to do

  1. Write a whole-stack policy JSON and run stack solve against a fixture tree, naming every artifact the flags emit.

  2. Tell a package-profile stack-policy TOML from a whole-stack policy JSON.

  3. Read a stack.diff.md and say which packages moved, and which file a sequential eb loop should consume instead.

Before this page

The package plan evaluates one package’s profiles against a robot tree. The annual bump of a site stack creates a new question. The system has many roots and a single target generation. The system asks which jointly consistent set is built. The system also asks for the build order of the set and the changes since the previous year. The command is stack solve.

A policy for many roots

The fixture policy at fixtures/gromacs_2025_to_next/policies/prefer_newer.json represents

{
 "toolchain": {"name": "foss", "version": "2025b"},
 "roots": ["GROMACS"],
 "root_priority": ["GROMACS"],
 "pins": [],
 "forbid": [],
 "objective": "prefer_newer",
 "require_upgrade": {"name": "GROMACS", "relative_to_baseline": true}
}

Roots and each declared runtime and build requirement are co‑selected. root_priority stabilizes a multi‑root solve according to list order. Pins employ EasyBuild‑shaped requirements such as ==0.3.24 and >=1.14. forbid accepts either a package name or a full easyconfig path. require_upgrade with relative_to_baseline fails if the baseline package is absent or if no newer jointly feasible candidate exists. This JSON is not the TOML --stack-policy of Inspect; it writes a work queue rather than a recipe. Package commands accept TOML preferences for a single product. Whole‑stack solve uses this JSON schema. Mixing the files produces a parse error rather than a clever override.

Four artifacts from one solve

eb-stack stack solve \
 --easyconfigs fixtures/gromacs_2025_to_next/easyconfigs \
 --policy fixtures/gromacs_2025_to_next/policies/prefer_newer.json \
 --baseline-easyconfigs fixtures/gromacs_2025_to_next/easyconfigs \
 --lock-out stack.lock.json \
 --sbom-out stack.cdx.json \
 --build-list-out build.list \
 --stack-diff-out stack.diff.md

--easyconfigs may be specified multiple times. Later paths replace earlier ones when name, version, toolchain and versionsuffix match. A site‑only package is added to the universe. --stack-diff-out requires --baseline-easyconfigs. Omitting the baseline causes an error instead of a silent skip. stack.lock.json follows schema 1. toolchain denotes the policy target. packages is the co‑selected set ordered by name; each entry includes its own toolchain, an optional versionsuffix, and an easyconfig_path. solver.engine is set to resolvo_cdcl_sat. build.list lists one easyconfig path per line, arranged topologically over the co‑selected stack with ties resolved by package name. An empty lock produces an empty file. A sequential eb loop, a Jenkins step, or xargs -n1 reads the file. The file is not markdown nor an SBOM. stack.diff.md is the pull‑request body. Each co‑selected package is labeled unchanged, added, removed, or version-bumped relative to the baseline.

# Stack diff

Baseline (`foss-2025a`) -> solved (`foss-2025b`).

## Summary

- **unchanged**: 1
- **added**: 0
- **removed**: 0
- **version-bumped**: 3

The file stack.cdx.json generated during solve retains the candidate graph. Dependency edges. The alternative SBOM command does not include them.

eb-stack stack sbom --lock stack.lock.json --out stack.cdx.json

A lock‑only SBOM cannot rebuild edges and does not create them. Apply --sbom-out to stack solve while the graph remains in memory.

EB-Stack-1 — Which file answers

A site ran the fixture solve above. Four questions arrive the next morning. Name the file that answers each one, or say the solve was missing a flag.

  1. “In which order do we eb these?”

  2. “What do we tell the pull request?”

  3. “Which OpenMPI did Resolvo actually pick?”

  4. “Give us a CycloneDX with dependency edges, from the lock we already committed, without re-solving.”

Solution
  1. build.list. Topological, one path per line.

  2. stack.diff.md. That is why it is markdown.

  3. stack.lock.json, the packages entry whose name is OpenMPI.

  4. That file cannot be produced from the lock alone. stack sbom --lock will write a document without edges. The solve needed --sbom-out while the graph was available.

What to remember

  • stack solve is the multi-root annual-bump solver. Its policy is JSON. The package command’s --stack-policy is TOML. They are not interchangeable.

  • build.list is the install order. stack.diff.md is the pull request. stack.lock.json is the Resolvo assignment.

  • A lock-only SBOM has no dependency edges. Edges are written only when --sbom-out is passed to stack solve.