Skip to content

bump-objectui.sh never deepens when the OLD pin object is absent, so a shallow checkout emits a patch changeset for a minor range #14178

Description

@claude

Found while bumping the console pin (#14027 / PR #14165), on the first of two bump runs. Sibling of the closed #9408, but a different branch of the same guard.

What #9408 fixed, and the case that still degrades

#9408 taught the digest to detect a range that is walkable but truncated (findRangeTruncation, the parentless-inside-the-range test) and to DEEPEN rather than degrade. That works.

The case here is one step earlier. When the FROM endpoint's commit object is absent outright, the endpoint guard in objectui-changeset-digest.mjs returns first:

try {
  git(objectuiRoot, ['cat-file', '-e', `${from}^{commit}`]);
  git(objectuiRoot, ['cat-file', '-e', `${to}^{commit}`]);
} catch {
  console.error(`cannot walk ${from}..${to} in ${objectuiRoot}`);
  return 2;                      // <- deepen is never considered
}

findRangeTruncation is below that return, so the documented default deepen (git fetch --unshallow, the one the script header advertises and OBJECTUI_NO_DEEPEN=1 opts out of) is never reached. A deepen is exactly what would have repaired it.

Measured, on this container

The dispatch container's ../objectui is a 50-commit shallow clone, so the old pin object is absent. Same range, same command, before and after git fetch --unshallow:

releasing changesets breaking bump level list
shallow (degraded path) not derived not derived patch tip commit only, 1 line
unshallowed 218 15 minor full, 143 lines

The degraded entry does label itself degraded, so nothing lies. But the bump level it emits is wrongpatch where the range declares minor — and 15 declared-breaking entries are invisible in it. Both feed @objectstack/console's CHANGELOG and the curated release notes. It also silently skips the ADR-0087 disposition prompt, because that fires on a declared-breaking changeset and the degraded one declares none.

An operator who does not happen to know the checkout is shallow has no cue: the run exits 0, writes a changeset and commits it.

Options

  1. Try the deepen in the absent-endpoint branch too, then re-ask — the same shape as the truncated branch, whose re-check (not the fetch status) already decides the outcome per the C17 self-test case.
  2. Leave the deepen alone but make the degraded path REFUSE when the bump level could not be derived from declarations, rather than emitting patch as a default.
  3. Leave as is and document that a shallow objectui checkout must be deepened before a pin bump.

Option 1 mirrors the existing branch and needs no new policy; option 2 is worth pairing with it, since patch as a fallback is a guess that reads like a declaration.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions