Skip to content

Dependency bumps are structurally unmergeable: go.mod and go.sum sit inside the bundle source boundary, and refreshing the lock needs an approved operation #24

Description

@rldyourmnd

PR #3 has been blocked since 2026-08-17. It is not a flaky check and not dependabot's fault — the repository's own contract makes this class of PR impossible to land unattended.

The chain

core/projections/generator.go:34 lists the committed source boundary that identifies one development bundle:

var developmentBundleSourcePaths = []string{
	".gds/repository.yaml",
	"core/app", "core/compiler", "core/domain", "core/manifest",
	"core/projections", "core/providers/git", "core/serialization",
	"core/validation",
	"go.mod",      // <-
	"go.sum",      // <-
	"policies",

go.mod and go.sum are in it. So a dependency bump changes SourceTreeDigest, the committed .gds/bundle.lock.yaml no longer matches, and core/context/provenance.go:141 raises GDS_CONTEXT_POLICY_SOURCE_DIGEST_MISMATCH. gds context and gds status then return not-proven, exit 3, and three packages fail: core/assurance, core/cli, core/context.

Reproduced locally with a binary built from PR #3's own head (a9612d7), not from the installed toolchain:

expected sha256:fbc3c835ba2ed32b482c89c761a70036a8ca33591ea252c4439b451807fb88dd
observed sha256:19faa612aeb7afbcd594c3b3e8ef1bec59f5639e73f1ecb8e63c7756d126144c

observed is the value committed in .gds/bundle.lock.yaml; expected is the digest of the branch's actual source.

Why dependabot cannot resolve it

Refreshing the lock is not a file write. It is projections.MaterializeAction, planned at core/app/anchor_change.go:87 with RequiresApproval: true — a governed plan → approval → apply → verify transaction. The file itself says # GENERATED FILE - DO NOT EDIT DIRECTLY. Dependabot has no way to run that, and hand-editing the digest to match would forge exactly the provenance the lock exists to carry.

The signature in the PR history

PR touches outcome
#1 gomod group go.mod, go.sum closed, never merged
#3 gomod group go.mod, go.sum open since 2026-08-17, blocked
#2 actions/attest workflow pin only closed (superseded)
#4 actions/attest workflow pin only merged

The two that touch the bundle boundary never land; the one outside it merged normally. This is not going to resolve itself, and #3 will be joined by every future gomod bump.

Not a request to weaken the boundary

Binding go.mod/go.sum into the bundle identity is correct — the bundle is only meaningful as "compiled from this source with this toolchain". The gap is that there is no path from an automated bump to an approved lock refresh. Options, in rough order of how much they preserve:

  1. a gds operation that takes a bump branch and produces the approved lock refresh as its own governed step, invoked by a maintainer on the PR;
  2. a CI job that detects a bump-only diff and opens the paired refresh rather than failing opaquely;
  3. grouping bumps so the refresh is performed once, deliberately, on a schedule.

Whichever is chosen, the failure should say this rather than GDS_CONTEXT_POLICY_SOURCE_DIGEST_MISMATCH — today the message describes the symptom and names no remedy (Remediation is nil on this finding).

Same family as #22 and #23, and the direct analogue of NDDev-OpenNetwork/ci-workflows#37, where an automated bump likewise cannot update the generated artifact that pins it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions