Skip to content

[cuebot] Fix issue on getWhatDependsOn(Frame) (#2278) - #1

Open
aghiles wants to merge 100 commits into
masterfrom
claude/gifted-clarke-0vluzy-v2
Open

[cuebot] Fix issue on getWhatDependsOn(Frame) (#2278)#1
aghiles wants to merge 100 commits into
masterfrom
claude/gifted-clarke-0vluzy-v2

Conversation

@aghiles

@aghiles aghiles commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Related Issues

Fixes AcademySoftwareFoundation#2277

Summarize your change.

Summary by CodeRabbit

  • Chores
  • Reformatted internal database access code for improved consistency and
    readability. No functional changes or impact to user-facing features.

Review Change Stack

DiegoTavares and others added 30 commits May 11, 2026 19:08
…ion#2278)

## Related Issues

Fixes AcademySoftwareFoundation#2277 

## Summarize your change.

- 86664de Fixes the indentation to make queries legible
- ea5abd0 Fixes a bug on the `GET_WHAT_DEPENDS_ON_FRAME` query. Ready
AcademySoftwareFoundation#2277 for more details

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Reformatted internal database access code for improved consistency and
readability. No functional changes or impact to user-facing features.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2278)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summarize your change.

Queries were wrapped with `// spotless: off/on` to allow formatting them
for legibility.

The content of queries has been checked to ensure they contain exactly
the same string as before.

## LLM usage disclosure

Claude Opus was used to apply the changes and to write a scrip that
confirmed the string content is exactly the same.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Style**
* Reformatted SQL statement constants across the database access layer
for improved code readability and formatting consistency.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2297)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…olumn in two (AcademySoftwareFoundation#2313)

## Related Issues
- AcademySoftwareFoundation#2314

## Summarize your change.

Bug: Down host or misreporting hosts can publish free > total (seen on
DOWN hosts where /mcp metrics were never refreshed), which makes used
negative and the free-fill rect extend past the cell - bleeding the
bar's green into the columns to the left.

New changes:

1) Bug fix: Temp bar overflow
- `_paintDifferenceBar` computed `used = total - free`, which became
negative when stale hosts published `free > total`.
- The free-fill rect was then built with `rect.adjusted(<negative>, 0,
0, 0)`, shifting its left edge beyond the cell boundary.
- Since the Temp delegate paints last in the row, its green free portion
bled leftward across Idle Memory, Total Memory, GPU Memory, Physical,
and Swap, causing the "green bar spanning many columns".
- Clamp `used` to `[0, total]` so misreporting hosts render as fully
free (all green) without overflowing the cell.
- Add `painter.setClipRect(rect)` as a safeguard so future arithmetic
issues cannot paint outside the intended cell.
- Tighten the early-return guard to also bail when `total <= 0`.

2) New improvement: "Temp Free" column split
- The combined "Temp Free" column value (e.g.: 23.5G (50%)) display made
it difficult to sort by absolute free space. Sorting by percentage could
rank a `1.0G / 100%` host above a `900G / 45%` host, which is
counterproductive when scanning for actual available headroom.
- Replace the single Temp Free column with two: a) "Temp Free" (e.g.
`"23.5G"`), sorted by "free_mcp" and b) "Temp Free %" (e.g. `"50%"`),
sorted by usage ratio and left empty when "total_mcp" is unknown
- The adjacent Temp bar continues to sort by ratio for visual
continuity.
- `_formatTempCell` is replaced by `_formatTempFreeAmount` and
`_formatTempFreePercent`.

3) Column width tuning: Increase default widths for columns that were
truncating content under production fonts:
- GPU Memory
- Total Memory
- Idle Memory
- Temp Free
- Temp Free %
- Idle Cores
- Idle GPUs
- GPU Mem
- GPU Mem Idle
- Ping
- Hardware
- Locked
- ThreadMode
- Header labels and common values now fit without clipping or hover-only
visibility, making Monitor Hosts easier to scan.

4) Update tests:
- Replace `_formatTempCell` tests with dedicated helper coverage:
- Amount renders even when total is unknown
- Percentage rounds to the nearest integer
- Percentage remains empty when total is unavailable
- Add a delegate-wiring assertion for the new `Temp Free %` column at
index `10`.

Docs:
- Update `cuecommander-administration-guide.md` to document all three
Temp-related columns (`Temp`, `Temp Free`, `Temp Free %`) and their
sorting behavior.
…ior (AcademySoftwareFoundation#2316)

## Related Issues
- AcademySoftwareFoundation#2314

## Summarize your change.
Revise the 'Temp Free' and 'Temp Free %' columns tooltip to reflect
percentage-based /mcp/ free space reporting, ratio-based sorting, and
empty values when total /mcp/ size is unavailable.
…wareFoundation#2321)

The windows-tests job was timing out because every PR rebuilt all of
rqd's transitive deps from scratch on a slow Windows runner, with no job
timeout (default 6h).

.github/workflows/rust-pipeline.yml:
- Add Swatinem/rust-cache@v2 to all four jobs so target/ and the
registry are reused across runs (typically 5-10x faster on Windows after
the first build).
- Add timeout-minutes per job (30-60 min) so stalled runs fail fast.
- Set CARGO_INCREMENTAL=0 (no upside on ephemeral CI, hurts clean
builds) plus CARGO_NET_RETRY / RUSTUP_MAX_RETRIES = 10 for Windows
registry flakiness.
- Split windows-tests into `cargo test -p rqd --no-run` then `cargo test
-p rqd` so compile-vs-run timing is obvious and the cache lands even
when a test fails.
- Drop `--verbose` from the Windows jobs . Log volume noticeably slows
Windows runners.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Updated CI/CD pipeline configuration to improve build reliability and
performance through enhanced caching mechanisms and retry
configurations.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2321)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Fixes AcademySoftwareFoundation#2311


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Corrected exit signal computation for Docker containers when exit
codes exceed standard thresholds.
* Fixed exit-status interpretation on Unix systems for proper signal
detection.

* **Tests**
* Added validation tests for exit-status handling across container and
Unix environments.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2312)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
The application os not properly closing the grpc channel at shutdown,
leaving this SEVERE warning:

```
Channel ManagedChannelImpl{logId=2787, target=elk0815:8444} was not shutdown properly
```

Explanation:

`RqdClientGrpc`
(cuebot/src/main/java/com/imageworks/spcue/rqd/RqdClientGrpc.java:71-89)
holds a Guava `LoadingCache<String, ManagedChannel>`. The
`removalListener` calls `conn.shutdown()` **on cache eviction** — but
never on application shutdown. The bean has no `destroy-method`
(applicationContext-service.xml:39, no destroy hook), and
`RqdClientGrpc` has no `shutdown()` method at all. So when cuebot stops:

