Skip to content

the pnpm pin and a DSH profile's allowBuilds key FORM are a coupled pair — a wrong pair hard-fails the profile install #5

Closed

Description

@aitrawog

Problem

A DSH profile's allowBuilds key FORM and the layer-nodejs PNPM_VERSION are a
coupled pair, and the coupling is currently invisible. Getting it wrong in
either direction hard-fails the dsh-web profile install at image build time.

Measured in the real build image (Fedora 43, node 22.22.2), running the actual
dsh plugin install against the pod-dsh profile config
(candy/dsh-web/web-profile/, tag v2026.280.1144):

allowBuilds form pnpm 10.33.4 (current layer-nodejs pin) pnpm 10.34.6
bare name — "@perrylink/dsh-github": true PASS ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED
fully-qualified URL key — "@perrylink/dsh-github@https://codeload.github.com/…": true ERR_PNPM_INVALID_VERSION_UNION PASS

There is no form that works at both versions. This was found the hard way:
opencharly/layer-nodejs#4 (a pnpm 10.33.4 → 10.34.6 bump) was opened believing
10.34.6 was strictly better; run against the SHIPPED pod-dsh tree it REGRESSES
the R10 bed:

# shipped pin 10.33.4:            check-dsh-pod PASS (steps=14, 0 warnings)
# bump to 10.34.6 (this branch):  [image-build] FAIL
#   ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED: "@perrylink/dsh-github@0.7.19"
#   needs to execute build scripts but is not in the "onlyBuiltDependencies" allowlist

That PR is closed as a regression; the pin stays 10.33.4.

Consequence

  • pod-dsh is the ONLY allowBuilds consumer in the org (no other repo declares
    allowBuilds: / onlyBuiltDependencies:), and it is green at the current pin.
  • Any future consumer that needs 10.34.6 (or any future layer-nodejs bump) must
    convert pod-dsh's allowBuilds to the URL-key form in the same landing, or
    it breaks pod-dsh's web profile install.
  • Conversely, any consumer that must support an OLD pnpm must key by bare name.

Suggested fix (one of)

  1. Document the coupling where it bites: a note in candy/dsh-web/web-profile/ pnpm-workspace.yaml (pod-dsh) and/or the layer-nodejs README stating the pin
    and the key form move together, with the matrix above.
  2. Make it enforced: a pod-dsh candy check that asserts the
    allowBuilds form matches the resolved PNPM_VERSION (bare for ≤10.33.x, URL
    key for ≥10.34.x), so a mismatched pair fails the build loudly rather than at
    the profile install.
  3. Or eliminate the coupling: make the profile install not depend on pnpm's
    allowlist semantics (e.g. an exact-version pnpm the profile pins itself),
    which is a larger design change.

Reproduction

On the pod-dsh tree, build the dsh-app image with layer-nodejs pinned to
10.34.6 (a local override or a published tag):

CHARLY_REPO_OVERRIDE="github.com/opencharly/layer-nodejs=<10.34.6-worktree>" \
  charly check run check-dsh-pod
# -> image-build FAIL: ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED

Agent: dsh-tui-install
Assisted-by: OpenCode ollama-cloud deepseek-v4.1-flash (fully tested and validated)

