flare-upstream-watch.sh 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/env bash
  2. # Watch NVIDIA/spark-local-inference upstream (renamed from
  3. # `flare-local-inference` on 2026-11-03; the old name redirects, so an older
  4. # clone keeps working).
  5. #
  6. # OUR RUNTIME PIN is not just the upstream HEAD: the prod lanes build
  7. # `main` + PR #184 ("Run parallel Engram disk workers on Linux with io_uring
  8. # lanes") — branch `pr184-on-main`, which is what the agent binary on the
  9. # nodes runs. When bumping the pin, rebase that branch onto the new HEAD,
  10. # rebuild, and reinstall on EVERY rank node (a mixed set fails at rendezvous
  11. # with "incompatible protocol"). Why that patch exists:
  12. # specs/tech-architecture/flare-roce-poison.md.
  13. #
  14. # FLARE moves several times a day (12+ commits in one night), and our clones,
  15. # the per-host agent binaries and the prepared packages all have to agree with
  16. # it: the RoCE proxy ABI is pinned in the repo, the model recipes change, and a
  17. # package prepared with one revision can be refused by another.
  18. #
  19. # scripts/flare-upstream-watch.sh # what changed since the pin
  20. # scripts/flare-upstream-watch.sh --bump # move the pin to current HEAD
  21. #
  22. # The pin lives next to this file's spec (specs/tech-architecture/
  23. # flare-upstream.pin) as a single line: <sha> <committer-date>.
  24. set -euo pipefail
  25. REPO="NVIDIA/spark-local-inference"
  26. ROOT="$(cd "$(dirname "$0")/.." && pwd)"
  27. PIN_FILE="$ROOT/specs/tech-architecture/flare-upstream.pin"
  28. API="https://api.github.com/repos/$REPO"
  29. pin_sha=""
  30. pin_date=""
  31. if [[ -f "$PIN_FILE" ]]; then
  32. read -r pin_sha pin_date <"$PIN_FILE" || true
  33. fi
  34. json="$(curl -fsSL -m25 "$API/commits?per_page=100")"
  35. head_sha="$(printf '%s' "$json" | python3 -c 'import json,sys; print(json.load(sys.stdin)[0]["sha"])')"
  36. head_date="$(printf '%s' "$json" | python3 -c 'import json,sys; d=json.load(sys.stdin)[0]["commit"]["committer"]; print(d["date"][:16])')"
  37. echo "upstream: $REPO"
  38. echo " HEAD ${head_sha:0:10} $head_date"
  39. echo " pinned ${pin_sha:0:10} ${pin_date:-never}"
  40. if [[ "${1:-}" == "--bump" ]]; then
  41. printf '%s %s\n' "$head_sha" "$head_date" >"$PIN_FILE"
  42. echo " pin moved to ${head_sha:0:10}"
  43. exit 0
  44. fi
  45. if [[ -z "$pin_sha" ]]; then
  46. echo " no pin recorded — run with --bump after reviewing"
  47. exit 0
  48. fi
  49. if [[ "$pin_sha" == "$head_sha" ]]; then
  50. echo " up to date"
  51. exit 0
  52. fi
  53. echo
  54. echo "new commits since the pin:"
  55. TMP_JSON="$(mktemp)"
  56. trap 'rm -f "$TMP_JSON"' EXIT
  57. printf '%s' "$json" >"$TMP_JSON"
  58. python3 - "$pin_sha" "$TMP_JSON" <<'PY'
  59. import json, re, sys
  60. pin = sys.argv[1]
  61. commits = json.load(open(sys.argv[2]))
  62. SIGNIFICANT = re.compile(
  63. r"roce|abi|flashinfer pin|speculat|dspark|dflash|mtp|recipe|deepseek|glm"
  64. r"|mimo|qwen|kimi|package|prepare|export|agent|orbit",
  65. re.I,
  66. )
  67. stopped = False
  68. for c in commits:
  69. sha = c["sha"]
  70. if sha == pin:
  71. stopped = True
  72. break
  73. msg = c["commit"]["message"].splitlines()[0]
  74. date = c["commit"]["committer"]["date"][:16]
  75. flag = " ⚠" if SIGNIFICANT.search(msg) else " "
  76. print(f"{flag} {sha[:10]} {date} {msg[:110]}")
  77. if not stopped:
  78. print("(pin is older than the 40 commits listed — fetch more)")
  79. PY
  80. cat <<'EOF'
  81. Before re-running a FLARE experiment, pull and rebuild BOTH sides — the
  82. per-host `flare` agent binaries and the prepared packages must come from the
  83. same revision, or the runtime refuses (see the "proxy ABI" row in
  84. specs/tech-architecture/flare-bringup.md).
  85. EOF