- The cache is GC'd
- Each `ManagedChannel` is finalized **without** `shutdown()` having
been called
- gRPC logs `SEVERE: Channel ... was not shutdown properly!!!` per
leaked channel, with the stack capturing where the channel was first
allocated (the `RuntimeException: ManagedChannel allocation site` —
that's a diagnostic stack, not a real exception)


## LLM usage disclosure

Claude Opus was used for investigating the origin of the log and
proposing a fix


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved application shutdown procedure to properly clean up network
resources and prevent potential resource leaks during shutdown.
* Enhanced shutdown sequencing to ensure proper initialization and
cleanup order of internal services.

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2274)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…d Frame (AcademySoftwareFoundation#2325)

## Related Issues
- AcademySoftwareFoundation#2319

## Summarize your change.

Exposes when an object became eligible to run (left DEPEND for WAITING,
or the job's submission time when never blocked) so callers can measure
how long a frame waited to be picked up by a render proc:

wait_for_pickup = frame.startTime() - frame.eligibleTime()

Proto files
- Adds `eligible_time` field to Frame, Job, NestedJob, and Layer.

Cuebot
- V41 migration adds `ts_eligible` column to the frame, layer, and job
tables.
- `layer.ts_eligible` and `job.ts_eligible` default to
`current_timestamp`; existing rows are backfilled from `job.ts_started`.
- Extends the existing DEPEND -> WAITING trigger so it stamps
`frame.ts_eligible` whenever a frame unblocks.
- V42 migration adds a SETUP -> WAITING trigger to stamp `ts_eligible`
on the path frames actually take through Cuebot (frames are inserted as
SETUP and bulk-transitioned to WAITING by
`JobManagerService.activateJob`, so V41's BEFORE INSERT trigger never
fires in practice).
- V42 also backfills `ts_eligible` for frames that already made the
SETUP -> WAITING jump before this migration ran.
- `WhiteboardDaoJdbc` and `NestedWhiteboardDaoJdbc` map the column into
the proto's `eligible_time` via a `getEligibleTimeInEpoch` helper,
falling back to the job's submission time when `ts_eligible` is NULL
(frames still in DEPEND).

PyCue
- Adds `Frame.eligibleTime()`.
- Adds `Job.eligibleTime(format=None)` and
`Layer.eligibleTime(format=None)`, mirroring the format-string behavior
of `Job.startTime()`.
- Propagates `eligible_time` through `NestedJob.asJob()`.
- New unit tests cover all four wrappers.

CueGUI
- Adds an "Eligible Time" column to `FrameMonitorTree`.
- Adds an "Eligible" column to `JobMonitorTree` and `LayerMonitorTree`.
- "Eligible" was chosen over "Available" because the latter can imply
the object will run next, when other gates (resources, paused state,
etc.) may still block dispatch.

Docs
- Adds `eligibleTime` to the Job and Frame REST API reference schemas
and example payloads.
- Documents the new monitor-tree columns in the Cuetopia monitoring
guide.
…hinx_docs.sh (AcademySoftwareFoundation#2334)

## Summarize your change.

- The `aswf/ci-opencue:2023` container has no `pip` binary on PATH, so
the job failed with `pip: command not found`.
- Switch both `pip install` calls to `python -m pip install`, matching
`ci/run_python_tests.sh`.
…SRF) (AcademySoftwareFoundation#2332)

## Related Issues
- AcademySoftwareFoundation#2333

## Summarize your change.

- Upgrade `next` from ^14.2.35 to ^15.5.18 (resolves to 15.5.18) to fix
GHSA-c4j6-fc7j-m34r: self-hosted Next.js Node server can proxy crafted
WebSocket upgrade requests to arbitrary internal/external destinations,
enabling SSRF against cloud metadata endpoints and internal services.
- Upgrade `eslint-config-next` from 14.0.4 to ^15.5.18 to align with the
Next.js major version.
- Regenerate `package-lock.json` so `npm ci` in Docker resolves the
patched dependency tree correctly.
- Address Next.js 15 breaking change: `next/dynamic` no longer supports
`ssr: false` inside Server Components. Moved client-only `DataTable`
dynamic import into `app/jobs/data-table-client.tsx`, marked with `"use
client"`, and imported it from `app/page.tsx` to preserve behavior.
- Verified `npm run build` and clean `docker compose build --no-cache
cueweb` both succeed; container starts and serves correctly on :3000.

Not affected: CueWeb does not use `next/headers`, `next/cache`,
middleware, `unstable_*` APIs, or async `params`/`searchParams`, so no
additional Next 15 migration changes were required.

See:
https://cybersecuritynews.com/next-js-vulnerability-exposes-credentials/

Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>
Co-authored-by: Filipe Lacerda <tifilipebr@gmail.com>
…demySoftwareFoundation#2335)

## Related Issues
Fixes AcademySoftwareFoundation#2284 

## Summary
Adds a bell icon per job row in the cueweb jobs table. Clicking
subscribes the browser to a system notification when the job reaches
FINISHED. State is stored in localStorage. An app-wide poller checks
subscribed jobs every 15 seconds and fires browser notifications via the
Web Notifications API.

The bell has three visual states:
  - **Outline bell**: not subscribed &rarr; click to subscribe
  - **Filled bell**: subscribed, waiting &rarr; click to cancel
- **Filled bell + green dot**: notification fired &rarr; click to clear

The bell is disabled (faded, with tooltip) on jobs that are already
FINISHED when first viewed.

## Screenshots
### 1. First-click permission prompt
<img width="800" alt="browser permission prompt on first subscribe"
src="https://github.com/user-attachments/assets/69544b4a-b219-4fd0-8de9-4448f7760ffc"
/>

### 2. Subscribed (bell turns filled)
<img width="800" alt="bell shows filled BellRing icon after subscribe"
src="https://github.com/user-attachments/assets/22083793-6a8a-4f66-831c-d115e73bcdf1"
/>

### 3. Notified (OS notification fires, bell shows green dot)
<img width="800" alt="bell shows filled + green dot after job finished
and notification fired"
src="https://github.com/user-attachments/assets/094a409e-6f48-45b4-9681-21abcc497ce3"
/>

### 4. Disabled bell on already-finished jobs
<img width="800" alt="bell faded on FINISHED jobs, tooltip explains why"
src="https://github.com/user-attachments/assets/aed24fbc-4e76-4297-9eef-d1edc4461951"
/>

### 5. Permission denied (toast refusal)
<img width="800" alt="toast warning when browser notifications are
blocked"
src="https://github.com/user-attachments/assets/33bea528-4ff1-4ea0-ab21-7837f97bbddf"
/>

## LLM usage disclosure
Assisted-by: Claude / Opus 4.7 

Used for implementation planning, initial code drafting, and writing
unit tests.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Bell icon in the jobs table to subscribe/unsubscribe to job completion
notifications.
* Background poller that checks subscribed jobs and triggers browser
notifications when jobs finish.
* Subscriptions persist across sessions and can be managed from the UI.
* Permission request for browser notifications with user-facing warning
if denied.

* **Tests**
* Added comprehensive tests covering subscription CRUD, defensive
parsing, and notification selection logic.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2335?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Michael Vallido <vallido.michael@gmail.com>
… another user (AcademySoftwareFoundation#2340)

## Related Issues
Fixes AcademySoftwareFoundation#2324 

## Summarize your change.
This PR adds a **Take Ownership** action to the CueGUI Hosts context
menu so users can reclaim NIMBY-locked hosts that are currently deeded
to someone else, without requiring manual pycue scripting or admin
intervention.

## Main changes:

1. New Hosts action in CueGUI (`cuegui/MenuActions.py`,
`cuegui/HostMonitorTree.py`)
- **Take Ownership** entry in the Hosts right-click menu.
- Enabled only when exactly one host is selected and that host is
`NIMBY_LOCKED` (matches the backend's
`OwnerManagerService.takeOwnership` invariant).
- Re-checks `lock_state` inside the action itself as defense-in-depth
against a stale selection.

2. Explicit ownership-transfer UX
- Prompts for the username that should own the host (defaults to
`getpass.getuser()`).
- Resolves the owner via `opencue.api.getOwner(name)`; if the username
doesn't exist yet, lazily creates the owner record via `findShow(SHOW or
"pipe").createOwner(name)`, same pattern as
`LocalBookingWidget.deedLocalhost`.
- Looks up the host's current deed and:
- If the host has **no current deed** -> skip the confirmation entirely
(nothing to transfer from).
- If the host is owned by **another user** -> confirm with `Host <name>
is currently owned by <user>. Take ownership?`.
- If the host is **already owned by the requested user** -> no-op
confirmation.
- If the deed lookup **fails** for an unexpected reason -> log the
exception and prompt with `Host <name> ownership could not be
determined. Take ownership?`.
- On confirm, calls `owner.takeOwnership(host_name)` and refreshes the
host row.
- Owner creation happens **after** confirmation (verified by a dedicated
test) so a cancelled prompt never leaves a stray owner record behind.
- Errors at any stage (getOwner, createOwner, takeOwnership) surface
through `cuegui.Utils.showErrorMessageBox` instead of leaking gRPC
tracebacks.

3. Reused existing backend; completed missing client-side plumbing
- Uses existing `OwnerInterface.TakeOwnership` flow, no backend API
change required.
- The backend already replaces any existing deed atomically
(`deedDao.deleteDeed(host)` -> `deedDao.insertDeed(owner, host)` in
`OwnerManagerService.takeOwnership`).
- Added a new pycue wrapper `Host.getDeed()`
(`pycue/opencue/wrappers/host.py`) so CueGUI can read the current owner
via the deed before confirmation. The underlying gRPC
`HostInterface.GetDeed` was already implemented in `ManageHost.java`;
only the Python-side wrapper was missing.

4. Tests (`cuegui/tests/test_menu_actions.py`)
Added `HostActionsTests` coverage for:
- `test_canTakeOwnership`: NIMBY-only enablement gate.
- `test_takeOwnership`: Happy path with cross-user confirmation.
- `test_takeOwnership_missingOwnerCreatesAfterConfirm`: Verifies
`createOwner` is **only** called after the user confirms.
- `test_takeOwnership_deedLookupFailureStillPrompts`: Generic
deed-lookup failure still prompts so the user can decide.
- `test_takeOwnership_unownedHostSkipsConfirmation`:
`EntityNotFoundException` (host has no deed) is distinguished from a
generic lookup failure, and the confirmation dialog is skipped.
- `test_takeOwnership_ownerLookupFailure`: Owner lookup failure surfaces
an error dialog without proceeding.
- `test_takeOwnership_ignored_for_non_nimby`: Non-NIMBY host is a no-op
even if the action is somehow invoked.

Focused test slice runs cleanly:
QT_QPA_PLATFORM=offscreen python -m pytest
cuegui/tests/test_menu_actions.py -k HostActionsTests

5. Documentation (`docs/`)
- `docs/_docs/user-guides/cuecommander-administration-guide.md`: Monitor
Hosts -> Manage Host States: added the new action with its NIMBY-only
gate and confirmation behavior.
- `docs/_docs/tutorials/using-cuegui.md`: Added **Take Ownership
(NIMBY-locked only)** to the right-click host menu tree.
- `docs/_docs/reference/CueGUI-app.md`: Added the action to the Managing
hosts "common actions include" list.
- pycue Sphinx docs auto-pick up `Host.getDeed()` from its docstring via
`automodule :members:`: no manual `.rst` edit needed.

## Why?
The backend already supports atomic ownership replacement, but CueGUI
had no UI surface for reclaiming a host owned by another user, the only
workaround was a pycue shell session or an admin request. This closes
that usability gap directly in the Hosts workflow.

## LLM usage disclosure: Olaiwon Ismail
Model used: GPT-5.3-Codex (GitHub Copilot)
Usage:
- Helped me understand the codebase
- Analyzed existing CueGUI host action architecture and pycue ownership
wrappers
- Assisted with syntax and boilerplate generation for the new host
action and UI gating logic
- Generated unit test scaffolding to execute the focused test slice

Co-authored-by: Olaiwon Ismail <olaiwonismail@gmail.com>
Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>
…SoftwareFoundation#2336)

## Related Issues
- AcademySoftwareFoundation#2287 

## Summarize your change.

The existing `Age` column in the jobs table displays time in HHH:MM
format (e.g., `048:32`), which requires mental conversion to understand
at a glance.

I added a new `Readable Age` column that shows the same datum in a more
natural format:
- Jobs under a day: `2h 14m`
- Jobs over a day: `3d 4h`

The column is hidden by default and can be enabled through the column
chooser dropdown, so existing workflows aren't disrupted. The header
pairs with the existing `Age` column to make the relationship (same
value, different format) obvious.

Implementation notes:
- New formatter `secondsToHumanAge` in
`cueweb/app/utils/layers_frames_utils.ts`
- New column `readable age` in `cueweb/app/jobs/columns.tsx` with a
numeric `sortingFn` so rows sort by actual elapsed seconds (not the
formatted string)
- `getJobAgeInSeconds` clamps to non-negative and floors to whole
seconds, so the sort key always matches what the formatter displays
(addresses CodeRabbit feedback on clock-skew / fractional-second edge
cases)
- Docs updated: new row in the Job Information Columns table in
`docs/_docs/user-guides/cueweb-user-guide.md`

Testing:
- Formatter edge cases verified: negative values, zero, minutes-only,
hours-only, multi-day jobs
- Confirmed the column appears in the chooser, is hidden by default, and
sorts correctly by actual age in seconds
- Verified end-to-end in the sandbox stack (`docker compose --profile
all up`)

Co-authored-by: Vishal Kumar Singh <vishal.kr.singh2021@gmail.com>
Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>
…n#2342)

Bumps [faraday](https://github.com/lostisland/faraday) from 2.13.4 to
2.14.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lostisland/faraday/releases">faraday's
releases</a>.</em></p>
<blockquote>
<h2>v2.14.2</h2>
<h2>Security Note</h2>
<p>This release contains a security fix, we recommend all users to
upgrade as soon as possible.
A Security Advisory with more details will be posted shortly.</p>
<h2>What's Changed</h2>
<ul>
<li>Add Ruby 4 to CI by <a
href="https://github.com/larouxn"><code>@​larouxn</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1659">lostisland/faraday#1659</a></li>
<li>Modernize RuboCop configuration and fix offenses by <a
href="https://github.com/larouxn"><code>@​larouxn</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1660">lostisland/faraday#1660</a></li>
<li>Lint: Style/OneClassPerFile by <a
href="https://github.com/olleolleolle"><code>@​olleolleolle</code></a>
in <a
href="https://redirect.github.com/lostisland/faraday/pull/1668">lostisland/faraday#1668</a></li>
<li>fix(docs): fix incorrect link label by <a
href="https://github.com/JohnnyKei"><code>@​JohnnyKei</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1667">lostisland/faraday#1667</a></li>
<li>chore: Upgrade package.json packages using audit fix by <a
href="https://github.com/olleolleolle"><code>@​olleolleolle</code></a>
in <a
href="https://redirect.github.com/lostisland/faraday/pull/1669">lostisland/faraday#1669</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/larouxn"><code>@​larouxn</code></a> made
their first contribution in <a
href="https://redirect.github.com/lostisland/faraday/pull/1659">lostisland/faraday#1659</a></li>
<li><a href="https://github.com/JohnnyKei"><code>@​JohnnyKei</code></a>
made their first contribution in <a
href="https://redirect.github.com/lostisland/faraday/pull/1667">lostisland/faraday#1667</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lostisland/faraday/compare/v2.14.1...v2.14.2">https://github.com/lostisland/faraday/compare/v2.14.1...v2.14.2</a></p>
<h2>v2.14.1</h2>
<h2>Security Note</h2>
<p>This release contains a security fix, we recommend all users to
upgrade as soon as possible.
A Security Advisory with more details will be posted shortly.</p>
<h2>What's Changed</h2>
<ul>
<li>Add comprehensive AI agent guidelines for Claude, Cursor, and GitHub
Copilot by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1642">lostisland/faraday#1642</a></li>
<li>Add RFC document for Options architecture refactoring plan by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1644">lostisland/faraday#1644</a></li>
<li>Bump actions/checkout from 5 to 6 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/lostisland/faraday/pull/1655">lostisland/faraday#1655</a></li>
<li>Explicit top-level namespace reference by <a
href="https://github.com/c960657"><code>@​c960657</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1657">lostisland/faraday#1657</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@​Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/lostisland/faraday/pull/1642">lostisland/faraday#1642</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lostisland/faraday/compare/v2.14.0...v2.14.1">https://github.com/lostisland/faraday/compare/v2.14.0...v2.14.1</a></p>
<h2>v2.14.0</h2>
<h2>What's Changed</h2>
<h3>New features ✨</h3>
<ul>
<li>Use newer <code>UnprocessableContent</code> naming for 422 by <a
href="https://github.com/tylerhunt"><code>@​tylerhunt</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1638">lostisland/faraday#1638</a></li>
</ul>
<h3>Fixes 🐞</h3>
<ul>
<li>Convert strings to UTF-8 by <a
href="https://github.com/c960657"><code>@​c960657</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1624">lostisland/faraday#1624</a></li>
<li>Fix <code>Response#to_hash</code> when response not finished yet by
<a href="https://github.com/yykamei"><code>@​yykamei</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1639">lostisland/faraday#1639</a></li>
</ul>
<h3>Misc/Docs 📄</h3>
<ul>
<li>Lint: use <code>filter_map</code> by <a
href="https://github.com/olleolleolle"><code>@​olleolleolle</code></a>
in <a
href="https://redirect.github.com/lostisland/faraday/pull/1637">lostisland/faraday#1637</a></li>
<li>Bump <code>actions/checkout</code> from v4 to v5 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/lostisland/faraday/pull/1636">lostisland/faraday#1636</a></li>
<li>Fixes documentation by <a
href="https://github.com/dharamgollapudi"><code>@​dharamgollapudi</code></a>
in <a
href="https://redirect.github.com/lostisland/faraday/pull/1635">lostisland/faraday#1635</a></li>
</ul>
<h2>New Contributors</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/lostisland/faraday/commit/2ecd5e05388303087c3f6872ef7f98f260e9560f"><code>2ecd5e0</code></a>
Update version.rb</li>
<li><a
href="https://github.com/lostisland/faraday/commit/3f1280c69e93297d574e85a2d462d05ebadf1d09"><code>3f1280c</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/lostisland/faraday/commit/81dc1688742ad30fa747daba5a82592a1e4df8a8"><code>81dc168</code></a>
Upgrade package.json packages using audit fix (<a
href="https://redirect.github.com/lostisland/faraday/issues/1669">#1669</a>)</li>
<li><a
href="https://github.com/lostisland/faraday/commit/8b4d1fd06fd47dd33f3720794d4df38498c240ec"><code>8b4d1fd</code></a>
Create SECURITY.md</li>
<li><a
href="https://github.com/lostisland/faraday/commit/a01039c948d3e9e41e03d152aed7244f0fb4d5ca"><code>a01039c</code></a>
fix(docs): fix incorrect link label in request-options and remove dead
link i...</li>
<li><a
href="https://github.com/lostisland/faraday/commit/7df3f24bc32d309136c67d94a9f5e4679085af0d"><code>7df3f24</code></a>
Lint: Style/OneClassPerFile (<a
href="https://redirect.github.com/lostisland/faraday/issues/1668">#1668</a>)</li>
<li><a
href="https://github.com/lostisland/faraday/commit/c6988a840738760fae1a40d653fa2ccd0da425b9"><code>c6988a8</code></a>
Modernize RuboCop configuration and fix offenses (<a
href="https://redirect.github.com/lostisland/faraday/issues/1660">#1660</a>)</li>
<li><a
href="https://github.com/lostisland/faraday/commit/32e010f1c3d5cf0f854fd52df553adf9b29985f4"><code>32e010f</code></a>
Add Ruby 4 to CI (<a
href="https://redirect.github.com/lostisland/faraday/issues/1659">#1659</a>)</li>
<li><a
href="https://github.com/lostisland/faraday/commit/16cbd38ef252d25dedf416a4d2510a2f3db10c87"><code>16cbd38</code></a>
Version bump to 2.14.1</li>
<li><a
href="https://github.com/lostisland/faraday/commit/a6d3a3a0bf59c2ab307d0abd91bc126aef5561bc"><code>a6d3a3a</code></a>
Merge commit from fork</li>
<li>Additional commits viewable in <a
href="https://github.com/lostisland/faraday/compare/v2.13.4...v2.14.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=faraday&package-manager=bundler&previous-version=2.13.4&new-version=2.14.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/AcademySoftwareFoundation/OpenCue/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>
## Summary
- add a hover tooltip to CueWeb job progress bars with per-state frame
counts and percentages
- centralize progress segment and tooltip calculations in a utility
- cover progress percentages, tooltip rows, and zero-frame jobs with
unit tests

Fixes AcademySoftwareFoundation#2285

## Testing
- npm test -- --runTestsByPath
app/__tests__/api/utils/job_progress_utils.test.ts
- npx tsc --noEmit
- git diff --check
## Related Issues
- AcademySoftwareFoundation#2290

## Summarize your change.

[cueweb] Add frame state filter chips
- Add frame-state filter chips above CueWeb frame tables with per-state
counts
- Support OR-based filtering for selected frame states
- Persist selected frame states in the `frameStates` URL query parameter
- Add unit tests covering frame state counts and filtering behavior

[cueweb] Improve frame state filter parsing and pagination behavior
- Trim whitespace and deduplicate values when parsing the `frameStates`
URL parameter, ensuring URLs like `?frameStates=WAITING, RUNNING`
correctly preserve valid states
- Reset pagination to page 1 whenever frame state filters change,
preventing empty result pages after narrowing filters
- Preserve the current page during polling-based refreshes via
`autoResetPageIndex: false`

[cueweb/docs] Document job progress tooltip and frame state filter chips
- Update the user guide, reference, tutorial, quick-start, additional
guides, and CueWeb README
- Document the job progress bar tooltip
(AcademySoftwareFoundation#2331),
including per-state frame counts and percentages
- Document frame state filter chips
(AcademySoftwareFoundation#2330),
including:
  - Per-state counts
  - OR-combined filtering behavior
  - URL persistence through the `frameStates` query parameter
  - Whitespace-tolerant and deduplicated parsing
  - Pagination reset behavior when filters change

## Testing
- npm test -- --runTestsByPath
app/__tests__/api/utils/frame_columns.test.ts
- npx tsc --noEmit
- git diff --check

Co-authored-by: Mukunda Katta <mukunda.vjcs6@gmail.com>
Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>
…ademySoftwareFoundation#2327)

When there's only one active show, the logic to randomize show order
inadvertently removes it from the list, leading to a frozen queue.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved shuffle behavior so host dispatching now randomizes show
order correctly when shuffle is enabled.

* **Tests**
* Updated unit test expectations to reflect the corrected dispatch
behavior.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2327)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…SoftwareFoundation#2343)

## Related Issues
- AcademySoftwareFoundation#2344

## Summarize your change.

- Replace QStyle.CE_ProgressBar in ProgressDelegate with manual QPainter
rendering (dark background, green chunk, centered text)
- macOS aqua style ignores opts.rect inside item-view delegate paints
and renders its thin animated indicator at the row's leftmost cell,
painting a stray blue line over the Name column
- Manual painting matches the cross-platform approach already used by
JobProgressBarDelegate, so the Progress column now renders consistently
on macOS, Linux, and Windows
- Clamp progress to [0, 100] to guard against backend over/underreports
…reFoundation#2346)

## Related Issues
- AcademySoftwareFoundation#2347

## Summarize your change.

- Bump @sentry/nextjs from ^8.52.0 to ^10.53.1 to resolve high-severity
vulnerabilities in rollup (path traversal) and the Sentry dependency
chain.
- Run npm audit fix to update transitive dependencies, resolving:
- form-data (critical: unsafe random boundary)
- @babel/plugin-transform-modules-systemjs (arbitrary code generation)
- flatted (DoS / prototype pollution)
- lodash (code injection, prototype pollution)
- minimatch 3.x/5.x/8.x/9.x (ReDoS)
- picomatch 2.x/4.x (ReDoS, method injection)
- serialize-javascript (RCE, DoS)
- terser-webpack-plugin (via serialize-javascript)

Build, type-check, and full test suite (36/36) pass.
…areFoundation#2348)

## Related Issues
- AcademySoftwareFoundation#2284

## Summarize your change.

PR AcademySoftwareFoundation#2335 added the per-job subscribe bell to the CueWeb Jobs table but
shipped without doc updates. Add coverage across all cueweb doc surfaces
that enumerate UI features, columns, or developer components so the
feature is discoverable from every entry point.

- user-guides/cueweb-user-guide.md: Add Notify column to Job Information
Columns and a Job-finished notifications subsection under Real-time
Updates and Monitoring covering the three bell states, the permission
prompt, the 15s poll cadence, localStorage persistence, and auto-cleanup
of deleted jobs.
- developer-guide/cueweb-development.md: Register JobSubscriptionPoller
under Core Components and SubscribeBell under UI Components; add a
Subscription store note covering the cueweb:job-subscriptions key, the
cueweb:subscriptions-changed event bus, and the defensive parser.
- reference/cueweb.md: Add Notify column to the Jobs Table and a
behavior table covering trigger, polling, notification, persistence,
auto-cleanup, and cross-component sync.
- quick-starts/quick-start-cueweb.md: Add Job-finished Notifications
bullet to Expected Interface and step 7 to Frame Operations.
- tutorials/cueweb-tutorial.md: Add a Subscribe to Job Completion step
to Viewing Your Jobs and a bullet to Auto-refresh Settings.
…cademySoftwareFoundation#2349)

## Related Issues
- AcademySoftwareFoundation#2279

## Summarize your change.

Replicates the CueGUI Comments dialog (cuegui/cuegui/Comments.py) in
CueWeb: list, add, edit, and delete per-job comments, plus per-browser
predefined-comment macros.

- New page at app/jobs/[job-name]/comments with comment list, sanitized
markdown preview, editor, and New / Save / Delete actions. Edit and
delete are gated by author check.
- Predefined macro CRUD stored in localStorage (cueweb-comment-macros),
matching CueGUI's Add / Edit / Delete predefined comment workflow.

- Proxy routes:
    POST /api/job/getcomments         -> JobInterface/GetComments
    POST /api/job/action/addcomment   -> JobInterface/AddComment
    POST /api/comment/action/save     -> CommentInterface/Save
    POST /api/comment/action/delete   -> CommentInterface/Delete

- Helpers getJobComments / addJobComment / saveJobComment /
deleteJobComment in app/utils.
- Sticky-note indicator next to job names when Job.hasComment is true,
with username threaded through TanStack Table meta so the indicator
click opens the page with the right author context.
- "Comments" entry added to the job-row context menu.
- Markdown rendered via react-markdown + rehype-sanitize.

Docs updated across user guide, reference, REST API reference, developer
guide, tutorial, other-guides, quick start, and concepts.
…ySoftwareFoundation#2350)

## Related Issues
- AcademySoftwareFoundation#2351

## Summarize your change.

Adds the standard OpenCue Apache 2.0 license header to all CueWeb source
files (TS, TSX, JS, JSX, CSS) that were missing it, using the
JS/TS-equivalent /* ... */ block comment form of the canonical Python
header.

- 107 files updated across app/, components/, lib/, public/workers/,
jest/, root config (next.config.js, tailwind.config.{js,ts},
postcss.config.js, jest.config.js), and the Sentry config entries.
- For files that begin with a "use client" / "use server" / "use strict"
directive, the directive remains on line 1 (Next.js / V8 requirement)
and the header is inserted immediately below it.
- app/__tests__/utils/subscription_utils.test.ts keeps its
`@jest-environment jsdom` docblock as the first comment so Jest still
picks up the environment override; the license header sits below it.
- next-env.d.ts is intentionally skipped, it is auto-generated and
carries an explicit "should not be edited" note.

No behavior changes. Type check and the full Jest suite (42 tests) pass;
the cueweb Docker image builds clean.
…mySoftwareFoundation#2337)

## Related Issues
- AcademySoftwareFoundation#2326

## Summarize your change.

Adds `submissionTime()` to `Frame`, exposing the parent job's submission
timestamp directly on the frame object. This avoids requiring callers to
fetch the parent job or overload `eligibleTime()` to infer submission
time.

`Frame.startTime()` represents when the frame began executing on a
render host, not when the job was submitted. Since `Job.startTime()` and
`Layer.startTime()` already serve as submission timestamps for those
objects, only `Frame` needed this additional accessor.

With `submissionTime()`, callers can now compute frame lifecycle timing
directly from a single `Frame` object:

- `blocked_by_depends = frame.eligibleTime() - frame.submissionTime()`

- `blocked_by_pickup  = frame.startTime() - frame.eligibleTime()`

- `total_turnaround   = frame.stopTime() - frame.submissionTime()`

Proto files
- Adds `submission_time` field to `Frame`.

Cuebot
- Updates `WhiteboardDaoJdbc.FRAME_MAPPER` to populate `submission_time`
from the existing `job.ts_started` join (already aliased as
`job_ts_started` for the `eligibleTime()` fallback).
- No database migration is required, since the source column already
exists.

PyCue
- Adds `Frame.submissionTime()`.
- Includes a new unit test covering the Python wrapper.

CueGUI
- Adds a new "Submission Time" column to `FrameMonitorTree`, positioned
next to the existing "Eligible Time" column.
- Re-anchors the `*_COLUMN` visual-index constants in
`FrameMonitorTree`, which had drifted from their intended columns over
years of insertions (last touched in 2018). The new "Submission Time"
column made the staleness visible by shifting `LASTLINE_COLUMN` further
out of place:
- `PROC_COLUMN`: 5 -> 6 (was pointing at GPUs; now correctly points to
Host).
- `CHECKPOINT_COLUMN`: 7 -> 8 (was pointing at Retries; now correctly
points to the icon-only `_CheckpointEnabled` column where the checkmark
decoration belongs).
- `RUNTIME_COLUMN`: 9 -> 10 (was pointing at the hidden
`_CheckpointEnabled`; now correctly points to Runtime).
- `MEMORY_COLUMN`: 11 -> 12 (was pointing at LLU; now correctly points
to Memory (RSS)).
- `LASTLINE_COLUMN`: 15 -> 20 (was pointing at Remain; now correctly
points to Last Line).
- As a side effect, `redrawRunning()` now emits `dataChanged` over the
correct Runtime -> Last Line range, restoring smooth repaints for
Runtime/Memory/Last Line cells on running frames. The `PROC_COLUMN`
foreground-color and alignment, plus the `CHECKPOINT_COLUMN` icon
decoration, also land on the right cells now.
- Adds a header comment noting these are visual indices that must be
updated in lockstep when columns are inserted, removed, or reordered.

Docs
- Adds `submissionTime` to the Frame REST API reference schema and
example payloads.
- Updates the Cuetopia monitoring guide to document the new column.

VERSION.in
- Bumped up to 1.22
…Foundation#2352)

The satisfy logic that runs to clean up stale depends would catch both
EATEN and SUCCESS frames as a sign its dependents should be cleaned, but
this behavior is only acceptable when
`depend.satisfy_only_on_frame_success` is false.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added `depend.satisfy_only_on_frame_success` configuration flag to
control how EATEN frames are treated during dependency recovery. When
enabled (default), only SUCCEEDED frames satisfy dependencies; when
disabled, EATEN frames also count as completion.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2352?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…cademySoftwareFoundation#2341)

## Related Issues
- AcademySoftwareFoundation#2335

## Summarize your change.

Builds on top of the per-job subscribe bell (AcademySoftwareFoundation#2335):

- Replace the OS browser Notification API with the existing
react-toastify channel (toastSuccess). Removes the first-click
permission prompt; the bell now subscribes/unsubscribes immediately.
Drops requestNotificationPermission() and the "permission denied" toast
warning from the bell click handler.

- SSR-guard getSubscriptions(): return {} when window is undefined,
matching subscribeToChanges and the (now removed)
requestNotificationPermission helper.

- Cross-tab sync in subscribeToChanges(): also listen for the browser
'storage' event so a mutation in one tab updates bells in other open
tabs.

- Harden the poller tick:
* Wrap each getJob() call in try/catch so one failed fetch does not
reject Promise.all and silently lose the tick.
* Wrap the whole tick body in try/catch so failures show up as a
console.error instead of an unhandled rejection.
* Re-read each entry from localStorage right before firing and skip if
notifiedAt is no longer null. Narrows the cross-tab race window where
two tabs both pick the same FINISHED entry and toast twice.
…reFoundation#2328)

The scheduler was inadvertently booking non-threadable jobs on
threadable machines. Going against cuebot's behavior.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Streamlined thread-mode validation logic in the scheduler's core
reservation and host matching systems.
  * Removed redundant code paths and consolidated validation logic.

* **Tests**
* Enhanced test coverage for thread-mode compatibility validation across
different thread-mode configurations.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2328)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…yer (AcademySoftwareFoundation#2338)

## Related Issues
- AcademySoftwareFoundation#2339

## Summarize your change.

[cuebot/proto/pycue/cuegui/docs] Add Layer startTime() and stopTime()

Layer previously had no start/stop time accessors. Callers that needed
the execution window for a layer had to fetch every frame and compute
MIN/MAX client-side, which was wasteful in CueGUI (N extra RPCs per
refresh for a job with N layers) and unavailable to tools that only
queried layers.

This change denormalizes layer timing onto `layer_stat` and exposes the
values directly on the Layer API:

- `Layer.startTime()` = `layer_stat.ts_started` (stamped on first entry
to RUNNING)
- `Layer.stopTime()` = `layer_stat.ts_stopped` (stamped on each exit
from RUNNING, but surfaced as 0 until every frame on the layer has
stopped)

`stopTime()` remains `0` while any frame is still pending, running, or
in DEPEND, mirroring `Job.stopTime()` so callers can use the same "is it
done?" idiom consistently.

Proto
- Add `start_time` (field 24) and `stop_time` (field 25) to the `Layer`
message.

Cuebot
- Add `ts_started` and `ts_stopped` (`TIMESTAMP WITH TIME ZONE`) to
`layer_stat`.
- Maintain both values through the existing
`trigger__update_frame_status_counts` trigger (`AFTER UPDATE ON frame`):
* entry to RUNNING stamps `ts_started` from `NEW.ts_started` via
`COALESCE(...)` (first-writer-wins; retries do not update it)
* exit from RUNNING stamps `ts_stopped` from `NEW.ts_stopped`
(latest-writer-wins)
- Copy timestamps from the updated frame row instead of sampling
`current_timestamp`, ensuring `layer_stat.ts_stopped` exactly matches
`MAX(frame.ts_stopped)`.
- Preserve `COALESCE(..., current_timestamp)` as a fallback for callers
that change state without explicitly updating timestamps.
- Update `GET_LAYER` and `GET_LAYER_WITH_LIMITS` to read
`layer_stat.ts_started` and `layer_stat.ts_stopped` directly, replacing
two correlated frame-table aggregates per layer query.
- Move "stopTime stays 0 until all frames are done" logic into
`WhiteboardDaoJdbc.LAYER_MAPPER` using existing counters:
`int_waiting_count + int_running_count + int_depend_count == 0`
- Align layer timing behavior with existing denormalized
`job.ts_started` / `job.ts_stopped`.
- Add V43 migration to create and backfill both columns from existing
frame aggregates, with no manual follow-up required.

PyCue
- Add `Layer.startTime(format=None)` and `Layer.stopTime(format=None)`,
matching `Job.startTime()` formatting behavior.
- Add unit tests for both epoch and formatted outputs.

CueGUI
- Add "Start Time" and "Stop Time" columns to `LayerMonitorTree`,
alongside the existing "Eligible" column.

Docs
- Add `startTime` and `stopTime` to the Layer example payload in the
REST API reference.
- Document the new monitor-tree columns in the Cuetopia monitoring
guide.

VERSION.in
- Bump version to 1.23.
CueJobMonitorTree was fetching the same job data twice every 22s: once
via cached getJobWhiteboard, then once per group via an uncached
getJobs(id=...). On a show with N populated groups, one tick cost 1 + N
gRPC round-trips and SQL executions.

Changes:
- Add `repeated Job inline_jobs = 18` to NestedGroup (strictly additive;
`repeated string jobs` retained). Cuebot populates it from the existing
GET_NESTED_GROUPS row data — the only column added to the SELECT is
`str_loki_url`. Reuses WhiteboardDaoJdbc.JOB_MAPPER.
- Bump whiteboard cache TTL 5s→10s and add per-show single-flight
(synchronized-on-show), so concurrent clients share one SQL execution
per TTL window.
- cuegui: drop UPDATE_INTERVAL 22s→5s; override _update with a
skip-if-running guard; rewrite _processUpdate as an incremental diff
(takeChild only stale IDs, no clear()), so selection, scroll, and
expansion survive add/remove/reparent.
- cuegui: consume inline_jobs; fall back to opencue.api.getJobs against
older Cuebot.

## LLM usage disclosure
Claude Opus was used to implement this optimization

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Display inline job data within nested job groups.

* **Performance**
  * Faster job tree refresh (22s → 5s).
  * Incremental tree updates to avoid full rebuilds.
* Improved whiteboard caching with per-show refresh control and longer
timeout.

* **Bug Fixes**
  * Ensure work/task completion callbacks fire even on failure.

* **Tests**
  * Added a test verifying inline jobs populate in nested groups.

* **Chores**
  * Project version updated to 1.24.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2370?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Diego Tavares <dtavares@imageworks.com>
…2371)

The following warning has been poluting cuegui's log for a while. This
QT warning can be triggered by different locations, this PR treats one
of them.

```
WARNING   Main       Qt thread-affinity violation:
  File "cuegui/ThreadPool.py", line 218, in run
    result = work[0]()
  File "cuegui/HostMonitorTree.py", line 291, in _getUpdate
    parent.updateOSFilterList(os_values)
  File "cuegui/HostMonitor.py", line 483, in updateOSFilterList
    action = QtWidgets.QAction(menu)
  File "cuegui/Main.py", line 140, in warning_handler
    logger.warning("Qt thread-affinity violation:\n%s", "".join(traceback.format_stack()))
```

The previous solution called a parent function from a different thread
directly. This fix uses a signal to
allow triggering the same function on its own thread.

## LLM usage disclosure
Claude Code was used to propose a fix once the issue was identified.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Resolved thread-safety issues in host monitoring by implementing
proper synchronization for OS filter list updates. This prevents race
conditions and potential crashes when the background worker discovers
and updates operating system values during host monitoring operations.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2371?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…oftwareFoundation#2378)

For some unknown reason, this change was resulting on a Segmentation
Fault when a combination of unrelated factors were involved. For now
this PR simple reverts the previous version in an effort to avoid
crashes.



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Stopped emitting completion signals for tasks that fail, preventing
failed background jobs from appearing as completed and avoiding
premature cleanup of job state.
* Improved background fetch error handling with clearer logging,
distinct handling for transient RPC errors, and ensured failed fetches
return safely so they are retried on the next update tick.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/AcademySoftwareFoundation/OpenCue/pull/2378?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Diego Tavares <dtavares@imageworks.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
dependabot Bot and others added 30 commits June 22, 2026 00:10
…ion#2450)

Bumps [form-data](https://github.com/form-data/form-data) from 4.0.5 to
4.0.6.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/form-data/form-data/blob/master/CHANGELOG.md">form-data's
changelog</a>.</em></p>
<blockquote>
<h2><a
href="https://github.com/form-data/form-data/compare/v4.0.5...v4.0.6">v4.0.6</a>
- 2026-06-12</h2>
<h3>Commits</h3>
<ul>
<li>[Fix] escape CR, LF, and <code>&quot;</code> in field names and
filenames <a
href="https://github.com/form-data/form-data/commit/8dff42c6da654ed4e7ad4acb7f8ccd3831217c99"><code>8dff42c</code></a></li>
<li>[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>tape</code> <a
href="https://github.com/form-data/form-data/commit/f31d21ef10bf46e46344c3ee4f99acbef6be43e1"><code>f31d21e</code></a></li>
<li>[Deps] update <code>hasown</code>, <code>mime-types</code> <a
href="https://github.com/form-data/form-data/commit/92ae0eb5da94d6f01925d5f4fcffb2a1e50ed7cd"><code>92ae0eb</code></a></li>
<li>[Dev Deps] update <code>js-randomness-predictor</code> <a
href="https://github.com/form-data/form-data/commit/67b0f65c2e0b065a511d42227d35e4d367644e97"><code>67b0f65</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/form-data/form-data/commit/64190db548c0179e37206858e39f27cf513e9435"><code>64190db</code></a>
v4.0.6</li>
<li><a
href="https://github.com/form-data/form-data/commit/92ae0eb5da94d6f01925d5f4fcffb2a1e50ed7cd"><code>92ae0eb</code></a>
[Deps] update <code>hasown</code>, <code>mime-types</code></li>
<li><a
href="https://github.com/form-data/form-data/commit/f31d21ef10bf46e46344c3ee4f99acbef6be43e1"><code>f31d21e</code></a>
[Dev Deps] update <code>@ljharb/eslint-config</code>,
<code>auto-changelog</code>, <code>tape</code></li>
<li><a
href="https://github.com/form-data/form-data/commit/8dff42c6da654ed4e7ad4acb7f8ccd3831217c99"><code>8dff42c</code></a>
[Fix] escape CR, LF, and <code>&quot;</code> in field names and
filenames</li>
<li><a
href="https://github.com/form-data/form-data/commit/67b0f65c2e0b065a511d42227d35e4d367644e97"><code>67b0f65</code></a>
[Dev Deps] update <code>js-randomness-predictor</code></li>
<li>See full diff in <a
href="https://github.com/form-data/form-data/compare/v4.0.5...v4.0.6">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=form-data&package-manager=npm_and_yarn&previous-version=4.0.5&new-version=4.0.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/AcademySoftwareFoundation/OpenCue/network/alerts).

</details>

Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ndation#2451)

Bumps
[@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core)
from 7.25.2 to 7.29.6.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/babel/babel/releases">@​babel/core's
releases</a>.</em></p>
<blockquote>
<h2>v7.29.6 (2026-05-25)</h2>
<h4>:bug: Bug Fix</h4>
<ul>
<li><code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18014">#18014</a>
Catchup source map position in preserveFormat (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/18001">#18001</a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-core</code>, <code>babel-generator</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17998">#17998</a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17992">#17992</a>)
(<a href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 3</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
<li>Mateusz Burzyński (<a
href="https://github.com/Andarist"><code>@​Andarist</code></a>)</li>
<li>Nicolò Ribaudo (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<h2>v7.29.5 (2026-05-05)</h2>
<h4>:house:  Internal</h4>
<ul>
<li><code>babel-preset-env</code>
<ul>
<li>Update <code>@babel/*</code> dependencies</li>
</ul>
</li>
</ul>
<h2>v7.29.4 (2026-05-05)</h2>
<h4>:bug: Bug Fix</h4>
<ul>
<li><code>babel-plugin-transform-modules-systemjs</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17974">#17974</a>
[7.x backport]fix(systemjs): improve module string name support (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>Committers: 1</h4>
<ul>
<li>Huáng Jùnliàng (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
<h2>v7.29.3 (2026-04-30)</h2>
<h4>:eyeglasses: Spec Compliance</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17923">#17923</a>
Support flow extends bound (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>:bug: Bug Fix</h4>
<ul>
<li><code>babel-helper-create-class-features-plugin</code>,
<code>babel-plugin-proposal-decorators</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17931">#17931</a>
fix(decorators): replace super within all removed static elements (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
<li><code>babel-register</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17915">#17915</a> Fix
thread synchronization issues in <code>@babel/register</code> (<a
href="https://github.com/liuxingbaoyu"><code>@​liuxingbaoyu</code></a>)</li>
</ul>
</li>
<li><code>babel-compat-data</code>,
<code>babel-plugin-bugfix-safari-rest-destructuring-rhs-array</code>,
<code>babel-preset-env</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17788">#17788</a> Add
bugfix plugin for Safari array rest destructuring bug (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>:nail_care: Polish</h4>
<ul>
<li><code>babel-parser</code>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17782">#17782</a>
Improve trailing comma comment handling (<a
href="https://github.com/JLHwung"><code>@​JLHwung</code></a>)</li>
</ul>
</li>
</ul>
<h4>:memo: Documentation</h4>
<ul>
<li><a
href="https://redirect.github.com/babel/babel/pull/17847">#17847</a>
Replace npmjs.com links with npmx.dev (<a
href="https://github.com/nicolo-ribaudo"><code>@​nicolo-ribaudo</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/babel/babel/commit/04ea6b27fdac8f40c3481aec2080ac9678779509"><code>04ea6b2</code></a>
v7.29.6</li>
<li><a
href="https://github.com/babel/babel/commit/99f498a9b9fa0b900d603fbe8f6601bb3b9e42bb"><code>99f498a</code></a>
[7.x packport]Improve input source map handling (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/18001">#18001</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/feba0a3654c596bd369d1ef1231f5d56666d56dc"><code>feba0a3</code></a>
Preserve original identifier names from input sourcemaps (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17992">#17992</a>)
(<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17998">#17998</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/aa8394e454337d118ac3d40bfa3ee1a3cb3f3ed2"><code>aa8394e</code></a>
v7.29.0</li>
<li><a
href="https://github.com/babel/babel/commit/ad0d03f0c92404a60ec6b1c12f15febd38e2397a"><code>ad0d03f</code></a>
[7.x backport] feat: Allow specifying startLine in code frame (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17739">#17739</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/d7f400889567ae18ef9ac41b024b5120f6060e17"><code>d7f4008</code></a>
v7.28.6</li>
<li><a
href="https://github.com/babel/babel/commit/e130225028e93e106135586f344cfa44c4aac847"><code>e130225</code></a>
Polish(standalone): improve message on invalid preset/plugin (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17606">#17606</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/99dcba5e71de3bd81ce14077cfa5b6df58e9b177"><code>99dcba5</code></a>
chore: enable some ts-eslint rules (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17592">#17592</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/c92c4919771105140015167f25f7bacac77c90d9"><code>c92c491</code></a>
Improve Unicode handling in code-frame tokenizer (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17589">#17589</a>)</li>
<li><a
href="https://github.com/babel/babel/commit/d725e399fd6a4da463cff4918cf71aa03b8beb14"><code>d725e39</code></a>
Add <code>BABEL_7_TO_8_DANGEROUSLY_DISABLE_VERSION_CHECK</code> (<a
href="https://github.com/babel/babel/tree/HEAD/packages/babel-core/issues/17569">#17569</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/babel/babel/commits/v7.29.6/packages/babel-core">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a
href="https://www.npmjs.com/~GitHub%20Actions">GitHub Actions</a>, a new
releaser for <code>@​babel/core</code> since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@babel/core&package-manager=npm_and_yarn&previous-version=7.25.2&new-version=7.29.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/AcademySoftwareFoundation/OpenCue/network/alerts).

</details>

Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ndation#2452)

Bumps
[concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby)
from 1.3.5 to 1.3.7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ruby-concurrency/concurrent-ruby/releases">concurrent-ruby's
releases</a>.</em></p>
<blockquote>
<h2>v1.3.7</h2>
<!-- raw HTML omitted -->
<p>There are 3 security fixes in this release, so updating is
recommended.
These security vulnerabilities are not very likely to be hit in practice
and have a corresponding <code>Low</code> severity score.</p>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<ul>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-h8w8-99g7-qmvj">CVE-2026-54904</a>
<code>AtomicReference#update</code> livelocks when the stored value is
<code>Float::NAN</code>. Fix by <a
href="https://github.com/joshuay03"><code>@​joshuay03</code></a> and <a
href="https://github.com/eregon"><code>@​eregon</code></a></li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-wv3x-4vxv-whpp">CVE-2026-54905</a>
<code>ReentrantReadWriteLock</code> read-count overflow grants a write
lock without exclusivity. Fix by <a
href="https://github.com/joshuay03"><code>@​joshuay03</code></a></li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-6wx8-w4f5-wwcr">CVE-2026-54906</a>
<code>ReadWriteLock</code> allows wrong-thread write release and stray
read-release counter corruption. Fix by <a
href="https://github.com/joshuay03"><code>@​joshuay03</code></a></li>
<li>concurrent-ruby-ext: fix build on Darwin 32-bit by <a
href="https://github.com/barracuda156"><code>@​barracuda156</code></a>
in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1064">ruby-concurrency/concurrent-ruby#1064</a></li>
<li>Add SECURITY.md by <a
href="https://github.com/eregon"><code>@​eregon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1104">ruby-concurrency/concurrent-ruby#1104</a></li>
<li>Add Ruby 4.0 in CI by <a
href="https://github.com/eregon"><code>@​eregon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1106">ruby-concurrency/concurrent-ruby#1106</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/barracuda156"><code>@​barracuda156</code></a>
made their first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1064">ruby-concurrency/concurrent-ruby#1064</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.6...v1.3.7">https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.6...v1.3.7</a></p>
<h2>v1.3.6</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<ul>
<li>Run tests without the C extension in CI by <a
href="https://github.com/eregon"><code>@​eregon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1081">ruby-concurrency/concurrent-ruby#1081</a></li>
<li>Fix typo in Promise docs by <a
href="https://github.com/danieldiekmeier"><code>@​danieldiekmeier</code></a>
in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1083">ruby-concurrency/concurrent-ruby#1083</a></li>
<li>Correct word in readme by <a
href="https://github.com/wwahammy"><code>@​wwahammy</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1084">ruby-concurrency/concurrent-ruby#1084</a></li>
<li>Fix mistakes in MVar documentation by <a
href="https://github.com/trinistr"><code>@​trinistr</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1087">ruby-concurrency/concurrent-ruby#1087</a></li>
<li>Fix multi require concurrent/executor/cached_thread_pool by <a
href="https://github.com/OuYangJinTing"><code>@​OuYangJinTing</code></a>
in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1085">ruby-concurrency/concurrent-ruby#1085</a></li>
<li>Use typed data APIs by <a
href="https://github.com/nobu"><code>@​nobu</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1096">ruby-concurrency/concurrent-ruby#1096</a></li>
<li>Add Joshua Young to the list of maintainers by <a
href="https://github.com/eregon"><code>@​eregon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1097">ruby-concurrency/concurrent-ruby#1097</a></li>
<li>Asynchronous pruning for RubyThreadPoolExecutor by <a
href="https://github.com/joshuay03"><code>@​joshuay03</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1082">ruby-concurrency/concurrent-ruby#1082</a></li>
<li>Mark RubySingleThreadExecutor as a SerialExecutorService by <a
href="https://github.com/meineerde"><code>@​meineerde</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1070">ruby-concurrency/concurrent-ruby#1070</a></li>
<li>Allow TimerTask to be safely restarted after shutdown and avoid
duplicate tasks by <a
href="https://github.com/bensheldon"><code>@​bensheldon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1001">ruby-concurrency/concurrent-ruby#1001</a></li>
<li>Flaky test fix: allow ThreadPool to shutdown before asserting
completed_task_count by <a
href="https://github.com/bensheldon"><code>@​bensheldon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1098">ruby-concurrency/concurrent-ruby#1098</a></li>
<li><code>ThreadPoolExecutor#kill</code> will
<code>wait_for_termination</code> in JRuby; ensure <code>TimerSet</code>
timer thread shuts down cleanly by <a
href="https://github.com/bensheldon"><code>@​bensheldon</code></a> in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1044">ruby-concurrency/concurrent-ruby#1044</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/danieldiekmeier"><code>@​danieldiekmeier</code></a>
made their first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1083">ruby-concurrency/concurrent-ruby#1083</a></li>
<li><a href="https://github.com/wwahammy"><code>@​wwahammy</code></a>
made their first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1084">ruby-concurrency/concurrent-ruby#1084</a></li>
<li><a href="https://github.com/trinistr"><code>@​trinistr</code></a>
made their first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1087">ruby-concurrency/concurrent-ruby#1087</a></li>
<li><a
href="https://github.com/OuYangJinTing"><code>@​OuYangJinTing</code></a>
made their first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1085">ruby-concurrency/concurrent-ruby#1085</a></li>
<li><a href="https://github.com/nobu"><code>@​nobu</code></a> made their
first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1096">ruby-concurrency/concurrent-ruby#1096</a></li>
<li><a href="https://github.com/joshuay03"><code>@​joshuay03</code></a>
made their first contribution in <a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/pull/1082">ruby-concurrency/concurrent-ruby#1082</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.5...v1.3.6">https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.5...v1.3.6</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ruby-concurrency/concurrent-ruby/blob/master/CHANGELOG.md">concurrent-ruby's
changelog</a>.</em></p>
<blockquote>
<h2>Release v1.3.7 (16 June 2026)</h2>
<p>concurrent-ruby:</p>
<ul>
<li>See the <a
href="https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7">release
notes on GitHub</a>.</li>
</ul>
<h2>Release v1.3.6 (13 December 2025)</h2>
<p>concurrent-ruby:</p>
<ul>
<li>See the <a
href="https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.6">release
notes on GitHub</a>.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/4c8fc28ab6bb9bd8258a4c0c2fa6d35ebe77b3cb"><code>4c8fc28</code></a>
Release 1.3.7</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/d91ca9426cb819d6cc63f1bd64bfe54644d0beca"><code>d91ca94</code></a>
Fix AtomicReference#update livelock when stored value is Float::NAN on
JRuby ...</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/7e4d711bacf7a1dac3ef6bda44004387be2dc7e6"><code>7e4d711</code></a>
Fix <code>ReentrantReadWriteLock</code> read hold overflow into
write-lock bit</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/6e37e0644b83b182971dc540d2e4bee38df61386"><code>6e37e06</code></a>
Fix <code>AtomicReference#update</code> livelock when stored value is
<code>Float::NAN</code></li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/2825cfa12cb708b76557803957f76862eb1151a2"><code>2825cfa</code></a>
Cleanup spec</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/3fd493283ca5f84f0ef4e84aabd43ad68df4626b"><code>3fd4932</code></a>
Fix <code>ReadWriteLock</code> wrong-thread write release and stray read
release</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/1974b4772efc034ee8eaa562b4370343f4c5c54b"><code>1974b47</code></a>
Add Ruby 4.0 in CI</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/df8706d40c483d76bbb0b3a35a633c68fa9e17be"><code>df8706d</code></a>
Add SECURITY.md (<a
href="https://redirect.github.com/ruby-concurrency/concurrent-ruby/issues/1104">#1104</a>)</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/7a1b78941c081106c20a9ca0144ac73a48d254ab"><code>7a1b789</code></a>
Bump actions/upload-pages-artifact from 4 to 5</li>
<li><a
href="https://github.com/ruby-concurrency/concurrent-ruby/commit/9b2dbf712896a638a73d2fa221206961c8d6484d"><code>9b2dbf7</code></a>
Bump actions/deploy-pages from 4 to 5</li>
<li>Additional commits viewable in <a
href="https://github.com/ruby-concurrency/concurrent-ruby/compare/v1.3.5...v1.3.7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=concurrent-ruby&package-manager=bundler&previous-version=1.3.5&new-version=1.3.7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/AcademySoftwareFoundation/OpenCue/network/alerts).

</details>

Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…n#2453)

Bumps [faraday](https://github.com/lostisland/faraday) from 2.14.2 to
2.14.3.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/lostisland/faraday/releases">faraday's
releases</a>.</em></p>
<blockquote>
<h2>v2.14.3</h2>
<h2>Security Note</h2>
<p>This release contains a security fix, we recommend all users to
upgrade as soon as possible.
A Security Advisory with more details will be posted shortly.</p>
<h2>What's Changed</h2>
<ul>
<li>Upgrade CI lint step from Ruby 3 to 4 by <a
href="https://github.com/larouxn"><code>@​larouxn</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1673">lostisland/faraday#1673</a></li>
<li>feat(test): add Stubs#clear to remove all stubs by <a
href="https://github.com/SAY-5"><code>@​SAY-5</code></a> in <a
href="https://redirect.github.com/lostisland/faraday/pull/1675">lostisland/faraday#1675</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/SAY-5"><code>@​SAY-5</code></a> made
their first contribution in <a
href="https://redirect.github.com/lostisland/faraday/pull/1675">lostisland/faraday#1675</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/lostisland/faraday/compare/v2.14.2...v2.14.3">https://github.com/lostisland/faraday/compare/v2.14.2...v2.14.3</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/lostisland/faraday/commit/f1ace878bae16c1df298b6af7c34657f2c4dcddb"><code>f1ace87</code></a>
Version bump to 2.14.3</li>
<li><a
href="https://github.com/lostisland/faraday/commit/36764bfc48aa9fc08336d36600ea67af149c80fa"><code>36764bf</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/lostisland/faraday/commit/59334e0e9b1918bd26b143f4a7bbc8c765de3ac4"><code>59334e0</code></a>
feat(test): add Stubs#clear to remove all stubs (<a
href="https://redirect.github.com/lostisland/faraday/issues/1675">#1675</a>)</li>
<li><a
href="https://github.com/lostisland/faraday/commit/469f25c793f25bcfdd416a54edeb454d045c08d6"><code>469f25c</code></a>
Upgrade CI lint step from Ruby 3 to 4 (<a
href="https://redirect.github.com/lostisland/faraday/issues/1673">#1673</a>)</li>
<li>See full diff in <a
href="https://github.com/lostisland/faraday/compare/v2.14.2...v2.14.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=faraday&package-manager=bundler&previous-version=2.14.2&new-version=2.14.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/AcademySoftwareFoundation/OpenCue/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…enhancements (AcademySoftwareFoundation#2426)

## Related Issues

Main issue:
- AcademySoftwareFoundation#2016

Issues related to this PR:
- TBD
- AcademySoftwareFoundation#2289
- AcademySoftwareFoundation#2291

## Summarize your change.

[cueweb] Job/Layer/Frame context-menu parity + frame log viewer
enhancements

Bring the Cuetopia tables to CueGUI parity across the Job, Layer and
Frame right-click menus, add the supporting REST-gateway routes and
dialogs, and extend the frame log viewer (search, follow/tail, line
numbers, per-line copy, preview). Also adds a Blender render demo to the
sandbox.

1) Job menu
- [x] Set User Color paints the whole row with CueGUI's 15 default
swatches plus a bright palette (app/utils/user_colors.ts);
- [x] Change Comments in a new tab to Comments popup
(job-comments-dialog.tsx);
- [x] New auto-eat column;
- [x] Set Min/Max Cores
- [x] Set Min/Max GPUs
- [x] Max Retries
- [x] Use Local Cores
- [x] Reorder
- [x] Stagger via job-extra-dialogs.tsx;
- [x] Show Progress Bar. This option shows a configurable command. Layer
menu (layer-extra-dialogs.tsx + routes)
- [x] View Layer
- [x] View Dependencies
- [x] Dependency Wizard (LAYER_ON_LAYER)
- [x] Mark done
- [x] Reorder
- [x] Stagger
- [x] Properties (min cores/memory/gpu-memory, threadable, tags)
- [x] Eat and Mark done
- [x] View Processes.

2) Frame menu (frame-extra-dialogs.tsx + routes)
- [x] View Host
- [x] View Dependencies
- [x] Dependency Wizard (FRAME_ON_FRAME)
- [x] Drop depends
- [x] Mark as waiting
- [x] Mark done
- [x] Filter Selected Layers
- [x] Reorder
- [x] Preview All (external viewer configurable)
- [x] Eat and Mark done
- [x] View Processes.
- [x] Frame range selector (frame-range-selector.tsx): drag /
shift-click to select a contiguous range and Retry / Eat / Kill it.

3) Frame log viewer (app/frames/[frame-name]/page.tsx)
- [x] Search bar with highlight, n/total counter, Enter/Shift+Enter
navigation, case + regex toggles (frame-log-search.tsx).
Follow tail mode: 
- [x] Auto-scroll on new lines
- [x] Pause on scroll-up
- [x] Jump to bottom
- [x] "Tail Log" action opens it by default (last 200 lines, 1s poll).
- [x] Absolute line numbers + hover/click per-line copy with toast.
- [x] Frame preview thumbnail viewer (frame-preview-panel.tsx +
/api/frame/preview + preview_utils.ts)

4) Fixes
- [x] Correct gateway package on the layer/frame createdepend* routes
(/layer.* and /frame.* -> /job.LayerInterface and /job.FrameInterface);
depend creation now succeeds.
- [x] Mount DependencyWizardDialog once per page (was opening twice on
Monitor Jobs); Add an initialType open option.

New API routes
Frame: 
- [x] getdepends
- [x] dropdepends
- [x] markaswaiting
- [x] preview
Job: 
- [x] addrenderpart
- [x] markdoneframes
- [x] reorderframes
- [x] staggerframes
- [x] setmingpus
- [x] setmaxgpus
Layer:
- [x] getdepends
- [x] getoutputpaths
- [x] markdone
- [x] reorderframes
- [x] staggerframes
- [x] setmincores
- [x] setminmemory
- [x] setmingpumemory
- [x] settags
- [x] setthreadable

Config
Dockerfile + docker-compose.yml:
- [x] NEXT_PUBLIC_CUEPROGBAR_COMMAND
- [x] NEXT_PUBLIC_PREVIEW_COMMAND
- [x] NEXT_PUBLIC_PREVIEW_URL build args + runtime env.

Sandbox
load_test_jobs.py: 
- [x] New `blender` subcommand renders a real image sequence and
registers the layer output path so the frame preview has real frames
- [x] Cross-platform Blender discovery (macOS/Windows/Linux)
- [x] Standalone render_blender_demo.py wrapper
- [x] README updated.

[cueweb] Other menu: add Immersive + Split view to sidebar/mobile;
document job/layer/frame + log-viewer features

Code:
- [x] app-sidebar / mobile-nav-sheet: the left sidebar (collapsed
icon-rail and expanded) and the mobile nav drawer now carry the full
Other menu, matching the header — Attributes, Immersive (full-screen),
Split view, Show Shortcuts, Notify on Shortcut (Immersive toggles via
useImmersiveMode; Split view links to the split workspace).

Docs (Job/Layer/Frame context-menu parity + frame log viewer
enhancements):
- [x] reference: added the new env vars
(NEXT_PUBLIC_CUEPROGBAR_COMMAND/_URL, NEXT_PUBLIC_PREVIEW_COMMAND/_URL);
de-placeholdered the Job/Layer/Frame action tables (Reorder/Stagger,
Unbook, Properties, dependency items, Preview All, Mark done, etc.) and
added Set Min/Max GPUs, Use Local Cores, Set User Color, Mark as
waiting; new "Frame log viewer features" table (search, follow/tail,
line numbers, per-line copy, download, preview panel).
- [x] developer-guide: new section listing the *-extra-dialogs,
frame-log-search, frame-preview-panel, frame-range-selector,
preview_utils, user_colors files and all new API routes, plus the
depend-package fix, single-wizard-mount, configurable commands, and the
Blender sandbox demo.
- [x] getting-started / quick-starts: the new env vars in the .env
config.
- [x] user-guide / other-guides / tutorials: frame actions (Mark as
waiting, Mark done, Preview All, frame-range selector) and the
log-viewer features.
- [x] README: full Job/Layer/Frame menu parity + frame log viewer
bullets.

Other-menu parity reflected across all guides + README (header, sidebar,
and mobile drawer enumerations now include Immersive (full-screen) and
Split view).

## LLM usage disclosure
Parts of this solution's implementation were developed with assistance
from Claude Opus.
…wareFoundation#2423)

## Related Issues

Main issue:
- AcademySoftwareFoundation#2016

Issues related to this PR:
- AcademySoftwareFoundation#2424

## Summarize your change.

[cueweb] Add Monitor Cue page (CueCommander parity)

Add the /monitor-cue route (previously a dead sidebar link) replicating
CueGUI's Monitor Cue window:
- [x] "Shows" multi-select (All Shows / Clear / per-show, persisted)
drives a show-grouped job table.
- [x] Full column set: Run, Cores, Gpus, Wait, Depend, Total, Min, Max,
Min G, Max G, Pri, ETA, MaxRss, MaxGpuMem, Age, Progress (frame-state
colored bar). Row coloring by paused/dead/depend/waiting.
- [x] Toolbar: Eat / Retry / Pause / Unpause / Kill (confirm) on
selected jobs, Refresh + Auto-refresh (5s), Expand/Collapse All, Select
search + Clr + selectMine.
- [x] Reuses the existing JobContextMenu (+ job action dialogs) for the
per-job right-click menu and JobProgressBar for Progress.

[cueweb] Monitor Cue: CueGUI parity for menu, columns, booking bar,
selection

Bring the CueCommander Monitor Cue table and its right-click menu closer
to CueGUI/CueCommander.

Right-click job menu
- [x] Add "Send To Group..." (Monitor Cue only) with a group picker
dialog (send-to-group-dialog.tsx) that reparents the job via
reparentJobs.
- [x] Merge "Auto-Eat On/Off" into a single state-aware toggle: "Enable
auto eating" / "Disable auto eating".
- [x] Rename "Unbook..." to "Unbook Frames..." (CueGUI naming).
- [x] Move "Set Priority..." after the cores/gpus setters (CueGUI
order).
- [x] Monitor Cue only (hidden on Cuetopia/Monitor Jobs): Unmonitor, Set
User Color / Clear User Color, Use Local Cores, and the
resource/priority/unbook setters (Set Min/Max Cores, Set Minimum/Maximum
Cores, Set Minimum/Maximum Gpus, Set Priority, Unbook Frames) - matching
where CueGUI exposes them.
- [x] Toolbar action buttons now show icons
(eat/retry/pause/unpause/kill).

Table
- [x] Comment + auto-eat columns matching Monitor Jobs (amber
sticky-note, yellow Pacman), and a "Readable Age" column.
- [x] Booking Bar column (job-booking-bar.tsx) mirroring CueGUI's
JobBookingBarDelegate: running/waiting bar with full-height min (cyan)
and max (red) core markers.
- [x] Sortable columns (asc/desc) with header arrows.
- [x] Show/hide + reorder columns via a Columns dropdown, plus a "Filter
jobs..." search box, both at the top-right of the table (persisted to
localStorage).
- [x] Select-all header checkbox; Shift+click range selection of rows.
- [x] CueGUI row tint: blue=paused, red=dead, yellow=high maxRss,
green=waiting, purple=all-depend. Removed the white-on-hover row
highlight.
- [x] "Select:" (name/regex) box now selects matching jobs live as you
type.

Fixes
- [x] Kill failed on Monitor Cue in no-auth mode: fall back to
UNKNOWN_USER (not "") so the username-required kill request validates.
- [x] Mount JobExtraDialogs / JobCommentsDialog / SendToGroupDialog on
the page so every job-menu action (Set Min/Max Cores, Reorder, Comments,
etc.) works.

[cueweb/docs] Document the Monitor Cue page (CueCommander parity)

Document the new /monitor-cue page across all CueWeb guides and the
README:

- [x] user-guide: a "Monitor Cue" section - choosing shows, the full
column set, booking bar, row coloring, toolbar + selection, and the
Monitor-Cue-only
job actions.
- [x] reference: a "Monitor Cue" behavior table - Shows multi-select,
data source (getActiveShows -> getShowGroups -> getGroupJobs, 5s
refresh), columns + localStorage keys, booking bar, jobRowClass tints,
toolbar, context-menu gating, Send To Group
(group.GroupInterface/ReparentJobs), and the UNKNOWN_USER no-auth kill
fix.
- [x] developer-guide: a "Monitor Cue page" section - files, tree/data
flow, pathname-gated context menu, mounted dialogs, and the no-auth kill
fix.
- [x] other-guides: a feature-list entry (renumbered the CueCommander
pages so Monitor Cue precedes Monitor Hosts, matching menu order).
- [x] concepts: extended the GroupInterface row (GetJobs /
ReparentJobs).
- [x] getting-started: a deploy note (no extra services; gate the
destructive job actions via the group-authz admin gate).
- [x] quick-starts / tutorials: "Monitor the cue" walkthroughs.
- [x] README: a Monitor Cue feature bullet.

## LLM usage disclosure
Parts of this solution's implementation were developed with assistance
from Claude Opus.
…click to open (AcademySoftwareFoundation#2457)

## Related Issues

Main issue:
- AcademySoftwareFoundation#2016

Issues related to this PR:
- AcademySoftwareFoundation#2458

## Summarize your change.

JobDependencyGraph (Cuetopia > View Job Graph) now matches CueGUI's
JobMonitorGraph more closely:

- Always render the focus job's layers (ingestFocusLayers via
/api/job/getlayers), so a job with no cross-job dependencies still shows
its structure instead of an empty "No dependencies found" panel.
- Right-click a layer node for a context menu that reuses the
Layers-table actions via a { original: layer } shim: Auto Layout Nodes;
Dependencies (View Dependencies / Dependency Wizard / Mark done);
Reorder Frames; Stagger Frames; Properties; Kill / Eat / Retry / Retry
Dead Frames. The layer dialogs + Dependency Wizard are already mounted
by the host page, so the events resolve in both the inline panel and
/jobs/[name].
- Open the job detail page on double-click (onNodeDoubleClick) instead
of a single click, so a click no longer navigates away by accident.

Docs: updated the Job Dependency Graph coverage across the user-guide,
reference, developer-guide, other-guides, quick-starts, tutorials, and
concepts, and added the graph + right-click-menu screenshots (light
mode; dropped two redundant *_dark images).

## LLM usage disclosure
Parts of this solution's implementation were developed with assistance
from Claude Opus.
…oard (AcademySoftwareFoundation#2459)

## Related Issues

Main issue:
- AcademySoftwareFoundation#2016

Issues related to this PR:
- AcademySoftwareFoundation#2460

## Summarize your change.

Instrument CueWeb end-to-end so operators can see who uses what, how
often, and how fast - per user, per page/module, per action - with
bounded Prometheus cardinality. Mirrors the asset-search metrics
approach.

Metrics (GET /api/metrics, never gated by the authz gate):
- cueweb_page_views_total{user,page}, cueweb_actions_total{user,action}
- cueweb_api_requests_total{endpoint,status},
cueweb_api_request_duration_seconds{endpoint}
- cueweb_logins_total{user},
cueweb_facility_selected_total{user,facility}

Implementation:
- lib/metrics-service.ts: metric set + helpers + page/action allow-lists
(unknown values map to "other" so cardinality stays bounded).
- lib/track-user.ts: extractUser() resolves the user server-side
(session -> X-User/X-Forwarded-User -> anonymous); the client never sets
it.
- app/api/track/route.ts + app/utils/usage_tracking.ts +
components/ui/usage-tracker.tsx: client beacons for page views (on route
change) and actions (via the shared accessActionApi dispatcher).
- app/utils/gateway_server.ts handleRoute: records API request count +
latency for all proxy routes; best-effort, never affects responses.
- NEXT_PUBLIC_USAGE_TRACKING=off opts out the client beacon (the
/api/metrics endpoint and server-side metrics stay enabled).

Wiring + dashboard:
- sandbox/config/prometheus-monitoring.yml: cueweb scrape job
(cueweb:3000/api/metrics).
- sandbox/config/grafana/dashboards/cueweb-usage.json: "CueWeb User
Usage" (overview, pages, actions, API p50/p90/p99 over a fixed 5m
window, top-N users, $user variable).

Docs: reference (Usage metrics section + NEXT_PUBLIC_USAGE_TRACKING),
developer-guide (instrumentation flow + files), and deploying-cueweb
(scrape job + dashboard), with /api/metrics, Prometheus-query, and
Grafana screenshots.

## LLM usage disclosure
Parts of this solution's implementation were developed with assistance
from Claude Opus.
…reFoundation#2461)

## Related Issues

Main issue:
- AcademySoftwareFoundation#2016

Issues related to this PR:
- AcademySoftwareFoundation#2462

## Summarize your change.

Record who performed which state-changing action, when, against which
target, on which facility, and with what outcome, surfaced on a new
admin-only page reachable from the top menu and left sidebar (Admin ->
CueWeb Audit).

Implementation:
- Capture every mutating action at the single gateway chokepoint
(handleRoute in app/utils/gateway_server.ts -> auditGatewayCall in
lib/audit.ts): classify endpoint, extract target, resolve actor and
facility, sanitize params, skip read-only calls. Sign in/out captured
via NextAuth events in lib/auth.ts.
- Persist to an append-only JSONL store (lib/audit-store.ts), mirroring
the facility-store pattern so CueWeb stays stateless. Configurable via
CUEWEB_AUDIT_STORE; size-bounded via CUEWEB_AUDIT_MAX_RECORDS.
- Admin-gated read API (app/api/admin/audit) and SSR page
(app/admin/audit) with a filterable, paginated, mobile-friendly table:
search, actor/category/result/time filters, page navigation with
rows-per-page matching Monitor Jobs, auto-refresh, expandable details,
CSV export.
- Reuse the optional group-authorization gate: add /admin and /api/admin
to ADMIN_PATH_PREFIXES; isGateActive/isEffectiveAdmin show the page to
everyone when no group authorization is configured, else restrict to
CUEWEB_ADMIN_GROUPS. Hide admin-only menus from non-admins in the
header, sidebar, and mobile nav.
- Document the feature across all eight CueWeb docs sections and add
unit tests for the store/query logic and the effective-admin gating.

## LLM usage disclosure
Parts of this solution's implementation were developed with assistance
from Claude Opus.
…areFoundation#2354)

This PR just complement it:
AcademySoftwareFoundation#222

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added "Reorder Dispatch..." option to the layer context menu to set
dispatch priority for one or multiple layers.
* Exposed a layer dispatch-order API so layers can be reordered
programmatically.
* Added a Python SDK Layer method to update dispatch order from scripts.

* **Chores**
  * Version bumped to 1.26
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Alexis Oblet <alexis@theyard-vfx.com>
Signed-off-by: Alexis Oblet <aoblet@users.noreply.github.com>
Signed-off-by: Filipe Lacerda <53842848+tifilipebr@users.noreply.github.com>
Co-authored-by: Diego Tavares <dtavares@imageworks.com>
Co-authored-by: Alexis Oblet <alexis@theyard-vfx.com>
Co-authored-by: Alexis Oblet <aoblet@users.noreply.github.com>
…Foundation#2464)

Booking + accounting stress suite for the Rust scheduler.
cluster feed → job query → host matching → dispatch) against a realistic
farm in
two phases inside one process:

drain — farm capacity comfortably exceeds demand. Benchmarks booking
throughput (frames/s over the active booking window) and requires ≥90%
(STRESS_DRAIN_TARGET) of frames to dispatch.

saturation — demand vastly exceeds tight subscription bursts and per-job
core caps, so the Redis Lua cap check becomes the binding constraint.
Verifies
enforcement (no booking above burst / job max-cores) and that rejections
actually flowed through the accounting hot path.
After each phase, an audit cross-checks every Redis acct:* hash against
SUM(proc) in Postgres plus host/frame/stat invariants — with the
recompute and
limit-reseed loops pushed beyond the test horizon, agreement proves the
dispatch
hot path (Lua book + force-rollback) kept accounting exact on its own.
Requirements


## LLM Usage Disclaimer

Claude Opus was used to implement the tests and github actions on this
PR
* **Bug Fixes**
* Enforced per-job core caps during layer dispatching by clamping frame
core reservations to the job’s remaining allowance
* Added an early job-at-cap pre-check to avoid checkout attempts when a
job is already at or over its configured core limit
* Updated job pending/capacity calculations to use live “booked”
core/GPU usage from active processes

* **New Features**
* Added a Prometheus counter to track when job-level core-cap pre-checks
skip layer matching

* **Chores**
  * Improved formatting and updated/added unit tests for cap behavior


## LLM Usage Disclaimer

Claude Code Opus was used to help design and implement the changes on
this PR

---------

Signed-off-by: Diego Tavares <dtavares@imageworks.com>
…undation#2465)

The cluster feed round-robined the full cluster universe, whose size
scales with host/tag count rather than workload: a single show could fan
out to ~180 clusters (mostly hostname/manual) of which ~90% were idle,
so most passes ended in no_jobs and the round-trip p50 degraded as the
lap grew.

Add a periodic awake-gate scan that recomputes which (facility, show,
tag) tuples have plausibly-dispatchable work (JobDao::scan_active_tags),
and have the producer round-robin only that awake subset. Clusters with
no work stay out of the rotation until a later scan re-activates them;
the producer is woken immediately on an empty -> non-empty transition
via active_notify rather than waiting out the idle poll.

The scan query is a provable superset of the per-cluster dispatch query:
it keeps only a strict subset of that query's conjuncts
(PENDING/not-paused/ facility, a waiting layer carrying the tag, show
active+scheduler-managed) and drops the folder/job caps, so it can never
produce a false negative. Its subscription gate is the cheap static
`int_burst > 0` only -- the dynamic live-headroom check is deliberately
omitted to avoid an O(farm) full-`proc` aggregation every interval and
the over-count/false-exclude foot-gun that a global proc-sum would
carry. Burst enforcement stays in the per-cluster path, where an
over-burst-but-busy show backs off on cluster_saturated_sleep.

The existing per-pass sleep_map backoff is unchanged and still handles
the superset residual (clusters that are awake but turn out
capped/saturated on a real pass); the awake gate sits on top of it.

Adds config knob `active_scan_interval` (default 2s, the idle->dispatch
latency lever) and metrics scheduler_clusters_active,
scheduler_active_tags, and scheduler_active_scan_duration_seconds.
Covered by a new stress-test that asserts the scan is a superset of the
per-cluster query against live PG.

The remaining diff is rustfmt normalization.

## LLM Usage Disclosure

Some of the work of this PR was done using Claude Code Opus. 


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Scheduler now periodically focuses on clusters with dispatchable work,
reducing unnecessary re-checks and improving dispatch responsiveness.
  * Added new monitoring for the active cluster subset and scan timing.
* Configuration now includes a new interval to control how often active
clusters are re-scanned.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
… 4MB default (AcademySoftwareFoundation#2466)

## Related Issues
- AcademySoftwareFoundation#2467

## Summarize your change.
GetJobs on a busy facility can return tens of MB (35MB observed on
prod), exceeding gRPC's 4MB default and failing with "received message
larger than max". Set MaxCallRecvMsgSize to 256MB, overridable via
…ion (AcademySoftwareFoundation#2468)

## Related Issues
- AcademySoftwareFoundation#2431

## Summarize your change.

Extend the group-based authorization gate so the entire CueCommander
section and CueSubmit are admin-only, in the menus and server-side.

- authz.ts: add the remaining CueCommander routes to ADMIN_PATH_PREFIXES
(/monitor-cue, /hosts, /settings/facilities) and fix /stuck-frame ->
/stuck-frames so the prefix matches the actual route.
- menus.ts / app-sidebar.tsx: mark CueCommander and CueSubmit adminOnly
so both the top and left navs hide them from non-admins.
- app-header.tsx: hide "Manage facilities…" from non-admins.
- Update authz-admin tests for the newly gated paths.
…Foundation#2471)

If a lostProc could not be confirmed to have been killed, don't release
the frame to Waiting state. Wait for the host to have been confirmed
dead to release the proc for booking.

Flapping and genuinely-dead hosts are indistinguishable at kill time. If
the kill could not confirm the frame is stopped and the host is not
confirmed dead, releasing the frame now would re-book it onto a second
host while this RQD keeps rendering. In that case we DEFER the release:
the proc row and RUNNING frame are left intact (preserving the
host<->frame link, which is otherwise lost once the proc is deleted) so
the frame is reclaimed later, once the host is confirmed DOWN
(clearDownProcs) or the frame completes naturally. A genuinely dead host
(marked DOWN, or no longer Up) leaves no live RQD, so release is safe.
See design/frame_double_booking_v2.md.

## LLM usage disclaimer

Claude Code Opus was used to help investigating this issue

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added a new system metric for “deferred release procs” (lost procs
held back instead of released immediately).
* Introduced `dispatcher.defer_release_on_failed_kill_enabled` (default:
enabled) to defer releasing when the frame stop can’t be confirmed and
the host isn’t confirmed dead.

* **Bug Fixes**
* Improved lost-proc release/deferral logic to reduce double-booking
during frame-stop uncertainty and host flapping.
* Adjusted cleared-proc metrics so deferred cases no longer inflate
cleared counts.
* Enhanced orphaned-proc/frame maintenance reporting and warnings when
records are already missing.

* **Tests**
  * Expanded lost-proc decision-path coverage.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…demySoftwareFoundation#2470)

## Related Issues
- AcademySoftwareFoundation#2424

## Summarize your change.

The booking bar was h-8 (32px), making job rows taller than the show and
group header rows. Reduce it to h-5 (20px) so it matches the text-row
height; the min/max core markers still span the box and the running bar
stays centered.
…wareFoundation#2475)

## Related Issues
- AcademySoftwareFoundation#2476

## Summarize your change.
[cueweb] Request Okta groups scope for group memberships

- Add `groups` to the OIDC scopes so the Okta ID token carries group
claims consumed by extractGroups; required when using a custom Okta
Authorization Server.
…demySoftwareFoundation#2480)

## Related Issues
- AcademySoftwareFoundation#2481

## Summarize your change.

[cueadmin] Add lock-state filter and idle sort to host list

Add two options to `cueadmin -lh` to help surface idle hosts:

- `-lock-state {OPEN,LOCKED,NIMBY_LOCKED}` filters the host list to a
single lock state (e.g. NIMBY_LOCKED).
- `-sort-idle` sorts the output by most idle resources first (idle
cores, then idle memory) instead of by host name.

Filtering and sorting are applied client-side in displayHosts(), so no
gRPC or backend changes are required. Existing default behavior (sort by
name, no filter) is unchanged.

[docs/cueadmin] Document -lock-state and -sort-idle host list options

Document the two new `cueadmin -lh` options for surfacing idle hosts:

- `-lock-state {OPEN,LOCKED,NIMBY_LOCKED}` filters the host list to a
single lock state.
- `-sort-idle` sorts the output by most idle resources first.

Updates the cueadmin command and tools reference, the cueadmin tutorial,
the desktop rendering control guide, and the cueadmin README, noting
that NIMBY_LOCKED indicates an active user and that `-lh` reports
current state only (poll over time to track idle duration).
… menu (AcademySoftwareFoundation#2482)

## Related Issues
- AcademySoftwareFoundation#2483

## Summarize your change.

[cuegui/docs] Add search and scrolling to frame monitor Filter Layers
menu

- Replace the flat QMenu of checkable layer actions with an embedded
search box and a fixed-height, scrollable QListWidget, so jobs with
hundreds or thousands of layers no longer wrap into off-screen columns
with no way to scroll (the QMenu approach also ignored menu-scrollable
on some styles)
- Filter the layer list as you type; keep a Clear button to remove all
layer filters
- Preserve active layer filters across job refresh and guard
programmatic list updates so they don't clobber the current selection
- Update page-state and by-layer sync handlers to read the list widget
- Document the search box and scrollable list in the Cuetopia monitoring
guide
…re + PG LISTEN/NOTIFY (AcademySoftwareFoundation#2472)

The accounting subsystem coordinated Cuebot and the Rust scheduler
through Redis to enable horizontal scaling across N scheduler instances.
The scheduler is and will remain single-instance (N=1), so Redis's only
unique benefit is unreachable while it manufactured an entire class of
accounting-drift bugs (limit-seeding fail-closed, mass dispatch
rejection, double-booking, CAS starvation). A single in-process counter
is the source of truth that makes that bug class structurally
impossible.

**Scheduler** — Redis → in-memory `Store`:
- `accounting/store.rs`: one `Mutex`, atomic check-and-increment across
the three enforced vertices (subscription burst, folder/job max
cores+gpus). Layer/point were incremented but never read, so they're
dropped.
- Live updates via PG `LISTEN/NOTIFY` (`accounting/listener.rs`):
`acct_release` and `acct_limit_change`.
- Recompute from `SUM(proc)` is the backstop (absolute overwrite, no
CAS), carrying in-flight bookings forward via an epoch double-buffer so
it can never erase a not-yet-snapshot-visible booking → never over-books
a hard cap.
- Blocking seeds gate dispatch: bootstrap and managed-flip both seed
caps **and** booked counters before enforcing.
- Deleted `redis_client.rs`, `lua.rs`, `acct:seq`/CAS, the `redis`
dependency.

**Cuebot** — `LettuceAccountingRedisPublisher` → `AccountingNotifier`:
- Transactional `pg_notify` on proc release (same txn as `DELETE proc` →
delivered iff it commits, a stronger model than the old afterCommit
publish) and on the five enforced admin cap changes.
- `accounting.redis.*` and the Lettuce dep removed; replaced by a safe
`accounting.notify.enabled` kill-switch (off → scheduler degrades to
recompute-only, which under-books, never over-books). The old
over-booking startup guardrail is gone.

**Docs** — `redis-accounting.md` → `scheduler-accounting.md` (full
rewrite) plus `scheduler.md`, `deploying-scheduler.md`, stress-testing,
and properties.

- Caps are hard (license/OOM); every failure mode is safe-direction: a
dropped NOTIFY leaves a counter reading high → under-book → healed by
the next recompute.
- N=1 is now an assumption of the in-memory design; multi-scheduler
would need a shared store again (revisit trigger documented).

- Rust: 177 lib tests pass (incl. straddle, managed-flip, dropped-NOTIFY
invariants); clippy clean; stress suite compiles; bin builds.
- Cuebot: `compileJava`/`compileTestJava`/`spotlessJavaCheck` pass (JDK
11).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Scheduler resource accounting now uses an in-memory model synchronized
with PostgreSQL.
* Resource releases and limit changes are reflected transactionally,
improving accounting consistency.
  * Added support for monitoring accounting recomputation duration.

* **Bug Fixes**
* Improved booking rollback and confirmation handling when dispatch
operations fail.
* Preserved unlimited resource limits and improved handling of
managed-show transitions.

* **Documentation**
* Updated deployment, scheduler, and stress-testing guidance for the new
accounting architecture.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
)

Bumps [ws](https://github.com/websockets/ws) from 8.20.1 to 8.21.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/websockets/ws/releases">ws's
releases</a>.</em></p>
<blockquote>
<h2>8.21.1</h2>
<h1>Bug fixes</h1>
<ul>
<li>Empty fragments are now counted toward the limit (a2f4e7c0).</li>
<li>The default values of the <code>maxBufferedChunks</code> and
<code>maxFragments</code> options have
been reduced (f197ac65).</li>
</ul>
<h2>8.21.0</h2>
<h1>Features</h1>
<ul>
<li>Introduced the <code>maxBufferedChunks</code> and
<code>maxFragments</code> options (2b2abd45).</li>
</ul>
<h1>Bug fixes</h1>
<ul>
<li>Fixed a remote memory exhaustion DoS vulnerability (2b2abd45).</li>
</ul>
<p>A high volume of tiny fragments and data chunks could be sent by a
peer, using
modest network traffic, to crash a <code>ws</code> server or client due
to OOM.</p>
<pre lang="js"><code>import { WebSocket, WebSocketServer } from 'ws';
<p>const wss = new WebSocketServer({ port: 0 }, function () {
const data = Buffer.alloc(1);
const options = { fin: false };
const { port } = wss.address();
const ws = new WebSocket(<code>ws://localhost:${port}</code>);</p>
<p>ws.on('open', function () {
(function send() {
ws.send(data, options, function (err) {
if (err) return;
send();
});
})();
});</p>
<p>ws.on('error', console.error);
ws.on('close', function (code, reason) {
console.log(<code>client close - code: ${code} reason:
${reason.toString()}</code>);
});
});</p>
<p>wss.on('connection', function (ws) {
ws.on('error', console.error);
ws.on('close', function (code, reason) {
console.log(<code>server close - code: ${code} reason:
${reason.toString()}</code>);
});
});
</code></pre></p>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/websockets/ws/commit/ae1de54330cef77e487548890fabfeb9aae1d83d"><code>ae1de54</code></a>
[dist] 8.21.1</li>
<li><a
href="https://github.com/websockets/ws/commit/8e9511b86b3fc6deebbd97dd9af7c9056deea8d1"><code>8e9511b</code></a>
[ci] Trust Coveralls Homebrew tap</li>
<li><a
href="https://github.com/websockets/ws/commit/f197ac65140920bdcecdab74bfc69c2d7858e55d"><code>f197ac6</code></a>
[fix] Lower default values of <code>maxBufferedChunks</code> and
<code>maxFragments</code></li>
<li><a
href="https://github.com/websockets/ws/commit/8df8265c2f63fd44af3193a98e23cf38888cd991"><code>8df8265</code></a>
[ci] Update actions/checkout action to v7</li>
<li><a
href="https://github.com/websockets/ws/commit/a2f4e7c046c2112bbce6fef39a083dac77d6f0d2"><code>a2f4e7c</code></a>
[fix] Count empty fragments toward the limit (<a
href="https://redirect.github.com/websockets/ws/issues/2329">#2329</a>)</li>
<li><a
href="https://github.com/websockets/ws/commit/e79f912cb3f492ae04c28feb9459a209e186b0ad"><code>e79f912</code></a>
[pkg] Approve install scripts for bufferutil and utf-8-validate</li>
<li><a
href="https://github.com/websockets/ws/commit/4ea355d6d3069394994f82ca1b6d38c32ba208fb"><code>4ea355d</code></a>
[doc] Document 32-bit signed integer coercion for option values</li>
<li><a
href="https://github.com/websockets/ws/commit/2120f4c8c625a76316792680a231496e1b615252"><code>2120f4c</code></a>
[example] Remove uuid dependency</li>
<li><a
href="https://github.com/websockets/ws/commit/4c534a6b8a5224a563af116e85c6ced7d4ca60cf"><code>4c534a6</code></a>
[security] Add latest vulnerability to SECURITY.md</li>
<li><a
href="https://github.com/websockets/ws/commit/bca91adf15677e47dbe4f959653452727be28b94"><code>bca91ad</code></a>
[dist] 8.21.0</li>
<li>Additional commits viewable in <a
href="https://github.com/websockets/ws/compare/8.20.1...8.21.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ws&package-manager=npm_and_yarn&previous-version=8.20.1&new-version=8.21.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/AcademySoftwareFoundation/OpenCue/network/alerts).

</details>

Co-authored-by: Ramon Figueiredo <rfigueiredo@imageworks.com>

Signed-off-by: dependabot[bot] <support@github.com>
…demySoftwareFoundation#2399) (AcademySoftwareFoundation#2427)

## Related Issues

Resolves
AcademySoftwareFoundation#2399
Originally reported as
AcademySoftwareFoundation#1042
Related (not addressed here):
AcademySoftwareFoundation#2400

## Summarize your change.

CueGUI's `TasksDialog` is written entirely against the pycue wrapper
API, but the `Department` wrapper it depends on was never implemented —
so opening the dialog raised `AttributeError` on `Show.getDepartments()`
(`TasksDialog.py:94`). This adds the missing wrapper layer and fixes two
related gaps found while wiring it up.

**pycue**
- New `opencue/wrappers/department.py`: `Department` wrapper following
the existing `task.py` pattern (`self.data` + `self.stub`, one method
per RPC), covering the `DepartmentInterface` RPCs that cuebot
implements: `addTask`, `addTasks`, `clearTasks`, `clearTaskAdjustments`,
`enableTiManaged`, `disableTiManaged`, `getTasks`, `replaceTasks`,
`setManagedCores`. `DepartmentInterface.Delete` is intentionally **not**
wrapped — cuebot has no implementation for it.
- `Show.getDepartment()` / `Show.getDepartments()`, mirroring the
existing `getGroups()`.
- Module-level `api.addDepartmentName()` / `api.removeDepartmentName()`,
alongside the existing `getDepartmentNames()`.
- `Task.clearAdjustments()`, used by the Tasks dialog context menu.

**cuegui**
- `TaskActions.clearAdjustment` called `task.clearAdjustment()`, which
never existed on the wrapper; the unit test mocked the attribute, so the
gap was never caught. Both now call the real `Task.clearAdjustments()`.

**cuebot / proto**
- The proto declared `rpc SetMangedCores` (typo) while the servant
implements `setManagedCores`. Because the names differed, the servant
never overrode the generated base method and the RPC always returned
`UNIMPLEMENTED` — so the "Minimum Cores" control in `TasksDialog` would
fail even with the wrapper in place. Renamed the RPC to
`SetManagedCores` and added `@Override` on the servant. The rename is
safe: no client could have called the old RPC successfully, and nothing
references the old name. `VERSION.in` is bumped 1.25 → 1.26 as required
by `ci/check_version_bump.py` for proto changes.

**Tests**: new `tests/wrappers/test_department.py`, plus
`getDepartment`/`getDepartments` in `test_show.py`, `clearAdjustments`
in `test_task.py`, and
`getDepartmentNames`/`addDepartmentName`/`removeDepartmentName` in
`test_api.py`.

**Open question for the reviewer**: AcademySoftwareFoundation#2400 suggested naming these
`createDepartment` / `deleteDepartment`. I chose `addDepartmentName` /
`removeDepartmentName` instead, to match the underlying RPC names and
the existing `getDepartmentNames()`, and because they manage the
allowed-name whitelist rather than creating a show's department entity
(entities are auto-created when a name is assigned to a group — see
`department.proto`). Happy to rename if the `create`/`delete` spelling
is preferred.

## LLM usage disclosure

Claude (Opus) was used to build up testing environment across
cuegui/pycue/cuebot, write the unit tests, and draft this PR
description.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Added department support across the Python API and wrappers, including
listing/viewing departments from a show and managing department task
settings and managed cores.
  * Added API actions to add or remove department names.
  * Added task-level support to clear all task adjustments.

* **Bug Fixes**
* Renamed the department managed-cores RPC to the corrected method name.
* Updated task adjustment clearing behavior to consistently use the
plural clear operation.

* **Documentation**
  * Expanded Sphinx API docs to include the department wrapper.

* **Tests**
* Added/updated unit tests for department, show, task, and API
behaviors.

* **Chores**
  * Updated the project version to 1.28.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Hai Shun <o927416847@gmail.com>
Signed-off-by: Diego Tavares <dtavares@imageworks.com>
Co-authored-by: Diego Tavares <dtavares@imageworks.com>
…order (AcademySoftwareFoundation#2479)

## Related Issues
- AcademySoftwareFoundation#2016

## Summarize your change.

Add `news/2026-07-07-cueweb-full-cuegui-parity-release.md` announcing
the first full release of CueWeb, replicating all CueGUI functionality
(Cuetopia and CueCommander) on the master branch. Includes feature
summary, screenshots, contributor list with per-PR credits, and links to
the full CueWeb and REST Gateway documentation set.

Reassign `nav_order` across all existing news posts (via
`news/update_nav_order.py`) so the new post sorts first.
…mySoftwareFoundation#2484)

## Related Issues
- AcademySoftwareFoundation#1800

## Summarize your change.
- Update product name in docs, headings, frontmatter titles, UI labels,
table cells, image alt text, and link display text across 26 docs files
- Rename rendered diagram labels (mermaid sequence diagram, ASCII
architecture box) and .env/bash code-block comments for consistency
- Preserve verbatim PR/commit titles in release notes, the CueWebIcon
component identifier, and the literal kill-reason string
- Leave lowercase cueweb slugs, URLs, permalinks, image paths, CUEWEB_*
env vars, and file names unchanged to avoid breaking links

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Updated product branding throughout from “CueWeb” to **OpenCueWeb**
(titles, labels, navigation, and links).
* Refreshed getting started, deployment, quick-starts, user/developer
guides, tutorials, and references with updated screenshots, diagrams,
and UI text.
* Clarified **authentication/authorization** behavior, **OpenCueWeb
Audit** trail details, **multi-facility** routing, REST Gateway/JWT
naming, and operational guidance (including job submission and real-time
updates).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
…tery

A tick-driven, in-process scheduler (scheduler.enabled) that plans placements
by E-PVM opportunity cost instead of relying on the report-driven dispatcher:

- E-PVM placement scored on cores/memory/GPU stranding, with a same-host
  locality bonus so a completing proc's cores tend to refill from the same layer.
- Whole-host reservations + EASY backfill so wide jobs never strand behind
  narrow work; dispatcher.frame_cores_max raises the per-frame core clamp for
  whole-host jobs.
- Priority-weighted lottery (Efraimidis-Spirakis) for booking order, so a
  sustained high-priority backlog cannot starve lower-priority work. Priority
  becomes a rate, not a rank (see Scheduler.md section 3.5).
- License limits and folder/group core ceilings honored in-tick. The candidate
  query skips layers whose limit (limit_record.int_max_value) is full or whose
  folder (folder_resource.int_max_cores) is at its ceiling, so no doomed bookings
  are planned. Limits stay exact through the existing downstream frame query; the
  folder ceiling is held exactly by a pre-commit pass that trims any planned frame
  which would push a capped folder past its cap (planHost has no folder clause, so
  the batch must be trimmed before it commits).
- Per-frame OOM memory handling: bump the offending frame and escalate the whole
  layer only after repeated OOMs, instead of ratcheting the layer on every kill.
- Batch-commit robustness: skip a full host instead of aborting the whole tick,
  plus reserved/backfilled-core instrumentation on the scheduler stat line.

Gated behind scheduler.enabled: with the scheduler off and booking on, the legacy
dispatcher path is unchanged. The standalone-scheduler handoff mode (scheduler off
+ dispatcher.turn_off_booking=true) additionally suppresses FrameCompleteHandler's
reactive rebook paths, so cuebot only reconciles RQD reports while an external
planner owns booking.
A one-command simulator that runs a real cuebot + Postgres against a fake RQD
and a synthetic farm (up to ~1553 hosts) to exercise the scheduler under load:

- Workload feeders: steady fill, priority streams, and wide-job strand tests;
  a per-layer memory model (baseline + jitter) so a layer's frames cluster
  realistically instead of drawing memory independently.
- Live stats and end-of-run graphs (utilization, throughput, cores-vs-memory,
  reservation subsystem, DB load), each stamped with the simulate.py command
  line so every graph is traceable to the config that produced it.
- --strand-cores for whole-host (128-core) reservation tests.

--verify is the recommended way to run it: one command that exercises the
scheduler end to end. It runs six scenarios back-to-back, each a fresh, fully
torn-down sim that writes its own graphs, then prints a PASS/FAIL summary
(nonzero exit if any scenario fails):

    OOM               -- memory failures bump the layer's memory per-frame,
                         no legacy ratchet, and frames retry
    PRIORITY          -- completion share is ordered by priority across 10
                         classes (Spearman rho)
    PRIORITY_STARVING -- a low-priority stream survives a high-priority flood
                         (stays above a 3% floor)
    RESERVATIONS      -- stranded wide jobs are rescued by reservations +
                         backfill and actually run
    LIMIT             -- a global license cap (limit_record.int_max_value) holds
                         concurrent running frames at the cap under a deep backlog
    FOLDER            -- a folder/group core ceiling (folder_resource.int_max_cores)
                         holds the folder's running cores at the cap under a deep
                         backlog

Run it exactly as `simulate.py --verify`, with no other flags. Each scenario is
tuned (farm size, oversubscription, frame length) so its verdict is meaningful;
changing the options on a --verify run is unsupported and easily misleading
(e.g. PRIORITY only shows proportional shares on a small, heavily oversubscribed
farm -- on the full farm priority looks absent though the scheduler is correct).
Only SIM_VERIFY_SECONDS (per-scenario length) is meant to be adjusted.

The simulator's what/how, the --verify guidance, and the full flag reference
live in cuebot/scheduler-sim/README.md.
The new scheduler files and touched shared files were written wrapped at
~80 columns; the project's spotless config (eclipse JDT, jdtls.xml) wraps
javadoc and code at 100. Formatting only -- no behavior change.
…res branch

- doTick: clear plannedByHost with the other per-tick resets. It is
  normally drained every tick, but a tick that throws mid-placement left
  stale (host, layer) pairings that the next tick would plan against a
  fresh snapshot.
- planHost: remove the stranded-cores block copied from dispatchHost. The
  plan phase must stay read-only, and the branch was unreachable anyway:
  the only strandCores() producer is the legacy completion path (gated off
  by bookingOff in facility mode), and it sets the field on its own
  DispatchHost instance while the planner works from freshly DAO-loaded
  hosts that never carry it. The tick planner also replans every tick,
  which subsumes the legacy refill-freed-cores-fast behaviour stranded
  cores existed for.
… tags

Address review comments on the scheduler-sim harness:

* drain_test.py: the per-job local `spec` shadowed `import farm_spec as
  spec`, so `spec.GRPC` on the first line of main() raised
  UnboundLocalError -- the drain test crashed on startup. Rename the
  local to `job_spec`.

* make_graphs.py, make_graphs_ba.py, analyze_sweep.py: the DB-sampler CSV
  carries blks_read/blks_hit before active/lockwait, but the readers
  still mapped active/lockwait to indices 8/9 -- plotting blks_read and
  blks_hit instead. Remap to 10/11 and fix the column-legend comment.

* status_pinger.py, status_pinger_fast.py: hosts were registered with
  tags=[TAG], dropping the per-host capability tag, so the SIM_NTAGS>=2
  fragmentation model silently did nothing. Use host_tags(name).

* gen_jobs.py, metrics.py, stats.py: replace hardcoded farm sizes (57248
  cores, /1553 hosts) with farm_spec.total_cores()/total_hosts() so they
  track SIM_HOST_COUNTS small-farm mode.

* db_sampler.py: resolve psql via SIM_PG_BIN instead of a bare "psql".

* BUILD.md: add language hints to fenced code blocks and drop a stray
  trailing code fence.
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.

[cuebot] Missing parentheses in getWhatDependsOn(Frame) SQL changes WHERE clause scope