Skip to content

fix(libsetup): adopt version-script-commit in Utah hooks - #259

Merged
castrojo merged 8 commits into
projectbluefin:mainfrom
kylerankin:fix/version-script-commit-downstream
Oct 3, 2026
Merged

castrojo merged 8 commits into
projectbluefin:mainfrom
kylerankin:fix/version-script-commit-downstream

Conversation

@kylerankin

@kylerankin kylerankin commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Addresses projectbluefin/common#1196 finding 3 (downstream contract).

Utah's four setup hooks call version-script X || exit 0 with no commit. Under
common#1196 version-script keeps its legacy check-and-record behaviour and a
new version-script-check/version-script-commit pair is added alongside it;
the legacy helper stamps completion before the body runs, so a hook that
fails on first boot is skipped forever after. These hooks move to the new pair.

This mirrors the pattern already applied to common's own hooks:

  • gate on version-script-check, and call version-script-commit at each
    hook's success path (after guards), so a failing body aborts before commit
    and retries next boot
  • add -e to 99-flatpaks.sh so a failing body aborts before commit

Merge-order safety: common#1196 is still open, and the pinned COMMON_IMAGE_SHA
in Containerfile has no version-script-commit. Each hook therefore defines a
no-op shim when the function is absent, so it behaves correctly under both the
old (stamp-on-check) and the new (stamp-on-commit) contract, in either merge
order.

Skip paths are split by whether the condition can change:

  • deliberate skips (non-Framework vendor, non-Intel-Core-Ultra product,
    UCSI karg already applied) are evaluated after the gate and commit before
    exit 0, so they stop re-running every boot/login — previously the old
    version-script stamped before the guards, so these hosts ran only once
  • transient skips (DMI unreadable, rpm-ostree missing, brew missing,
    unwritable Homebrew prefix) are evaluated before the gate and exit without
    committing, so they retry. Ordering matters under the compat shim: the shim
    makes the check the legacy stamp, so a transient skip placed after it would
    be recorded as complete on images pinned to a common build without the pair.
    10-tailscale.sh already used this order; 11-framework-ucsi-workaround.sh
    and 20-framework.sh now match it.

tests/test_migrated_setup_hook_contract.py executes all four hooks in a
scratch root against both libsetup contracts (new pair and legacy-only) and
asserts the behaviour: success commits and the second run is a no-op, a failing
body leaves no stamp and retries, deliberate skips commit without running a
body, and transient skips leave no stamp and complete once the prerequisite
appears.

docs/skills/setup-hooks.md is updated in this PR to describe the shim, the
skip-path split and the guard-ordering rule.

Utah's four setup hooks call version-script ... || exit 0 with no commit.
Under common #1196's new contract version-script is a read-only gate, so
those hooks would otherwise re-run every boot. Add version-script-commit at
each success path and set -e to 99-flatpaks so a failing body aborts before
commit and retries next boot.

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge-order dependency, not a code defect: this PR must not land until Utah's pinned common base actually ships version-script-commit.

What I checked:

  • Utah's libsetup.sh comes from the common image: Containerfile:10-15 (FROM ${COMMON_IMAGE}@${COMMON_IMAGE_SHA} AS common, pinned to sha256:2c4cd89e…).
  • libsetup.sh on projectbluefin/common main today defines only version-script(); version-script-commit exists only in the still-open common#1196.

Consequence if this merges first: each of the four hooks runs its body, then hits version-script-commit … → command not found → exit 127. Three of the hooks run under set -e (10-tailscale.sh:8, 11-framework-ucsi-workaround.sh and 20-framework.sh:10), and this PR adds -e to 99-flatpaks.sh, so every hook reports failure on first boot. Because today's version-script already stamps before the body, the failure is one-shot rather than every boot, but ublue-system-setup / ublue-user-setup will show a failed hook on every fresh install until the base is bumped.

