Skip to content

feat: show storage quota and maintenance-shortened sessions in the notice line - #11

Merged
jayhesselberth merged 1 commit into
mainfrom
worktree-quota-and-maint-panel
Aug 26, 2026
Merged

feat: show storage quota and maintenance-shortened sessions in the notice line#11
jayhesselberth merged 1 commit into
mainfrom
worktree-quota-and-maint-panel

Conversation

@jayhesselberth

Copy link
Copy Markdown
Member

Two things a session should tell you about itself and until now did not: that
your writes are about to start failing, and that the allocation you got is not
the one you asked for.

Closes #8.

The notice line

Rendered from the real functions, with live numbers:

━━━━━━━━━━━━━━━━━━━━━━━━━ ⚠ OVER QUOTA  30.2T / 30T · over by 204.8G ━━━━━━━━━━━━━━━━━━━━━━━━━

━ ⚠ OVER QUOTA  30.2T / 30T · over by 204.8G │ SHORT SESSION · ends before monthly-maint at Thu 06:00 ━

━━━━━━━━━━━━━━━━━━━ SHORT SESSION · ends before monthly-maint at Thu 06:00 ━━━━━━━━━━━━━━━━━━━

It is now ranked rather than single-purpose: over-quota (red) outranks a
short session (yellow), which outranks the scrolling Claude Code hint. The
first two are static — a marquee is right for an invitation and wrong for a
warning — and share the line when both apply, since both stay true for the
whole session. A session showing a static warning also stops paying for the
marquee's 0.3s redraw.

Quota, without the head node

quota_check lives only on amc-bodhi, so the obvious implementation is
ssh head quota_check on a timer — every session depending on passwordless
SSH back to a host it has no other reason to talk to.

It turns out not to be necessary. The hard limit is a shared file, and the
daemons that know usage listen to the compute nodes directly, answering
QUOTA <uid> with OK <kilobytes> per target. So a session just asks. The
whole probe is bash and /dev/tcp, takes about a second, and reproduces
quota_check -b exactly:

$ sinteractive --check-quota
OVER QUOTA: 30.2T of 30T used (100.7%), over by 204.8G

$ quota_check -b          # on the head node, for comparison
jhessel    30.2T    30T    100.7%

Cached per user, not per session — quota is a property of the account and
you often have six sessions open; one probe per interval serves all of them.

--check-quota rewrites the cache and pokes every session, so the warning
clears within a tick rather than at the end of the ten-minute poll. That is
the command to hand an agent that has just deleted something: leaving a stale
warning on your screen makes it look like the deletion did not work. The
bodhi-storage skill and --agent-context now both say so.

Verified end to end on a live session — simulating freeing space cleared the
red notice within 8 seconds, and restoring the real limit brought it back.

Maintenance: trim, don't refuse

Slurm defers a job that would run into a reservation until the window closes,
so at the default day-long request a session simply stops starting as
maintenance approaches. The previous code caught this and printed the shorter
command to run instead — correct, but it hands the arithmetic back to you at
the moment you wanted a shell:

# before
$ sinteractive --time=30h
Error: --time=1-06:00:00 conflicts with scheduled maintenance.
  ...shorten --time to fit before maintenance:
  sinteractive --time=17h

# after
$ sinteractive -n analysis
Maintenance (monthly-maint) starts Thu Aug 27 06:00.
Shortened the request from 24:00:00 to 17:10:43 so the session ends before it.

Confirmed the granted allocation matches: TIME_LIMIT 17:11:00. A request
that already fits is left alone (a --time=1h launch got its full hour and no
notice), a launch is refused when under 10 minutes remain, and an explicit
--reservation is untouched.

Two bugs found by testing against the cluster

  • next_maintenance_window printed without a trailing newline, so read
    reported failure after setting its variables and the || return 0 skipped
    trimming entirely. A one-day request was not being shortened at all.
  • quota_probe queried the daemons before reading the quota file. Bash's
    /dev/tcp has no connect timeout, so where those addresses are unroutable
    this could stall the status loop for minutes. The local file read now gates
    the network half — somewhere without the quota file never opens a socket.

Portability

Every input is overridable (SINTERACTIVE_QUOTA_FILE, _HOSTS, _PORT,
_TIMEOUT, _POLL) and every failure is silent, so a cluster that does its
quotas differently never shows the notice.

All four validate.yml gates pass locally.

🤖 Generated with Claude Code

…tice line

Two things a session should tell you about itself and until now did not: that
your writes are about to start failing, and that the allocation you got is not
the one you asked for.

Quota. Bodhi's quota_check lives only on the head node, so the obvious
implementation is `ssh head quota_check` on a timer — every session depending
on passwordless ssh back to a host it has no other reason to talk to. It turns
out not to be necessary. The hard limit is a shared file, and the daemons that
know usage listen to the compute nodes directly, answering "QUOTA <uid>" with
"OK <kilobytes>" per target. So a session can just ask: the whole probe is
bash and /dev/tcp, takes about a second, and reproduces quota_check -b's
numbers exactly (30.2T of 30T, 100.7%).

The result is cached per user rather than per session. Quota is a property of
the account and a user often has six sessions open; there is no sense in each
of them interrogating nine daemons on its own schedule. One probe per interval
serves all of them, and --check-quota rewrites the cache and pokes every
session so the warning clears within a tick rather than at the end of the
ten-minute poll. That is the command to hand an agent that has just deleted
something: leaving a stale warning on the user's screen makes it look like the
deletion did not work. The bodhi-storage skill and --agent-context now both
say so.

Maintenance. Slurm will not start a job that runs into a reservation; it
defers it until the window closes, which can be a day or more. At the default
day-long request a session therefore just stops starting as maintenance
approaches, with no obvious reason. The previous code caught this and printed
the shorter command to run instead, which is correct but hands the arithmetic
back to the user at the moment they wanted a shell. It now trims the request
to fit and says so, and the session carries the fact for its whole life rather
than only in launch output that scrolls away.

The notice line is now ranked rather than single-purpose: over-quota (red)
outranks a short session (yellow), which outranks the scrolling Claude hint.
The first two are static — a marquee is right for an invitation and wrong for
a warning — and share the line when both apply, since both stay true for the
whole session. A session showing a static warning also stops paying for the
marquee's 0.3s redraw.

Two bugs found by testing against the live cluster rather than by reading:

  - next_maintenance_window printed without a trailing newline, so `read`
    reported failure after setting its variables and the `|| return 0` skipped
    trimming entirely. A one-day request was not being shortened at all.
  - quota_probe queried the daemons before reading the quota file. Bash's
    /dev/tcp has no connect timeout, so on a cluster where those addresses are
    unroutable this could stall the status loop for minutes. The local file
    read now gates the network half, and somewhere without the quota file
    never opens a socket.

Every input is overridable (SINTERACTIVE_QUOTA_FILE, _HOSTS, _PORT, _TIMEOUT,
_POLL) and every failure is silent, so a cluster that does its quotas
differently simply never shows the notice.

Closes #8.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jayhesselberth
jayhesselberth merged commit 6bf329f into main Aug 26, 2026
1 check passed
@jayhesselberth
jayhesselberth deleted the worktree-quota-and-maint-panel branch August 26, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Warn in the pane border when over storage quota (blocked: quota_check is login-node only)

1 participant