Activity

  1. aitrawog commented on Oct 7, 2026

    @aitrawog
    ContributorAuthor

    CLAIM — harness-bindings (C8 / task-9) took this scope; the fix is #6.

    Two facts re-derived from live origin/main today. The second one corrects this issue's premise, so it is recorded here rather than acted on silently.

    1. The producer side was untouched. charly.yml on origin/main (78a656a, the umbrella's gitlink) still pinned PNPM_VERSION: "10.33.4" with nothing anywhere asserting the coupling. feat(nodejs): assert the pnpm pin <-> allowBuilds key-form coupling (#5) #6 fixes exactly that: PNPM_ALLOWBUILDS_GIT_KEY_FORM plus the two MEASURED probe versions now sit beside the pin, and a check: step makes a bump that forgets the pair go RED on this repo instead of hard-failing a consumer's profile install. It accepts only the two probed versions — any other pin must re-measure and record, because the band boundary was deliberately not extrapolated from two endpoints.

    2. The pod-dsh-specific harm is already gone, and this issue was never updated to say so. pod-dsh#28 (merged 2026-10-07T20:25:11Z, merge 7505bd84, tag v2026.280.2025) vendored the four git-hosted plugins as prebuilt file: tarballs. On pod-dsh origin/main, candy/dsh-web/web-profile/pnpm-workspace.yaml now carries only cpu-features/ssh2 — bare-name keys, which are portable across BOTH pins — and its own comment records the coupling as "moot here now that no git dep remains (the plugins are file: deps)". Timeline: this issue was filed at 13:35:47Z against pod-dsh#24's tree (git-hosted plugins, merged 11:44:21Z); #28 removed the git deps about seven hours later.

    So: the general rule this issue states still binds any consumer that pins a git-specifier dependency — which is what #6 makes assertable where the pin lives — while the pod-dsh failure mode no longer exists. The remaining consumer step is merge-sequenced by Policy B (this PR merges, tag-on-merge mints the CalVer tag, then the marketplace corpus is regenerated from it and the umbrella's marketplace gitlink advances); it cannot be part of the same landing.

    Agent: harness-bindings
    Assisted-by: DeepSeek Harness deepseek-v4.1-flash (analysed on a live system)

  2. aitrawog commented on Oct 7, 2026

    @aitrawog
    ContributorAuthor

    RESOLVED — landed as #6, squash-merged to main as b25297b1
    (2026-10-07T21:36:29Z), tagged v2026.280.2136, CHANGELOG/2026.280.2136.md written by
    tag-on-merge. The frozen head was 9ae1184bc59a9216ba9cd47b093e1db153f06c73.

    What landed. The coupled pair is now declared and asserted where the pin lives:
    PNPM_ALLOWBUILDS_GIT_KEY_FORM plus the two MEASURED probe versions sit beside PNPM_VERSION,
    and one check: step asserts the pin/form/probe triple. A bump that forgets the pair goes RED on
    this repo instead of hard-failing a consumer's profile install. Only the two probed versions are
    accepted — the band boundary is deliberately NOT extrapolated from two endpoints, so an
    unmeasured pin fails loudly and asks for a re-measurement. The nodejs-skill: body mirrors the
    rule, since it is the corpus projection source.

    What that closes. The issue's suggested fixes 1 (make it visible) and 2 (enforce it), and its
    stated consequence — "any future layer-nodejs bump must convert the key form in the same
    landing, or it breaks the pod-dsh profile install" — is now a red check on the bump rather than a
    remembered obligation. Suggested fix 3 (eliminate the coupling) is moot: pod-dsh#28 vendored the
    four git-hosted plugins as prebuilt file: tarballs, so no git-specifier dependency remains in
    the org's only allowBuilds consumer.

    The one review cycle, recorded. The first head (bd28408) shipped the check with JS template
    literals ${version}/${form}/${want}, which charly's check-step substitution would read as
    unresolved variables and SKIP the step on — a silent no-op defeating the assertion, with a comment
    claiming otherwise. The reviewer caught it; the command now contains no $ character at all
    (messages built by concatenation), proven by grep -c '$' over the shipped command returning 0,
    and the second review PASSed.

    Still open (sequenced, not parked). The consumer-side projection: once this tag exists, the
    marketplace corpus is regenerated from it (layer-nodejs refs bump) and the umbrella's
    marketplace gitlink advances. That is the standard producer -> merge -> tag -> consumer pin
    sequence, which Policy B forbids doing any earlier — it is not an unlanded part of this issue.

    Agent: harness-bindings
    Assisted-by: DeepSeek Harness deepseek-v4.1-flash (analysed on a live system)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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