From 8fee35a6ad59a601ebd3181a78ce2e05a0e15c3e Mon Sep 17 00:00:00 2001 From: garrytan Date: Tue, 3 Nov 2026 08:12:14 +0000 Subject: [PATCH] fix: keep an unreadable identity unknown, keep a converted hold's age, and document each run's 120-minute bound (GST-1205 review round 2) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- bin/gstack-lease | 8 ++++---- changelog.d/gst-1205-upgrade-lease.md | 2 +- docs/capy-install.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/gstack-lease b/bin/gstack-lease index 1efc45145..8fe9a0139 100755 --- a/bin/gstack-lease +++ b/bin/gstack-lease @@ -11,7 +11,8 @@ # gstack-lease touch [--root ] [--pid

| --from ] [--run ] # write /gstack-leases/ holding the pid's start identity # and the open run (gstack-skill-start's SESSION_ID); without --run -# it records a hold no release closes; a run or hold counts 120 min; +# it records a hold no release closes; a run counts 120 min from its +# start and a hold 120 min from its last renewal; # pid defaults to the harness pid behind this call # (bin/gstack-harness-pid.sh, the same derivation the session marker # uses), or behind --from (a caller whose own parent is short-lived @@ -67,7 +68,7 @@ while [ $# -gt 0 ]; do done case "$VERB" in touch|live|list|release) ;; - -h|--help|'') sed -n '2,33p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + -h|--help|'') sed -n '2,34p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; *) echo "gstack-lease: unknown verb '$VERB'" >&2; exit 2 ;; esac [ -n "$ROOT" ] || ROOT=$(gstack_source_root "$BIN") @@ -280,7 +281,6 @@ case "$VERB" in } _tmp="$DIR/.$PID.$$" _id=$(identity "$PID") _keep="" _held=0 _now=$(date +%s) - [ -n "$_id" ] || _id=$(head -1 "$DIR/$PID" 2>/dev/null) if [ -f "$DIR/$PID" ] && [ "$(head -1 "$DIR/$PID" 2>/dev/null)" = "$_id" ]; then if [ -n "$RUN" ]; then _keep=$(fresh "$DIR/$PID" "run $RUN"); else _keep=$(fresh "$DIR/$PID" hold); fi [ -z "$(sed -n '2,$p' "$DIR/$PID" 2>/dev/null | grep -v '^$')" ] && _held=1 @@ -289,7 +289,7 @@ case "$VERB" in printf '%s\n' "$_id" [ -z "$_keep" ] || printf '%s\n' "$_keep" if [ -n "$RUN" ]; then - [ "$_held" -eq 1 ] && echo "hold $_now" + [ "$_held" -eq 1 ] && echo "hold $(stat -c %Y "$DIR/$PID" 2>/dev/null || stat -f %m "$DIR/$PID" 2>/dev/null || echo "$_now")" echo "run $RUN $_now" elif [ -n "$_keep" ]; then echo "hold $_now" fi diff --git a/changelog.d/gst-1205-upgrade-lease.md b/changelog.d/gst-1205-upgrade-lease.md index 22ec018c0..babaa140a 100644 --- a/changelog.d/gst-1205-upgrade-lease.md +++ b/changelog.d/gst-1205-upgrade-lease.md @@ -1,3 +1,3 @@ ### Fixed -- **A finished /ship no longer blocks `gstack-upgrade` for two hours (GST-1205).** Each `gstack-skill-start` writes a workflow lease that `gstack-upgrade` checks before moving a shared checkout. Nothing released it when the workflow ended, and on Capy every session's lease names the machine's one `capy-server`. So after a /ship finished, its own lease kept refusing the upgrade with UPGRADE_BUSY until it was 120 minutes old, unless you set `GSTACK_UPGRADE_FORCE=1`. Now `gstack-skill-start` records its `SESSION_ID` as an open run on the lease, and `gstack-skill-end` closes it with the new `gstack-lease release`. Once every run on a lease is closed, the lease is idle and blocks nothing (`gstack-lease list` shows `idle`). A run another session still has open keeps blocking. So does a holder that records no run (an older gstack, or `gstack-lease touch` without `--run`, which now leaves a `hold` entry that no release removes). A run that never reaches `gstack-skill-end` stops counting 120 minutes after its last renewal, even while other sessions keep renewing the lease. +- **A finished /ship no longer blocks `gstack-upgrade` for two hours (GST-1205).** Each `gstack-skill-start` writes a workflow lease that `gstack-upgrade` checks before moving a shared checkout. Nothing released it when the workflow ended, and on Capy every session's lease names the machine's one `capy-server`. So after a /ship finished, its own lease kept refusing the upgrade with UPGRADE_BUSY until it was 120 minutes old, unless you set `GSTACK_UPGRADE_FORCE=1`. Now `gstack-skill-start` records its `SESSION_ID` as an open run on the lease, and `gstack-skill-end` closes it with the new `gstack-lease release`. Once every run on a lease is closed, the lease is idle and blocks nothing (`gstack-lease list` shows `idle`). A run another session still has open keeps blocking. So does a holder that records no run (an older gstack, or `gstack-lease touch` without `--run`, which now leaves a `hold` entry that no release removes). Each run counts for 120 minutes from its own start, so one that never reaches `gstack-skill-end` stops blocking on time even while other sessions keep starting. A nested skill's own run covers it while it runs, but other sessions' starts no longer extend a run past its 120 minutes. diff --git a/docs/capy-install.md b/docs/capy-install.md index 8fabc8b78..6f0feef46 100644 --- a/docs/capy-install.md +++ b/docs/capy-install.md @@ -187,7 +187,7 @@ run from inside a workflow (/ship's docs step running `install.sh --for document-release`, #3571) prints `SELF_UPGRADE: skipped (a gstack run in this session holds a workflow lease on this installation: ... (UPGRADE_BUSY))`, leaves the checkout where the run started and stays ok with `behind=`. Each -`gstack-skill-start` renews the lease and records its `SESSION_ID` as an open run; `gstack-skill-end` closes that run, and a lease whose runs are all closed is idle and blocks nothing, so a finished /ship no longer holds the upgrade back (GST-1205). A lease with no recorded run (written without `--run`, or by an older gstack) counts as before. On Capy the leased pid is the machine's +`gstack-skill-start` renews the lease and records its `SESSION_ID` as an open run; `gstack-skill-end` closes that run, and a lease whose runs are all closed is idle and blocks nothing, so a finished /ship no longer holds the upgrade back (GST-1205). Each run counts for 120 minutes from its own start, whatever other sessions renew. A lease with no recorded run (written without `--run`, or by an older gstack) counts as before. On Capy the leased pid is the machine's long-lived `capy-server`, so the deferral ends when the lease turns 120 minutes old, not when the process exits. Every session on the machine runs under that same `capy-server`, so `bin/gstack-upgrade` run by hand also