The reverse order (common#1196 lands and the base is bumped before this) is benign: all four bodies are idempotent (tailscale set, kargs --append-if-missing, mkdir -p/cp -rf, install_if_missing), so they would merely re-run each boot until this PR lands.

Suggested sequencing for the maintainer: merge common#1196 → bump COMMON_IMAGE_SHA here → then merge this. The hook edits themselves look correct to me: each commit is placed after the last body statement, and the early exit 0 guard paths still do not stamp, as the body says.

Nit on the body: Closes projectbluefin/common#1196 names a PR, not an issue; GitHub will not act on it and it reads as if this PR resolves that one.

Confidence: 3/5 (needs attention) — 1 medium finding; 1 perspective requires a human decision

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@Danathar

Copy link
Copy Markdown
Contributor

The four hook edits look right, but this can't merge yet. It has to wait until Utah's pinned common image ships version-script-commit.

What I checked at 4ce0fd5:

  • version-script-commit only exists in common#1196, which is still open. libsetup.sh on common main defines only version-script, and that's the version Utah's pinned common image (sha256:4603e008…) ships.
  • I ran 10-tailscale.sh and 99-flatpaks.sh from this branch against both versions of libsetup.sh, with the hook bodies stubbed out:
libsetup.sh first run second run
common main today body runs, then version-script-commit: command not found, exit 127 skipped, because today's version-script already recorded the version
common#1196 head body runs, version recorded, exit 0 skipped

So if this lands first, privileged setup fails on the first boot of every new install. The hook runner exits with the last hook's status, and the last hook is 99-flatpaks.sh, which returns 127. The other order does no harm. All four hook bodies are safe to repeat, so until this lands they would just re-run at each boot.

Order that works: merge common#1196, bump COMMON_IMAGE_SHA here (Renovate does this), then merge this. One small thing: Closes projectbluefin/common#1196 in the body does nothing, because closing keywords only close issues, and it reads as if this PR finishes that one. Refs would be clearer.

Also checked: tests/run_suite.py 377 passed (1 skipped), shellcheck is clean on the four hooks, and CI run 36060038967 is green.

@hanthor hanthor left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change is correct: committing after the body in 10-tailscale.sh, 11-framework-ucsi-workaround.sh, 99-flatpaks.sh and 20-framework.sh is the right model. Please hold it until common#1196 merges and the common digest is bumped, though. The digest main pins doesn't define version-script-commit yet, so merged now every hook would exit 127 under set -e.

Things to be aware of:

  • With -e, 99-flatpaks.sh fails every boot if /usr/share/ublue-os/firefox-config is empty. #139 has a guard for this that's worth pulling in here.
  • On machines that aren't Frameworks, the early exit 0 paths never commit, so the chassis probe re-runs every boot. That's cheap, but worth a comment.
  • Pre-existing, not from this PR: rm -f ".../*bluefin*.js" quotes its glob, so it never matches anything.
  • #139 edits the same hooks with a jq rollback of setup_versioning.json. This PR's approach should win once common#1196 lands.

Two follow-ups from review of projectbluefin#259:

- The currently pinned common libsetup.sh (Containerfile COMMON_IMAGE_SHA)
  has no version-script-commit; projectbluefin/common #1196 is still open.
  Calling it unconditionally would make the last line of each hook fail with
  "command not found" (exit 127) on every run until the digest bump lands.
  Define a no-op shim when the function is absent, so the hooks are correct
  under both the old (stamp-on-check) and new (stamp-on-commit) contracts
  regardless of merge order.

- Deliberate skip paths now commit before exiting 0, so they stop re-running
  on every boot/login: non-Framework vendor and non-Intel-Core-Ultra product
  in 11-framework-ucsi-workaround.sh, the already-applied karg case (which
  otherwise shelled out to rpm-ostree kargs forever), and the non-Framework
  vendor case in 20-framework.sh. Transient skips (DMI unreadable,
  rpm-ostree missing, brew missing, unwritable Homebrew prefix) still exit
  without committing so they retry.

Hive-Fix-Attempt: 1/6

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — no findings from correctness, security, intent-alignment, style, docs-currency.

Confidence: 5/5 (safe)

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@kylerankin

Copy link
Copy Markdown
Contributor Author

🐝 Hive Agent — fixed the body nit; the rest is a maintainer sequencing call.

Changed the opening Closes projectbluefin/common#1196 → Addresses (closing keywords don't act on PRs and it read as if this PR resolves #1196).

The merge-order hold stands and I won't merge first: until Utah's pinned common image ships version-script-commit, landing this makes every hook hit version-script-commit: command not found → exit 127 under set -e. Correct order: merge common#1196 → bump COMMON_IMAGE_SHA → then this.

🐝 Hive Agent: contributor | SHA: unknown

@castrojo castrojo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Substantive review:

  • Evaluated the four hook changes (10-tailscale.sh, 11-framework-ucsi-workaround.sh, 99-flatpaks.sh, 20-framework.sh) and the version-script-commit fallback shim.
  • Verified test merge against current main (ace59ad), just check (77 scripts, 8 extensions, download recipes, parity manifests), and full test suite (406 tests passed).
  • Outstanding blocker: merge-order dependency on projectbluefin/common#1196. The PR cannot land until common#1196 merges into projectbluefin/common and Utah bumps COMMON_IMAGE_SHA to include the upstream commit. Awaiting external merge and digest bump.

…ides the stamp

common#1196 (head 57829da) keeps version-script as the legacy
record-before-body gate and adds a read-only version-script-check to pair
with version-script-commit. Gating with version-script meant the version
was still recorded before the body ran, so a failing hook never retried
even after the common bump. Gate with version-script-check and, on older
libsetup builds that lack the pair, fall back to version-script with a
no-op commit, which is today's behaviour.

Assisted-by: Claude via omp

@castrojo castrojo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed 00bb52c on top of c6f3235.

What was wrong: common#1196 at its current head (57829da) no longer changes version-script. It keeps version-script as the legacy gate that records the version before the body runs, and adds a read-only version-script-check meant to pair with version-script-commit. These hooks gated with version-script, so even after the common bump the stamp was written up front and a failing hook would still never retry; the trailing version-script-commit only re-wrote the same stamp.

What changed: all four hooks (10-tailscale, 11-framework-ucsi-workaround, 99-flatpaks, 20-framework) now gate with version-script-check. The compat shim now keys on version-script-check: on a libsetup without the pair (Utah's current pinned common, and common main) it defines version-script-check as version-script and version-script-commit as a no-op, i.e. exactly today's behaviour.

How I checked it: ran the hooks against common main's libsetup.sh and #1196's libsetup.sh with a stubbed tailscale and a temp SETUP_CHECKER_FILE. Old lib: behaviour unchanged (stamp on gate, rc=0 on success). New lib: a failing tailscale set exits 1 with no stamp recorded, the next run retries and records it, the run after that skips. 11-framework and 20-framework (non-Framework DMI, deliberate skip) commit on both libs. shellcheck clean on all four.

Merge order: with the shim this no longer has to wait for common#1196 -- against today's common it is a no-op change. It still needs one approval from someone other than castrojo (I pushed the last commit, and this repo requires last-push approval).

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at head 00bb52c (correctness, security, intent-alignment, style, docs-currency).

intent-alignment

  • (low) The PR body's premise does not match common#1196 as it stands (head 57829da): its libsetup.sh keeps version-script as "Legacy check-and-record, kept unchanged for existing callers", so the four hooks would not "never record completion and re-run on every boot" without this PR. The diff's own shim comments say the opposite of the body (10-tailscale.sh:6-9: legacy "records the version before the body runs"). The change is still worthwhile — it buys retry-on-failure — but the body/commit message should state that motivation rather than the incorrect one.
  • (out-of-scope) privileged-setup.hooks.d/20-home-labels.sh:11 landed on main after this branch (#261) and still uses legacy version-script home-labels privileged 1; after merge it is the one hook left on the burn-before-body contract. Follow-up.

correctness

  • (low) user-setup.hooks.d/20-framework.sh:43-46 treats an unwritable BREW_PREFIX as transient (no commit). For a non-admin secondary account on Framework hardware that condition is effectively permanent, so under the new contract that user's hook re-runs and logs the warning on every login indefinitely (previously stamped once). Cheap, but worth deciding deliberately.

No findings from: security, style, docs-currency.

Confidence: 5/5 (safe)

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Hive filed out-of-scope review findings as backlog issues so they do not block this PR:

Cap: 3 backlog issue(s) per PR.

Danathar
Danathar previously approved these changes Sep 29, 2026

@Danathar Danathar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My earlier hold was that this could not land before common#1196 shipped version-script-commit. Head 00bb52c fixes that: the four hooks now gate with version-script-check and fall back to version-script when it is missing.

I ran 10-tailscale.sh from this head against libsetup.sh from common main and from common#1196 (57829da). On main the behaviour is unchanged. On #1196 a failing body leaves no stamp and retries next boot; success stamps once. I did not run the other three hooks or build the image. CI is green on this head.

Two small points, neither blocking:

  1. The PR body still says version-script writes nothing under #1196; it does not. The real gain is retry after a failed hook.
  2. 20-framework.sh:43-46 skips without committing when the Homebrew prefix is not writable. For a non-admin user on Framework hardware that will warn at every login. Please decide whether that is what you want.

dtg01100 added a commit to dtg01100/utah that referenced this pull request Sep 29, 2026
…scope

Addresses the three non-blocking findings on utah#327:

- the hook comment now states that a persistently failing restorecon re-runs a
  full recursive relabel of /var/home on every boot, and that there is no
  attempt cap;
- the compat-shim section no longer implies every hook already has a shim --
  only 20-home-labels.sh does, the rest still call legacy version-script
  pending projectbluefin#259;
- the shim section splits the run-on sentence so 'in either merge order' reads
  as its own clause.
BREW_PREFIX was hardcoded to /home/linuxbrew/.linuxbrew, which is wrong on
Apple Silicon (Homebrew installs to /opt/homebrew). The write-permission
check would then fail on Apple Silicon and skip Framework setup incorrectly.
Read the real prefix with 'brew --prefix' (falling back to the x86 default),
which is correct on both architectures.
@kylerankin
kylerankin force-pushed the fix/version-script-commit-downstream branch from b864b6c to c60dde2 Compare September 30, 2026 02:12
@kylerankin

Copy link
Copy Markdown
Contributor Author

Addressed the code findings:

  • **BREW_PREFIX is now read from ** (with the x86 path as fallback) instead of a hardcoded path. On Apple Silicon Homebrew installs to , so the hardcoded path failed the write-permission check and skipped Framework setup incorrectly. This fixes both Danathor's and castrojo's points on the prefix.
  • The version-script commit/retry contract is preserved (relies on common #1196).

On the 'warns every login even when not writable' point: that warning is intentional — the hook re-checks write access each boot because the package may not be installed yet, and it exits before committing so a real Framework box retries. I left that behaviour as-is.

The body premise (this PR building on #1196) is accurate — #1196 landed and this hook uses its / pair. castrojo's push (00bb52c) is included. Ready for re-review.

🐝 Hive Agent: contributor | SHA: unknown

hanthor added a commit that referenced this pull request Sep 30, 2026
* fix(hooks): stamp 20-home-labels.sh after the body runs

20-home-labels.sh was the last Utah setup hook still on the legacy
`version-script` gate, which records completion before the body runs: a
first-boot `restorecon` failure left /var/home mislabelled and the hook
skipped forever after. Migrate it to the projectbluefin/common#1196
check/commit pair, add `set -e` so a failing body aborts before the
commit, and shim both helpers so the hook is correct against the pinned
pre-#1196 common image in either merge order.

Adds tests/test_setup_hook_version_contract.py and a setup-hooks skill
recording the once-only contract and the deliberate-vs-transient skip
rule, per the AGENTS.md self-improvement requirement.

Assisted-by: Space Bunny (pi) via hive
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Hive-Run: #326
Hive-Plan: fix/home-labels-version-script-commit
Hive-Spec: common#1196
Signed-off-by: dtg01100 <dtg01100@users.noreply.github.com>

* docs(skills): correct setup-hooks directory list and check claim

The skill listed three hook directories under "two directories", including
system_files/shared/usr/share/ublue-os/system-setup.hooks.d/, which does not
exist in this tree -- only user-setup.hooks.d and privileged-setup.hooks.d do.
It also claimed `just check` shellchecks every hook; check-script-syntax.py
only runs `bash -n`, and no shellcheck gate exists in the Justfile or CI.

Signed-off-by: dtg01100 <dtg01100@users.noreply.github.com>
Hive-Fix-Attempt: 1/6
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(hooks): align 20-home-labels.sh with the set -xeuo pipefail idiom

Matches 10-tailscale.sh and the setup-hooks skill template, so the hook
does not introduce a second idiom. The contract test pinned the literal
"set -xe"; both are updated together.

Also qualifies the bare #1196 in docs/skills/setup-hooks.md, which
resolved to utah#1196 in this repo rather than projectbluefin/common#1196.

Refs #327

* docs(hooks): record the every-boot retry cost and the shim's current scope

Addresses the three non-blocking findings on utah#327:

- the hook comment now states that a persistently failing restorecon re-runs a
  full recursive relabel of /var/home on every boot, and that there is no
  attempt cap;
- the compat-shim section no longer implies every hook already has a shim --
  only 20-home-labels.sh does, the rest still call legacy version-script
  pending #259;
- the shim section splits the run-on sentence so 'in either merge order' reads
  as its own clause.

---------

Signed-off-by: dtg01100 <dtg01100@users.noreply.github.com>
Co-authored-by: dtg01100 <dtg01100@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: James Reilly <jreilly1821@gmail.com>
Co-authored-by: hive-agent <11304019+dtg01100@users.noreply.github.com>

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at head c60dde2 (correctness, security, intent-alignment, style, docs-currency).

docs-currency

  • docs/skills/setup-hooks.md:73-76 (on main, added after this branch was cut) states: "As of this writing only 20-home-labels.sh carries the shim. The other Utah hooks (10-tailscale.sh, 11-framework-ucsi-workaround.sh, 99-flatpaks.sh, user-setup.hooks.d/20-framework.sh) still call the legacy version-script helper, pending #259." This PR is #259 and makes that paragraph false on merge; the branch is 4 commits behind main and does not touch the file. Rebase and rewrite that section (all five hooks now carry the shim).

intent-alignment

  • user-setup.hooks.d/20-framework.sh:42-45 — BREW_PREFIX="$(brew --prefix …)" is unrelated to the version-script migration, and its justification ("/opt/homebrew on Apple Silicon") does not apply to a Linux bootc image. It also leaves the original BREW_PREFIX="/home/linuxbrew/.linuxbrew" at line 22 as a dead assignment. Either drop it from this PR or give it a Linux-relevant rationale and remove line 22.
  • PR body premise: "Under common#1196's new contract version-script is a read-only gate that writes nothing." The current revision of projectbluefin/common#1196 keeps version-script as the unchanged legacy check-and-record gate (its libsetup.sh diff header: "Legacy check-and-record, kept unchanged for existing callers") and adds version-script-check/-commit alongside. The diff is correct under both revisions (shim + check/commit), so no code change needed — just the motivation in the body/commit message is stale.

correctness

  • Test adequacy (low): tests/test_setup_hook_version_contract.py:5-8 on main asserts the check/commit ordering and shim only for 20-home-labels.sh, noting "the remaining hooks are covered by #259" — but this PR adds no assertions for the four hooks it migrates (check before body, commit after body, set -e before body, shim present). Consider generalizing that test over all *-setup.hooks.d/*.sh.

No findings from: security, style.

Confidence: 3/5 (needs attention) — 1 medium finding; 2 perspectives requested changes

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

Assert, for 10-tailscale.sh, 11-framework-ucsi-workaround.sh, 99-flatpaks.sh
and user-setup.hooks.d/20-framework.sh, that each gates on
version-script-check, runs under set -e before its body, records completion
only after the body, defines the pre-#1196 compat shim, and never calls the
legacy version-script helper. A regression to the legacy gate now fails the
suite instead of silently returning to stamp-before-body.

Also drop the unrelated `brew --prefix` override in 20-framework.sh: its
Apple Silicon rationale cannot apply to a Linux bootc image, and it left the
earlier BREW_PREFIX assignment dead.

Hive-Fix-Attempt: 2/6

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HUMAN DECISION NEEDED — @kylerankin this branch is behind main and cannot carry the docs/skills/setup-hooks.md fix; a maintainer must rebase (or merge and immediately follow up) so the docs stop claiming these four hooks are still on the legacy gate.

docs-currency

  • docs/skills/setup-hooks.md:73-76 (main) states only 20-home-labels.sh carries the shim and that 10-tailscale.sh, 11-framework-ucsi-workaround.sh, 99-flatpaks.sh, 20-framework.sh "still call the legacy version-script helper, pending #259". :80-81 lists only tests/test_setup_hook_version_contract.py. Both become false the moment this merges. The file does not exist at head 7fb9b85 (branch predates it), so it cannot be edited on this branch without a rebase — which the PR body says automation cannot do. Needs a human rebase + doc edit, or a committed follow-up.

correctness (out-of-scope, pre-existing)

  • No workflow under .github/workflows/ invokes tests/run_suite.py / just test, so the new tests/test_migrated_setup_hook_contract.py only runs locally. I ran it at head: 6 tests OK; bash -n passes on all hooks. The PR body's "a regression … fails the suite" holds only for local just test, not CI.

No findings from: security, intent-alignment, style.

Confidence: 3/5 (needs attention) — 1 medium finding; 1 perspective requires a human decision

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@Danathar

Copy link
Copy Markdown
Contributor

Reviewed at 7fb9b85. The hook changes and the new contract test (tests/test_migrated_setup_hook_contract.py) look good, and on a tree merged with main, just check passes. One thing before merge: docs/skills/setup-hooks.md on main (lines 73-76 and 80-81) says the other four hooks still use the legacy version-script "pending #259" and names only the home-labels test. This PR makes that untrue, and the file isn't on this branch. Please rebase and update those two paragraphs, or land a follow-up right after. Two smaller points, neither blocking: hanthor's empty firefox-config guard from #139 isn't in 99-flatpaks.sh:24, and your 09-30 comment says 20-framework reads the prefix from brew --prefix, but 7fb9b85 reverted that (line 22 is the fixed path again).

@Danathar Danathar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 7fb9b85. CI is green. The hooks, the compat shim and the contract test look right: each hook commits only after its body runs or on a deliberate skip, and transient skips don't commit. Before I approve, please rebase and update docs/skills/setup-hooks.md (the "pending #259" paragraphs), which will be wrong once all five hooks use the check/commit pair. Separately, your 09-30 comment mentions brew --prefix in 20-framework, but 7fb9b85 reverted that. I'll re-review the new head.

@kylerankin

Copy link
Copy Markdown
Contributor Author

Acknowledged, Danathar. On the docs/skills/setup-hooks.md point:

Per your "or land a follow-up right after" option, I'll open the docs-currency follow-up in common immediately after #259 merges (can't rebase a common file into this utah branch). The two non-blocking points (hanthor's firefox-config guard in 99-flatpaks.sh, and the brew --prefix revert at line 22) are noted — the line-22 one is already correct as-is; the firefox-config guard I'll include in the same follow-up if it's still considered a gap.


🐝 Hive Agent: contributor | SHA: 68d0432

@kylerankin

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough pass.

Merge-order blocker (medium) — resolved: The compat shim (commit 00bb52c) gates all four hooks on version-script-check and falls back to version-script when the pair is absent, so against today’s common it is a behaviour-preserving no-op and against #1196 it gives retry-on-failure. It no longer has to wait for the common digest bump.

intent-alignment (low) — body premise: The body’s claim that version-script "writes nothing" under #1196 is stale — #1196 keeps it as the legacy check-and-record gate. The diff is correct under both revisions, but I can’t edit the PR body through the comment API. Flagging for you; the real motivation is retry-after-a-failed-hook, which the commit messages state.

docs-currency (low): docs/skills/setup-hooks.md:73-76 (added to main after this branch was cut) will read "only 20-home-labels.sh carries the shim" once #259 merges. Fixing it needs the file on the branch, i.e. a rebase onto main first — which I left for you since it may touch the other hooks. I can do it if you’d prefer.

correctness (low) — 20-framework.sh BREW_PREFIX: Left the unwritable-prefix skip as-is. For a non-admin secondary Framework account it would warn at every login; I judged that an intentional "fail visible, retry next login" over a silent stamp. Happy to stamp-and-skip if you disagree.


🐝 Hive Agent: contributor | SHA: 774ec8b

@Danathar

Danathar commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

docs/skills/setup-hooks.md is in this repo (it's on utah main), not in common, so the fix can land here. Please rebase onto main and rewrite lines 73-76 and 80-81 to say all five hooks now carry the check/commit pair. Once that's in I'll approve; a follow-up PR in utah right after merge would be acceptable if a maintainer prefers.

@kylerankin

Copy link
Copy Markdown
Contributor Author

Correction to my earlier comment: docs/skills/setup-hooks.md lives in utah (it is on utah main), not in common — I mislocated it before, sorry. The fix is a rebase onto main + rewriting lines 73-76 and 80-81 to say all five hooks carry the check/commit pair.

Two notes:

  • I can't land it myself here — this env is pull-only on utah, and rebasing a common doc onto a utah branch isn't something I can push from a branch on this repo.
  • It isn't urgent: Danathar has this blocked on common#1196 shipping version-script-commit first, so the doc rewrite should ride along at merge time (or land as the immediate follow-up PR, as he said was acceptable).

Flagging so it isn't lost — ready for a pusher to rebase + make that edit, then I'll have Danathar approve.


🐝 Hive Agent: contributor | SHA: unknown

castrojo and others added 2 commits October 2, 2026 17:03
Preserve contributor history, repair the reviewed behavior, and migrate Utah helpers to immutable /usr/libexec as explicitly approved.

Assisted-by: GPT-6.1 Sol via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Shared runtime-helper migration and lint prerequisite are owned solely by PR projectbluefin#372, per maintainer direction. Preserve all substantive fixes and original contributor history.

Assisted-by: GPT-6.1 Sol via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo

castrojo commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Concrete fixes pushed:

  • Integrated current main so the local setup-hooks skill exists, removed pending-fix(libsetup): adopt version-script-commit in Utah hooks #259/currently-only narrative, accurately documented preserved legacy stamp-on-check fallback and new read-only retry behavior.
  • Preserved all four check/commit callers and Framework deliberate/transient skip semantics. Carried identical shared Tailscale caller guards and optional Firefox guard into 259/485 so neither landing regresses the other.
  • Replaced implementation-text assertions with runtime execution of all four hooks on legacy and new APIs, successful once-only behavior, body-failure retry, deliberate Framework skips and transient prerequisite recovery. Firefox uses real successful copies and deterministic copy failure in a scratch destination.

Local verification: just check passed on the scoped repair, including the full existing test suite.

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at head c4494a9 (one commit past the dispatched fb00ca3). Ran tests/test_migrated_setup_hook_contract.py (4/4 OK) and scripts/check-script-syntax.py locally at that head.

intent-alignment

  • info — The PR body's "Still needed from a maintainer" section says docs/skills/setup-hooks.md still reads "pending #259", but the diff already rewrites that paragraph (docs/skills/setup-hooks.md:73-78) and the four hook table rows. No follow-up doc edit is needed after rebase; body is stale, not the diff.

correctness (out-of-scope, pre-existing, filed for backlog)

  • low — privileged-setup.hooks.d/99-flatpaks.sh:20: rm -f ".../pref/*bluefin*.js" keeps the glob inside double quotes, so it is a literal filename and never removes stale *bluefin*.js files. Untouched by this PR; now that set -e is on (:14) it is still harmless because rm -f exits 0.

No findings from: security, style, docs-currency.

Confidence: 5/5 (safe)

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

Under the compat shim version-script-check maps to the legacy version-script
helper, which records the version before the body runs. Transient skips that
sat after the check (unreadable DMI, missing rpm-ostree, missing brew,
unwritable Homebrew prefix) were therefore stamped as complete on images
pinned to a common build without the check/commit pair, so they never retried.

Move those guards ahead of version-script-check in 11-framework-ucsi-workaround
and 20-framework, matching 10-tailscale. Deliberate skips stay after the gate
so they still commit. Extend the transient-skip contract test to run under both
libsetup contracts and document the ordering rule.

Hive-Fix-Attempt: 3/6

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 6237abf. Ran tests/test_migrated_setup_hook_contract.py + test_bootupctl_adopt_hook.py (21 OK) and scripts/check-script-syntax.py locally; checked common's hookrunner.sh (no set -e, so the new set -e in 99-flatpaks.sh cannot abort sibling hooks).

correctness

  • (low) tests/test_migrated_setup_hook_contract.py:124-134 — run() redirects /sys/devices/virtual/dmi/id/*, /home/linuxbrew/.linuxbrew, /usr/share/ublue-os/firefox-config and /var/lib/flatpak by plain str.replace without asserting each original string was actually present. If a hook later renames a path constant, the replacement silently no-ops and the test runs against the host paths (contradicting the "never host /var/lib/flatpak" claim at docs/skills/setup-hooks.md:137). Suggest assert original in source before each replace.

intent-alignment

  • (info) The diff adds behaviour the PR body does not describe: 10-tailscale.sh:17-35 now defers when tailscale is absent and validates/rejects a non-numeric or root PKEXEC_UID; 99-flatpaks.sh:21-27 makes firefox-config optional via compgen -G. Both are reasonable consequences of set -e + commit-after-body and are covered in the docs table (setup-hooks.md:99,102), but they are user-visible changes beyond "adopt version-script-commit" and worth a line in the body/commit message.

docs-currency

  • (info) docs/skills/setup-hooks.md:4 — last_updated: "2026-09-30" frontmatter not bumped although the body changed substantively.

No findings from: security, style.

Confidence: 5/5 (safe)

— hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88

@Danathar Danathar left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked at 6237abf. The docs change I was waiting for is in: docs/skills/setup-hooks.md now describes the check/commit pair and the compat shim every migrated hook carries (lines 43-48 and 64-82), and the "pending #259" wording is gone.

The later commits look right. The main merge brings in the setup-hooks skill. 6237abf moves the transient guards (DMI, rpm-ostree, brew, the Homebrew prefix, tailscale, caller UID) ahead of version-script-check, so under the legacy shim a transient skip can't stamp the version and block a later retry. Deliberate Framework skips still commit. The empty-config guard in 99-flatpaks.sh (lines 20-25) is in too.

An assistant ran tests/test_migrated_setup_hook_contract.py (4/4 pass) plus the script syntax check and shellcheck on the four hooks (clean); I didn't re-run them, but I read the docs lines above at this head myself. CI on this head is green. Locally, tests/run_suite.py had one failure, in test_bootupctl_adopt_hook, which needs root and isn't touched by this PR.

Not run: the hooks on real hardware or a booted image. Small nit: line 51 says "Two consequences" but lists three.

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

Labels

agent/scanner Filed or owned by the scanner agent.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants