Skip to content

v1.40.0.0 migration writes done-marker even when jq is missing, leaving privacy-map unpatched #1581

@drmusayilmaz

Description

@drmusayilmaz

Summary

gstack-upgrade/migrations/v1.40.0.0.sh unconditionally touches its done-marker (~/.gstack/.migrations/v1.40.0.0.done) at the end of the script — even when the .brain-privacy-map.json patch was skipped because jq is missing. The migration logs only a WARN: line during a noisy ./setup, and subsequent /gstack-upgrade invocations no-op against the done-marker without re-checking, so the privacy-map repair never actually lands unless the user spots the warning, installs jq, manually removes the marker, and re-runs.

Repro

  1. Box without jq installed (e.g., Debian 12 without jq from apt).
  2. Upgrade from any pre-1.40 gstack to v1.40.0.0.
  3. ./setup runs the migration and emits:
    [v1.40.0.0] WARN: jq not found; skipping privacy-map repair. Install jq and re-run gstack-upgrade, or run gstack-artifacts-init manually.
    
  4. Then unconditionally touches ~/.gstack/.migrations/v1.40.0.0.done.
  5. Install jq and re-run /gstack-upgrade (or the migration script directly) — the script short-circuits at [ -f "${DONE}" ] && exit 0 and never patches the privacy-map.

.brain-allowlist and .gitattributes were patched on the first pass (no jq needed there), so the inconsistency is silent: federation sync still drops /plan-eng-review test plans because the privacy-map class is missing, but allowlist/gitattributes look fine.

Workaround

sudo apt install jq
rm ~/.gstack/.migrations/v1.40.0.0.done
bash ~/.claude/skills/gstack/gstack-upgrade/migrations/v1.40.0.0.sh

After this, jq '[.[] | select(.pattern | test("eng-review-test-plan"))]' ~/.gstack/.brain-privacy-map.json returns the artifact-class entry.

Suggested fix

Two options, pick one:

  1. Defer touch "${DONE}" until all three target files are either patched or confirmed up to date. Track per-file success; only mark done when nothing was skipped. The "fresh-init user with nothing to patch" path stays a no-op because all three if ! grep -Fq ... / if ! jq -e ... gates report "already present."

  2. Use a per-prerequisite marker. When jq is missing, write v1.40.0.0.jq-missing instead of v1.40.0.0.done. The migration runner treats .jq-missing as "retry on next run" and only promotes it to .done once jq is found and the patch lands.

Option 1 is simpler and matches the existing single-marker scheme; Option 2 is more general and would help future migrations with optional-tool dependencies.

Either way, the WARN: line should probably also surface louder — ./setup output is long enough that a single warning line scrolls past easily.

Environment

  • gstack v1.40.0.0 (upgraded from v1.39.1.0)
  • Debian 12 / Linux 6.1, install_type=global-git
  • jq not installed at upgrade time; installed after the fact

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions