)]}'
{
  "log": [
    {
      "commit": "eefd8600b6cf75da9e5d3067bc531ac3bc4faba9",
      "tree": "14b1cb6f67c92311ffb19c5787a733aecf708254",
      "parents": [
        "86dd852085db10e8fe7c2db59a9232ef8347eb67"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 06:49:49 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 06:49:49 2026 +0000"
      },
      "message": "fix(computing-unit): repair the owner-avatar accessor in the spec (#7633)\n\n### What changes were proposed in this PR?\n\n**`main` does not compile.** Any PR whose `build / amber` or `build /\namber-integration` jobs run after this landed fails on it regardless of\nwhat the PR itself touches — #7631 is an example, where the only change\nis four tests in an unrelated module\u0027s spec.\n\nScoping that honestly: PRs whose amber jobs ran *before* the breakage\nstill show green and would fail on re-run, and frontend-labelled PRs\nskip the amber stack, so this is \"every amber run from now until it is\nfixed\" rather than \"every open PR is red today\".\n\n`ComputingUnitManagingResourceSpec` asserts on\n`DashboardWorkflowComputingUnit.ownerGoogleAvatar`, but the field is\nnamed `ownerAvatar`, so `ComputingUnitManagingService / Test` fails with\ntwo \"value ownerGoogleAvatar is not a member\" errors.\n\nTwo PRs raced to produce it: #7563 renamed the field to `ownerAvatar`,\nwhile #7580 added assertions written against the old name. Each was\ngreen against its own base, and the combination is what breaks — the\nkind of thing per-PR CI cannot see when two PRs touch different files.\n\nThis renames the two accessor calls. Nothing else changes.\n\n### How was this PR tested?\n\nConfirmed the breakage is real and that this is the whole of it, by\nstashing the change and re-running on otherwise-clean `main`:\n\n```\nsbt \"ComputingUnitManagingService/Test/compile\"\n```\n\n| | Result |\n|---|---|\n| unpatched `main` | exit 1, exactly 2 × `value ownerGoogleAvatar is not\na member` |\n| with this change | exit 0, compiles clean |\n\nThen the spec itself:\n\n```\nsbt \"ComputingUnitManagingService/testOnly org.apache.texera.service.resource.ComputingUnitManagingResourceSpec\"\n```\n\n```\n[info] Total number of tests run: 31\n[info] Tests: succeeded 31, failed 0, canceled 0, ignored 0, pending 0\n```\n\nAll 31 pass, so the assertions were correct about the value and only the\naccessor name was stale. `Test/scalafmtCheck` and `Test/scalafix\n--check` both pass.\n\n### Any related issues, documentation, discussions?\n\nCloses #7632\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "86dd852085db10e8fe7c2db59a9232ef8347eb67",
      "tree": "3b7b6dbdbc8458c8972019f3b9e6e80fb3ba8a57",
      "parents": [
        "7a6ee7cf9198de7b103bacf685b4237b804a6ef4"
      ],
      "author": {
        "name": "Matthew B.",
        "email": "mgball@uci.edu",
        "time": "Thu Aug 13 06:15:06 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 06:15:06 2026 +0000"
      },
      "message": "test(frontend): cover the workflow-snapshot render path in ReportGenerationService (#6471)\n\n### What changes were proposed in this PR?\n\nCovers the last uncovered part of `ReportGenerationService`: the render\ncallback of\n`generateWorkflowSnapshot`, which encodes the canvas html2canvas hands\nback as a PNG and completes\nthe observable. No production code changed.\n\nWhile this PR sat, main grew its own `report-generation.service.spec.ts`\n(#7383, #7541), which\ntook over every case this branch originally added and left exactly one\ngap — lines 93-95 of the\nservice:\n\n```ts\n.then((canvas: HTMLCanvasElement) \u003d\u003e {\n  const dataUrl: string \u003d canvas.toDataURL(\"image/png\");   // 93\n  observer.next(dataUrl);                                  // 94\n  observer.complete();                                     // 95\n})\n```\n\nmain\u0027s suite deliberately leaves the render alone (\"it needs a real\ncanvas\") and asserts only on\nthe image-inlining step that precedes it. This PR closes that gap, so\nthe merge keeps main\u0027s\nversion of the file wholesale and adds one `describe` on top of it.\n\n| | statements | uncovered | tests in file |\n| --- | --- | --- | --- |\n| main | 126/129 (97.7%) | 93, 94, 95 | 24 |\n| this PR | **129/129 (100%)** | none | 26 |\n\nBranches stay at 25/25 and functions go from one uncovered (the callback\nat line 92) to none.\n\n**Why the original approach could not work.** The first version of this\ntest replaced the renderer\nwith `vi.mock(\"html2canvas\", () \u003d\u003e ({ default: vi.fn() }))`. That passes\non its own and fails in\nCI, which is what the `build / frontend` job was reporting:\n\n```\nTypeError: Cannot read properties of null (reading \u0027scale\u0027)\n ❯ new ForeignObjectRenderer node_modules/html2canvas/dist/html2canvas.esm.js:7570:19\n```\n\n`@angular/build`\u0027s unit-test runner sets `isolate: false` (\"Default to\n`false` to align with the\nKarma/Jasmine experience\"), so every spec file shares one module\nregistry. `MenuComponent`\u0027s spec\npulls this service in transitively, so whichever spec loads html2canvas\nfirst pins it for the whole\nrun — the mock reaches the spec\u0027s own import but not the\nalready-instantiated service, which keeps\nthe real module and dies on jsdom\u0027s unimplemented `getContext`. Solo,\nnothing loads the service\nfirst, so the mock applies and the test passes; that gap between the two\nis why this only showed up\nin CI.\n\nSo the real renderer is used instead, with jsdom given the three pieces\nit lacks: a permissive 2D\ncontext, an `\u003cimg\u003e` that reports a data-URL source as loaded, and a PNG\nencoder. That also lets the\nfailure path be pinned with a known error instead of jsdom\u0027s incidental\none.\n\n### Any related issues, documentation, discussions?\n\nCloses #6459\n\n### How was this PR tested?\n\nTwo new cases, both run in the full-suite configuration that broke the\noriginal:\n\n```bash\ncd frontend \u0026\u0026 yarn test:ci\n```\n\n`200 test files passed`, `4444 passed | 1 skipped`, up from `4442 passed\n| 1 skipped` on main.\nCoverage of `report-generation.service.ts` was read out of\n`coverage/gui/coverage-final.json` from\nthat same full-suite run, on main and on this branch, to get the numbers\nin the table above.\n\nThe file on its own:\n\n```bash\ncd frontend \u0026\u0026 npx ng test --watch\u003dfalse --include\u003d\u0027**/report-generation.service.spec.ts\u0027\n```\n\n`26 tests` pass. `yarn format:ci` is clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nYes, in compliance with ASF policy. The original spec was co-authored\nwith Claude Opus 4.8; the\nconflict resolution and the CI fix were co-authored with Claude Code.\n\nGenerated-by: Claude Code (Claude Opus 5)\n\n---------\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "7a6ee7cf9198de7b103bacf685b4237b804a6ef4",
      "tree": "5439b8148d0454688850dfadbc7c3f08a7df617f",
      "parents": [
        "f7fb3c1715470ddeb4428c131dd5ba60cd71a5c3"
      ],
      "author": {
        "name": "Yicong Huang",
        "email": "17627829+Yicong-Huang@users.noreply.github.com",
        "time": "Thu Aug 13 06:14:43 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 06:14:43 2026 +0000"
      },
      "message": "feat(local-dev): pick a usable Python and offer to install a missing toolchain (#7078)\n\n\u003e **Depends on the Linux-support PR** (`feat(local-dev): support\nLinux`), which this needs for the platform detection. That branch is\nthis one\u0027s parent commit, so it shows up in this diff too — review it\nthere, and read only the second commit here. I\u0027ll rebase once it lands.\n\n### What changes were proposed in this PR?\n\nTwo halves of the same fresh-machine problem.\n\n**The interpreter that runs Python UDFs was picked blindly.**\n`UDF_PYTHON_PATH` defaulted to `command -v python3` at source time — the\nsystem interpreter, which almost never has `amber/requirements.txt`\ninstalled. Python UDFs then failed at worker launch on a stack of import\nerrors that pointed nowhere near the interpreter choice. The venv\nAGENTS.md tells contributors to create (`\u003cworkspace\u003e/venv312`) was\nignored, as was an already-activated `$VIRTUAL_ENV`.\n\nResolution is now lazy, and takes the first candidate that is Python\n3.12 **and** can import what a worker needs:\n\n```\n$UDF_PYTHON_PATH  -\u003e  $VIRTUAL_ENV  -\u003e  \u003cworkspace\u003e/venv312  -\u003e  pyenv 3.12\n  -\u003e  python3.12 on PATH  -\u003e  python3 on PATH\n```\n\nThe choice is reported the way the JDK probe reports `JAVA_HOME`. An\nexplicit `UDF_PYTHON_PATH` still wins — it is the documented override —\nbut now says so when it can\u0027t import the deps. \"No 3.12 anywhere\" and\n\"3.12 without amber\u0027s deps\" are reported differently, because they need\ndifferent fixes and the old default silently produced the second one.\nLazy so `status` / `logs` / `--help` don\u0027t spawn an interpreter per\ncandidate, and never fatal: the JVM services run fine without a Python\ntoolchain, only UDFs don\u0027t.\n\n**A missing tool was described, never offered.** `_install_hint` printed\na suggestion and gave up, so a fresh machine meant hand-installing five\nor six things, re-running `up` after each to discover the next gap. A\nmissing JDK 17, Node or Python 3.12 is now offered for install, after\nshowing the exact command:\n\n| Tool | Installer |\n| --- | --- |\n| JDK 17 | distro package manager\n(`apt-get`/`dnf`/`yum`/`pacman`/`zypper`), `brew` on macOS, SDKMAN when\nthere is none |\n| Node 24 | `nvm` (bootstraps nvm first if absent) |\n| Python 3.12 | `pyenv` (bootstraps pyenv first if absent) |\n\n`jenv` is not used: it switches between JDKs, it cannot install one.\n\nThe decision helpers (`_pkg_manager`, `_install_cmd_for`) only ever\n*print* what would run; a separate step executes it. That keeps the\nchoice unit-testable without installing anything, and it means the user\nsees the command — `sudo` included — before being asked.\n\nBehaviour deliberately preserved for non-interactive callers: **without\na TTY nothing is ever prompted** and the old print-a-hint-and-fail path\nstands, so scripted and CI runs cannot hang on a `read`.\n`--install-missing` answers yes without asking, `--no-install` only ever\nprints the hint, and the contradiction is refused rather than silently\nresolved. docker and sbt stay hint-only — docker needs a daemon, group\nmembership and a re-login, which is not something to do behind a y/n\nprompt.\n\n### Any related issues, documentation, discussions?\n\nCloses #7066 Depends on the Linux-support PR (#7065).\n\n### How was this PR tested?\n\nNew coverage in the existing `infra`-job suite. Everything goes through\nthe pure decision helpers, so CI asserts on *what would be installed*\nwithout installing anything; the Python probes are driven by fake\ninterpreters that echo a version or set an exit code:\n\n```\n$ bash bin/local-dev/tests/test_local_dev_sh.sh\n...\n  ✓ pkg manager: apt-get → apt-get\n  ✓ pkg manager: dnf only → dnf\n  ✓ pkg manager: pacman only → pacman\n  ✓ pkg manager: apt-get preferred over dnf → apt-get\n  ✓ pkg manager: nothing installed (refuses)\n  ✓ _pkg_manager keeps the Darwin/brew branch\n  ✓ install cmd: java via apt names openjdk-17-jdk\n  ✓ install cmd: java via apt asks for sudo explicitly\n  ✓ install cmd: java via dnf names java-17-openjdk-devel\n  ✓ install cmd: java with no package manager falls back to SDKMAN\n  ✓ install cmd: node uses nvm\n  ✓ install cmd: python uses pyenv\n  ✓ install cmd: python pins 3.12\n  ✓ install cmd: refuses \u0027docker\u0027\n  ✓ install cmd: refuses \u0027sbt\u0027\n  ✓ install cmd: refuses \u0027definitely-not-a-tool\u0027\n  ✓ consent: refuses without a TTY (never prompts)\n  ✓ consent: TEXERA_INSTALL_MISSING\u003d1 assumes yes\n  ✓ consent: TEXERA_INSTALL_MISSING\u003d0 refuses\n  ✓ python probe: 3.12 accepted\n  ✓ python probe: 3.11 rejected\n  ✓ python probe: missing interpreter rejected\n  ✓ python probe: importable deps accepted\n  ✓ python probe: missing deps rejected\n  ✓ python probe: empty path rejected\n  ✓ python candidates: $VIRTUAL_ENV before sibling venv312\n  ✓ python candidates: venv312 before bare python3 on PATH\n  ✓ _require_udf_python helper is defined\n  ✓ cmd_up resolves the UDF interpreter before launching\n  ✓ cmd_auto resolves the UDF interpreter before launching\n  ✓ cmd_up_one resolves the UDF interpreter before launching\n  ✓ _require_udf_python points at amber\u0027s requirements, not the TUI hint\n  ✓ UDF_PYTHON_PATH no longer defaults to bare python3 at source time\n  ✓ --help documents --install-missing / --no-install\n  ✓ up rejects --install-missing together with --no-install (rc\u003d2)\n\n103 passed, 0 failed\n```\n\n```\n$ python -m pytest bin/local-dev/tests/ -q\n1 failed, 42 passed\n```\n\n`test_is_dirty_after_seed_then_edit` is **pre-existing and unrelated** —\nit reproduces identically on a pristine `upstream/main` checkout on this\nmachine, and this PR touches neither `tui.py` nor that test. Filed as\n#7075 and fixed there.\n\nManually, on Ubuntu 24.04.4 with the amber deps installed into a sibling\n`venv312` and nothing in `UDF_PYTHON_PATH` — it finds the venv rather\nthan the system interpreter the old default would have taken:\n\n```\n$ bin/local-dev.sh auto\n  ✓  python: /home/…/Repos/venv312/bin/python  (runs Python UDFs)\n\n$ command -v python3            # what the old default resolved to\n/usr/bin/python3\n$ /usr/bin/python3 -c \"import pyarrow\"\nModuleNotFoundError: No module named \u0027pyarrow\u0027\n```\n\nThe consent path, forced by pinning a version that cannot exist\n(`TEXERA_PYTHON_VERSION\u003d3.99`). With a TTY it shows the command and\nasks; the answer here was `n`, and the run continued:\n\n```\n  ⚠  python: no Python 3.99 found — Python UDFs will not run\n  looked in: $VIRTUAL_ENV, \u003cworkspace\u003e/venv312, pyenv, PATH\n  or point at one yourself: export UDF_PYTHON_PATH\u003d/path/to/python3.99\n\n  python is missing. I can run:\n\n      curl -fsSL https://pyenv.run | bash \u0026\u0026 export PYENV_ROOT\u003d\"$HOME/.pyenv\" \u0026\u0026 … \u0026\u0026 pyenv install -s 3.99\n\n  Run it now? [y/N]\n```\n\nWithout a TTY (`\u003c/dev/null`) the same run prints the warning, never\nprompts, does not hang, and exits 0. Both flags are accepted on their\nown (`auto --no-install`, `auto --install-missing` → rc 0) and rejected\ntogether (rc 2).\n\nNot exercised end-to-end: actually running the JDK / Node / pyenv\ninstallers, since this machine already has all three. The commands\nthemselves are asserted by the tests above; the execution step is a\n`bash -lc` of exactly the string shown to the user.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)"
    },
    {
      "commit": "f7fb3c1715470ddeb4428c131dd5ba60cd71a5c3",
      "tree": "e869ec255e6b2cab4afaf7ea671b5c6f1021f295",
      "parents": [
        "19fb99fc89d70eabea84feca712002c2ee8ecd77"
      ],
      "author": {
        "name": "roshiiiiz",
        "email": "roshaanzafar12@gmail.com",
        "time": "Thu Aug 13 06:11:26 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 06:11:26 2026 +0000"
      },
      "message": "feat(operator): provide user-friendly error message when binary file scan hits memory limit (#6811)\n\n\u003c!--\nThanks for sending a pull request (PR)! Here are some tips for you:\n1. If this is your first time, please read our contributor guidelines:\n[Contributing to\nTexera](https://github.com/apache/texera/blob/main/CONTRIBUTING.md)\n  2. Ensure you have added or run the appropriate tests for your PR\n  3. If the PR is work in progress, mark it a draft on GitHub.\n  4. Please write your PR title to summarize what this PR proposes, we \n    are following Conventional Commits style for PR titles as well.\n  5. Be sure to keep the PR description updated to reflect all changes.\n--\u003e\n\n### What changes were proposed in this PR?\n\u003c!--\nPlease clarify what changes you are proposing. The purpose of this\nsection\nis to outline the changes. Here are some tips for you:\n  1. If you propose a new API, clarify the use case for a new API.\n  2. If you fix a bug, you can clarify why it is a bug.\n  3. If it is a refactoring, clarify what has been changed.\n  3. It would be helpful to include a before-and-after comparison using \n     screenshots or GIFs.\n  4. Please consider writing useful notes for better and faster reviews.\n--\u003e\nThis PR improves the user experience for the File Scan operator\u0027s\nin-memory read path by gracefully catching natural Java memory limits\nand surfacing a helpful UI error message, rather than allowing the\nworker JVM to crash.\n\n**Why is it needed?**\nPreviously, when users mistakenly attempted to read massive files using\nthe `binary` attribute type (instead of the streaming `large binary`\ntype), `ByteArrayOutputStream` would attempt to allocate the entire file\ninto memory. If the file exceeded the JVM\u0027s available heap space or the\nmaximum Java array size, it triggered an unhandled `OutOfMemoryError` or\n`IllegalArgumentException`, causing the `computing-unit-master` to lock\nup or crash entirely without reporting a user-friendly error to the\nfrontend UI.\n\n**What was changed:**\n- Wrapped the stream reader in `FileScanUtils.safeToByteArray` with a\n`try-catch` block.\n- Intercepts natural `OutOfMemoryError` and `IllegalArgumentException`\nthrown by the JVM or `ByteArrayOutputStream`.\n- Throws a clean, user-friendly `RuntimeException` directly to the\nfrontend directing the user to use the `large binary` attribute type\ninstead for massive files.\n\n*(Note: Based on maintainer feedback, an initial hardcoded size\nthreshold approach was dropped in favor of this cleaner architectural\napproach that relies on natural JVM limits).*\n\n### Any related issues, documentation, discussions?\n\u003c!--\nPlease use this section to link other resources if not mentioned\nalready.\n1. If this PR fixes an issue, please include `Fixes #1234`, `Resolves\n#1234`\nor `Closes #1234`. If it is only related, simply mention the issue\nnumber.\n  2. If there is design documentation, please add the link.\n  3. If there is a discussion in the mailing list, please add the link.\n--\u003e\nCloses #3271 \n\n### How was this PR tested?\n\u003c!--\nIf tests were added, say they were added here. Or simply mention that if\nthe PR\nis tested with existing test cases. Make sure to include/update test\ncases that\ncheck the changes thoroughly including negative and positive cases if\npossible.\nIf it was tested in a way different from regular unit tests, please\nclarify how\nyou tested step by step, ideally copy and paste-able, so that other\nreviewers can\ntest and check, and descendants can verify in the future. If tests were\nnot added,\nplease describe why they were not added and/or why it was difficult to\nadd.\n--\u003e\n**Manual Verification:**\n1. Uploaded an 8.9 GB CSV test file to the workspace.\n2. Created a workflow with the `File Scan` operator configured to use\nthe `binary` attribute type (which intentionally attempts to load the\nentire file into memory).\n3. Ran the workflow.\n**Result:** The workflow caught the JVM\u0027s `OutOfMemoryError` when\nattempting the massive allocation, safely aborted the thread, and\nsuccessfully threw the custom user-friendly error message in the UI\nwithout crashing the server.\n\n**Automated Tests:**\n- Updated the mock in `FileScanUtilsSpec.scala` to simulate a natural\n`OutOfMemoryError` being thrown during stream reading to prove the\n`catch` block reliably intercepts it and translates it to the\nuser-friendly exception.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\u003c!--\nIf generative AI tooling has been used in the process of authoring this\nPR,\nplease include the phrase: \u0027Generated-by: \u0027 followed by the name of the\ntool\nand its version. If no, write \u0027No\u0027. \nPlease refer to the [ASF Generative Tooling\nGuidance](https://www.apache.org/legal/generative-tooling.html) for\ndetails.\n--\u003e\nGenerated-by: Antigravity (DeepMind)\n\n---------\n\nCo-authored-by: probe \u003cprobe@x\u003e\nCo-authored-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "19fb99fc89d70eabea84feca712002c2ee8ecd77",
      "tree": "30546ccd19e8029b2cfca47d88521441675bdeb7",
      "parents": [
        "052cf38c02797d8c10afceea2c39f11d3d16dfdd"
      ],
      "author": {
        "name": "William Wong",
        "email": "120128836+wwong0@users.noreply.github.com",
        "time": "Thu Aug 13 05:58:39 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:58:39 2026 +0000"
      },
      "message": "feat(workflow-compiling-service): LogicalLink OperatorIdentity round-trip (#5729)\n\n\u003c!--\nThanks for sending a pull request (PR)! Here are some tips for you:\n1. If this is your first time, please read our contributor guidelines:\n[Contributing to\nTexera](https://github.com/apache/texera/blob/main/CONTRIBUTING.md)\n  2. Ensure you have added or run the appropriate tests for your PR\n  3. If the PR is work in progress, mark it a draft on GitHub.\n  4. Please write your PR title to summarize what this PR proposes, we \n    are following Conventional Commits style for PR titles as well.\n  5. Be sure to keep the PR description updated to reflect all changes.\n--\u003e\n\n### What changes were proposed in this PR?\n\u003c!--\nPlease clarify what changes you are proposing. The purpose of this\nsection\nis to outline the changes. Here are some tips for you:\n  1. If you propose a new API, clarify the use case for a new API.\n  2. If you fix a bug, you can clarify why it is a bug.\n  3. If it is a refactoring, clarify what has been changed.\n  3. It would be helpful to include a before-and-after comparison using \n     screenshots or GIFs.\n  4. Please consider writing useful notes for better and faster reviews.\n--\u003e\nBug fix: `LogicalLink` `@JsonCreator` constructor (`amber` and\n`workflow-compiling-service`)\n\n`@JsonCreator` was previously placed on the `String` convenience\nconstructor of `LogicalLink` in both modules. `OperatorIdentity` is a\ncase class that Jackson serializes as an object (`{\"id\":\"op-A\"}`), not a\nplain string. When reading back a serialized `LogicalLink`, Jackson\ndispatched to the `@JsonCreator` String constructor but could not coerce\nthe `{\"id\":\"op-A\"}` object node to a `String`, causing any\n`writeValueAsString` → `readValue` round-trip to fail with\n`MismatchedInputException`.\n\nThe fix introduces a private `readOperatorIdentity(node: JsonNode,\nfieldName: String)` helper in the companion object and moves\n`@JsonCreator` to a new `JsonNode` constructor that delegates to it. The\nhelper accepts both the plain-string shape (front-end input) and the\nobject shape (serialized form), maps null/absent ids to\n`OperatorIdentity(null)`, and rejects malformed nodes. The `String`\nconvenience constructor is retained but no longer carries\n`@JsonCreator`.\n\n\n### Any related issues, documentation, discussions?\n\u003c!--\nPlease use this section to link other resources if not mentioned\nalready.\n1. If this PR fixes an issue, please include `Fixes #1234`, `Resolves\n#1234`\nor `Closes #1234`. If it is only related, simply mention the issue\nnumber.\n  2. If there is design documentation, please add the link.\n  3. If there is a discussion in the mailing list, please add the link.\n--\u003e\nCloses #5042\nThis PR continues and adopts work from #5175\n\n### How was this PR tested?\n\u003c!--\nIf tests were added, say they were added here. Or simply mention that if\nthe PR\nis tested with existing test cases. Make sure to include/update test\ncases that\ncheck the changes thoroughly including negative and positive cases if\npossible.\nIf it was tested in a way different from regular unit tests, please\nclarify how\nyou tested step by step, ideally copy and paste-able, so that other\nreviewers can\ntest and check, and descendants can verify in the future. If tests were\nnot added,\nplease describe why they were not added and/or why it was difficult to\nadd.\n--\u003e\nThe new `workflow-compiling-service` `LogicalLinkSpec` adds unit\ncoverage of `LogicalLink` and `readOperatorIdentity` model-level logic\nthat existing tests do not cover and pins the leniency contract (no\n`require` guards in the compiler-service variant).\n\nThe existing `amber` `LogicalLinkSpec` was updated to match the renamed\nconstructor section, drop the now-invalid `MismatchedInputException`\nexpectation, and add a passing round-trip test.\n\nRun with:\n```\nsbt \"WorkflowExecutionService/testOnly *LogicalLinkSpec\"\n```\nResult: 18/18 tests pass\n```\nsbt \"WorkflowCompilingService/testOnly *LogicalLinkSpec\"\n```\nResult: 15/15 tests pass\n\n\n\n### Was this PR authored or co-authored using generative AI tooling?\n\u003c!--\nIf generative AI tooling has been used in the process of authoring this\nPR,\nplease include the phrase: \u0027Generated-by: \u0027 followed by the name of the\ntool\nand its version. If no, write \u0027No\u0027. \nPlease refer to the [ASF Generative Tooling\nGuidance](https://www.apache.org/legal/generative-tooling.html) for\ndetails.\n--\u003e\nGenerated-by: Claude Sonnet 4.6\n\n---------\n\nSigned-off-by: William Wong \u003c120128836+wwong0@users.noreply.github.com\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e\nCo-authored-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "052cf38c02797d8c10afceea2c39f11d3d16dfdd",
      "tree": "347dad88f05b8b76f077855b1fc2273e9ab8de53",
      "parents": [
        "baefb5d5984c86a78b829167ae2344996f2ef5a2"
      ],
      "author": {
        "name": "Yicong Huang",
        "email": "17627829+Yicong-Huang@users.noreply.github.com",
        "time": "Thu Aug 13 05:46:48 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:46:48 2026 +0000"
      },
      "message": "fix(local-dev): don\u0027t abort `up` on an already-applied sql/updates changeSet (#7076)\n\n### What changes were proposed in this PR?\n\n`bin/local-dev.sh up` against a fresh docker volume never reached the\nsbt build: it died on the last `sql/updates` changeSet.\n\nPostgres applies `sql/texera_ddl.sql` itself — compose mounts `sql/`\ninto `/docker-entrypoint-initdb.d` — and that DDL is kept in sync with\n`sql/updates/*`, so the changeSets local-dev replays immediately\nafterwards re-create objects that are already there. 23–27 are\nincidentally idempotent and pass; `28.sql`\u0027s\n`dataset_owner_uid_name_key` is not, and `sql/texera_ddl.sql`\u0027s `UNIQUE\n(owner_uid, name)` on `dataset` already created it under exactly that\nauto-generated name.\n\n`infra_ensure_db_schema` picks seed-vs-replay by probing for the\n`feedback` table. On a fresh volume the entrypoint has just created it,\nso the replay path is taken — and the `seed` branch written for this\nvery case (record every changeSet as applied without executing it) is\nunreachable, because the entrypoint always wins the race.\n\n```\nBefore:  fresh volume -\u003e entrypoint applies full DDL -\u003e replay 23-28 -\u003e 28 fails -\u003e no build\nAfter:   fresh volume -\u003e entrypoint applies full DDL -\u003e 28 recorded as applied -\u003e build runs\n```\n\nThe fix is in the replay loop rather than the probe: a psql failure\nwhose every `ERROR:` line is `already exists` means the changeSet\u0027s\neffect is already in the schema, so record it and carry on. That covers\nthe next `sql/updates/N.sql` that isn\u0027t accidentally idempotent too,\ninstead of fixing only `28.sql`.\n\n`_sql_errors_all_already_exist` is deliberately narrow — a `duplicate\nkey` is a data conflict rather than an applied schema change, and a\nfailure with no `ERROR:` line at all is never assumed harmless — so an\nincomplete schema still stops the build instead of reaching jOOQ codegen\nwith tables that aren\u0027t there.\n\nWhile in the same lines: psql\u0027s stderr is kept instead of redirected to\n`/dev/null`. It holds the one line that explains the abort, and the old\ncode discarded it and then told the operator to re-run the file by hand\nto find out why.\n\n### Any related issues, documentation, discussions?\n\nCloses #7064\n\n### How was this PR tested?\n\nUnit coverage for the detector in both directions, plus two structural\nguards on the wiring, in the existing `infra`-job suite:\n\n```\n$ bash bin/local-dev/tests/test_local_dev_sh.sh\n...\n  ✓ already-applied detector: relation already exists (the #7064 failure)\n  ✓ already-applied detector: several already-exists errors, nothing else\n  ✓ already-applied detector: already-exists around harmless NOTICE/ROLLBACK chatter\n  ✓ already-applied detector: non-ASCII identifier already exists\n  ✓ already-applied detector: syntax error\n  ✓ already-applied detector: missing relation\n  ✓ already-applied detector: one already-exists mixed with one real error\n  ✓ already-applied detector: duplicate key is a data conflict, not an applied change\n  ✓ already-applied detector: empty stderr\n  ✓ already-applied detector: no ERROR line at all\n  ✓ already-applied detector: missing stderr file\n  ✓ already-applied detector: no argument\n  ✓ infra_apply_sql_updates consults the already-applied detector\n  ✓ infra_apply_sql_updates keeps psql stderr for diagnosis\n\n64 passed, 0 failed\n```\n\nThe pytest half of the same job reports `1 failed, 42 passed` on this\nbranch. That failure is `test_is_dirty_after_seed_then_edit`, which is\nunrelated to this change — it reproduces identically on a pristine\n`main` checkout, and this PR touches neither `tui.py` nor that test. It\nis #7075, fixed separately.\n\nEnd-to-end on the real stack (Ubuntu 24.04.4, docker 29.1.3),\nreproducing the failure and then confirming the fix:\n\n```sh\nbin/local-dev.sh down\ndocker volume rm texera-local-dev_postgres_data\nbin/local-dev.sh up\n```\n\nBefore:\n\n```\n  →  postgres: applying sql/updates/28.sql (changeSet 28)\n  ✗  postgres: sql/updates/28.sql failed -- inspect with: docker exec -i texera-postgres psql -U texera -d texera_db \u003c sql/updates/28.sql\n```\n\nAfter:\n\n```\n  →  postgres: applying sql/updates/27.sql (changeSet 27)\n  →  postgres: applying sql/updates/28.sql (changeSet 28)\n  ○  postgres: sql/updates/28.sql already in schema (recording changeSet 28)\n  ✓  postgres: 6 sql/update(s) applied\n  ...\n  ✓ 14 of 14 services healthy\n```\n\nThe changeSet is recorded, so it is not retried on the next run:\n\n```\n$ docker exec texera-postgres psql -U texera -d texera_db -tAc \\\n    \"SELECT id||\u0027:\u0027||exectype FROM public.databasechangelog ORDER BY orderexecuted\"\n23:EXECUTED\n24:EXECUTED\n25:EXECUTED\n26:EXECUTED\n27:EXECUTED\n28:EXECUTED\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)\n\n---------\n\nCo-authored-by: Claude Opus 4.8 (1M context) \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "baefb5d5984c86a78b829167ae2344996f2ef5a2",
      "tree": "84480275dcd3533b62ebfd924a1b6f6f3deba261",
      "parents": [
        "1b75787631ba4cae44473d2131168cd1d2ef1de3"
      ],
      "author": {
        "name": "Tanishq Gandhi",
        "email": "56472134+tanishqgandhi1908@users.noreply.github.com",
        "time": "Thu Aug 13 05:24:05 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:24:05 2026 +0000"
      },
      "message": "feat(storage): accept legacy unprefixed dataset paths for backward compatibility (#7622)\n\n### What changes were proposed in this PR?\n\n#6502 made the `datasets` resource-type prefix **required** on dataset\nlogical paths. This PR makes the readers accept **both** forms again, so\nthe prefix becomes required only once the ML-model work has landed and\nevery stored path has been migrated.\n\n```\nprefixed (target): /datasets/\u003cowner\u003e/\u003cname\u003e/\u003cversion\u003e/\u003cfile\u003e\nlegacy (accepted): /\u003cowner\u003e/\u003cname\u003e/\u003cversion\u003e/\u003cfile\u003e\n```\n\nMotivation: `sql/updates/36.sql` rewrites the `fileName` and\n`datasetVersionPath` operator properties, but it cannot rewrite a path a\nuser hardcoded inside a Python UDF (that lives in the operator\u0027s `code`\nproperty). Those paths worked before #6502 and started raising\nafterwards. Rewriting user source in a migration would be unsafe, so the\nreaders tolerate the legacy form during the transition instead.\n\nDisambiguation: a leading segment that names a known `ResourceType`\ncommits to the prefixed form, so `/datasets/\u003cowner\u003e/\u003cname\u003e/\u003cversion\u003e`\n(too few segments) is rejected rather than silently re-read as a legacy\npath with owner `datasets`.\nEach tolerant branch carries a `TODO(datasets-prefix)` marker so the\nfallback can be removed in one pass.\n\n\n### Any related issues, documentation, discussions?\nFollow-up to #6502 Part of the ML-model resource work tracked in #6495.\n\n\n### How was this PR tested?\n\nUpdated and added unit tests, all passing locally:\n\nAlso verified end-to-end against a local instance, using workflows whose\nstored paths had the prefix stripped:\n- CSV File Scan on `/\u003cowner\u003e/reviews/v1/reviews.csv` ran green and\nemitted rows, as did two further scan workflows.\n- A Python UDF calling\n`DatasetFileDocument(\"/\u003cowner\u003e/iris/v2/Iris.csv\")` parsed the legacy\npath successfully\n\n\n\n### Was this PR authored or co-authored using generative AI tooling?\nGenerated-by: Claude Code (Claude Opus 4.8)\n\n---------\n\nCo-authored-by: ali \u003cali.risheh876@gmail.com\u003e\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "1b75787631ba4cae44473d2131168cd1d2ef1de3",
      "tree": "26828592bac3a0a8de916fafe7fb5837736fd959",
      "parents": [
        "10c46f1e4d31893e5f9d12e7c19ff98e79932d04"
      ],
      "author": {
        "name": "gupta-sahil01",
        "email": "01guptasahil@gmail.com",
        "time": "Thu Aug 13 05:08:21 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:08:21 2026 +0000"
      },
      "message": "feat(frontend): confirm before removing a package from an environment (#7342)\n\n\u003c!--\nThanks for sending a pull request (PR)! Here are some tips for you:\n1. If this is your first time, please read our contributor guidelines:\n[Contributing to\nTexera](https://github.com/apache/texera/blob/main/CONTRIBUTING.md)\n  2. Ensure you have added or run the appropriate tests for your PR\n  3. If the PR is work in progress, mark it a draft on GitHub.\n  4. Please write your PR title to summarize what this PR proposes, we \n    are following Conventional Commits style for PR titles as well.\n  5. Be sure to keep the PR description updated to reflect all changes.\n--\u003e\n\n### What changes were proposed in this PR?\n\nClicking the trash icon next to a package in the dashboard\n**Environments** page previously only marked the row (turned it red) via\na `deleteToggle` flag; the row wasn\u0027t dropped until the user clicked\nSave. A trash icon implies immediate removal, so the interaction was\nambiguous.\n\nThis PR replaces that toggle with an `nz-popconfirm` on the trash\nbutton. On confirm the row is removed from the draft list; on cancel\nnothing changes.\n\n- `togglePackageDelete(pkg)` → `removePackage(index)`, which splices the\nrow out of `currentDraft.newPackages`\n- Dropped the now-unused `deleteToggle` field from `PveUserPackageRow`\nand the `[class.highlighted-btn]` binding\n- `saveEnvironment()` no longer needs to skip `deleteToggle` rows, since\nremoved rows are already gone from the draft\n\nSave behaviour is unchanged: it still sends the full package map and the\nbackend performs the uninstall/install reconciliation as before. This is\na UI-only change — no backend or API changes.\n\nScoped deliberately to the dashboard Environments page ( `user-venv` ).\nThe computing-unit panel ( `computing-unit-selection` ) still uses the\nmark-then-save pattern; happy to follow up there if that\u0027s wanted.\n\n\u003cimg width\u003d\"1279\" height\u003d\"400\" alt\u003d\"image\"\nsrc\u003d\"https://github.com/user-attachments/assets/67e7e173-67bf-436d-9ec0-bb454af99580\"\n/\u003e\n\n\n\u003c!--\nPlease clarify what changes you are proposing. The purpose of this\nsection\nis to outline the changes. Here are some tips for you:\n  1. If you propose a new API, clarify the use case for a new API.\n  2. If you fix a bug, you can clarify why it is a bug.\n  3. If it is a refactoring, clarify what has been changed.\n  3. It would be helpful to include a before-and-after comparison using \n     screenshots or GIFs.\n  4. Please consider writing useful notes for better and faster reviews.\n--\u003e\n\n\n### Any related issues, documentation, discussions?\nCloses: #6937 \nDiscussed in: #6725 \n\u003c!--\nPlease use this section to link other resources if not mentioned\nalready.\n1. If this PR fixes an issue, please include `Fixes #1234`, `Resolves\n#1234`\nor `Closes #1234`. If it is only related, simply mention the issue\nnumber.\n  2. If there is design documentation, please add the link.\n  3. If there is a discussion in the mailing list, please add the link.\n--\u003e\n\n### How was this PR tested?\nUpdated `user-venv.component.spec.ts`: replaced the\n`togglePackageDelete` test with two for `removePackage` (removes the row\nat the given index; no-op when there\u0027s no draft), and dropped the\n`deleteToggle` row from the save-path test.\n\n\n`cd frontend`\n`npx ng test --include\nsrc/app/dashboard/component/user/user-venv/user-venv.component.spec.ts\n--watch\u003dfalse`\n\n25 tests pass. Also verified manually: the confirm dialog appears on the\ntrash icon, confirming removes only that row, cancelling leaves the list\nunchanged, and Save persists the remaining packages.\n\u003c!--\nIf tests were added, say they were added here. Or simply mention that if\nthe PR\nis tested with existing test cases. Make sure to include/update test\ncases that\ncheck the changes thoroughly including negative and positive cases if\npossible.\nIf it was tested in a way different from regular unit tests, please\nclarify how\nyou tested step by step, ideally copy and paste-able, so that other\nreviewers can\ntest and check, and descendants can verify in the future. If tests were\nnot added,\nplease describe why they were not added and/or why it was difficult to\nadd.\n--\u003e\n\n\n### Was this PR authored or co-authored using generative AI tooling?\nGenerated-by: Claude\n\u003c!--\nIf generative AI tooling has been used in the process of authoring this\nPR,\nplease include the phrase: \u0027Generated-by: \u0027 followed by the name of the\ntool\nand its version. If no, write \u0027No\u0027. \nPlease refer to the [ASF Generative Tooling\nGuidance](https://www.apache.org/legal/generative-tooling.html) for\ndetails.\n--\u003e\n\n---------\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "10c46f1e4d31893e5f9d12e7c19ff98e79932d04",
      "tree": "9680f7a741c7a4ddf416d4e07ea6b86a7831e9a1",
      "parents": [
        "c7e7362a4022d41238227f47ec474dadd225150e"
      ],
      "author": {
        "name": "Kary Zheng",
        "email": "150742834+kz930@users.noreply.github.com",
        "time": "Thu Aug 13 05:08:17 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:08:17 2026 +0000"
      },
      "message": "feat(contour-plot): plot at the default grid size when the field is left alone (#7343)\n\n### What changes were proposed in this PR?\n\nContour Plot\u0027s Grid Size is declared an optional string, but the\ngenerated code consumes it as `int(\u003cvalue\u003e)` with no guard, so the only\ncontent the operator accepts is an integer literal. Typing `2.5` into a\nfield described as \"Grid resolution of the final image\" aborts the run\nwith `ValueError: invalid literal for int() with base 10: \u00272.5\u0027`, and\nthe message names no field, so nothing points back to Grid Size. Any\nnon-integer text does the same.\n\nThe field is now an `Option[Int]` falling back to the documented default\nof 10, and the number is emitted directly rather than wrapped in\n`int()`. The form renders it as a numeric input, so the free text that\nreached `int()` no longer exists.\n\n`contentAs` names the boxed class because `Option` erases its element\ntype; without it a blank would read as 0 rather than as absent.\n\n### Any related issues, documentation, discussions?\n\nCloses #7212.\n\nSplit out of #7233, which covers the same numeric-settings gap in Bullet\nChart and Gauge Chart.\n\n### How was this PR tested?\n\n`ContourPlotOpDescSpec` covers it: the generated code carries the grid\nsize as a number, falling back to 10 when the field is unset, and emits\nan explicit value as itself. It also pins the deserialization — a JSON\nnumber, the numeric string a workflow saved before the field was\nnumeric, and an absent value read as unset rather than as zero.\n\n```\nsbt \"WorkflowOperator/testOnly org.apache.texera.amber.operator.visualization.contourPlot.ContourPlotOpDescSpec\"\n```\n\nNine cases, all passing.\n\nIn the UI on main, a Contour Plot fed three numeric columns with Grid\nSize set to `2.5` aborts the run:\n\n\u003cimg width\u003d\"1290\" height\u003d\"918\" alt\u003d\"Screenshot 2026-08-07 at 3 16 14 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/f93c8403-6eac-427c-b16f-9b7af858e786\"\n/\u003e\n\nWith this PR the field only accepts a number and the generated code no\nlonger calls `int()` at all.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)\n\nCo-authored-by: Claude Opus 5 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "c7e7362a4022d41238227f47ec474dadd225150e",
      "tree": "6f2036d235257ccab876b218750c52866a3260a2",
      "parents": [
        "befcf3f0813371c8dd351bc962b70c1bdc94f4b1"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 05:01:38 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:01:38 2026 +0000"
      },
      "message": "test(computing-unit): extend ComputingUnitManagingResourceSpec to cover the create, rename and configuration endpoints (#7580)\n\n### What changes were proposed in this PR?\n\nThis PR extends `ComputingUnitManagingResourceSpec` (added in #6853,\nextended in #7337) to the endpoints of `ComputingUnitManagingResource`\nthat had no coverage. The existing spec only covered\n`getComputingUnitInfo`, `getComputingUnitMetricsEndpoint`,\n`listComputingUnits` and `terminateComputingUnit`; the create, rename\nand configuration endpoints were untested.\n\nAll new tests keep the existing spec\u0027s approach: local-type units driven\nagainst the embedded Postgres (`MockTexeraDB`), so no Kubernetes calls\nare made. New coverage, by endpoint:\n\n- **createWorkflowComputingUnit** — local happy path (persisted with a\ngenerated `cuid`, the user URI landing in both the `uri` column and the\nresource JSON\u0027s `nodeAddresses`, response reporting owner/WRITE/Running\nwith NaN metrics); whitespace-only name rejected with\n`ForbiddenException` and nothing stored; unknown type (`quantum`)\nrejected; `kubernetes` type rejected while disabled; missing and blank\nURI rejected; the per-user running-unit quota not applying to local\nunits.\n- **renameComputingUnit** — owner success; non-owner without access 403\n(name kept); READ-only grantee 403; WRITE grantee success; blank name\n400; nonexistent unit `NotFoundException`; database failure (name\noverflowing the VARCHAR(128) column) rolling back and keeping the name;\nand an admin who neither owns nor was granted access getting 403\n(rename, unlike terminate, has no ADMIN bypass).\n- **terminateComputingUnit** — a WRITE grantee rejected with 400 and the\nunit not terminated (terminate requires strict ownership or the ADMIN\nrole).\n- **getComputingUnitInfo** — a READ grantee sees the unit with `isOwner\n\u003d false` and `accessPrivilege \u003d READ`; a nonexistent unit yields\n`NotFoundException`; the owner response also reports the non-empty owner\navatar.\n- **getComputingUnitTypes** — lists exactly `local` while Kubernetes is\ndisabled.\n- **getComputingUnitLimitOptions** — returns the configured\ncpu/memory/gpu option lists.\n- **getComputingUnitResourceLimit** — the local branch returns NaN\nlimits for the owner; a non-owner gets `BadRequestException`; a\nnonexistent unit yields `NotFoundException`.\n- **getComputingUnitMetricsEndpoint** — adds the missing negative\ndirection: a non-owner gets `BadRequestException`.\n\nNote: the Kubernetes-only validation in `createWorkflowComputingUnit`\nsits behind the supported-type gate and is unreachable while\n`kubernetes.enabled` is false; that flag is a load-time val the test JVM\ndoes not override, so those branches cannot be exercised in this suite.\nA spec comment records this.\n\nNo production code is changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7576\n\n### How was this PR tested?\n\nThis PR is itself test-only. The new specs were run with:\n\n```\nsbt \"ComputingUnitManagingService/testOnly org.apache.texera.service.resource.ComputingUnitManagingResourceSpec\"\n```\n\nAll 31 tests pass (7 pre-existing + 24 new) against the embedded\ndatabase; no external services are needed. The suite was\nmutation-checked: targeted mutations of the resource (removing the\nblank-name and missing-URI checks, inverting the rename ownership gate,\nskipping the rename blank-name 400, making `getComputingUnitTypes` also\nreturn `kubernetes`, and removing the non-owner check in\n`getComputingUnitResourceLimit`) each caused at least one new test to\nfail, and the source was restored afterwards.\n`ComputingUnitManagingService/Test/scalafmtCheck` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Fable 5)"
    },
    {
      "commit": "befcf3f0813371c8dd351bc962b70c1bdc94f4b1",
      "tree": "695042dfc69d772e637e84d83470939990dacc27",
      "parents": [
        "289189741dad32c7d613108ecd9fe75a8eca420d"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 05:01:23 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:01:23 2026 +0000"
      },
      "message": "test(amber): cover the sync endpoint\u0027s result truncation engine (#7604)\n\n### What changes were proposed in this PR?\n\n`collectOperatorResult` decides what an external caller actually\nreceives from a synchronous run — how many rows come back, **which rows\nare dropped** when a result exceeds the character budget, and how\nindividual cells are shortened. Roughly 180 lines, none of it covered.\n\nThe spec\u0027s own scaladoc claimed the region was unreachable. It is not:\n`ExecutionResultServiceSpec` has been creating real Iceberg-backed\ndocuments in amber\u0027s test scope for some time via `DocumentFactory`\nagainst the ambient postgres catalog. The same pattern reaches this\nengine with **no build change and no new dependency**. That paragraph is\nrewritten in this PR to say what is true.\n\nAdds 10 tests to the existing spec:\n\n| | Before | After |\n|---|---|---|\n| Lines | 230/406 (56.7%) | **340/406 (83.7%)** |\n| Branches | 109 | 143 |\n\nThe +110 lines are the whole of 523–708, including both catch arms.\n\nCovered: the empty-result short circuit, the visualization single-tuple\npath and its `__is_visualization__` flag, a first row that alone fills\nthe budget, the sliding window that drops the middle of an oversized\nresult, the second window that walks the tail once the front half is\nexactly full, per-cell truncation at both call sites, a\ndisabled-warehouse refusal reaching the caller, and a registered URI\nwith no document behind it degrading rather than throwing.\n\n### Verification\n\n14 mutations from the build pass, then three more run independently\nafterwards — the all-rows-fit `truncated` flag, the empty-result short\ncircuit, and the sliding window evicting the newest row instead of the\noldest. All red, production diff empty.\n\nTwo things worth stating plainly:\n\n- **One mutation initially looked like a survivor and was not.**\nRelaxing the first-row bound from `\u003e\u003d` to `\u003e` appeared to survive, but\nonly because it had been applied alongside two others that together\nreproduced the same tuple. Re-run in isolation it fails. Batched\nmutation runs can manufacture false survivors, and this one nearly went\ninto the report as a hole.\n- **One genuine survivor is an equivalent mutant.** The front-loop bound\n`frontSize \u003c halfLimit` can be relaxed to `\u003c\u003d` with no observable\ndifference: tuple sizes are strictly positive, so the relaxed loop\nimmediately fails its next fit check and falls into the same window over\nthe same iterator position. Verified by running it. Recorded in a\ncomment rather than chased, and the test that would have claimed it\nstill kills two other mutations.\n\nAlso, three of my own first-draft mutations were malformed — renaming a\nprivate method just breaks compilation, which proves nothing. Re-done\nagainst the real code.\n\n### Deliberately not included\n\n- **`processedCount`** is written in all three walk paths and never\nread. The tests execute those lines but assert nothing about it, so\ndeleting the variable stays a safe cleanup.\n- **`validateWorkflow`** remains dead with zero call sites, still\nreported rather than tested.\n- The residual 66 missed lines are live-engine paths — the\n`Observable.amb` wait, the console-error and results-ready arms,\n`shutdownPreviousExecution` — plus the dead method above.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7603\n\n### How was this PR tested?\n\n```\nSTORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres sbt \"WorkflowExecutionService/testOnly org.apache.texera.web.resource.SyncExecutionResourceSpec\"\n```\n\n```\n[info] Total number of tests run: 33\n[info] Tests: succeeded 33, failed 0, canceled 0, ignored 0, pending 0\n```\n\n10 new on top of the existing 23. CI already provides what this needs —\n`build.yml` creates `texera_iceberg_catalog` and sets\n`STORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres` for the unit job — so no\nworkflow change. `Test/scalafmtCheck` and `Test/scalafix --check` both\npass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "289189741dad32c7d613108ecd9fe75a8eca420d",
      "tree": "c44f7812d74d5b7e84eecdf5ba77910381710e08",
      "parents": [
        "976499472ac4d406894206931bc53f8a7886a835"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 05:01:17 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:01:17 2026 +0000"
      },
      "message": "fix(amber): guard cloneWorkflow with a read-access check (#7605)\n\n### What changes were proposed in this PR?\n\n`cloneWorkflow` fetched the source workflow by `wid` and copied its\ncontent into a workflow owned by the caller, with no access check on the\nway in. Any authenticated REGULAR user could `POST\n/workflow/clone/\u003cwid\u003e` for a wid they hold no privilege on and receive a\nfull copy of a private workflow\u0027s content — operator configurations,\nfile paths and all.\n\n**Root cause.** Every sibling on this path guards; this one endpoint did\nnot.\n\n| Endpoint | Guard |\n|---|---|\n| `retrieveWorkflow` | `hasReadAccess` directly |\n| `duplicateWorkflow` | `hasReadAccess` directly |\n| `cloneVersion` (`/version/clone/{vid}`) | inherits it via\n`retrieveWorkflowVersion` |\n| **`cloneWorkflow`** | **none** |\n\nThat reads as an oversight rather than a decision. SECURITY.md states\nthat REGULAR users \"cannot access other users\u0027 private resources without\ngranted permissions\", so the endpoint contradicted the project\u0027s own\ndeclared model.\n\n**Before → after**\n\n```\n caller with no privilege on wid\n   |\n   v                                   v\n POST /workflow/clone/{wid}          POST /workflow/clone/{wid}\n   |                                   |\n   |  (no check)                       +-- hasReadAccess(wid, uid)? --\u003e no --\u003e 403\n   v                                   |\n fetchOneByWid(wid)                    v  yes (owner / READ grant / public)\n   |                                 fetchOneByWid(wid)\n   v                                   |\n full content copied to caller         v\n                                     full content copied to caller\n```\n\nThe fix adds the same three lines the siblings use. `hasReadAccess`\nalready returns true for public workflows, so the hub\u0027s clone button —\nthe only caller, and always acting on a published workflow — is\nunaffected. A caller holding an explicit READ grant can still clone.\n\n### Any related issues, documentation, discussions?\n\nFound while reviewing the clone-endpoint test in #7592, now merged; the\nnew cases here build on the spec helpers that landed with it. Not filed\nas an issue, because SECURITY.md asks that security bugs not be reported\nthrough public issues.\n\nThe `release/v1.2` backport preflight comes back grey: the guard itself\napplies, but the two new test cases depend on helpers that arrived with\n#7592, which was not backported. The backport needs those cases\nrewritten self-contained, so it will have to be resolved by hand rather\nthan pushed straight through.\n\n### How was this PR tested?\n\nTwo cases added to the existing `WorkflowResourceSpec`, and the\npre-existing success case in #7592 now publishes its source first so it\nexercises the public path.\n\n| Test | Pins |\n|---|---|\n| `clone a private workflow the caller has been granted read access to`\n| the guard does not over-block a legitimate READ grant |\n| `reject a caller with no access to the source workflow` | 403, no copy\nreaches the caller, and no `WORKFLOW_USER_CLONES` row is written for the\nrejected attempt |\n\nRed before the guard, green after — with the guard reverted the\nrejection case fails and the other 69 pass, so it is the guard the test\nis pinning and not a fixture.\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.web.resource.dashboard.file.WorkflowResourceSpec\"\n```\n\n```\n[info] Total number of tests run: 70\n[info] Tests: succeeded 70, failed 0, canceled 0, ignored 0, pending 0\n```\n\n`scalafmtCheck` and `scalafix --check` pass for both `Compile` and\n`Test`.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "976499472ac4d406894206931bc53f8a7886a835",
      "tree": "b3ab38568b0802f3e5001ef3abd1459a63d97874",
      "parents": [
        "640534c3ed933635f71aa2b6f430c41572a98e5d"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 05:01:13 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:01:13 2026 +0000"
      },
      "message": "chore(workflow-core): remove the unused VirtualCollection (#7620)\n\n### What changes were proposed in this PR?\n\nDeletes `VirtualCollection` and its spec — an abstract class with no\nimplementations and no call sites. Pure deletion, no behaviour change:\n**−198 lines**.\n\nNothing in the repository extends it. The storage layer\u0027s live\nabstractions are `VirtualDocument` and `ReadonlyVirtualDocument`,\nneither of which derives from it. With no subclass anywhere, no instance\ncan exist, so none of its methods can run.\n\n\u003e Reviewer note: its spec exercises a private stub defined inside the\nspec file itself, which is why the class currently looks live. That spec\ncovers this class and nothing else, so it goes with it.\n`VirtualDocument` and `ReadonlyVirtualDocument` are untouched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7617\n\n### How was this PR tested?\n\nExisting tests only — this PR adds none, since it removes code and the\nspec that covered it.\n\nLocally, from the repo root with Java 17:\n\n- `sbt \"WorkflowExecutionService/Test/compile\"` — success (main and test\nsources).\n\nVerification, re-runnable by a reviewer:\n\n```\ngit grep -n VirtualCollection            # only the two deleted files\ngit grep -n \"extends VirtualCollection\"  # no implementations\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)"
    },
    {
      "commit": "640534c3ed933635f71aa2b6f430c41572a98e5d",
      "tree": "2c529eea16c2f36e36d277dcb8eeeba6b9ffd80c",
      "parents": [
        "3da8f6a7fe7ea63f8ce94b6397e7f8848b30d62e"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 05:01:10 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:01:10 2026 +0000"
      },
      "message": "test(amber): cover the computing unit master\u0027s service wiring (#7613)\n\n### What changes were proposed in this PR?\n\n`ComputingUnitMaster` sat at **6.5% of 93 lines**. It assembles the\nwhole service — JWT auth and the session-user value factory, the session\nhandler, the websocket upgrade filter, the request log, the resource\nregistrations, and the recurring cleanup of expired execution results —\nand almost none of it was verified.\n\nAdds 24 tests to the existing spec, taking it to **78.5% of lines**\n(73/93).\n\n`run()` is driven once against a **real** Dropwizard `Environment`\nrather than a mock. That is not a stylistic choice:\n`WebSocketUpgradeFilter.configureContext` needs a live\n`MutableServletContextHandler`, so the sibling Mockito pattern does not\nreach it. Once run that way the whole method executes outside a server,\nincluding `scheduleRecurringCallThroughActorSystem`, which needs only\nthe scheduler.\n\n### Verification\n\n32 mutations applied and reverted, production diff empty each time. Four\nsurvived on first application; three were fixed and one is reported as\nunpinnable rather than papered over.\n\nSix further mutations were then run independently, chosen for failure\nmodes the build had not aimed at. All six killed the test they should —\nincluding two \"does another collaborator also set this?\" probes, which\nneeded deleting `environment.servlets.setSessionHandler(...)` and the\n`AuthValueFactoryProvider.Binder` registration to answer, and a\nnegative-direction bound probe on the expiry window.\n\n### A cross-suite hazard, and what this PR does about it\n\n`run()` repoints the JVM-wide `SqlServer` singleton at\n`StorageConfig.jdbcUrl`, and `initConnection` **closes the pool it\nreplaces**. This spec now points the singleton back at its own embedded\ndatabase in `afterAll` before shutting that pool down, so it is never\nleft aimed at production storage for whatever runs next.\n\nThe residual risk is stated in the spec rather than hidden: amber sets\nneither `Test / fork` nor `Test / parallelExecution :\u003d false`, unlike\nevery other module that mixes `MockTexeraDB` (`build.sbt:175` sets it,\nwith a comment explaining exactly this). A `Tags.limit(Tags.Test, 1)`\ndoes not substitute — as `common/workflow-core/build.sbt` notes, that\nbounds sbt task concurrency, not ScalaTest\u0027s in-JVM distributor.\n\nVerified empirically that this spec does not disturb its neighbours:\n`SessionStateSpec` + `WorkflowServiceSpec` pass 11/11 alone, and 45/45\nwith this suite added.\n\nThat build gap looks worth closing on its own, but it is not this PR\u0027s\nto make.\n\n### Deliberately not included\n\n`createAmberRuntime`, `main`, and the `CLEANUP_ALL_EXECUTION_RESULTS`\nbranch, all of which need a started runtime.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7612\n\n### How was this PR tested?\n\n```\nSTORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres sbt \"WorkflowExecutionService/testOnly org.apache.texera.web.ComputingUnitMasterSpec\"\n```\n\n```\n[info] Total number of tests run: 34\n[info] Tests: succeeded 34, failed 0, canceled 0, ignored 0, pending 0\n```\n\n24 new on top of the existing 10. `Test/scalafmtCheck` and\n`Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "3da8f6a7fe7ea63f8ce94b6397e7f8848b30d62e",
      "tree": "e38a6a9f3f5666cbd88fa74dcd4d4acef59c4e02",
      "parents": [
        "310ab88e4c78da14182284199bde34a1d22d489b"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 05:01:07 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 05:01:07 2026 +0000"
      },
      "message": "test(amber): cover the web application\u0027s bootstrap and filters (#7615)\n\n### What changes were proposed in this PR?\n\n`TexeraWebApplication` had no spec and sat at **0% of 76 lines**. It\nassembles the public web service — the asset bundle serving the built\nfrontend, the collaboration websocket endpoint, the CORS and\ncache-control filters, the request log, and the 404-to-index rule behind\nAngular\u0027s deep links — and none of it was verified.\n\nAdds 14 tests, taking it to **88.2% of lines** (67/76). `initialize()`\nand `run()` are driven against a real Dropwizard `Environment`, and\nevery assertion inspects the wiring they leave behind.\n\n### Verification\n\n28 mutations applied and reverted, production diff empty each time.\n\n**Reviewing the tests then found two that claimed more than they\npinned**, which is the part worth reading:\n\n| Weakness | Why it passed | Fix |\n|---|---|---|\n| the asset test asserted only the servlet mapping | `FileAssetsBundle`\ntakes three arguments and only the uriPath was observed — point it at a\ndirectory that does not exist and the servlet is still registered at\n`/*`, it just serves nothing, while the test\u0027s name claims it serves the\nfrontend from the filesystem | assert `getIndexFile`, and read\n`resourcePath` reflectively |\n| both request-log tests pinned the guard, not the level | move the\nemission to WARN and both still pass: at INFO the guard holds and the\nappender collects an identical line, at WARN the guard stops it and the\nsuppression test still sees nothing | the helper now returns the logging\nevents, and the test asserts `Level.INFO` |\n\nThree mutations confirm the fixes: a missing asset directory, a\ndifferent index file, and the access line emitted at WARN — all red,\nwhere the first two and the level were green before.\n\n### Deliberately not included\n\n- **`main()`** binds a port; **one unused logger** is the other\nuncovered line.\n- **The ordering of `chain.doFilter` against the logging block.** In\nproduction, moving it would make every access line report a status that\nhas not been written yet — but the fixture\u0027s response is a\n`java.lang.reflect.Proxy` answering `getStatus` with a constant, so no\nassertion built on it can see the difference. Recorded rather than\npapered over with a test that cannot fail.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7614\n\n### How was this PR tested?\n\n```\nSTORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres sbt \"WorkflowExecutionService/testOnly org.apache.texera.web.TexeraWebApplicationSpec\"\n```\n\n```\n[info] Total number of tests run: 14\n[info] Tests: succeeded 14, failed 0, canceled 0, ignored 0, pending 0\n```\n\n`Test/scalafmtCheck` and `Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "310ab88e4c78da14182284199bde34a1d22d489b",
      "tree": "97c989f81c2c98abbb38a850170e8ea9db9c2780",
      "parents": [
        "6e56294657faaa5fd1271b093460568b7b41c415"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 04:06:19 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 04:06:19 2026 +0000"
      },
      "message": "chore(frontend): downloading workflows as a ZIP no longer saves each one individually (#7611)\n\n### What changes were proposed in this PR?\n\nSelecting several workflows and using the toolbar\u0027s \"Download added\nworkflow as a ZIP file\" action saved one loose `.json` file per selected\nworkflow **in addition to** the archive, so N selected workflows\nproduced N+1 downloads.\n\nRoot cause is in\n`frontend/src/app/dashboard/service/user/download/download.service.ts`.\n`downloadWorkflow(id, name)` both retrieves a workflow and saves it to\ndisk — the save is the `tap(this.saveFile.bind(this))` at the end of the\npipe — which is exactly what the per-row download action needs.\n`createWorkflowsZip` reused that same method purely to obtain each blob,\nso the save fired for every entry before the blob was added to the\narchive.\n\nThis is a regression rather than intended behaviour: before #2920\n(`57984370c`, \"Refactor Frontend to Centralize Downloads Using\nDownloadService\") the bulk path assembled the zip inline and called\n`saveAs` exactly once. That refactor moved the logic into\n`DownloadService` and reused `downloadWorkflow` for retrieval,\ninheriting its save side effect.\n\nThe fix splits retrieval from saving:\n\n- new private `retrieveWorkflowItem(id, name)` returns the\n`DownloadableItem` (blob + file name) **without** saving — it is the\nformer body of `downloadWorkflow` minus the `tap`;\n- `downloadWorkflow` is now\n`retrieveWorkflowItem(...).pipe(tap(this.saveFile.bind(this)))`, i.e.\nbehaviour is unchanged for the three per-row callers\n(`user-workflow-list-item.component.ts`, `list-item.component.ts`,\n`card-item.component.ts`), which subscribe without a value handler and\nrely solely on that side effect;\n- `createWorkflowsZip` calls `retrieveWorkflowItem` directly.\n\n`A.pipe(map, tap)` and `A.pipe(map).pipe(tap)` compose the same chain,\nso the emitted value, timing, subscription semantics and error\npropagation of `downloadWorkflow` are unchanged. The public API is\nuntouched and no call site needed updating.\n\n**Before** — three workflows selected, then \"Download as ZIP\": the\narchive plus `test1.json`, `test2.json`, `test3.json`, four files in\ntotal.\n\n\u003cimg width\u003d\"1493\" height\u003d\"755\" alt\u003d\"Screenshot 2026-08-12 at 3 48 45 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/7a7b8cb0-330a-452f-b853-b7aabfc04acd\"\n/\u003e\n\n**After** — same three workflows, same action: only\n`workflowExports-*.zip`.\n\n\u003cimg width\u003d\"1482\" height\u003d\"750\" alt\u003d\"Screenshot 2026-08-12 at 4 43 38 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/bdc64245-91bc-4fa0-a06d-2b80e2871706\"\n/\u003e\n\n### Any related issues, documentation, discussions?\n\nCloses #7608\n\n### How was this PR tested?\n\nSeven cases were added to\n`frontend/src/app/dashboard/service/user/download/download.service.spec.ts`\n(23 → 30). Three of them fail on `main` and pass with this change.\n\nPinning the fix:\n\n- `saves only the zip, not one JSON per workflow, when several workflows\nare zipped` — three workflows, asserts `saveAs` is called exactly once\nwith the archive, and that no `Alpha.json` / `Beta.json` / `Gamma.json`\nwas saved\n- `saves only the zip for a single-workflow selection` — the N\u003d1\nboundary, which a plain \"one extra file\" check would miss\n\nGuarding the other direction, so the bug cannot be \"fixed\" by deleting\nthe save:\n\n- `still saves the file when a single workflow is downloaded on its own`\n— passes before and after; it fails if `downloadWorkflow` stops saving,\nwhich would break the per-row download action\n\nEdge cases:\n\n- `saves nothing when one of the workflows fails to retrieve` — the\narchive aborts as a whole, so the workflows that did come back must not\nbe left behind as loose files (previously they were already saved by the\ntime `forkJoin` errored)\n- `writes the workflow content into the zip entries` — reads an entry\nback out of the produced archive and parses it, since the pre-existing\ntests only asserted entry *names*\n- `does not save anything when the standalone workflow download fails` —\nerror propagates, nothing is written; mirrors the existing dataset /\nsingle-file error cases\n- `saves nothing for an empty selection` — `forkJoin([])` completes\nwithout emitting, so nothing is retrieved and no empty archive is\nwritten (the toolbar already guards this case)\n\n```\ncd frontend\nnode --max-old-space-size\u003d8192 ./node_modules/@angular/cli/bin/ng test --watch\u003dfalse \\\n  --include\u003d\"src/app/dashboard/service/user/download/download.service.spec.ts\"\n```\n\n`Test Files 1 passed (1)` / `Tests 30 passed (30)`. Reverting only the\nsource change makes exactly three of them fail.\n\nThe specs of the three components that depend on `downloadWorkflow`\nstill saving were also run and pass unchanged (`list-item`, `card-item`,\n`user-workflow-list-item`).\n\nManually verified against a local stack, as shown in the screenshots\nabove: create three workflows, select them, click the ZIP download\naction, and compare the browser\u0027s download list before and after the\nchange.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Opus 5)"
    },
    {
      "commit": "6e56294657faaa5fd1271b093460568b7b41c415",
      "tree": "daeb49948dcda81545aa45c9c7afc0928e7b880e",
      "parents": [
        "f6a85265552acd3dc7c1c6e03ac3484468a3cdb7"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 04:00:13 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 04:00:13 2026 +0000"
      },
      "message": "test(amber): cover the worker StartChannelHandler (#7609)\n\n### What changes were proposed in this PR?\n\nThis PR adds `StartChannelHandlerSpec`, the first unit coverage for\n`amber/src/main/scala/org/apache/texera/amber/engine/architecture/worker/promisehandlers/StartChannelHandler.scala`.\nThe handler was last changed by #6913, which adjusted the boundary-state\nemission but added only integration coverage (`LoopIntegrationSpec`) and\nPython-side unit tests, so the Scala handler\u0027s state-emission and\nexception paths were unasserted at the unit level.\n\nNo production code is changed; this is a test-only PR.\n\nThe spec drives a real `DataProcessor` and asserts on the worker\u0027s\noutgoing messages, so the marker and the emitted state are checked as\nthe wire payloads a downstream worker would actually receive rather than\nas mocked calls. The 15 tests pin the handler\u0027s three steps and the\norder between them:\n\n- the input port is resolved from the channel the ECM arrived on, and\nthat port is what `produceStateOnStart` receives;\n- the unaligned START_CHANNEL marker reaches every data channel and no\ncontrol channel, after the pending output is flushed;\n- the operator\u0027s boundary state is emitted to every data channel with\nthe \"no loop\" envelope, an empty-but-present state is still emitted, and\nno state is emitted when the operator produces none;\n- every marker precedes every state, and the marker still goes out first\nwhen the operator throws;\n- a sink worker with no data channels emits nothing at all yet still\nreplies successfully, and a second invocation repeats the whole sequence\nbecause the handler has no once-only guard;\n- an operator exception, an operator `Error`, and a failure raised\ninside `emitState` are all swallowed, reported through\n`handleExecutorException`, and answered with a successful reply, while a\n`ControlThrowable` escapes and an unassigned port fails the RPC\noutright.\n\nFour of these record current behavior that a reader may find surprising,\nand each says so in a comment rather than implying endorsement.\n`ErrorUtils.safely` swallows `java.lang.Error` because its\n`OutOfMemoryError` guard is a commented-out line, the port resolution\nsits before the `try` so an unassigned port escapes as an RPC failure\ninstead of being reported like every other failure one line later, and\nthe RPC replies successfully even after the operator fails because the\nfailure is surfaced out of band. If any of these is later changed\ndeliberately, the corresponding test turns red and forces that decision\nto be explicit, which is the point of pinning them.\n\n### Any related issues, documentation, discussions?\n\nCloses #7606\n\n### How was this PR tested?\n\nThe 15 new tests were run locally, together with the three pre-existing\nspecs in the same package and the wider worker package:\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.worker.promisehandlers.StartChannelHandlerSpec\"\n  -\u003e Tests: succeeded 15, failed 0\n\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.worker.promisehandlers.*\"\n  -\u003e Suites: completed 4, Tests: succeeded 31, failed 0\n\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.worker.*\"\n  -\u003e Suites: completed 14, Tests: succeeded 112, failed 0\n\nsbt \"WorkflowExecutionService/Test/scalafmtCheck\"\n  -\u003e success\n```\n\nBoth positive and negative directions are covered, along with the empty\nand boundary cases: a produced state and no produced state, an\nempty-but-present state, zero downstream data channels, a\nnever-registered input channel, and a repeated invocation.\n\nThe assertions were mutation-checked rather than assumed to be\nmeaningful. Fifteen mutations were applied to the production code one at\na time and every one of them turned the spec red, including flipping\n`NO_ALIGNMENT` to `PORT_ALIGNMENT`, swapping `METHOD_START_CHANNEL` for\n`METHOD_END_CHANNEL`, inverting `isDefined`, deleting the `emitState`\ncall, passing a constant port to `produceStateOnStart`, sending the\nmarker after the `try` block instead of before it, dropping the\n`handleExecutorException` call, restricting the marker to the first data\nchannel only, deleting the `outputManager.flush()` that precedes the\nmarker, hoisting `emitState` out of the `try`, adding an idempotence\nguard, and pausing with a different `PauseType`. The production files\nwere restored and verified byte-identical to `HEAD` afterwards.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)"
    },
    {
      "commit": "f6a85265552acd3dc7c1c6e03ac3484468a3cdb7",
      "tree": "b269292ea911569e9989f96d4e345e5688f5caba",
      "parents": [
        "eeae6bd8d77b39cdb84056b86490133e1f201436"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 03:59:58 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 03:59:58 2026 +0000"
      },
      "message": "test(amber): cover the coordinator WorkerStateUpdatedHandler (#7610)\n\n### What changes were proposed in this PR?\n\nThis PR adds `WorkerStateUpdatedHandlerSpec`, the first unit coverage\nfor\n`amber/src/main/scala/org/apache/texera/amber/engine/architecture/coordinator/promisehandlers/WorkerStateUpdatedHandler.scala`.\nThe handler had no references anywhere in the test tree. The\nversion-ordered state model it feeds was fixed and tested in #6011,\nwhich gave `WorkerExecution` a spec, but the handler wiring itself was\nunpinned.\n\nNo production code is changed; this is a test-only PR.\n\nThe spec drives a real `CoordinatorProcessor` with no ActorSystem and\ncaptures the dispatched client events through the coordinator\u0027s output\nhandler. The 20 tests pin the handler\u0027s lookup, the update it applies,\nand the broadcasts it emits:\n\n- the physical operator is derived from `ctx.sender`, and the update\nlands on that worker alone rather than on the operator\u0027s other workers\nor on another operator;\n- reports are ordered by the request\u0027s `stateVersion`, so a stale or\nre-delivered version is ignored while a strictly newer one applies, and\nthe version each worker carries is its own rather than shared across the\noperator;\n- a terminal state absorbs every later report, reached both through a\nCOMPLETED report and through a TERMINATED one, and the reports refused\nthis way are still broadcast;\n- only running region executions are consulted, and only the first one\nowning the operator, while the broadcast statistics span every region\nexecution including completed ones;\n- the skip branch this coverage exists for: when no running region\nexecution owns the sender\u0027s operator the report is dropped, yet\n`ExecutionStatsUpdate` and `RuntimeStatisticsPersist` still fire and the\nreply is still an empty success;\n- both boundaries of the version guard, since `lastStateVersion` starts\nat `-1` and the comparison is strictly-greater: a first report at `-1`\nis dropped as if stale, and a report at `Long.MaxValue` freezes a worker\neven when its state is not terminal.\n\nTwo of these record current behavior that a reader may find surprising,\nand each says so in a comment rather than implying endorsement. An\nunknown worker of a known operator throws a `NullPointerException`,\nbecause `getWorkerExecution` is a `ConcurrentHashMap.get` whose `null`\nis dereferenced immediately, and on that path both client broadcasts are\nlost, which is the opposite of how an unknown operator is handled one\nbranch away. A report carrying the proto default `UNINITIALIZED` at\nversion 0 is applied invisibly and consumes the first real version, so\nthe worker\u0027s genuine first transition is then dropped without a trace.\nIf either is later changed deliberately, the corresponding test turns\nred and forces that decision to be explicit.\n\n### Any related issues, documentation, discussions?\n\nCloses #7607\n\nRelated: #6011 introduced the version-ordered state model this handler\nfeeds.\n\n### How was this PR tested?\n\nThe 20 new tests were run locally, together with the six pre-existing\nspecs in the same package and the wider coordinator package:\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.coordinator.promisehandlers.WorkerStateUpdatedHandlerSpec\"\n  -\u003e Tests: succeeded 20, failed 0\n\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.coordinator.promisehandlers.*\"\n  -\u003e Suites: completed 7, Tests: succeeded 48, failed 0\n\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.coordinator.*\"\n  -\u003e Suites: completed 19, Tests: succeeded 171, failed 0\n\nsbt \"WorkflowExecutionService/Test/scalafmtCheck\"\n  -\u003e success\n```\n\nBoth positive and negative directions are covered, along with the empty\nand boundary cases: an applied update and a skipped one, a workflow\nexecution with no region execution at all, the `-1` version sentinel,\nand the `Long.MaxValue` ceiling.\n\nThe assertions were mutation-checked rather than assumed to be\nmeaningful. Mutations were applied one at a time to\n`WorkerStateUpdatedHandler.scala`, `WorkerExecution.scala` and\n`OperatorExecution.scala`, and each turned the spec red: dropping either\n`sendToClient` call, swapping their order, guarding them behind a\nnon-empty statistics map, replacing `getRunningRegionExecutions` with\nall region executions, widening `find` to `filter`, deriving the\noperator from `ctx.receiver` instead of `ctx.sender`, computing the\nstatistics snapshot before applying the update, forwarding a constant\nversion to `updateState`, moving the sentinel off `-1`, changing the\nversion comparison to `\u003c\u003d` or `!\u003d`, adding a state-equality condition to\nthe guard, removing `TERMINATED` from the terminal check, and returning\none shared `WorkerExecution` for every worker. The production files were\nrestored and verified byte-identical to `HEAD` afterwards.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)"
    },
    {
      "commit": "eeae6bd8d77b39cdb84056b86490133e1f201436",
      "tree": "e299e22d5db606f272ac8eb6875fa7e91e9dd416",
      "parents": [
        "81299d1248fe7e7adf00006839e392da1512264b"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 03:59:24 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 03:59:24 2026 +0000"
      },
      "message": "test(workflow-operator): cover the vectorizer branches of Sklearn code generation (#7577)\n\n### What changes were proposed in this PR?\n\nThis PR adds unit test coverage for the vectorizer branches of the\nPython code generation in the two shared Sklearn base descriptors:\n\n- `SklearnTrainingOpDesc` (base of the 26 Sklearn training operators)\n- `SklearnClassifierOpDesc` (base of the 25 Sklearn classifier\noperators)\n\nBoth templates branch on the `countVectorizer` and `tfidfTransformer`\nproperties to select the text column and prepend `CountVectorizer()` /\n`TfidfTransformer()` stages to the generated `make_pipeline` call, but\nno test in the repository generated code with either flag set: every\nexisting `generatePythonCode()` assertion runs with both flags\ndefault-false, and the specs that do set `countVectorizer \u003d true` are\nJackson round-trip tests that never invoke code generation.\n\nTwo new specs exercise each base through a representative concrete\nsubclass (`SklearnTrainingKNNOpDesc` / `SklearnKNNOpDesc`), matching how\nthe operators use the bases:\n\n- `SklearnTrainingOpDescCodegenSpec` (4 tests)\n- `SklearnClassifierOpDescCodegenSpec` (4 tests)\n\nEach spec covers all four flag combinations the templates distinguish,\nwith positive and negative assertions: the both-false baseline\n(whole-feature path, no vectorizer stages), `countVectorizer` alone\n(text-column selection plus `CountVectorizer()` stage), both flags\n(stage order asserted via the full `make_pipeline(CountVectorizer(),\nTfidfTransformer(), ...)` call), and `tfidfTransformer` alone (a\nreachable codegen branch even though the UI hides the field when\n`countVectorizer` is off). Attribute names are `EncodableString`s, so\nthe expected values are built with the production\n`PythonTemplateBuilder.wrapWithPythonDecoderExpr`, pinning the real\nbase64 decode expressions in the generated code.\n\nNo production code is changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7574\n\n### How was this PR tested?\n\nThis PR is itself test-only. The new specs were run with:\n\n```\nsbt \"WorkflowOperator/testOnly org.apache.texera.amber.operator.sklearn.SklearnClassifierOpDescCodegenSpec org.apache.texera.amber.operator.sklearn.training.SklearnTrainingOpDescCodegenSpec\"\n```\n\nAll 8 tests pass. The suite was additionally mutation-checked: six\nmanual template mutations (swapping the\n`CountVectorizer`/`TfidfTransformer` stage order, gating the text-column\nselection on the wrong flag, and ignoring the `tfidfTransformer` flag,\nin each base) each caused test failures, and the sources were restored\nafterwards. `scalafmtCheck` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Fable 5)"
    },
    {
      "commit": "81299d1248fe7e7adf00006839e392da1512264b",
      "tree": "ca2c6eafe92c7fc8b454dec1e0db752c70c0d560",
      "parents": [
        "6f5602421381bf88be966bec0fb7c0e82f808b12"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 03:59:02 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 03:59:02 2026 +0000"
      },
      "message": "test(amber): add unit test coverage for FriesReconfigurationAlgorithm (#7578)\n\n### What changes were proposed in this PR?\n\nThe new `FriesReconfigurationAlgorithmSpec` (16 tests) pins the\nalgorithm\u0027s observable behaviors through `getReconfigurations`, with\npositive and negative assertions:\n\n- scope stays limited to the reconfigured operator when no one-to-many\noperator is upstream;\n- an upstream one-to-many operator with a reconfigured descendant is\npulled into the scope together with the connecting path, and becomes the\nepoch-marker source;\n- one-to-many operators with no reconfigured descendant, one-to-many\noperators downstream of the target, and side branches are all excluded;\n- parallel branches between a one-to-many operator and the target are\nall included (diamond);\n- disconnected closures split into separate components with\nper-component reconfiguration sets and sources, while connected\nreconfigured operators merge into one component;\n- multiple one-to-many operators converging on the target yield a single\ncomponent with multiple marker sources;\n- links are traversed on every input port, not just port 0;\n- edge cases: single-operator region, target that is itself a region\nsource, target that is itself one-to-many, multiple executing regions\nhandled independently, and an empty result when no region contains a\ntarget.\n\nFixtures build small regions with `PhysicalOp`/`PhysicalLink` wiring\n(the closure walks per-operator port links) and stub\n`WorkflowExecutionManager.getExecutingRegions`, following the patterns\nof `RegionSpec` and `WorkflowExecutionManagerSpec`. No production code\nis changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7573\n\n### How was this PR tested?\n\nThis PR is itself test-only. The new spec was run with:\n\n```\nsbt \"WorkflowExecutionService/testOnly *FriesReconfigurationAlgorithmSpec\"\n```\n\nAll 16 tests pass. The suite was additionally mutation-checked: four\nmanual mutations of the algorithm (dropping forward-closure propagation,\ndisabling the connected-component split, disabling the one-to-many\npull-in, and returning whole components instead of intersecting with the\nsource set) each caused multiple test failures, and the source was\nrestored afterwards. `scalafmtCheck` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Fable 5)"
    },
    {
      "commit": "6f5602421381bf88be966bec0fb7c0e82f808b12",
      "tree": "28ef3e8bc29902f1f7fe5693399d4392367a8a5f",
      "parents": [
        "dd7d813e92e9194e96d74b6926e48065462901ca"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Thu Aug 13 03:58:30 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 03:58:30 2026 +0000"
      },
      "message": "test(pyamber): add unit tests for IcebergTableWriter (#7579)\n\n### What changes were proposed in this PR?\n\nThis PR adds\n`amber/src/test/python/core/storage/iceberg/test_iceberg_table_writer.py`\nwith 14 pure unit tests using mocked catalog/table objects (no real\nIceberg catalog, no Postgres, no network). Covered behaviors:\n\n- Constructor: loads the table via\n`catalog.load_table(f\"{namespace}.{name}\")` and takes `buffer_size` from\n`StorageConfig.ICEBERG_TABLE_COMMIT_BATCH_SIZE`.\n- Buffer-threshold flush: `put_one` below the threshold does not flush;\nreaching `buffer_size` triggers a flush (serde called with schema +\nbuffered items, `table.append` called with serde\u0027s result, buffer\ncleared); items added after a flush start a fresh buffer.\n- `close()` flushes the remaining items when the buffer is non-empty,\nand performs no append when the buffer is empty.\n- `open()` clears a previously dirty buffer.\n- `remove_one()` removes a buffered item; removing an item already\nflushed out of the buffer raises `ValueError` (pinning the current\n`list.remove` behavior).\n- `_flush_buffer()` returns early on an empty buffer (no\nserde/append/refresh calls).\n- Retry path: `table.append` raising pyiceberg\u0027s `CommitFailedException`\ntwice then succeeding completes the flush, with `table.refresh()` called\nonce per attempt; a permanent failure is reraised after 10 attempts and\nthe buffer is NOT cleared.\n- A serde failure propagates without touching the table: serde runs\noutside the retry loop, so it is called exactly once, no refresh/append\nhappens, and the buffer is kept.\n- The retry decorator sets no exception filter, so a non-conflict error\n(e.g. `ValueError`) is also retried for all 10 attempts before being\nreraised (pinning the current behavior).\n\nThe retry tests patch `tenacity.nap.time.sleep`, so the\nexponential-backoff waits (`wait_random_exponential(0.001, 10)`) never\nsleep for real; the whole file runs in about a second.\n\nNo production code is changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7575\n\n### How was this PR tested?\n\nThis PR is itself test-only. The new spec was run with:\n\n```\ncd amber \u0026\u0026 pytest src/test/python/core/storage/iceberg/test_iceberg_table_writer.py -v\n```\n\nResult: 14 passed in about a second. The file is formatted with `black`\n(unchanged by `--check`). The suite was mutation-checked: targeted\nmutations of the writer (flipping the `\u003e\u003d` threshold to `\u003e`, dropping\nthe `buffer.clear()` after append, removing `table.refresh()` in the\nretry body, making `close()` skip the flush, removing the empty-buffer\nearly return, and lowering `stop_after_attempt`) each caused at least\none test to fail, and the source was restored afterwards.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Fable 5)"
    },
    {
      "commit": "dd7d813e92e9194e96d74b6926e48065462901ca",
      "tree": "f6015cdc6756aa6f1f504c81124dbd3a07d84d1e",
      "parents": [
        "a5563a95bc659bb37d16fd236480bb4aa8e745ff"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 03:44:20 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 03:44:20 2026 +0000"
      },
      "message": "chore(amber): remove the deprecated ExpansionGreedyScheduleGenerator (#7446)\n\n### What changes were proposed in this PR?\n\nActs on the removal notice `ExpansionGreedyScheduleGenerator` has\ncarried since #3542. Pure deletion of the class and its spec, no\nbehaviour change: **−832 lines**.\n\n#3144 (\"Refactoring of Schedule Generation\", 2024-12-14) made\n`CostBasedScheduleGenerator` the only generator the engine constructs.\n#3542 (2025-07-09) then annotated the greedy one with the notice it\nstill carries today:\n\n\u003e This greedy schedule generator will be removed in the future. Use\n`CostBasedScheduleGenerator` instead.\n\n```\nWorkflowScheduler.scala:46 -\u003e new CostBasedScheduleGenerator(...)   (live, untouched)\n                              ExpansionGreedyScheduleGenerator      (unreachable since #3144)\n```\n\nThe dead class is already costing maintenance: #7473 had to edit a call\nsite inside it purely to keep it compiling after `createPortBaseURI`\ngained a `warehouse` parameter.\n\nNo configuration can bring it back: the `schedule-generator` block in\n`application.conf` holds only CostBased tuning parameters\n(`max-concurrent-regions`, `use-global-search`, `use-top-down-search`,\n`search-timeout`, read at `ApplicationConfig.scala:87-90`), with no\ngenerator-selection key.\n\n\u003e Reviewer note: the abstract base `ScheduleGenerator` is **not**\ntouched — `CostBasedScheduleGenerator` extends it and is unaffected.\nOnly the greedy subclass and its spec are removed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7444\n\n### How was this PR tested?\n\nExisting tests only — this PR adds none, since it removes code and the\nspec that covered it.\n\nLocally, from the repo root with Java 17:\n\n- `sbt \"WorkflowExecutionService/Test/compile\"` — success (main and test\nsources).\n\nVerification that nothing references the removed class, re-runnable by a\nreviewer:\n\n```\ngit grep -n ExpansionGreedy          # only the two deleted files\ngit grep -in greedy -- \u0027*.conf\u0027 \u0027*.yml\u0027 \u0027*.yaml\u0027 \u0027*.json\u0027 \u0027*.properties\u0027   # no generator-selection key\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)"
    },
    {
      "commit": "a5563a95bc659bb37d16fd236480bb4aa8e745ff",
      "tree": "d3a1d7ec389901290542c5536e519a4ed5b504e6",
      "parents": [
        "c35bdb134cab4126b25c39974be3e29a0a17a672"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Thu Aug 13 03:24:15 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 13 03:24:15 2026 +0000"
      },
      "message": "test(amber): cover the workflow resource\u0027s permission and failure paths (#7592)\n\n### What changes were proposed in this PR?\n\n`WorkflowResource` sat at **82.6% of lines**, and its residue was not\nscattered: permission-guard arms, exception paths, and one whole\nendpoint that had never been called — `cloneWorkflow`. Permission guards\nare exactly where a silent regression matters, which is why this is\nworth doing despite the modest line count.\n\nAdds 16 tests to the existing spec (no third spec file), taking the file\nto **100% of lines**. Everything it reaches is database-only, so\n`MockTexeraDB` suffices — `WorkflowVersionResource.insertVersion` is\njOOQ plus Jackson `JsonDiff`, `HubResource.recordClone` is jOOQ, and\nnothing needs LakeFS, Docker or an engine.\n\n### Verification\n\n22 mutations applied and reverted, production diff confirmed empty each\ntime — the clone\u0027s `isPublic` argument, the version-insert ordering, the\naccess-level comparisons, and the exception-wrapping arms among them.\n\n**Reviewing my own tests then found three that claimed more than they\npinned.** All three are now stated in the spec rather than left to be\ndiscovered:\n\n| Claim | Reality | What changed |\n|---|---|---|\n| \"wrap a failure raised inside the transaction\" |\n`assignNewOperatorIds` fails *before* `createWorkflow` inserts, so \"no\ncopy was created\" holds with or without a transaction — replacing\n`context.transaction` with a plain block leaves the suite green |\nrenamed to what it pins (the exception wrapping), with the gap recorded\n|\n| the delete test covers the cleanup tail | it does not — emptying the\ncollected execution ids leaves the suite green. `LargeBinaryManager` is\nan S3-backed `object` with no seam, and document cleanup needs Iceberg\nfixtures this spec lacks | recorded as entered-not-verified. What the\ntest *does* pin was confirmed by mutation: removing the `case NonFatal`\narm of the outer catch turns it red, so an undecodable URI really is\ntolerated rather than aborting the delete |\n| two assertions in the write-access test | both already hold before\n`persistWorkflow` is called; its write branch touches only `WORKFLOW`\nand `WORKFLOW_VERSION` | relabelled as guards; the content and\nversion-count assertions carry the pin |\n\n### A note on the numbers\n\njacoco reports a wide line-versus-branch split here — branch coverage\nstays low even at 100% lines — because of the synthetic branches the\nScala compiler generates for this style of code. The line figure is the\nmeaningful one on this file.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7591\n\n### How was this PR tested?\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.web.resource.dashboard.file.WorkflowResourceSpec\"\n```\n\n```\n[info] Total number of tests run: 68\n[info] Tests: succeeded 68, failed 0, canceled 0, ignored 0, pending 0\n```\n\n16 new on top of the existing 52. `Test/scalafmtCheck` and\n`Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "c35bdb134cab4126b25c39974be3e29a0a17a672",
      "tree": "9134d3d0f1cc30e5dcb86c9fc5c5b6baafd733c7",
      "parents": [
        "321fe45505ecadf3aba184c2caee2b948c0d86dc"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Wed Aug 12 23:33:39 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 23:33:39 2026 +0000"
      },
      "message": "test(frontend): cover the workflow editor\u0027s remaining event handlers (#7590)\n\n### What changes were proposed in this PR?\n\n`workflow-editor.component.ts` sat at **79.9% of lines and 59.0% of\nbranches**. The branch number was the real gap: almost half its\nconditions had only ever been taken one way.\n\nAdds 42 tests as a new appended block — appended rather than interleaved\nso the diff stays off the region PR #6927 touches.\n\n| | Before | After |\n|---|---|---|\n| Lines | 449/562 (79.9%) | **562/562 (100%)** |\n| Branches | 138/234 (59.0%) | **203/234 (86.8%)** |\n\nNothing needs a browser, which is worth saying because it looks like it\nshould. The component is almost entirely an event-wiring layer, and both\nseams were already established in this spec: triggering paper events\nagainst a real `CellView`, and pushing directly onto the services\u0027\nsubjects.\n\nCovered: the magnet and connection validators, the read-only paper lock,\nthe recovering-state overrides and the transitions out of recovery,\nregion reshape and recolour, blank-canvas panning and window resize, the\nrepaint streams for view-result / reuse-cache / renamed operators and\nports, shift-multiselect over links and comment boxes, port\nhighlighting, the link hover tools, cursor presence, and the agent hover\nlabels.\n\n### Verification\n\n49 mutations applied and reverted, production diff confirmed empty each\ntime. Two survived during the build and were dealt with before this was\nraised — one test was vacuous because the un-guarded path throws inside\nan rxjs subscriber (reported asynchronously, so the assertion on the\nunchanged popover still held), and it was rewritten; the other is\ndisclosed below.\n\nThree further mutations were then run independently, chosen for failure\nmodes the build had not targeted rather than repeating its list:\n\n| Mutation | Result |\n|---|---|\n| the recovering override reports `Paused` instead of `Recovering` | red\n|\n| a highlighted port keeps the unhighlighted radius | red |\n| a blank-canvas click no longer clears the selection | red |\n\nOne of my own probes was a **bad mutation rather than a finding**:\nrewriting `currentOpenedOperatorID \u003d null` as `\u003d null as any` is\nsemantically identical, so its survival meant nothing. Re-run properly,\nthe handler is pinned.\n\n### Deliberately not included\n\n- **Line 354\u0027s `throw`** on an unknown transition out of recovering. It\nfires inside a subscriber, so rxjs reports it via `reportUnhandledError`\nasynchronously and `expect(...).toThrow()` does not catch it. Chasing\none line with a test that leaves a stray unhandled error in the run is\nnot worth it.\n- **The false arms at lines 726 and 1116** are **dead, not untested**:\nthe stream is pre-filtered to `hasOperator || hasCommentBox`, so inside\nthe non-shift `else` a false `hasOperator` implies `hasCommentBox`. This\nis why branch coverage stops at 86.8% rather than higher.\n- **`handleRegionEvents`\u0027 position filter** — one mutation on it\nsurvives and is genuinely unpinnable from this spec; the test that would\nhave claimed it was removed rather than left overclaiming.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7589\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/workflow-editor.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  104 passed (104)\n```\n\n42 new on top of the existing 62. The whole workflow-editor folder (5\nspec files, 167 tests) also stays green, so there is no cross-test\nleakage. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "321fe45505ecadf3aba184c2caee2b948c0d86dc",
      "tree": "e234d145c793c5f6f0940a292e9c5166a0213ac5",
      "parents": [
        "71faf440de7936d07451d214dbd5777e6906b949"
      ],
      "author": {
        "name": "Tanishq Gandhi",
        "email": "56472134+tanishqgandhi1908@users.noreply.github.com",
        "time": "Wed Aug 12 22:47:36 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 22:47:36 2026 +0000"
      },
      "message": "feat(storage): add datasets resource-type prefix to logical paths (#6502)\n\n### What changes were proposed in this PR?\n\nAdds an explicit resource-type prefix to asset logical file paths,\nchanging the format from\n\n`/\u003cowner\u003e/\u003cname\u003e/\u003cversion\u003e/\u003cfile\u003e` to\n`/datasets/\u003cowner\u003e/\u003cname\u003e/\u003cversion\u003e/\u003cfile\u003e`.\n\nMakes the `datasets` resource-type prefix **required** on dataset\nlogical file paths (`/datasets/\u003cowner\u003e/\u003cname\u003e/\u003cversion\u003e/\u003cfile\u003e`), so\nother resource types (e.g. models) can be told apart by the prefix and\nrouted to their own table. Unlike the initial approach, an **unprefixed\npath no longer resolves** — the prefix is what selects the resource\u0027s\ntable.\n\n\n- **Path resolver (`FileResolver`):** a dataset path must start with\n`datasets`; the previous \"parse unprefixed as-is\" fallback is removed.\n- **Python file API (`DatasetFileDocument`):** same rule, mirroring the\nbackend.\n- **File Lister operator:** parses the now-prefixed `datasetVersionPath`\n(the second dataset-path property, alongside scan sources\u0027 `fileName`).\n- **File tree / frontend:** tree rooted at a `datasets` node; the\nselection modal emits prefixed paths; relative-path extraction strips\nthe 4-segment prefix; unused client-side parser removed.\n- **Cover images (`DatasetResource`):** cover-image handlers now build\nprefixed paths.\n- **Example workflows:** updated to prefixed paths.\n- **Migration (`sql/updates/36.sql`):** one-time, Liquibase-run rewrite\nthat prepends `datasets/` to legacy paths in `workflow.content` and\n`workflow_version.content` (both `fileName` and `datasetVersionPath`).\nOnly values whose first two segments match an existing `(user.email,\ndataset.name)` are rewritten (local paths/URLs untouched; email format\nis irrelevant); idempotent.\n\n**Known migration limits:**\n\n- A path whose dataset was **renamed or deleted** since the workflow was\nsaved won\u0027t match `(email, name)`, so it stays unprefixed and will fail\nto resolve (it was already unusable).\n- **Hardcoded paths inside user code are not migrated (breaking).** The\nmigration rewrites only the `fileName` and `datasetVersionPath` operator\nproperties, so a path written by hand inside a Python UDF — e.g.\n`DatasetFileDocument(\"/bob@x.com/ds/v1/f.csv\")`, stored in the\noperator\u0027s `code` property — is left untouched and now raises\n`ValueError: Invalid file path format. Expected:\n/datasets/ownerEmail/datasetName/versionName/fileRelativePath`. Unlike\nthe renamed/deleted case above, these paths **were working before this\nchange**. Users must add the `datasets/` prefix in their UDF code; the\nerror message states the expected format. Rewriting arbitrary user\nsource in a SQL migration would risk corrupting code, so this is\ndocumented rather than automated — it needs a release note.\n- The migration assumes `content` is valid JSON (an app invariant) and\naborts on a malformed row rather than skipping, so a bad row rolls the\nwhole migration back instead of applying partially.\n\n### Any related issues, documentation, discussions?\nCloses #6495.\n\n### How was this PR tested?\nNew and updated unit tests, all passing locally:\n- `FileResolverSpec`: an unprefixed path (and an unknown resource-type\nprefix) no longer resolves; a valid prefixed path resolves;\ntoo-few-segments is rejected.\n- `FileListerSourceOpExecSpec` (new): a prefixed `datasetVersionPath`\nparses; unprefixed / unknown-resource-type / too-few rejected.\n- Frontend: `datasetVersionFileTree` and `dataset-selection-modal` specs\nupdated for the prefix.\n- Python: `test_dataset_file_document.py` — prefix required, presign\nre-emits it.\n\nThe migration (`36.sql`) was verified manually against sample data:\nunprefixed→prefixed;\nalready-prefixed left unchanged (idempotent); local paths/URLs\nuntouched; dangling\n(renamed/deleted) datasets untouched; operators without the property get\nno spurious key added;\nboth `fileName` and `datasetVersionPath` covered.\n\n### Was this PR authored or co-authored using generative AI tooling?\nGenerated-by: Claude Code (Claude Opus 4.8)\n\n---------\n\nCo-authored-by: ali \u003cali.risheh876@gmail.com\u003e\nCo-authored-by: Claude Opus 4.8 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "71faf440de7936d07451d214dbd5777e6906b949",
      "tree": "9dcb923c8b60fd699d5f791e962a6be1bd4a4ea5",
      "parents": [
        "7daf8d78415d5f40fc017678738ce57b137065c5"
      ],
      "author": {
        "name": "Kary Zheng",
        "email": "150742834+kz930@users.noreply.github.com",
        "time": "Wed Aug 12 21:46:55 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 21:46:55 2026 +0000"
      },
      "message": "feat(visualization): retarget attributeTypeRules at the properties they name (#7249)\n\n### What changes were proposed in this PR?\n\nFour `attributeTypeRules` name keys that match no property, so the\nproperty editor\u0027s `findAttributeType` returns `undefined` and\n`checkConstraint` returns without checking anything.\n\n`LineConfig` used the Scala field names rather than the `@JsonProperty`\nnames, and `ScatterMatrixChartOpDesc` named `value` where the property\nis `Selected Attributes`; both are retargeted at the property they\nmeant. `Scatter3dChartOpDesc` and `FunnelPlotOpDesc` constrained a\n`title` that neither operator declares, and did so with the bare string\n`\"string\"` rather than an object, so even under a correct key\n`constraint.enum` / `const` / `allOf` would all be undefined and the\ncheck would still no-op; those two rules are removed rather than\ninvented anew.\n\n### Why are the changes needed?\n\nA line chart\u0027s x and y axes accept string columns today despite\ndeclaring `[\"integer\", \"long\", \"double\"]`, and the same holds for the\nscatter matrix\u0027s dimensions. `BandConfig` extends `LineConfig` and\ninherited the same dead rule. Nothing reports a key that names no\nproperty, so the rules read as enforced while enforcing nothing.\n\n### Any related issues, documentation, discussions?\n\nCloses #7210\n\n### How was this PR tested?\n\n`WorkflowOperator/compile`, `WorkflowOperator/scalafmtCheckAll`, and the\nfour operators\u0027 existing descriptor specs (24 tests, all passing).\n\nThe new `AttributeTypeRuleTargetSpec` guards the class of mistake\nrepo-wide rather than just the four sites fixed here: it walks every\nregistered operator\u0027s generated schema and fails if an\n`attributeTypeRules` key names no declared property, or if a rule is not\nstated as an object.\n\n### Does this PR introduce any user-facing change?\n\nYes. Selecting a non-numeric column for a line chart\u0027s axes or the\nscatter matrix\u0027s Selected Attributes now shows the type warning the rule\nalways intended. Nothing changes for a numeric column, and removing the\ntwo `title` rules changes nothing at all, since they never applied.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Xuan Gu \u003c162244362+xuang7@users.noreply.github.com\u003e"
    },
    {
      "commit": "7daf8d78415d5f40fc017678738ce57b137065c5",
      "tree": "d43a19f02726871ab6be9aaed39af35fa82d0b7b",
      "parents": [
        "5021bc6f1a96d00cb26aa9c3a82c86fee67da0a9"
      ],
      "author": {
        "name": "Prateek Ganigi",
        "email": "91584519+PG1204@users.noreply.github.com",
        "time": "Wed Aug 12 18:51:52 2026 +0000"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 18:51:52 2026 +0000"
      },
      "message": "refactor(frontend): make redundant operator border repaints a no-op (#6927)\n\n### What changes were proposed in this PR?\n\nWhen an operator is added, its border was painted by two paths - the\noperator-add restore and the validation pass, producing the same color.\nHarmless, but a redundant repaint.\n\nThis PR adds a guarded border setter (`paintOperatorBorder`) in\n`JointUIService` that writes `rect.body/stroke` only when the color\nactually changes. Both `changeOperatorColor` and `changeOperatorState`\nroute their border write through it, so a repaint with the color the\nborder already has becomes a no-op, effectively \"painted once\" -\nincluding on the navigation-return (reload) path.\n\n**Deviation from the approach suggested on the issue:** the issue\nsuggested dropping the `applyOperatorBorder` call from the operator-add\nhandler and letting the validation pass set the border. I kept that call\nand used the guard instead, because `changeOperatorStatistics` already\npaints the border via `changeOperatorState` *without* checking validity.\nDropping `applyOperatorBorder` would make an invalid operator with a\ncached \"completed\" status rely on the validation pass firing afterward\nto correct green→red, reintroducing the order-dependent border fragility\nthat #5146 removed (and it would break in the edge case where\n`setDynamicSchema` skips its emit because the schema is unchanged). The\nguard reaches the same no-redundant-repaint goal while keeping the\nborder validity-correct regardless of event timing.\n\n### Any related issues, documentation, discussions?\nPart of #5726 \n\n### How was this PR tested?\n\nUnit tests:\n- `JointUIService`: the guarded setter skips the write when the border\nis already the requested color, and writes when it differs.\n- `WorkflowEditorComponent`: added a navigation-return test for a cached\n**Running** operator (orange), alongside the existing completed (green),\ndefault (gray), invalid (red), and invalid-over-cached-priority cases.\n- Full frontend suite: 3739 passing.\n\nManual (navigated away from a running workflow and back), border\nrestored correctly for:\n- Completed operators → green\n- Running operators → orange\n- Invalid operators → red\n- Valid, not run → default gray\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nThis PR was co-authored using Claude Code (Anthropic Claude Opus 4.7) in\ncompliance with ASF."
    },
    {
      "commit": "5021bc6f1a96d00cb26aa9c3a82c86fee67da0a9",
      "tree": "03a922333d2a97e36f689cfc276ee938a0da9072",
      "parents": [
        "f2f457e671b341bc499f1ea4169f09a56a6e8369"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Tue Aug 11 22:34:38 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 05:34:38 2026 +0000"
      },
      "message": "test(frontend): click the toolbar buttons rather than calling their handlers (#7547)\n\n### What changes were proposed in this PR?\n\nThe suite calls the handlers directly, which is not the same thing:\ncoverage for `(click)\u003d\"onClickX()\"` lands on the generated listener\nbody, so a button wired to the wrong handler — or to none — looks\nperfectly tested today.\n\nAdds 2 tests that click the real elements. The first is table-driven\nover six visually near-identical icon buttons, since a copy-paste\nleaving two of them on the same handler is the realistic defect. The\nsecond asserts the converse: clicking auto-layout must not also reset\nthe panels.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| auto layout wired to reset panels | red |\n| close panels wired to reset panels | red |\n| generate report unwired | red |\n| reset zoom wired to auto layout | red |\n| add comment unwired | red |\n| reset panels wired to close panels | red |\n\n### Deliberately not included\n\nThe four display switches live in the `#executionSettings` popover,\nwhich ng-zorro instantiates into a CDK overlay only on open. Opening the\nfirst `NzPopoverDirective` on the page yields one switch, not four —\nlocating the right one needs more overlay plumbing than four lines\njustify. They remain uncovered, and the issue records how to reach them.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7546\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/menu.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  83 passed (83)\n```\n\n2 new on top of the existing 81. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "f2f457e671b341bc499f1ea4169f09a56a6e8369",
      "tree": "fc47654208641cfd2e716cb02c2181aa79f595fc",
      "parents": [
        "360a13f56f31bbd21c577251a274a9a1706dd7f0"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Tue Aug 11 22:19:14 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 05:19:14 2026 +0000"
      },
      "message": "fix(deps): bump hono from 4.12.31 to 4.13.1 in /frontend (#7587)\n\nBumps [hono](https://github.com/honojs/hono) from 4.12.31 to 4.13.1.\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/honojs/hono/releases\"\u003ehono\u0027s\nreleases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev4.13.1\u003c/h2\u003e\n\u003ch2\u003eWhat\u0027s Changed\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003efix(trie-router): count every slash a pattern consumes by \u003ca\nhref\u003d\"https://github.com/Jaybhade\"\u003e\u003ccode\u003e@​Jaybhade\u003c/code\u003e\u003c/a\u003e in \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5189\"\u003ehonojs/hono#5189\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003efix(utils/stream): re-acquire writer lock when pipe() throws by \u003ca\nhref\u003d\"https://github.com/Sriharsha-dev369\"\u003e\u003ccode\u003e@​Sriharsha-dev369\u003c/code\u003e\u003c/a\u003e\nin \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/4988\"\u003ehonojs/hono#4988\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003efix(etag): skip unsafe methods or error responses on non-* case by\n\u003ca\nhref\u003d\"https://github.com/na-trium-144\"\u003e\u003ccode\u003e@​na-trium-144\u003c/code\u003e\u003c/a\u003e\nin \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5196\"\u003ehonojs/hono#5196\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003eNew Contributors\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/Jaybhade\"\u003e\u003ccode\u003e@​Jaybhade\u003c/code\u003e\u003c/a\u003e\nmade their first contribution in \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5189\"\u003ehonojs/hono#5189\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/Sriharsha-dev369\"\u003e\u003ccode\u003e@​Sriharsha-dev369\u003c/code\u003e\u003c/a\u003e\nmade their first contribution in \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/4988\"\u003ehonojs/hono#4988\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eFull Changelog\u003c/strong\u003e: \u003ca\nhref\u003d\"https://github.com/honojs/hono/compare/v4.13.0...v4.13.1\"\u003ehttps://github.com/honojs/hono/compare/v4.13.0...v4.13.1\u003c/a\u003e\u003c/p\u003e\n\u003ch2\u003ev4.13.0\u003c/h2\u003e\n\u003cp\u003eHono v4.13.0 is now available!\u003c/p\u003e\n\u003cp\u003eThe highlight of this release is performance: a batch of low-level\noptimizations makes the core request/response path significantly faster\n— up to 1.25x on common routes in our benchmark. This release also adds\nfirst-class support for the HTTP QUERY method, defined in \u003ca\nhref\u003d\"https://www.rfc-editor.org/rfc/rfc10008.html\"\u003eRFC 10008\u003c/a\u003e, a new\nMethod Not Allowed middleware, and more.\u003c/p\u003e\n\u003ch2\u003ePerformance improvements\u003c/h2\u003e\n\u003cp\u003eThis release includes a series of small optimizations: skipping\nunnecessary \u003ccode\u003eHeaders\u003c/code\u003e allocations, replacing regex tests with\n\u003ccode\u003eindexOf\u003c/code\u003e, allocating internal state lazily, and more.\u003c/p\u003e\n\u003cp\u003eHere is \u003ca\nhref\u003d\"https://github.com/honojs/hono/tree/main/benchmarks/fetch\"\u003e\u003ccode\u003ebenchmarks/fetch\u003c/code\u003e\u003c/a\u003e\ncomparing v4.12 and v4.13 (\u003ccode\u003eROUNDS\u003d5 ./compare.sh\u003c/code\u003e, Bun\n1.4.0, Apple Silicon — each measurement runs in a fresh process, and the\nvariant order is reversed every round to avoid warm-up bias):\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eBenchmark\u003c/th\u003e\n\u003cth align\u003d\"right\"\u003ev4.12\u003c/th\u003e\n\u003cth align\u003d\"right\"\u003ev4.13\u003c/th\u003e\n\u003cth align\u003d\"right\"\u003eSpeedup\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eping\u003c/code\u003e — \u003ccode\u003eGET /\u003c/code\u003e\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e165.83 ns\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e163.99 ns\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e1.01x\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003equery\u003c/code\u003e — \u003ccode\u003eGET /id/1?name\u003dbun\u003c/code\u003e\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e674.40 ns\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e616.99 ns\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e\u003cstrong\u003e1.09x\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ejson\u003c/code\u003e — \u003ccode\u003eGET /user\u003c/code\u003e\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e528.99 ns\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e422.44 ns\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e\u003cstrong\u003e1.25x\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003ebody\u003c/code\u003e — \u003ccode\u003ePOST /json\u003c/code\u003e\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e1.16 µs\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e1.00 µs\u003c/td\u003e\n\u003ctd align\u003d\"right\"\u003e\u003cstrong\u003e1.15x\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003eThe individual changes:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eperf(context): iterate the header record with \u003ccode\u003efor..in\u003c/code\u003e\n\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5118\"\u003ehonojs/hono#5118\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eperf(url): replace regex tests with \u003ccode\u003eindexOf\u003c/code\u003e \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5121\"\u003ehonojs/hono#5121\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eperf(context): skip \u003ccode\u003eHeaders\u003c/code\u003e creation when there are no\nheaders to merge \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5122\"\u003ehonojs/hono#5122\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eperf(urls): refactor \u003ccode\u003etryDecodeURIComponent\u003c/code\u003e \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5158\"\u003ehonojs/hono#5158\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eperf(request): allocate \u003ccode\u003e#validatedData\u003c/code\u003e lazily \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5175\"\u003ehonojs/hono#5175\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eperf(request): probe the body cache without allocating \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/pull/5176\"\u003ehonojs/hono#5176\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eIn addition, the RegExpRouter rewrite described below makes route\nregistration plus the first match roughly 20% faster.\u003c/p\u003e\n\u003cp\u003eThanks \u003ca\nhref\u003d\"https://github.com/kibertoad\"\u003e\u003ccode\u003e@​kibertoad\u003c/code\u003e\u003c/a\u003e for the\ncontributions!\u003c/p\u003e\n\u003ch2\u003eFirst-class QUERY method support\u003c/h2\u003e\n\u003cp\u003eThe QUERY method — a safe, idempotent method that carries a request\nbody — is now a first-class citizen in Hono. You can define QUERY\nhandlers with \u003ccode\u003eapp.query()\u003c/code\u003e:\u003c/p\u003e\n\u003cpre lang\u003d\"ts\"\u003e\u003ccode\u003econst app \u003d new Hono()\n\u003cp\u003e\u0026lt;/tr\u0026gt;\u0026lt;/table\u0026gt;\u003cbr /\u003e\n\u003c/code\u003e\u003c/pre\u003e\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e... (truncated)\u003c/p\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/cf785287b5ab41496a333c9c4b53b0f98ac731b9\"\u003e\u003ccode\u003ecf78528\u003c/code\u003e\u003c/a\u003e\n4.13.1\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/f6aa913c3f8915d0695b77ca3f78f6b8ecb248a0\"\u003e\u003ccode\u003ef6aa913\u003c/code\u003e\u003c/a\u003e\nfix(etag): skip unsafe methods or error responses on non-* case (\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/5196\"\u003e#5196\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/cd31bc196eb234bcaaae18ecf889784cf30004fd\"\u003e\u003ccode\u003ecd31bc1\u003c/code\u003e\u003c/a\u003e\nfix(utils/stream): re-acquire writer lock when pipe() throws (\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/4988\"\u003e#4988\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/569b4191a291ef7a4116881e521c3a0179407332\"\u003e\u003ccode\u003e569b419\u003c/code\u003e\u003c/a\u003e\nfix(trie-router): count every slash a pattern consumes (\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/5189\"\u003e#5189\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/192768fbaf9aa99a45404dc2f171541227c11d20\"\u003e\u003ccode\u003e192768f\u003c/code\u003e\u003c/a\u003e\n4.13.0\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/b0c2d90eb07fefa6c06dc556c97ed8ecffc8b2c0\"\u003e\u003ccode\u003eb0c2d90\u003c/code\u003e\u003c/a\u003e\nMerge pull request \u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/5154\"\u003e#5154\u003c/a\u003e\nfrom honojs/next\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/8f0702827002f0ada02434d908853458c17f862d\"\u003e\u003ccode\u003e8f07028\u003c/code\u003e\u003c/a\u003e\nfix(compress): set Vary: Accept-Encoding on negotiated responses (\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/5137\"\u003e#5137\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/8a0b18fd9b4d64dd2eb1d7f18e3536fc06cb54b2\"\u003e\u003ccode\u003e8a0b18f\u003c/code\u003e\u003c/a\u003e\nfeat(reg-exp-router): throw UnsupportedPathError during route\nregistration (#...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/3feb3551d46de1f633e82253f12cf1117316be93\"\u003e\u003ccode\u003e3feb355\u003c/code\u003e\u003c/a\u003e\nfix(jsx): allow a function component to return an array (\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/5179\"\u003e#5179\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/honojs/hono/commit/5d911d2ab7bcb2adb2e974ddd5b17742fb5a0bca\"\u003e\u003ccode\u003e5d911d2\u003c/code\u003e\u003c/a\u003e\nfeat(utils/headers): add HTTP fields newly registered with IANA (\u003ca\nhref\u003d\"https://redirect.github.com/honojs/hono/issues/5153\"\u003e#5153\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003eAdditional commits viewable in \u003ca\nhref\u003d\"https://github.com/honojs/hono/compare/v4.12.31...v4.13.1\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility\nscore](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003dhono\u0026package-manager\u003dnpm_and_yarn\u0026previous-version\u003d4.12.31\u0026new-version\u003d4.13.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore this major version` will close this PR and stop\nDependabot creating any more for this major version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop\nDependabot creating any more for this minor version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop\nDependabot creating any more for this dependency (unless you reopen the\nPR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the\n[Security Alerts page](https://github.com/apache/texera/network/alerts).\n\n\u003c/details\u003e\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "360a13f56f31bbd21c577251a274a9a1706dd7f0",
      "tree": "bbb0d8a612b237694d6fa3a9c39b8b98be46cd76",
      "parents": [
        "a3f2bf0a1db064c7dd710a1fb6b10bc2832f94dd"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Tue Aug 11 22:19:12 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 05:19:12 2026 +0000"
      },
      "message": "fix(deps): bump js-yaml from 4.2.0 to 4.3.1 in /frontend (#7588)\n\nBumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.2.0 to 4.3.1.\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/blob/4.3.1/CHANGELOG.md\"\u003ejs-yaml\u0027s\nchangelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e4.3.1 - 2026-07-31\u003c/h2\u003e\n\u003ch3\u003eSecurity\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e[backport] Remove quadratic complexity from \u003ccode\u003e!!omap\u003c/code\u003e\nduplicate key detection.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2\u003e4.3.0 - 2026-06-27\u003c/h2\u003e\n\u003ch3\u003eAdded\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e[backport] Added \u003ccode\u003emaxTotalMergeKeys\u003c/code\u003e (10000) loader\noption to limit the total number of\nkeys processed by YAML merge (\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e) across one\n\u003ccode\u003eload()\u003c/code\u003e / \u003ccode\u003eloadAll()\u003c/code\u003e call.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eFixed\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eRestore umd builds back to es5.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eRemoved\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e[backport] \u003ccode\u003emaxMergeSeqLength\u003c/code\u003e replaced with\n\u003ccode\u003emaxTotalMergeKeys\u003c/code\u003e for limiting YAML merge\nprocessing.\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/blockquote\u003e\n\u003c/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCommits\u003c/summary\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/86e91b815b8794c3c73a179c1770871e37ec2df8\"\u003e\u003ccode\u003e86e91b8\u003c/code\u003e\u003c/a\u003e\n4.3.1 released\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/c3cc4b0bb9ddb9af2dd9b61e0d56f5ce7983cd4a\"\u003e\u003ccode\u003ec3cc4b0\u003c/code\u003e\u003c/a\u003e\nBackport quadratic complexity fix for !!omap\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/33d05b5d29a8c21360f620f7e1c1706e24522eda\"\u003e\u003ccode\u003e33d05b5\u003c/code\u003e\u003c/a\u003e\n4.3.0 released\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/663bfab6db2b4a146a9366fd685f069345be4ddb\"\u003e\u003ccode\u003e663bfab\u003c/code\u003e\u003c/a\u003e\nDrop demo publish, to not override new v5 one.\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/1cb8c7b94bf75e15116869c1c0482dcb22785986\"\u003e\u003ccode\u003e1cb8c7b\u003c/code\u003e\u003c/a\u003e\nAdd v4-legacy tag for publish\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/02f27afad532763263cd2b6be35c24ee8e1f6157\"\u003e\u003ccode\u003e02f27af\u003c/code\u003e\u003c/a\u003e\nRestore umd builds back to es5\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/8be84edaf15e7c394fa3b813179d1bcc280e87fb\"\u003e\u003ccode\u003e8be84ed\u003c/code\u003e\u003c/a\u003e\nFix es5 compatibility\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/59423c6f8cdc78742ac00e25a4dd39ef16b702e4\"\u003e\u003ccode\u003e59423c6\u003c/code\u003e\u003c/a\u003e\nReplace \u003ccode\u003emaxMergeSeqLength\u003c/code\u003e option with\n\u003ccode\u003emaxTotalMergeKeys\u003c/code\u003e (more robust). Ba...\u003c/li\u003e\n\u003cli\u003e\u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/commit/6842ef6a02df01ca7282ea01dc3c70787710c05d\"\u003e\u003ccode\u003e6842ef6\u003c/code\u003e\u003c/a\u003e\ndoc polish\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca\nhref\u003d\"https://github.com/nodeca/js-yaml/compare/4.2.0...4.3.1\"\u003ecompare\nview\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility\nscore](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003djs-yaml\u0026package-manager\u003dnpm_and_yarn\u0026previous-version\u003d4.2.0\u0026new-version\u003d4.3.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)\n\nDependabot will resolve any conflicts with this PR as long as you don\u0027t\nalter it yourself. You can also trigger a rebase manually by commenting\n`@dependabot rebase`.\n\n[//]: # (dependabot-automerge-start)\n[//]: # (dependabot-automerge-end)\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003eDependabot commands and options\u003c/summary\u003e\n\u003cbr /\u003e\n\nYou can trigger Dependabot actions by commenting on this PR:\n- `@dependabot rebase` will rebase this PR\n- `@dependabot recreate` will recreate this PR, overwriting any edits\nthat have been made to it\n- `@dependabot show \u003cdependency name\u003e ignore conditions` will show all\nof the ignore conditions of the specified dependency\n- `@dependabot ignore this major version` will close this PR and stop\nDependabot creating any more for this major version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this minor version` will close this PR and stop\nDependabot creating any more for this minor version (unless you reopen\nthe PR or upgrade to it yourself)\n- `@dependabot ignore this dependency` will close this PR and stop\nDependabot creating any more for this dependency (unless you reopen the\nPR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the\n[Security Alerts page](https://github.com/apache/texera/network/alerts).\n\n\u003c/details\u003e\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "a3f2bf0a1db064c7dd710a1fb6b10bc2832f94dd",
      "tree": "eee3b8118b561501b3cc5cebcdae39e7df025a6d",
      "parents": [
        "06845321bc90800d3da77dcceebc63a94d1951d5"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Tue Aug 11 22:06:11 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 05:06:11 2026 +0000"
      },
      "message": "test(amber): cover result pagination and the result update loop (#7556)\n\n### What changes were proposed in this PR?\n\n`ExecutionResultService` sat at **22.9% of 122 lines**. Its 18 existing\ntests cover the JSON conversion helpers and the `WebOutputMode`\nround-trips and stop at the class\u0027s own behaviour, so nothing exercised\nthe paths a user actually hits: paging through a stored result,\nsearching and slicing its columns, and the polling loop that pushes\nupdates to the frontend while an execution runs.\n\nAdds 22 tests to the existing spec, taking the file to **99.2% of\nlines** (121/122).\n\nThe seam is `attachToExecution`\u0027s `client` parameter: `AmberClient` is\nnon-final with an overridable `registerCallback`, so a test subclass\ncaptures the registrations and fires them directly over a bare\n`ActorSystem` — the pattern `ExecutionConsoleServiceSpec` already uses.\nA fresh `ExecutionStateStore` that never sees RUNNING is what keeps\n`AmberRuntime` out of it.\n\nCovered: page origin and range end, case-insensitive column search,\ncolumn offset and limit, the warehouse read guard, all three output\nmodes and the internal-port filter, the dirty-page computation, snapshot\nversus delta reads, table statistics, the terminal-state transition that\ncancels polling and runs one final update, and the fatal-error path.\n\n### Verification\n\n32 mutations applied one at a time, each reverted with the production\ndiff confirmed empty before the next. All 32 red. Three were then re-run\nindependently after the fact — the page origin off-by-one page, the\ndirty-page count flooring instead of ceiling, and the delta reading from\nthe new tuple count instead of the old — all three red again.\n\nTwo details worth stating rather than glossing:\n\n- **The page end bound rests on one assertion.** Only the exact-id-list\ntest pins it; the \"clamp the last page\" test cannot, because with 7 rows\nboth `[6,9)` and `[6,10)` yield the same single row. The redundancy one\nwould assume is not there, so that test is load-bearing on its own.\n- **The warehouse-guard test uses `a[WarehouseUnavailableException]\nshould be thrownBy`**, which is a loose form — any collaborator throwing\nthat type satisfies it, and `DocumentFactory.openDocument` is a\nplausible second thrower since it also resolves warehouses. Dropping the\nguard was checked directly and fails exactly that one test, so the line\nis genuinely load-bearing for it.\n\n### Deliberately not included\n\nOne line remains uncovered, and it should be **deleted rather than\ntested**: the `case _ \u003d\u003e throw new RuntimeException(\"update mode\ncombination not supported: ...\")` in `convertWebResultUpdate`.\n`webOutputMode` is built immediately above from a total match over\n`OutputMode`, so it is provably one of `PaginationMode` /\n`SetSnapshotMode` / `SetDeltaMode` and all three are matched by the\npreceding cases. No test can kill a mutation there.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7555\n\n### How was this PR tested?\n\n```\nSTORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres sbt \"WorkflowExecutionService/testOnly org.apache.texera.web.service.ExecutionResultServiceSpec\"\n```\n\n```\n[info] Total number of tests run: 40\n[info] Tests: succeeded 40, failed 0, canceled 0, ignored 0, pending 0\n```\n\n22 new on top of the existing 18. Coverage measured with sbt-jacoco\nfiltered to this spec — note that a plain `testOnly` reports 0% for this\nmodule, since the destfile javaOption only comes from the `jacoco` task.\n`Test/scalafmtCheck` and `Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "06845321bc90800d3da77dcceebc63a94d1951d5",
      "tree": "eb80baf922599f409d0c9b245df33152b1a8fac2",
      "parents": [
        "408b33a98a73177ec5175806cef539603dcdb8ed"
      ],
      "author": {
        "name": "Neil Ketteringham",
        "email": "53205839+Neilk1021@users.noreply.github.com",
        "time": "Tue Aug 11 21:34:42 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 04:34:42 2026 +0000"
      },
      "message": "refactor(auth): store the identity provider\u0027s full avatar URL (#7563)\n\n### What changes were proposed in this PR?\n\n`\"user\".avatar` holds only the last path segment of Google\u0027s `picture`\nclaim, and the frontend\nrebuilds around it. Migration 33 renamed the user column from\n`google_avatar` but deliberately kept every value as-is, so the *value*\nis still Google-only: no other identity provider can be represented in\nit.\n\nThis stores the complete URL the provider supplied, and takes the\nGoogle-specific naming off the\nwire along with it.\n\n**Avatar value**\n- New `common/util/AvatarUtil`: keeps an avatar only when it is an\n`http(s)` URL on an allowlisted\nhost (`googleusercontent.com` today), and drops anything else rather\nthan failing the login.\nStoring a provider-chosen URL is what makes this necessary — the old\nfragment-plus-hardcoded-host\n  scheme gave that guarantee implicitly.\n- `GoogleAuthResource.profileOf` keeps `picture` whole instead of\n`_.split(\"/\").lastOption`.\n- `ExternalProfile.avatar` becomes `Option[String]`, so \"no avatar we\nwould store\" is one case that\nleaves the column alone. Previously a payload without `picture`\noverwrote a stored avatar with\n  `\"\"`.\n- `sql/updates/35.sql` widens the column to `VARCHAR(512)`, normalizes\n`\u0027\u0027` to `NULL`, and promotes\nexisting fragments to absolute URLs. Idempotent via a `NOT LIKE \u0027http%\u0027`\nguard.\n- The frontend fetches the stored URL verbatim; `getAvatar`\u0027s argument\nand cache key are the URL.\n\n**Naming**\n- The JWT claim `googleAvatar` is now `avatar`. Tokens live for\n`auth.jwt.expiration-in-minutes` (a week by default), so both\n`JwtParser` and `auth.service.ts`\nread the new name and fall back to the old one — otherwise every\nalready-signed-in user loses\ntheir avatar until their token is reissued. Both fallbacks are commented\nas deletable once\n  pre-rename tokens have expired, and are pinned by tests.\n- The same rename lands on the DTO fields that carry the value to the\nbrowser\n(`UserInfo.avatar`, `WorkflowExecutionEntry.avatar`,\n`DashboardWorkflowComputingUnit.ownerAvatar`),\n  the matching TS types, and `UserAvatarComponent`\u0027s `@Input`.\n\n### Any related issues, documentation, discussions?\n\nCloses #7296\n\n### How was this PR tested?\n\n- `sbt scalafmtCheckAll \"scalafixAll --check\" Test/compile Util/test\nAuth/test` — clean;\n  `Util/test` 24, `Auth/test` 99.\n- `WorkflowExecutionService/testOnly *GoogleAuthResourceSpec\n*ExternalAuthProvisionerSpec\n*AuthResourceSpec *AdminUserResourceSpec *WorkflowExecutionsResourceSpec\n*DashboardResourceSpec`\n— 116 tests, 0 failures. `ComputingUnitManagingService/test` — 91, 0\nfailures.\n- New coverage: `AvatarUtilSpec` (allowlist, subdomains, lookalike\nhosts, non-`http(s)` schemes,\nblank/absent); avatar cases in `GoogleAuthResourceSpec` (full URL\nstored, rotation, absent\npicture, keep-on-absent, disallowed host) and\n`ExternalAuthProvisionerSpec` (`None` leaves a\nstored avatar alone); claim back-compat in `JwtParserSpec` and\n`auth.service.spec.ts`.\n- Frontend: `yarn ng test` — 201 files / 4419 tests, 0 failures; `yarn\nformat:ci` clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\nGenerated-by: Claude Opus 4.8"
    },
    {
      "commit": "408b33a98a73177ec5175806cef539603dcdb8ed",
      "tree": "b7784b0230a180307827feb1b298f84074165828",
      "parents": [
        "cd3872a3a68393644ac28227532ae181b8a01b8f"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Tue Aug 11 20:58:13 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 03:58:13 2026 +0000"
      },
      "message": "test(config-service): cover ConfigService.run in its RunSpec (#7560)\n\n### What changes were proposed in this PR?\n\n`ConfigServiceRunSpec` only asserted role annotations on the resource\nclasses, so\n`ConfigService` itself was never instantiated and the file sat at 0%.\nAdds four tests\nthat call `run()` against a mocked Dropwizard `Environment`, following\n`AccessControlServiceRunSpec`. The existing role-annotation assertion is\nkept.\n\n| counter | before | after |\n| --- | --- | --- |\n| line | 0/30 | 13/30 |\n| instruction | 0/171 | 99/171 |\n| branch | 0/6 | 4/6 |\n| method | 0/8 | 4/8 |\n\n`run()` itself is now fully covered by line; every remaining missed line\nis in\n`initialize()` (39-51) or `object ConfigService.main` (95-108), which\nthe issue puts out\nof scope because #5983 moves that boilerplate into a shared\n`ServiceBootstrap`.\n\nWhat the tests pin:\n\n- the `/api/*` url pattern, the session handler on both the Jersey and\nservlet\nenvironments, and the `HealthCheckResource` / `ConfigResource`\nregistrations;\n- the auth stack `AuthFeatures.register` installs —\n`AuthDynamicFeature`,\n`UnauthorizedExceptionMapper` and `RolesAllowedDynamicFeature` — without\nwhich `@Auth`\nparameters do not resolve and `@RolesAllowed` on the settings endpoints\nis ignored;\n- `RequestLoggingFilter.register(environment.getApplicationContext)`,\nverified as the\n  `addFilter(FilterHolder, \"/*\", …)` it performs;\n- the default-settings preload, checked against the database rather than\na mock: every\nentry of `DefaultsConfig.allDefaults` must be present in `site_settings`\nwith its value;\n- that a preload failure is rethrown rather than swallowed — a service\nthat came up with\n  no settings would look healthy while serving none of them.\n\n`run()` ends by writing `default.conf` into `site_settings`, so it needs\na live\n`SqlServer`; mocking the `Environment` alone cannot reach the\nrequest-logging filter that\nfollows. The suite therefore mixes in `MockTexeraDB`, which gives it its\nown embedded\ndatabase and points `SqlServer` at it — `config-service` already\ndeclares\n`.dependsOn(DAO % \"test-\u003etest\")` for exactly this, and\n`ConfigResourceSpec` in the same\nmodule already does it. The failure case swaps in a `ConnectionProvider`\nthat cannot\nacquire a connection; `MockTexeraDB`\u0027s fixture reinstalls the healthy\ncontext before the\nnext test, so it stays local (the fixture does not truncate tables, so\ndropping one would\nnot have).\n\nThe two branches still missed are not application logic: one on the\nclass declaration\n(`with LazyLogging`, 3/4 arms covered) and the implicit non-`Exception`\narm of\n`case ex: Exception`.\n\nNo production code was changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7558.\n\n### How was this PR tested?\n\n`sbt \"ConfigService/testOnly *ConfigServiceRunSpec\"` — 5 tests pass, run\nrepeatedly with\nthe same result; `sbt ConfigService/jacoco` over the module is green (38\ntests) and gives\nthe table above. The failure path was verified by breaking the\nurl-pattern assertion (red,\nnon-zero exit) and restoring it. `ConfigService/Test/scalafmtCheck` and\n`ConfigService/Test/scalafix --check` are clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "cd3872a3a68393644ac28227532ae181b8a01b8f",
      "tree": "18c6a40f395d0f5ab9833f0d0f799fe0469f8e0d",
      "parents": [
        "a353b71c231f89d4d33a5fffa69be84d1ef675c5"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Tue Aug 11 20:58:11 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 03:58:11 2026 +0000"
      },
      "message": "test(workflow-compiling-service): cover WorkflowCompilingService.run (#7561)\n\n### What changes were proposed in this PR?\n\nExtends `WorkflowCompilingServiceRunSpec` to actually exercise\n`WorkflowCompilingService.run`, which had no coverage — the spec\npreviously only\nasserted role annotations on the resource classes. No production code\nwas\nchanged.\n\nFollowing `AccessControlServiceRunSpec` (the template the issue points\nat), a\nmocked Dropwizard `Environment` is handed to `run(config, env)` and the\nwiring it\ninstalls is verified, without starting a server:\n\n- `jersey.setUrlPattern(\"/api/*\")`\n- `jersey.register(classOf[HealthCheckResource])` and\n  `jersey.register(classOf[WorkflowCompilationResource])`\n- the auth stack from `AuthFeatures.register` — asserted through the\n`RolesAllowedDynamicFeature` and `UnauthorizedExceptionMapper` it\nregisters\n  (without the former Jersey silently ignores `@RolesAllowed`)\n- the request-logging filter added to the application context\n\nThe existing role-annotation assertion is kept.\n\nPer the issue\u0027s scope note, only `run()` is covered — `initialize()`,\n`main()`\nand the config/connection helpers are left alone since #5983 moves that\nboilerplate into a shared `ServiceBootstrap`.\n\nOne thing worth noting for reviewers: `run()` calls\n`SqlServer.initConnection`,\nwhich is safe here because it only constructs the `SqlServer` (the pool\nconnects\nlazily) — the same call is made by `AccessControlService.run`, whose\nspec already\nruns this way in CI.\n\n### Any related issues, documentation, discussions?\n\nCloses #7557\n\n### How was this PR tested?\n\nUnit tests, run locally. All pass, and the failure path was verified by\nbreaking\nan assertion to confirm the suite goes red:\n\n```\nsbt \"WorkflowCompilingService/testOnly *WorkflowCompilingServiceRunSpec\"\n# Tests: succeeded 5, failed 0\nsbt \"WorkflowCompilingService/Test/scalafmtCheck\"      # clean\nsbt \"WorkflowCompilingService/Test/scalafix --check\"   # clean\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "a353b71c231f89d4d33a5fffa69be84d1ef675c5",
      "tree": "3672abca2d71349ce9351aa91835968f65638ccd",
      "parents": [
        "cb6e5c649978215188ea92937ec583be9990c49e"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Tue Aug 11 20:57:48 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 12 03:57:48 2026 +0000"
      },
      "message": "test(amber): cover the synchronous execution endpoint (#7554)\n\n### What changes were proposed in this PR?\n\n`SyncExecutionResource` was the largest uncovered file in the repository\n— 406 instrumented lines, no spec, **0%**. It is the endpoint an\nexternal caller uses to run a workflow and get results back in one\nrequest, so its result assembly, error classification and\ncell-truncation rules are all user-visible.\n\nAdds 23 tests, taking the file to **56.7% of lines** (230/406). Nothing\nhere needs infrastructure: the class is a zero-arg Jersey resource that\nconstructs with no fixture, and MockTexeraDB plus a single\n`workflow_computing_unit` row is enough to drive the public endpoint end\nto end — `initExecutionService` absorbs the missing engine into a FAILED\nstate, after which the whole result-assembly tail runs.\n\nCovered: the state mapping and terminal-state predicate, console error\ndetection, symmetric cell truncation and tuple-size estimation, error\nclassification, sub-DAG computation, the 100-line operator-info\naggregator, console-log retrieval, and `executeWorkflowSync` itself.\n\n### Verification\n\n52 mutations applied one at a time and reverted, with the production\nfile\u0027s md5 compared against its pre-mutation value after each revert.\nProduction diff empty. Highlights: swapping input for output metrics in\nthe aggregator, taking the console title instead of the longer message\nas the error, walking the sub-DAG by the wrong link end, dropping the\nvisited-set early return, promoting a mid-line \"WARNING:\" mention to a\nreal warning, and reporting KILLED as FAILED.\n\n**Two assertions were found vacuous in review; one was fixed and one is\nreported as unpinnable.**\n\n*Fixed* — the in-memory console fallback\u0027s `.filter(_.nonEmpty)` could\nbe dropped and nothing noticed, because no fixture had an operator that\nwas *present* in `operatorConsole` while carrying zero messages. That\nstate is real: `ExecutionConsoleService` creates exactly that shape via\n`getOrElse(opId, OperatorConsole())` before it has anything to add.\nAdded a `\"silent\"` operator and asserted `consoleLogs` is `None` rather\nthan `Some(Nil)` — the frontend renders a console pane for `Some`, so\n`Some(Nil)` is an empty pane. That mutation is now red.\n\n*Reported, not papered over* — inverting the console-error arm at line\n328 leaves the suite green. The one test that exercises `stateString`\nruns a path where `terminatedByConsoleError` is false **and**\n`stateToString(finalState.state)` is also `\"Failed\"`, so the assertion\ncannot tell the two arms apart. Distinguishing them needs a run whose\nfinal state is not FAILED, which is impossible without a live engine —\nwith no coordinator, `initExecutionService` always stamps FAILED. This\nis stated in the spec at that test rather than left for the next reader\nto discover.\n\nOne further mutation survived and is an **equivalent mutant** rather\nthan a gap: `truncateSingleTuple`\u0027s `text.length \u003e maxCellChars` flipped\nto `\u003e\u003d`. The truncation it guards re-checks the same bound and returns\nthe cell unchanged, so no input can distinguish the two spellings. The\ntest was kept (the behaviour is real) and its comment corrected to say\nwhy the boundary is unobservable.\n\n### Deliberately not included\n\n- **~139 lines** behind real Iceberg result storage\n(`collectOperatorResult`, the symmetric-truncation engine).\n`DocumentFactory.openDocument` is an un-displaceable static for `vfs://`\nURIs. `common/workflow-core`\u0027s `LocalHadoopIcebergCatalog` would unlock\nit, but amber declares only `DAO % \"test-\u003etest\", Auth % \"test-\u003etest\"`\n(build.sbt:270), so it is not on amber\u0027s test classpath. Adding\n`WorkflowCore % \"test-\u003etest\"` would take this file to roughly 87% —\nworth doing, but as its own change.\n- **The `Observable.amb` wait and its timeout/termination arms**, which\nneed an execution that is still non-terminal, i.e. a live engine.\n- **`validateWorkflow` (905–924)** — it has **zero call sites**\nrepo-wide. It can be driven reflectively, which is not the same as being\nlive; testing it would cement dead code. Delete instead.\n- **The `if (executionService \u003d\u003d null)` early return**, effectively\nunreachable: `initExecutionService` publishes before calling\n`executeWorkflow()`, and the constructor is documented and verified\nside-effect-free.\n\n### Known follow-up\n\nMost helpers are reached through `PrivateMethodTester` because 14 of the\n16 methods are `private def` (there is repo precedent — eight existing\nspecs use it). One case was avoidable: `handleExecutionError` is\nreachable from the public endpoint by passing a wid with no `workflow`\nrow, which would additionally cover lines 343–346. Left as noted rather\nthan restructured here. Widening the nine pure helpers to\n`private[resource]` would remove nearly all the reflection for a\none-word change each.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7553\n\n### How was this PR tested?\n\n```\nSTORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres sbt \"WorkflowExecutionService/testOnly org.apache.texera.web.resource.SyncExecutionResourceSpec\"\n```\n\n```\n[info] Total number of tests run: 23\n[info] Tests: succeeded 23, failed 0, canceled 0, ignored 0, pending 0\n```\n\nCoverage measured with sbt-jacoco filtered to this spec (a bare `jacoco`\nruns amber\u0027s `@IntegrationTest` specs, which hang on Windows): 0/406\nbefore, 230/406 after. `Test/scalafmtCheck` and `Test/scalafix --check`\nboth pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "cb6e5c649978215188ea92937ec583be9990c49e",
      "tree": "56184d7f15e0353191a1c75ba190e9802b59b141",
      "parents": [
        "e878df3eee7ca3baee7b0c34eceb63548c59e68a"
      ],
      "author": {
        "name": "Ryan Zhang",
        "email": "97552093+zyratlo@users.noreply.github.com",
        "time": "Tue Aug 11 15:42:13 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 22:42:13 2026 +0000"
      },
      "message": "feat(python-notebook-migration, frontend): remove the workspace toolbar entry point (#7571)\n\n### What changes were proposed in this PR?\n\nThis is the first PR of moving the AI generate workflow entry point from\nthe workspace toolbar to the workflow dashboard (#7360). It removes the\nworkspace toolbar entry point and the UI that exists only to serve it,\nso the canvas and dashboard versions never coexist.\n\n**Menu toolbar (`menu.component.{ts,html,scss}`)**\n- Removes the \"AI generate workflow\" button and the flow it started\n- Removes the now unused output that signaled the loading overlay, along\nwith the imports and constructor dependencies that only the removed code\nused. The auto layout action and the workflow modifiable state stay,\nsince other toolbar buttons rely on them.\n\n**Workspace (`workspace.component.{ts,html,scss}`)**\n- Removes the loading overlay and its elapsed time stopwatch, which were\ndriven by the toolbar output.\n- Keeps the embedded notebook panel host. It displays a workflow\u0027s\nstored notebook and is driven by the workflow id, so it keeps working\nfor the dashboard entry point.\n\n**Retained (shared, reused by the dashboard entry point)**\n- The import modal component and its diagram asset and license\nattributions.\n- The notebook to workflow conversion service.\n- The embedded notebook panel and its per workflow initialization.\n- The expand Jupyter panel button\n\nAfter this change the tool has no entry point until the dashboard entry\npoint lands. The feature stays behind its existing feature flag, so\nusers see no change.\n\n### Any related issues, documentation, discussions?\n\nCloses #7564\nParent issue #4301\n\n### How was this PR tested?\n\nUpdated `menu.component.spec.ts` and `workspace.component.spec.ts` to\ndrop the tests for the removed button, the generation pipeline, and the\nloading timer. No new behavior is added, so no new tests were needed.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 4.8)"
    },
    {
      "commit": "e878df3eee7ca3baee7b0c34eceb63548c59e68a",
      "tree": "a1bbf2a4bdf52dea8a69b71163fd0c4086511c9e",
      "parents": [
        "686aedba6c41a95a509f44f88e0c336456aac382"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Tue Aug 11 09:25:28 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 08:25:28 2026 +0000"
      },
      "message": "chore(deps, ci): update github-actions (#7493)\n\nThis PR contains the following updates:\n\n| Package | Type | Update | Change |\n|---|---|---|---|\n| [docker/login-action](https://redirect.github.com/docker/login-action)\n| action | minor | `v4.4.0` → `v4.6.0` |\n| [node](https://redirect.github.com/actions/node-versions) | uses-with\n| minor | `24.10.0` → `24.19.0` |\n| [python](https://redirect.github.com/actions/python-versions) |\nuses-with | minor | `3.11` → `3.14` |\n| [python](https://redirect.github.com/actions/python-versions) |\nuses-with | minor | `3.12` → `3.14` |\n| [sbt/setup-sbt](https://redirect.github.com/sbt/setup-sbt) | action |\npatch | `v1.5.2` → `v1.5.7` |\n|\n[scalacenter/sbt-dependency-submission](https://redirect.github.com/scalacenter/sbt-dependency-submission)\n| action | minor | `v3.1.1` → `v3.2.3` |\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Release Notes\n\n\u003cdetails\u003e\n\u003csummary\u003edocker/login-action (docker/login-action)\u003c/summary\u003e\n\n###\n[`v4.6.0`](https://redirect.github.com/docker/login-action/compare/v4.5.2...v4.6.0)\n\n[Compare\nSource](https://redirect.github.com/docker/login-action/compare/v4.5.2...v4.6.0)\n\n###\n[`v4.5.2`](https://redirect.github.com/docker/login-action/compare/v4.5.1...v4.5.2)\n\n[Compare\nSource](https://redirect.github.com/docker/login-action/compare/v4.5.1...v4.5.2)\n\n###\n[`v4.5.1`](https://redirect.github.com/docker/login-action/compare/v4.5.0...v4.5.1)\n\n[Compare\nSource](https://redirect.github.com/docker/login-action/compare/v4.5.0...v4.5.1)\n\n###\n[`v4.5.0`](https://redirect.github.com/docker/login-action/compare/v4.4.0...v4.5.0)\n\n[Compare\nSource](https://redirect.github.com/docker/login-action/compare/v4.4.0...v4.5.0)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eactions/node-versions (node)\u003c/summary\u003e\n\n###\n[`v24.19.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.19.0-30872449280):\n24.19.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.18.1-30508414346...24.19.0-30872449280)\n\nNode.js 24.19.0\n\n###\n[`v24.18.1`](https://redirect.github.com/actions/node-versions/releases/tag/24.18.1-30508414346):\n24.18.1\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.18.0-28070977815...24.18.1-30508414346)\n\nNode.js 24.18.1\n\n###\n[`v24.18.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.18.0-28070977815):\n24.18.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.17.0-27765711116...24.18.0-28070977815)\n\nNode.js 24.18.0\n\n###\n[`v24.17.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.17.0-27765711116):\n24.17.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.16.0-26265092718...24.17.0-27765711116)\n\nNode.js 24.17.0\n\n###\n[`v24.16.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.16.0-26265092718):\n24.16.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.15.0-24511264946...24.16.0-26265092718)\n\nNode.js 24.16.0\n\n###\n[`v24.15.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.15.0-24511264946):\n24.15.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.14.1-23521883727...24.15.0-24511264946)\n\nNode.js 24.15.0\n\n###\n[`v24.14.1`](https://redirect.github.com/actions/node-versions/releases/tag/24.14.1-23521883727):\n24.14.1\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.14.0-22380502845...24.14.1-23521883727)\n\nNode.js 24.14.1\n\n###\n[`v24.14.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.14.0-22380502845):\n24.14.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.13.1-21889660756...24.14.0-22380502845)\n\nNode.js 24.14.0\n\n###\n[`v24.13.1`](https://redirect.github.com/actions/node-versions/releases/tag/24.13.1-21889660756):\n24.13.1\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.13.0-20981653924...24.13.1-21889660756)\n\nNode.js 24.13.1\n\n###\n[`v24.13.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.13.0-20981653924):\n24.13.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.12.0-20140960970...24.13.0-20981653924)\n\nNode.js 24.13.0\n\n###\n[`v24.12.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.12.0-20140960970):\n24.12.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.11.1-19282993875...24.12.0-20140960970)\n\nNode.js 24.12.0\n\n###\n[`v24.11.1`](https://redirect.github.com/actions/node-versions/releases/tag/24.11.1-19282993875):\n24.11.1\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.11.0-18894910158...24.11.1-19282993875)\n\nNode.js 24.11.1\n\n###\n[`v24.11.0`](https://redirect.github.com/actions/node-versions/releases/tag/24.11.0-18894910158):\n24.11.0\n\n[Compare\nSource](https://redirect.github.com/actions/node-versions/compare/24.10.0-18453495281...24.11.0-18894910158)\n\nNode.js 24.11.0\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eactions/python-versions (python)\u003c/summary\u003e\n\n###\n[`v3.14.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.7-31064857500):\n3.14.7\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.6-27283001424...3.14.7-31064857500)\n\nPython 3.14.7\n\n###\n[`v3.14.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.6-27283001424):\n3.14.6\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.5-25647354415...3.14.6-27283001424)\n\nPython 3.14.6\n\n###\n[`v3.14.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.5-25647354415):\n3.14.5\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.4-25113653268...3.14.5-25647354415)\n\nPython 3.14.5\n\n###\n[`v3.14.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.4-25113653268):\n3.14.4\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.3-21673711214...3.14.4-25113653268)\n\nPython 3.14.4\n\n###\n[`v3.14.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.3-21673711214):\n3.14.3\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.2-20014991423...3.14.3-21673711214)\n\nPython 3.14.3\n\n###\n[`v3.14.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.2-20014991423):\n3.14.2\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.1-19879739908...3.14.2-20014991423)\n\nPython 3.14.2\n\n###\n[`v3.14.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.1-19879739908):\n3.14.1\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.14.0-18313368925...3.14.1-19879739908)\n\nPython 3.14.1\n\n###\n[`v3.14.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.0-18313368925):\n3.14.0\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.15-31064747964...3.14.0-18313368925)\n\nPython 3.14.0\n\n###\n[`v3.13.15`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.15-31064747964):\n3.13.15\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.14-27320626148...3.13.15-31064747964)\n\nPython 3.13.15\n\n###\n[`v3.13.14`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.14-27320626148):\n3.13.14\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.13-27225391538...3.13.14-27320626148)\n\nPython 3.13.14\n\n###\n[`v3.13.13`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.13-27225391538):\n3.13.13\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.12-21673645133...3.13.13-27225391538)\n\nPython 3.13.13\n\n###\n[`v3.13.12`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.12-21673645133):\n3.13.12\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.11-20014977833...3.13.12-21673645133)\n\nPython 3.13.12\n\n###\n[`v3.13.11`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.11-20014977833):\n3.13.11\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.10-19879712315...3.13.11-20014977833)\n\nPython 3.13.11\n\n###\n[`v3.13.10`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.10-19879712315):\n3.13.10\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.9-18515951191...3.13.10-19879712315)\n\nPython 3.13.10\n\n###\n[`v3.13.9`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.9-18515951191):\n3.13.9\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.8-18331000654...3.13.9-18515951191)\n\nPython 3.13.9\n\n###\n[`v3.13.8`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.8-18331000654):\n3.13.8\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.7-16980743123...3.13.8-18331000654)\n\nPython 3.13.8\n\n###\n[`v3.13.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.7-16980743123):\n3.13.7\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.6-16792117939...3.13.7-16980743123)\n\nPython 3.13.7\n\n###\n[`v3.13.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.6-16792117939):\n3.13.6\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.5-15601068749...3.13.6-16792117939)\n\nPython 3.13.6\n\n###\n[`v3.13.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.5-15601068749):\n3.13.5\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.4-15433317575...3.13.5-15601068749)\n\nPython 3.13.5\n\n###\n[`v3.13.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.4-15433317575):\n3.13.4\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.3-14344076652...3.13.4-15433317575)\n\nPython 3.13.4\n\n###\n[`v3.13.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.3-14344076652):\n3.13.3\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.2-13708744326...3.13.3-14344076652)\n\nPython 3.13.3\n\n###\n[`v3.13.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.2-13708744326):\n3.13.2\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.1-13437882550...3.13.2-13708744326)\n\nPython 3.13.2\n\n###\n[`v3.13.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.1-13437882550):\n3.13.1\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.13.0-13707372259...3.13.1-13437882550)\n\nPython 3.13.1\n\n###\n[`v3.13.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.0-13707372259):\n3.13.0\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.13-27650778726...3.13.0-13707372259)\n\nPython 3.13.0\n\n###\n[`v3.12.13`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.13-27650778726):\n3.12.13\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.12-18393146713...3.12.13-27650778726)\n\nPython 3.12.13\n\n###\n[`v3.12.12`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.12-18393146713):\n3.12.12\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.11-15433310049...3.12.12-18393146713)\n\nPython 3.12.12\n\n###\n[`v3.12.11`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.11-15433310049):\n3.12.11\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.10-14343898437...3.12.11-15433310049)\n\nPython 3.12.11\n\n###\n[`v3.12.10`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.10-14343898437):\n3.12.10\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.9-13149478207...3.12.10-14343898437)\n\nPython 3.12.10\n\n###\n[`v3.12.9`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.9-13149478207):\n3.12.9\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.8-12154062663...3.12.9-13149478207)\n\nPython 3.12.9\n\n###\n[`v3.12.8`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.8-12154062663):\n3.12.8\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.7-11128208086...3.12.8-12154062663)\n\nPython 3.12.8\n\n###\n[`v3.12.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.7-11128208086):\n3.12.7\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.6-10765725458...3.12.7-11128208086)\n\nPython 3.12.7\n\n###\n[`v3.12.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.6-10765725458):\n3.12.6\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.5-10375840348...3.12.6-10765725458)\n\nPython 3.12.6\n\n###\n[`v3.12.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.5-10375840348):\n3.12.5\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.4-9947065640...3.12.5-10375840348)\n\nPython 3.12.5\n\n###\n[`v3.12.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.4-9947065640):\n3.12.4\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.3-11057844995...3.12.4-9947065640)\n\nPython 3.12.4\n\n###\n[`v3.12.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.3-11057844995):\n3.12.3\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.2-11057786931...3.12.3-11057844995)\n\nPython 3.12.3\n\n###\n[`v3.12.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.2-11057786931):\n3.12.2\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.1-11057762749...3.12.2-11057786931)\n\nPython 3.12.2\n\n###\n[`v3.12.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.1-11057762749):\n3.12.1\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.12.0-11057302691...3.12.1-11057762749)\n\nPython 3.12.1\n\n###\n[`v3.12.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.12.0-11057302691):\n3.12.0\n\n[Compare\nSource](https://redirect.github.com/actions/python-versions/compare/3.11.15-27649667267...3.12.0-11057302691)\n\nPython 3.12.0\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003esbt/setup-sbt (sbt/setup-sbt)\u003c/summary\u003e\n\n###\n[`v1.5.7`](https://redirect.github.com/sbt/setup-sbt/releases/tag/v1.5.7)\n\n[Compare\nSource](https://redirect.github.com/sbt/setup-sbt/compare/v1.5.6...v1.5.7)\n\n#### Updates\n\n- Update sbt to 2.0.5 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;122](https://redirect.github.com/sbt/setup-sbt/pull/122)\n- Update sbt to 2.0.6 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;123](https://redirect.github.com/sbt/setup-sbt/pull/123)\n\n**Full Changelog**:\n\u003chttps://github.com/sbt/setup-sbt/compare/v1...v1.5.7\u003e\n\n###\n[`v1.5.6`](https://redirect.github.com/sbt/setup-sbt/releases/tag/v1.5.6)\n\n[Compare\nSource](https://redirect.github.com/sbt/setup-sbt/compare/v1.5.5...v1.5.6)\n\n##### updates\n\n- Update sbt to 2.0.4 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;120](https://redirect.github.com/sbt/setup-sbt/pull/120)\n- Add results: none to ampel/verify by\n[@\u0026#8203;eed3si9n](https://redirect.github.com/eed3si9n) in\n[#\u0026#8203;121](https://redirect.github.com/sbt/setup-sbt/pull/121)\n\n**Full Changelog**:\n\u003chttps://github.com/sbt/setup-sbt/compare/v1...v1.5.6\u003e\n\n###\n[`v1.5.5`](https://redirect.github.com/sbt/setup-sbt/releases/tag/v1.5.5)\n\n[Compare\nSource](https://redirect.github.com/sbt/setup-sbt/compare/v1.5.4...v1.5.5)\n\n##### Updates\n\n- Bump carabiner-dev/actions/ampel/verify pin from v1.2.3 to v1.2.6 by\n[@\u0026#8203;ysolomon-plat](https://redirect.github.com/ysolomon-plat) in\n[#\u0026#8203;119](https://redirect.github.com/sbt/setup-sbt/pull/119)\n\n##### New Contributors\n\n- [@\u0026#8203;ysolomon-plat](https://redirect.github.com/ysolomon-plat)\nmade their first contribution in\n[#\u0026#8203;119](https://redirect.github.com/sbt/setup-sbt/pull/119)\n\n**Full Changelog**:\n\u003chttps://github.com/sbt/setup-sbt/compare/v1...v1.5.5\u003e\n\n###\n[`v1.5.4`](https://redirect.github.com/sbt/setup-sbt/releases/tag/v1.5.4)\n\n[Compare\nSource](https://redirect.github.com/sbt/setup-sbt/compare/v1.5.3...v1.5.4)\n\n#### Updates\n\n- fix: Recheck after actions/cache by\n[@\u0026#8203;arashi01](https://redirect.github.com/arashi01) +\n[@\u0026#8203;eed3si9n](https://redirect.github.com/eed3si9n) in\n[#\u0026#8203;116](https://redirect.github.com/sbt/setup-sbt/pull/116)\n\n**Full Changelog**:\n\u003chttps://github.com/sbt/setup-sbt/compare/v1...v1.5.4\u003e\n\n###\n[`v1.5.3`](https://redirect.github.com/sbt/setup-sbt/releases/tag/v1.5.3)\n\n[Compare\nSource](https://redirect.github.com/sbt/setup-sbt/compare/v1.5.2...v1.5.3)\n\n#### Updates\n\n- fix: Include `RUNNER_ARCH` into the cache key to fix Windows cache\nrestoration errors by\n[@\u0026#8203;eed3si9n](https://redirect.github.com/eed3si9n) in\n[#\u0026#8203;115](https://redirect.github.com/sbt/setup-sbt/pull/115)\n- Bump carabiner-dev/actions/ampel/verify from 1.2.1 to 1.2.3 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;113](https://redirect.github.com/sbt/setup-sbt/pull/113)\n\n**Full Changelog**:\n\u003chttps://github.com/sbt/setup-sbt/compare/v1...v1.5.3\u003e\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003escalacenter/sbt-dependency-submission\n(scalacenter/sbt-dependency-submission)\u003c/summary\u003e\n\n###\n[`v3.2.3`](https://redirect.github.com/scalacenter/sbt-dependency-submission/releases/tag/v3.2.3)\n\n[Compare\nSource](https://redirect.github.com/scalacenter/sbt-dependency-submission/compare/v3.2.2...v3.2.3)\n\n#### What\u0027s Changed\n\n- Retry GitHub API calls by\n[@\u0026#8203;kelvin-chappell](https://redirect.github.com/kelvin-chappell)\nin\n[#\u0026#8203;354](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/354)\n- Prepare v3.2.2 release for the Node 24 action runtime by\n[@\u0026#8203;Copilot](https://redirect.github.com/Copilot) in\n[#\u0026#8203;353](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/353)\n\n#### New Contributors\n\n- [@\u0026#8203;kelvin-chappell](https://redirect.github.com/kelvin-chappell)\nmade their first contribution in\n[#\u0026#8203;354](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/354)\n\n**Full Changelog**:\n\u003chttps://github.com/scalacenter/sbt-dependency-submission/compare/v3.2.2...v3.2.3\u003e\n\n###\n[`v3.2.2`](https://redirect.github.com/scalacenter/sbt-dependency-submission/releases/tag/v3.2.2)\n\n[Compare\nSource](https://redirect.github.com/scalacenter/sbt-dependency-submission/compare/v3.2.1...v3.2.2)\n\n#### What\u0027s Changed\n\n- Update scalafmt-core to 3.10.3 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;306](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/306)\n- Update sbt, scripted-plugin to 1.12.0 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;307](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/307)\n- Bump\n[@\u0026#8203;actions/github](https://redirect.github.com/actions/github)\nfrom 6.0.1 to 7.0.0 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;308](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/308)\n- Bump [@\u0026#8203;actions/core](https://redirect.github.com/actions/core)\nfrom 2.0.1 to 2.0.2 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;309](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/309)\n- Update dist by\n[@\u0026#8203;github-actions](https://redirect.github.com/github-actions)\\[bot]\nin\n[#\u0026#8203;310](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/310)\n- Update scalafmt-core to 3.10.4 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;312](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/312)\n- Update sbt, scripted-plugin to 1.12.1 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;316](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/316)\n- Bump [@\u0026#8203;actions/core](https://redirect.github.com/actions/core)\nfrom 2.0.2 to 2.0.3 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;318](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/318)\n- Update dist by\n[@\u0026#8203;github-actions](https://redirect.github.com/github-actions)\\[bot]\nin\n[#\u0026#8203;320](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/320)\n- Update munit to 1.2.2 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;321](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/321)\n- Update scalafmt-core to 3.10.5 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;322](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/322)\n- Update scalafmt-core to 3.10.6 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;326](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/326)\n- Update sbt, scripted-plugin to 1.12.2 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;327](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/327)\n- Update scalafmt-core to 3.10.7 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;328](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/328)\n- Update sbt, scripted-plugin to 1.12.3 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;329](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/329)\n- Update sbt, scripted-plugin to 1.12.4 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;331](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/331)\n- Update sbt-scalafix to 0.14.6 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;333](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/333)\n- Update munit to 1.2.3 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;334](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/334)\n- Update sbt, scripted-plugin to 1.12.5 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;335](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/335)\n- Update munit to 1.2.4 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;336](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/336)\n- Update sbt, scripted-plugin to 1.12.6 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;337](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/337)\n- Update action runtime to Node 24 by\n[@\u0026#8203;Copilot](https://redirect.github.com/Copilot) in\n[#\u0026#8203;339](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/339)\n- Update sbt, scripted-plugin to 1.12.7 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;340](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/340)\n- Update sbt, scripted-plugin to 1.12.8 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;341](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/341)\n- sbt 2.0.0-RC10 by\n[@\u0026#8203;xuwei-k](https://redirect.github.com/xuwei-k) in\n[#\u0026#8203;330](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/330)\n- Update sbt, scripted-plugin to 1.12.9 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;343](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/343)\n- Update munit to 1.3.0 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;344](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/344)\n- Update actions/github 8.0.1 and tsconf by\n[@\u0026#8203;dancewithheart](https://redirect.github.com/dancewithheart) in\n[#\u0026#8203;347](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/347)\n- Improve logging response after submitting dependencies by\n[@\u0026#8203;dancewithheart](https://redirect.github.com/dancewithheart) in\n[#\u0026#8203;346](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/346)\n- Update gigahorse-asynchttpclient to 0.9.4 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;348](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/348)\n- Update sbt, scripted-plugin to 1.12.10 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;349](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/349)\n- Update sbt, scripted-plugin to 1.12.11 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;350](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/350)\n- Update scalafmt-core to 3.11.1 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;351](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/351)\n\n#### New Contributors\n\n- [@\u0026#8203;Copilot](https://redirect.github.com/Copilot) made their\nfirst contribution in\n[#\u0026#8203;339](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/339)\n- [@\u0026#8203;xuwei-k](https://redirect.github.com/xuwei-k) made their\nfirst contribution in\n[#\u0026#8203;330](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/330)\n- [@\u0026#8203;dancewithheart](https://redirect.github.com/dancewithheart)\nmade their first contribution in\n[#\u0026#8203;347](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/347)\n\n**Full Changelog**:\n\u003chttps://github.com/scalacenter/sbt-dependency-submission/compare/v3.2.1...v3.2.2\u003e\n\n###\n[`v3.2.1`](https://redirect.github.com/scalacenter/sbt-dependency-submission/releases/tag/v3.2.1)\n\n[Compare\nSource](https://redirect.github.com/scalacenter/sbt-dependency-submission/compare/v3.2.0...v3.2.1)\n\n#### What\u0027s Changed\n\n- Update scalafmt-core to 3.10.2 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;297](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/297)\n- Update munit to 1.2.1 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;296](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/296)\n- Update scala3-library to 3.7.4 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;295](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/295)\n- Bump [@\u0026#8203;actions/exec](https://redirect.github.com/actions/exec)\nfrom 1.1.1 to 2.0.0 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;291](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/291)\n- Bump js-yaml from 4.1.0 to 4.1.1 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;293](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/293)\n- Bump [@\u0026#8203;actions/core](https://redirect.github.com/actions/core)\nfrom 1.10.1 to 2.0.1 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;289](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/289)\n- Update dist by\n[@\u0026#8203;github-actions](https://redirect.github.com/github-actions)\\[bot]\nin\n[#\u0026#8203;299](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/299)\n- Update scala-library to 2.12.21 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;294](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/294)\n- Bump [@\u0026#8203;vercel/ncc](https://redirect.github.com/vercel/ncc) from\n0.38.1 to 0.38.4 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;290](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/290)\n- Update dist by\n[@\u0026#8203;github-actions](https://redirect.github.com/github-actions)\\[bot]\nin\n[#\u0026#8203;301](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/301)\n- Bump\n[@\u0026#8203;octokit/webhooks-types](https://redirect.github.com/octokit/webhooks-types)\nfrom 7.5.1 to 7.6.1 by\n[@\u0026#8203;dependabot](https://redirect.github.com/dependabot)\\[bot] in\n[#\u0026#8203;292](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/292)\n- Update dist by\n[@\u0026#8203;github-actions](https://redirect.github.com/github-actions)\\[bot]\nin\n[#\u0026#8203;302](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/302)\n- Update sbt-scalafix to 0.14.5 by\n[@\u0026#8203;scala-center-steward](https://redirect.github.com/scala-center-steward)\\[bot]\nin\n[#\u0026#8203;304](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/304)\n- Set correct version in `action.yml` by\n[@\u0026#8203;mkurz](https://redirect.github.com/mkurz) in\n[#\u0026#8203;303](https://redirect.github.com/scalacenter/sbt-dependency-submission/pull/303)\n\n**Full Changelog**:\n\u003chttps://github.com/scalacenter/sbt-dependency-submission/compare/v3...v3.2.1\u003e\n\n\u003c/details\u003e\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n👻 **Immortal**: This PR will be recreated if closed unmerged. Get\n[config\nhelp](https://redirect.github.com/renovatebot/renovate/discussions) if\nthat\u0027s undesired.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\n---------\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e\nCo-authored-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e"
    },
    {
      "commit": "686aedba6c41a95a509f44f88e0c336456aac382",
      "tree": "37ab648aedda3ad77a4481285eec9e462a6ffe69",
      "parents": [
        "ed16a605dacc0185bc5f069d14157ee3e128b68a"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Tue Aug 11 00:14:53 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 07:14:53 2026 +0000"
      },
      "message": "test(amber): cover the execution statistics service (#7544)\n\n### What changes were proposed in this PR?\n\n`ExecutionStatsService` had no spec and sat at **0% of its 80 lines**,\nwhile being the class that tells the frontend what an execution is\ndoing: per-operator input/output metrics, worker assignment, elapsed\nduration, and the runtime statistics persisted for the dashboard\u0027s time\nseries.\n\nAdds 12 tests driven through the three-argument constructor. The client\nis an `AmberClient` subclass that captures the registered callbacks, so\nthe tests fire `ExecutionStatsUpdate`, `RuntimeStatisticsPersist`,\n`WorkerAssignmentUpdate`, `WorkflowRecoveryStatus`, `FatalError` and\n`ExecutionStateUpdate` directly; the state store is real, so events\ntravel through the production diff handlers. This follows\n`ExecutionRuntimeServiceSpec` and `ExecutionConsoleServiceSpec`.\n\nThe most valuable one is the carry-forward: an operator that stops\nreporting must still appear in the persisted statistics, or its row\nsilently vanishes from the time series mid-execution.\n\n### Verification\n\n19 mutations applied and reverted, production diff empty after each. All\nred, including the positional column layout of the persisted tuple, the\ncommit guard holding statistics back until a terminal state,\n`client.shutdown()` on `FatalError`, and the wid/eid argument order into\n`updateRuntimeStatsUri`.\n\nThree assertions were **found to be vacuous in review and\nstrengthened**, which is the part worth reading:\n\n| Weakness | Why it passed | Fix |\n|---|---|---|\n| running-duration arithmetic unpinned | the test asserted only\n`duration \u003e\u003d 1500`, so `currentTime - start` becoming `currentTime +\nstart` (~111 years) still passed | bounded on both sides with a window\ncaptured around the update |\n| \"every operator\" observed one operator | the fixture reported a single\noperator, so `operatorInfo.collect` could be narrowed to\n`.take(1).collect` | a second operator with different numbers |\n| \"publish nothing\" checked the payload, not the event | the helper\nflattened the event\u0027s map, so a present-but-empty churn event to the\nwebsocket was invisible | collect by event type and assert empty,\nmatching the two sibling tests |\n\nAll three mutations are now red.\n\n### Deliberately not included\n\n- The `catch` around `runtimeStatsWriter.close()` — Iceberg\u0027s close is\nidempotent, so nothing reaches it without injecting a throwing writer.\n- The `catch` in `storeRuntimeStatistics` — it runs on a private\nsingle-thread executor, which swallows the throwable, so no assertion\ncould observe the mutation.\n- Three dead lines in `computeStatsDiff` (`defaultMetrics`, `newKeys`,\nand the `++ newKeys.map(...)` merge). `updatedLastMetrics` is read only\nat `oldKeys.map(key \u003d\u003e key -\u003e updatedLastMetrics(key))`, and\n`oldKeys`/`newKeys` are disjoint by construction, so the merged entries\ncan never be selected — confirmed by replacing the whole expression with\n`lastPersistedMetrics` and seeing all 12 tests stay green. Reported\nrather than cemented; deleting beats testing.\n\nTwo notes for reviewers. The spec uses distinct workflow/execution ids\nbecause the runtime-statistics URI derives from them and\n`createDocument` overrides an existing table — a default\n`WorkflowContext` collides with `DefaultCostEstimatorSpec`, and sbt runs\namber suites in parallel in one JVM. And no temp Iceberg catalog is\ninstalled: `IcebergCatalogInstance.replaceInstance` is JVM-wide and the\nURI carries no warehouse, so installing one would hijack the catalog for\nevery other amber suite.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7542\n\n### How was this PR tested?\n\n```\nSTORAGE_ICEBERG_CATALOG_TYPE\u003dpostgres sbt \"WorkflowExecutionService/testOnly org.apache.texera.web.service.ExecutionStatsServiceSpec\"\n```\n\n```\n[info] Total number of tests run: 12\n[info] Tests: succeeded 12, failed 0, canceled 0, ignored 0, pending 0\n```\n\nThe env var matches what CI\u0027s unit job already sets\n(`.github/workflows/build.yml:293`); the committed default expects a\nLakekeeper. `Test/scalafmtCheck` and `Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "ed16a605dacc0185bc5f069d14157ee3e128b68a",
      "tree": "453b4921d5b11785249ce406f4c1bbba94188ad0",
      "parents": [
        "0414dc2c851d2ce591a3d4b9a65a728aa4fb50ba"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 23:57:45 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 06:57:45 2026 +0000"
      },
      "message": "refactor(amber): read the loop input table from its materialization instead of shipping it in state (#6971)\n\n### What changes were proposed in this PR?\n\nThe loop\u0027s input table used to ride **inside the State content**:\nLoopStart encoded its buffered input as Arrow IPC bytes, base64\u0027d into\nthe JSON `content` column, and that payload was re-written and re-read\nat **every loop-body hop, every iteration**.\n\nThat data already exists. In the fully-materialized mode loops require,\nthe Loop Start\u0027s input-port materialization holds exactly the loop\u0027s\ninput table for the whole loop — Loop Start re-reads it every iteration,\nand the back-edge truncates only the *state* doc at the same base URI,\nnever the *result* doc. So this PR ships the port\u0027s **base URI** in the\nsetup config and derives both addresses from it:\n\n```\nloopStartPortUris[LoopStart-id] \u003d \u003cbase URI of LoopStart\u0027s input port\u003e\n        ├── state_uri(base)   → back-edge write address   (as before, derived)\n        └── result_uri(base)  → the loop\u0027s input table    (NEW: read at EndChannel)\n```\n\n| Piece | Before | After |\n|---|---|---|\n| proto field 4 | `loopStartStateUris` \u003d state URI | `loopStartPortUris`\n\u003d base URI (renamed so the semantic change is loud) |\n| LoopStart\u0027s produced state | user vars + IPC-encoded table (base64 in\nJSON) | user vars only — small, pure JSON |\n| Loop-body hops | fat state re-materialized per hop, per iteration |\ntiny state |\n| LoopEnd\u0027s table | decoded from state content | read once per iteration\nfrom `result_uri(base)` at EndChannel, injected via a new runtime-only\n`attach_loop_table` hook |\n| `table_to_ipc_bytes` / `table_from_ipc_bytes` | second, divergent\nArrow codec (lossy `from_pandas` inference) | deleted — the read goes\nthrough the canonical iceberg reader |\n\n**When the read happens matters.** The read is issued at **EndChannel**\n(the matching state is stashed at consume and the operator\u0027s update runs\nin `complete()`), not at consume time. At consume time this worker\u0027s own\nmaterialization reader is still streaming, and issuing a second\niceberg/S3 read from the main loop thread in that window made the reader\nfail with S3 `Access Denied` — `LoopIntegrationSpec` hung to the CI job\ntimeout on both OSes. Deferring past the reader removes the overlap:\nintegration went from a 20-minute cancel to green in ~9 minutes. The\nmatching consume emits no state downstream, so moving it is unobservable\noutside the operator.\n\nSemantics deliberately preserved:\n- the reserved-`table` collision raise stays (a user var named `table`\nwould now be *silently shadowed* by the injected table — worse than\nbefore);\n- the \"consumed\" marker (`_loop_table`) is still set only by a\n**successful** `run_update`, so `condition()`\u0027s short-circuit for\npass-through-only Loop Ends is unchanged;\n- nested loops work by construction: the inner Loop Start\u0027s entry points\nat the outer Loop Start\u0027s output port, whose result doc is recreated per\n*outer* iteration but persists across *inner* iterations (the jump\nrewinds to the inner level only).\n\nWins: no ~33% base64 bloat, no JSON-column size ceiling on the table\n(large-table loops become viable), strictly less I/O for any non-empty\nloop body (one read per iteration replaces N state-doc writes+reads per\nhop), and one Arrow codec instead of two.\n\nNote: this deepens the read-side use of `storagePairs.head._1` — the\nsame shared upstream URI as the known back-edge fan-out design\ndiscussion; if that ever moves to a per-loop private doc, this read\nmoves with it.\n\n### Any related issues, documentation, discussions?\n\nBuilds on #5900 (State columns) and #6661 (envelope through JVM hops).\nRelated design context: #6660.\n\n### How was this PR tested?\n\n- **Unit** — `test_loop_operators.py` rewritten for the attach-based\nflow plus new pins: the produced state carries no `table`; attaching\nalone does **not** mark the loop consumed; `run_update` fails loud when\nno table was attached. `test_main_loop.py` pins the base-URI derivation\nfor the back-edge write (`state_uri(base)`), the missing-config\nfail-loud, and that the matching consume stashes the state without\ntouching storage, with the read + update happening once at EndChannel.\n`test_initialize_executor_handler.py` covers the renamed proto field.\n237 tests green locally (the only failures in a full sweep are\npre-existing environment ones, identical on unmodified main).\n- **Scala** — full test-compile (proto regen included),\n`scalafmtCheckAll`, `scalafixAll --check`, and the worker/descriptor\nspec suites (`WorkerSpec`, `WorkflowWorkerSpec`,\n`SerializationManagerSpec`, `WorkflowExecutionManagerSpec`,\n`LoopStartOpDescSpec`, `LoopEndOpDescSpec`) all pass on Java 17.\n- **E2E** — the four `LoopIntegrationSpec` cases (single, nested 3×3,\nJVM chain, nested JVM chain) exercise the full read path in the\n`amber-integration` CI job (both jobs green in ~9 min); the nested cases\nspecifically cover the inner-loop read against the outer Loop Start\u0027s\nper-outer-iteration output doc.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Fable 5)"
    },
    {
      "commit": "0414dc2c851d2ce591a3d4b9a65a728aa4fb50ba",
      "tree": "8d263b1b0ef9b6ea1dd90bf1c2e79ad4b3573308",
      "parents": [
        "af38ca99c13c0be4fbe69cc168c82d69aae36c56"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Mon Aug 10 23:42:40 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 06:42:40 2026 +0000"
      },
      "message": "test(amber): cover version-importance helpers and the email message builder (#7540)\n\n### What changes were proposed in this PR?\n\nCovers the remaining unit-testable pure logic in two of the three\nclasses the\nissue lists. No production code was changed.\n\n**`WorkflowVersionResource`** (+7 tests) — the version-importance\nhelpers, all\nprivate and exercised through `PrivateMethodTester`:\n\n- `isSnapshotImportant` — a patch whose ops are all `replace` is\nunimportant, any\n  other op makes it important, and an empty patch is unimportant.\n- `isVersionImportant` — a patch touching only `/operatorPositions/` is\n  unimportant; anything else is important.\n- `isWithinTimeLimit` — holds inside the aggregate window, not outside\nit.\n- `encodeVersionImportance` — the latest version is always important, a\nversion\ninside the aggregate window is folded in as unimportant, and one outside\nit is\n  judged on its content.\n\n\u003e The issue calls this gap `jsonTreeIterator`; that is a local variable\ninside\n\u003e `isSnapshotImportant` / `isVersionImportant` rather than a method, so\nthe tests\n\u003e target those two methods (plus the rest of the family).\n\n**`WorkflowEmailNotifier`** (+2 tests)\n\n- `createEmailMessage` — the assembled message addresses the recipient\nand\ncarries the same subject the dedicated builder produces, plus the\nworkflow\n  name, id and state in its content.\n- `sendStatusEmail` — the invalid-recipient arm returns before\ndispatching, so\n  the test never reaches `GmailResource.sendEmail`.\n\nAfter this change (measured with `sbt WorkflowExecutionService/jacoco`):\n`WorkflowVersionResource` 116/121 lines (95%), `WorkflowEmailNotifier`\n40/43\n(93%). The lines that remain are not unit-reachable:\n\n- `updateLatestVersion` — defined but has no callers anywhere in the\nrepo.\n- `sendStatusEmail`\u0027s dispatch arm — it calls `GmailResource.sendEmail`,\ni.e. it\n  would send real mail.\n- `cloneVersion`\u0027s catch block — needs a database-layer failure to\ntrigger.\n- `isSnapshotInRangeUnimportant`\u0027s `lowerBound \u003d\u003d UpperBound` early\nreturn is\nalready asserted by an existing test, but jacoco still reports it unhit:\nthe\nparameters are `java.lang.Integer`, so `\u003d\u003d` compares references rather\nthan\nvalues. Worth a look separately — this PR does not change production\ncode.\n\n**`ResultExportService`** — no tests added. Its in-scope pure logic is\nalready\ncovered by the existing spec: `parseOperators` (valid / empty /\nmalformed),\n`validateExportRequest` (both arms), `convertFieldToBytes` (all three\ncases),\n`generateFileName` (parquet→zip, path-separator stripping),\n`streamCellData`\n(all three guards), and the `errorMessages` accumulation the issue\nmentions\n(`exportToDataset` \"collect one message per operator\" / \"turn a thrown\nper-operator failure into an error entry\"). The `download.dat` default\nthe issue\nasks for is unreachable: when `exportOperatorResultAsStream` returns no\nfile\nname it also returns a null stream, and the preceding line throws. The\nremaining\nuncovered methods (`exportOperatorsAsZip`,\n`exportSingleOperatorToDataset`,\n`getOperatorDocument`) all go through `DocumentFactory`/storage, which\nthe issue\nplaces out of scope.\n\n### Any related issues, documentation, discussions?\n\nCloses #7537\n\n### How was this PR tested?\n\nUnit tests, run locally against embedded Postgres (`MockTexeraDB`). All\npass, and\nthe failure path was verified by breaking an assertion to confirm the\nsuite goes\nred:\n\n```\nsbt \"WorkflowExecutionService/testOnly *WorkflowVersionResourceSpec *WorkflowEmailNotifierSpec\"\n# Tests: succeeded 37, failed 0\nsbt \"WorkflowExecutionService/Test/scalafmtCheck\"      # clean\nsbt \"WorkflowExecutionService/Test/scalafix --check\"   # clean\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "af38ca99c13c0be4fbe69cc168c82d69aae36c56",
      "tree": "86e2377d55731a36e009c6aed1532cbf45ca6d4d",
      "parents": [
        "dcecfa69fd9a94319f931221e7f99420e9d5970b"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Mon Aug 10 23:42:26 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 06:42:26 2026 +0000"
      },
      "message": "test(frontend): cover the report-generation image pipeline and shared-editing branches (#7541)\n\n### What changes were proposed in this PR?\n\n18 new tests across two units.\n\n| file | statements | branches | functions |\n| --- | --- | --- | --- |\n| `report-generation.service.ts` | 126/129 (was 98/129) | 25/25 | 34/35\n|\n| `shared-editing.interface.ts` | 115/115 | 79/80 | 6/6 |\n\n**ReportGenerationService** — `fetchImageAsBase64` and the loop that\nfeeds it were entirely\nunhit. Covered: an image whose bytes convert (its `href` is rewritten to\nthe base64 result),\none whose `FileReader` fails, one whose request fails, and one with no\nsource at all (skipped\nwithout a request). `XMLHttpRequest` is replaced with a fake that\nsettles synchronously and\n`FileReader` with one that fires on a microtask, so nothing depends on\nthe network or on real\ntiming; both globals are restored afterwards.\n\nAlso covered while the report was in view: the two `|| \"Unknown error\"`\nfallbacks, the outer\n`catch` that reports a failure to build the report at all, and the\nvisualization snapshot that\nhas no wrapper `div` to resize. That takes branch coverage of the file\nto 25/25.\n\n**shared-editing.interface.ts** — the file is `createYTypeFromObject` /\n`updateYTypeFromObject`\nover Yjs types, so the tests drive real `Y.Doc`s in memory. Covered: the\n`typeof` arms no\ncaller passes (function, symbol, bigint), the boxed-String arms of both\nfunctions, the no-op\nwhen a string is already up to date, an `undefined` array entry becoming\n`null`, an array\nelement whose kind changes being replaced rather than merged, an array\nwhose additions sit\nbefore its removals, and the `return false` for a type the dispatch has\nno strategy for.\n\nNo production code was changed.\n\n### Coverage that is not reachable\n\n- `report-generation.service.ts:93-95` — the html2canvas success\ncallback. jsdom has no\ncanvas, and reaching it means standing in a CSS engine, a 2D context,\n`toDataURL` and the\nimage loader; that is a simulated renderer rather than a test, and it\nwould break on an\n  html2canvas or jsdom upgrade. Left alone deliberately.\n- `shared-editing.interface.ts:223` — the `_.isEqual` guard\u0027s false arm,\ni.e. an equal pair at\nthe same offset *inside* an unmatched segment. A script replicating the\nLCS walk and segment\nconstruction found none across all 1,185,921 array pairs of length 2-6\nover a 3-value\n  alphabet, so the alignment appears to preclude it.\n\nNote that html2canvas still runs for real in the image tests and jsdom\ncannot render it, so\nthose tests emit `Not implemented` notices on stderr. They are jsdom\u0027s,\nnot failures — the\ntests assert on what the inlining step did, not on the render.\n\n### One defect worth recording\n\n`createYTypeFromObject(new String(\"x\"))` returns an **empty** `Y.Text`:\n`new Y.Text(...)` only\naccepts a primitive, so the boxed value is dropped. The update path does\nnot share the bug —\n`Y.Text.insert` coerces — so the same input round-trips correctly\nthrough\n`updateYTypeFromObject`. The test asserts the real behaviour with a\ncomment saying what to flip\nwhen the branch unwraps the box.\n\n### Any related issues, documentation, discussions?\n\nCloses #7538.\n\nNote: the issue describes this file as a `switch` over shared-editing\nevents with awareness\nstate; the file is actually the two YType conversion functions above,\nwith an LCS-based array\ndiff. The tests follow the code.\n\n### How was this PR tested?\n\n`ng test --watch\u003dfalse` over the two specs — 52 passed (34 existing + 18\nnew), run 3x for\ndeterminism. Coverage (`--coverage`) gives the table above. The failure\npath was verified by\nbreaking one assertion in each spec (red, non-zero exit) and restoring\nthem; eslint and\nprettier are clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "dcecfa69fd9a94319f931221e7f99420e9d5970b",
      "tree": "13e2ae2a3c4156d0adcda0c9ac8f1ba8be297677",
      "parents": [
        "61f22afc1f9fd7c4833fbf54e621dcbef9068eac"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 23:41:08 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 06:41:08 2026 +0000"
      },
      "message": "test(frontend): render the hub workflow detail with its real children (#7535)\n\n### What changes were proposed in this PR?\n\n`hub-workflow-detail.component.html` reported 0 of 46 lines while its\nown `.ts` sat at 98% — the\nattribution loss from #7458, not a testing gap. The spec stubs its three\nchildren out through\n`TestBed.overrideComponent`, and any override re-JITs the component from\nits decorator metadata; the\nre-compiled template has no source map back to the `.html`, so the\nbindings execute uncounted.\n\nAdds a `describe` block that renders the component with its real\nchildren. That restores\nattribution:\n\n| | Before | After |\n|---|---|---|\n| lines | 0/46 (0.0%) | **45/46 (97.8%)** |\n| branches | — | 3/3 |\n\nThree tests: the real editor and mini-map resolving rather than the stub\nselectors, and the\n`*ngIf\u003d\"isHub\"` back button appearing and not appearing. It keeps its\nown `TestBed` so the 32 tests\nabove retain their mocked `WorkflowActionService` and the ten assertions\nthey make on it — the real\nservice is needed here only because the real editor injects\n`DynamicSchemaService`, which reads the\ngraph\u0027s operator streams.\n\n### Verification\n\nBoth `*ngIf` mutations were applied to the template and reverted\n(production diff empty):\n\n| Mutation | Result |\n|---|---|\n| back button always rendered (`*ngIf\u003d\"true\"`) | red |\n| back button never rendered (`*ngIf\u003d\"false\"`) | red |\n\nTwo assertions in the first test are honestly **guards, not behaviour\npins**: renaming the child\nelements only breaks the template build rather than producing a clean\nbehavioural failure, so they\nare there to stop the override creeping back in, and the coverage\nmeasurement above is their real\nevidence. Saying so rather than listing them as killed mutations.\n\nOne assertion was dropped during review of my own work: the clone\nbutton\u0027s\n`[disabled]\u003d\"!isLogin || !isHub || !isActivatedUser\"` does not reflect\nto the DOM `disabled`\nproperty under this fixture (it stays `false` with `isHub \u003d\u003d\u003d false`),\nso asserting on it would have\nbeen either vacuous or wrong. The back button discriminates cleanly and\nis what the tests use.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7534\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/hub-workflow-detail.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  35 passed (35)\n```\n\n3 new on top of the existing 32. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "61f22afc1f9fd7c4833fbf54e621dcbef9068eac",
      "tree": "75fbe6ca6e86b3c5c35507f452e20dd1b8695035",
      "parents": [
        "561cd0ef1fb85da3f2f59fe846947d93f5c14262"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 23:40:51 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 06:40:51 2026 +0000"
      },
      "message": "test(amber): cover the workflow service\u0027s client and execution wiring (#7545)\n\n### What changes were proposed in this PR?\n\n`WorkflowService` had no spec and sat at **14.6% of its 89 lines**. It\nowns what a connected client sees: the per-session subscriptions to the\nworkflow\u0027s own stores, the switch to the newest execution\u0027s stores when\none is published, and the execution state reported on disconnect — the\nvalue `WorkflowLifecycleManager.decreaseUserCount` branches on to decide\nwhether clean-up is postponed.\n\nAdds 8 tests. Construction is database-free (`SessionStateSpec` already\nsubclasses the class with no fixture), and executions are real\n`WorkflowExecutionService` instances with\n`coordinatorConfig`/`resultService` as `null` — the pattern\n`WorkflowExecutionServiceSpec` establishes — so the observed events\ntravel through the production diff handler.\n\nTwo collaborators are stubbed, for reasons stated in the spec header:\n`lifeCycleManager`, because the real one schedules on an actor system no\nunit test starts and reads `workflow_executions` from the database; and\n`resultService`, because a real one holds no subscriptions until\n`attachToExecution` gives it a live client, so \"unsubscribed\" would be\nindistinguishable from \"never called\".\n\n### Verification\n\n14 mutations applied and reverted, production diff empty after each.\n\n**Four assertions were found to be vacuous in review and strengthened**\n— all four on lines the tests claimed to cover:\n\n| Weakness | Why it passed | Fix |\n|---|---|---|\n| `disconnect` state read unpinned | RUNNING was the only non-empty\ncase, so reading the execution\u0027s state was indistinguishable from\nreturning the constant RUNNING — which would postpone clean-up forever\nfor any workflow that ever had an execution | a second disconnect\nasserting COMPLETED distinctly |\n| execution fan-out unpinned | `getAllStores` returns five stores; the\nspec drove only `metadataStore`, so the fan-out could be narrowed to\nthat one and a client would silently stop receiving stats, console,\nbreakpoint and reconfiguration events | drive a second store, with a\ndiff handler registered since `ExecutionStatsService` is not attached\nhere |\n| workflow-level forwarding truncation | every diff yielded one event,\nso `evts.foreach(onNext)` could become `evts.headOption.foreach(onNext)`\n| a two-event diff, asserted as two |\n| execution-level forwarding truncation | same, on the other closure |\nsame |\n\nAll four mutations are now red. Multi-event diffs are not hypothetical:\n`WorkflowExecutionService`\u0027s own handler appends a state event and an\nerror event together.\n\n### Deliberately not included\n\n- `initExecutionService` past its user-id check: the rest inserts an\nexecution row then hands a compiled plan to\n`ComputingUnitMaster.createAmberRuntime`, which builds an `AmberClient`\non a null actor system outside a started coordinator. Reaching past the\ninsert would mean asserting on that NPE — an accident, not a contract.\n- `clearExecutionResources` and its clean-up callback: both resolve URIs\nout of the database and open Iceberg documents.\n- `lastCompletedLogicalPlan`: nothing in the repository reads it, so a\ntest could only pin a write-only var.\n- Dropping the outer handle from `new\nCompositeDisposable(localDisposable, disposable)` — the `DO NOT\nOPTIMIZE` line. That mutation **survives**, and it is reported rather\nthan papered over: it leaks the `executionService` subscription but\nchanges nothing observable, because the already-disposed inner composite\nimmediately disposes anything a later callback adds. Pinning it would\nmean asserting on subscriber bookkeeping rather than behaviour. Noted in\nthe spec so the next reader does not re-derive it.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7543\n\n### How was this PR tested?\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.web.service.WorkflowServiceSpec\"\n```\n\n```\n[info] Total number of tests run: 8\n[info] Tests: succeeded 8, failed 0, canceled 0, ignored 0, pending 0\n```\n\nAlso green in a five-suite single-JVM run alongside\n`WorkflowExecutionServiceSpec`, `ClusterListenerSpec` and\n`ExecutionResultServiceSpec` (36 tests). `Test/scalafmtCheck` and\n`Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "561cd0ef1fb85da3f2f59fe846947d93f5c14262",
      "tree": "e113f35c56eef7bd98e4169828829c901f59e0ba",
      "parents": [
        "b44f7db7cb0962f06fab1bb4353e6bfa353d50e6"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 22:00:57 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 05:00:57 2026 +0000"
      },
      "message": "test(agent-service): drive sendMessage with a stand-in language model (#7487)\n\n### What changes were proposed in this PR?\n\n`sendMessage` held 238 of the 292 uncovered lines in `texera-agent.ts`,\nand the existing spec stops\nat the model boundary. Nothing in there actually needs the network:\n`ai/test` ships a\n`MockLanguageModelV4` satisfying the same `LanguageModel` type the\nconstructor already takes, so the\nloop runs in-process. `fetch` is spied on as a tripwire, and the\nno-delegate tests assert that not a\nsingle call escapes.\n\nAdds 25 tests in two blocks:\n\n| Block | Covers |\n|---|---|\n| `sendMessage` | branch bookkeeping and ancestor path, per-step and\nsummed usage, the assembled context replacing the raw message, tool\nprojection and rolling before/after snapshots, the `maxSteps` cap, turn\nchaining, an abandoned branch staying invisible to the model, DAG\ncompilation feeding schemas and cached results into the prompt |\n| `sendMessage` failures | a thrown model recorded as an error step, a\nnon-`Error` throw stringified, a failed turn staying on the branch,\ncancellation reported as stopped, an `AbortError`-named provider error\nread as a user stop, `stop()` mid-run preventing the next call,\n`GENERATING` for the duration |\n| `delegate mode` | the one-time backend refresh and a failed refresh\nbeing swallowed, auto-execution after `modifyOperator` and where its\nresult is keyed, the two guards that suppress it,\n`buildExecutionConfig`, and the debounced auto-persist plus its failure\npath |\n\n`texera-agent.ts` goes from **51.01% to 99.82% lines** (80.43% → 98.21%\nfuncs).\n\n### On what these tests actually pin\n\nLine coverage overstates this, and it is worth being precise. `bun`\ncredits a whole function body\nonce it is entered, so the first test alone takes the uncovered count\nfrom 292 to 27. Most of the\nremaining 24 buy no additional lines — they exist because each kills a\nmutation nothing else kills.\nThey are mutation guards, not coverage.\n\nThe matrix ran 44 mutations against a pristine source with a\ncheckout-and-verify between each. Six\nwere re-run independently after the tests were merged into the existing\nspec:\n\n| Mutation | Expected | Result |\n|---|---|---|\n| a tool call without `operatorId` still auto-executes | red | red |\n| an `[ERROR]` tool result no longer suppresses the follow-up run | red\n| red |\n| the `EXECUTE_AFTER_TOOLS` filter dropped | red | red |\n| input tokens not mapped | red | red |\n| `totalUsage` preferred over `usage` | **survives** | survives |\n| the `content: text \\|\\| \"\"` fallback | **survives** | survives |\n\nThe last two are listed deliberately. They survive because they are\nunobservable in `ai@7.0.48` —\n`totalUsage` and `usage` are the same object, and the SDK already hands\n`\"\"` to a text-less step.\nNo test claims to pin them, and no test was written to cement them.\n\nFive further fragments are line-covered but not behaviourally pinned,\nfor the same reason:\n`lastPreparedMessages \u003d undefined` (re-assigned before every step),\n`isError: !!(tr.output)?.error`\n(no tool ever returns an object), the `?? finalUsage?.promptTokens` /\n`?? completionTokens` arms\n(v4-era key names that no longer exist), and the delegate guard at\n408–410 (masked by the catch\nbelow it).\n\n### Deliberately not included\n\n- **`getStepsById` (line 261)** — the one line left uncovered. No call\nsite anywhere in the repo;\n`server.ts` uses `getReActSteps` / `getAllSteps` /\n`getVisibleReActSteps`. It also hands out the\nlive private `Map` by reference. Deleting it beats testing it, and that\nbelongs in its own change.\n- **`currentMessageId`** — five writes, zero reads. An assertion on it\nwould cement dead state.\n- **`maxSteps: 0`** — writing that test hangs the suite rather than\nfailing it. Filed as #7484.\n\nTwo defects surfaced while writing these and are filed rather than fixed\nhere, since this PR touches no production code: #7484 (a `maxSteps` of 0\nsilently disables the step cap) and #7485 (a falsy throw from the model\nmakes `sendMessage` reject instead of reporting an error step).\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7486\n\n### How was this PR tested?\n\n```\nbun test\n```\n\n```\n 253 pass\n 0 fail\n```\n\n25 new on top of the existing 228. `bun run typecheck` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "b44f7db7cb0962f06fab1bb4353e6bfa353d50e6",
      "tree": "f8f05994580b66a17743cd8bffd432232df9a3a1",
      "parents": [
        "133da7bbd6b27c7fba17a6ab894793745bf0c873"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Mon Aug 10 21:50:57 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Aug 11 04:50:57 2026 +0000"
      },
      "message": "feat(storage): warehouse REST API, Lakekeeper client, and per-execution injection (#7473)\n\n### What changes were proposed in this PR?\n\nThe backend of the per-user warehouse feature (umbrella #6870), all\ngated by `warehouseEnabled` (default off — nothing changes for existing\ndeployments):\n\n- **Warehouse management API** — `WarehouseResource`: `GET\n/warehouse/status` (always answers, so the frontend can hide the\nfeature), `POST /warehouse` and `DELETE /warehouse/{whid}` (403 while\nthe flag is off). Create validates the URI-safe name, mints the catalog\nname `user-\u003cuid\u003e-\u003cname\u003e`, creates in Lakekeeper first and records the\nrow after — a failed creation leaves no orphaned state.\n- **`LakekeeperClient`** — management-API create (Local flavor: storage\nprofile on the deployment\u0027s own object store, per-warehouse key prefix,\nSTS off) and **empty-first delete**: drop every table with\n`purgeRequested\u003dtrue`, then the namespaces, then the warehouse entity.\n- **Per-execution injection** — `WorkflowExecuteRequest` gains\n`warehouseId: Option[Int]`; `WorkflowService.resolveWarehouseName`\nchecks ownership and refuses an explicit pick while the feature is off\n(never a silent fallback — #6930); the resolved name rides\n`WorkflowContext.warehouse` into every storage URI (results, runtime\nstatistics, console messages); the chosen `whid` is recorded on\n`workflow_executions` (as `cuid` is today) so the picker can preselect\nthe workflow\u0027s last-used warehouse. `whid` is `ON DELETE SET NULL`:\ndeleting a warehouse purges its data, never the execution history.\n- **Explicit read failure** — `WarehouseReadGuard`: paginating a\n`/wh/\u003cname\u003e/…` result while the feature is off fails naming the\nwarehouse, instead of resolving against the shared warehouse and\nsurfacing \"table not found\" (#6930).\n\n### Any related issues, documentation, discussions?\n\nCloses #6932. Part of #6870 (design discussions #5293 and #6040). Builds\non #6944, #7359 and #7386.\n\n### How was this PR tested?\n\nFive specs, 30 cases green locally (`sbt\n\"WorkflowExecutionService/testOnly *LakekeeperClientSpec\n*WarehouseResourceSpec *WarehouseReadGuardSpec\n*WorkflowServiceWarehouseSpec *ExecutionsMetadataPersistServiceSpec\"`):\nthe Lakekeeper client runs against an in-process HTTP stub\n(create-payload shape; the purge → namespace → warehouse delete order);\nthe resource spec covers the disabled gate and the create/list/delete\nflow on MockTexeraDB with a stubbed client; resolution pins ownership\nand the no-silent-fallback rule; the read guard pins the explicit\nfailure message; the executions spec gains whid recording and the\nSET-NULL-on-delete case. A delete-order assertion was deliberately\nbroken once to confirm it fails red.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (claude-fable-5)"
    },
    {
      "commit": "133da7bbd6b27c7fba17a6ab894793745bf0c873",
      "tree": "77fe22a2b5c87076f3ff33da2c0b281b07ac35b0",
      "parents": [
        "c7dd5ae427b2fc7a09331fa311261e1ee2a7c2c2"
      ],
      "author": {
        "name": "Prateek Ganigi",
        "email": "91584519+PG1204@users.noreply.github.com",
        "time": "Mon Aug 10 15:19:57 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 22:19:57 2026 +0000"
      },
      "message": "fix(workflow-operator): report a clear error when a configured HF image/audio column is missing (#7299)\n\n### What changes were proposed in this PR?\n\nIf the HuggingFace operator\u0027s `Input Image Column` (or `Input Audio\nColumn`) named a column that doesn\u0027t exist in the input table,\n`use_image_column` / `use_audio_column` silently became false and the\nuser got the misleading \"No image source. Set an Input Image Column or\nupload an image.\", even though they *had* set one, just misspelled it.\n\nThis distinguishes the two cases: at that point there\u0027s no upload and\nthe column resolved to false, which when a column name is actually\nconfigured, can only mean it isn\u0027t in the table. So a non-empty\nconfigured column now produces a clear \"Input Image Column \u0027\u003cname\u003e\u0027 not\nfound in the input table. Available columns: [...]\" error instead of the\ngeneric \"No image source\" message. Same for audio.\n\n### Any related issues, documentation, discussions?\n\nCloses #7197.\n\n### How was this PR tested?\n\n`sbt \"WorkflowOperator/testOnly\norg.apache.texera.amber.operator.huggingFace.*\norg.apache.texera.amber.util.PythonCodeRawInvalidTextSpec\"`: passes (126\ntests). Added a test asserting the generated script produces the \"Input\nImage/Audio Column \u0027...\u0027 not found\" errors;\n`PythonCodeRawInvalidTextSpec` py-compiles the generated Python (guards\nthe added nested indentation). scalafmt clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nThis PR was co-authored with Claude Opus 4.8 in compliance with ASF\npolicy."
    },
    {
      "commit": "c7dd5ae427b2fc7a09331fa311261e1ee2a7c2c2",
      "tree": "bd68caec0dd78ad844eec1919c6c48254406e13d",
      "parents": [
        "557b84a770bf150bea199aa8115cd84c1d86eb46"
      ],
      "author": {
        "name": "Prateek Ganigi",
        "email": "91584519+PG1204@users.noreply.github.com",
        "time": "Mon Aug 10 15:19:06 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 22:19:06 2026 +0000"
      },
      "message": "fix(workflow-operator): accept single-segment HF model IDs and reject \u0027..\u0027 in the model-id check (#7474)\n\n### What changes were proposed in this PR?\n\nThe generated model-ID validation regex (`_HF_MODEL_ID_PATTERN`) had two\nproblems:\n\n1. It let `..` path-traversal segments through: e.g. `org/..` passed,\neven though the comment claimed `..` was rejected (the character class\nallowed dots, so `..` was a valid segment).\n2. It rejected legacy single-segment model IDs like `gpt2` and\n`bert-base-uncased`, because it required at least one `/`.\n\nThis adds a `(?!.*\\.\\.)` lookahead to reject any `..`, and makes the\ntrailing `/segment` group optional so single-segment IDs are accepted.\nThe comment and the \"Invalid Hugging Face model ID\" error message are\nupdated to match.\n\n### Any related issues?\n\nCloses #7196\n\n### How was this PR tested?\n\n- Existing HuggingFace operator unit tests + the\n`PythonCodeRawInvalidTextSpec` py-compile guard (confirms the new regex\nis valid Python).\n- Extended the existing MODEL_ID spec test to assert the lookahead and\nthe now-optional segment group are emitted.\n- Behavioral check of the emitted regex: `gpt2`, `bert-base-uncased`,\n`t5-small`, `org/model`, `org/model/revision` are accepted; `org/..`,\n`org/../secret`, `..` are rejected.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nThis PR was co-authored with Claude in compliance with ASF policy."
    },
    {
      "commit": "557b84a770bf150bea199aa8115cd84c1d86eb46",
      "tree": "0f6e6566ea6e037e00c34882ef78dc1aa72a1a47",
      "parents": [
        "18cdd72c3eb155ec6ffd12938272f40ae737019b"
      ],
      "author": {
        "name": "Neil Ketteringham",
        "email": "53205839+Neilk1021@users.noreply.github.com",
        "time": "Mon Aug 10 14:51:41 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 21:51:41 2026 +0000"
      },
      "message": "refactor(common/auth): move login credentials to auth_provider (#7055)\n\n### What changes were proposed in this PR?\nAs discussed in #6716 we\u0027d like to split authentication handling into\nits own table `auth_provider.` For future support of multiple sources of\nauthentication (e.g. github, IEEE accounts, etc.). This PR migrate the\nSchema from the image on the left to the one on the right.\n\n\u003cimg width\u003d\"247\" height\u003d\"305\" alt\u003d\"image\"\nsrc\u003d\"https://github.com/user-attachments/assets/6d436b42-8736-4b91-8f1e-d7300b3ad5d2\"\n/\u003e\n\u003cimg width\u003d\"441\" height\u003d\"292\" alt\u003d\"image\"\nsrc\u003d\"https://github.com/user-attachments/assets/acffa8e6-4f84-4886-bc94-3627a881523a\"\n/\u003e\n\n\n#### This PR:\n1. Creates a new `auth_provider` table in texera_ddl.\n2. Providers a migration script `33.sql` to migrate old account data to\nthe new schema.\n3. Refactors backend to match new schema.\n4. Refactors portions of `GoogleAuthService` to a generic\n`ExternalAuthProvisioner` to be used in future PRs adding new external\nlogins.\n\n### Any related issues, documentation, discussions?\nCloses #7048 \n\n### How was this PR tested?\nCompiled and ran all tests as well as deployed locally to verify\nfunctionality.\n\n### Was this PR authored or co-authored using generative AI tooling?\nCo-authored with Claude Opus 4.8\n\n---------\n\nSigned-off-by: Neil Ketteringham \u003c53205839+Neilk1021@users.noreply.github.com\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e\nCo-authored-by: Claude Opus 5 (1M context) \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e"
    },
    {
      "commit": "18cdd72c3eb155ec6ffd12938272f40ae737019b",
      "tree": "bfea08bb9245f7eb9c259054c29d2d1b7a10755e",
      "parents": [
        "a7f4386ba7ccb58155e44f79c8e10a25e60d2208"
      ],
      "author": {
        "name": "Neil Ketteringham",
        "email": "53205839+Neilk1021@users.noreply.github.com",
        "time": "Mon Aug 10 14:49:14 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 21:49:14 2026 +0000"
      },
      "message": "feat(frontend): consolidate login onto a dedicated /login page (#7339)\n\n### What changes were proposed in this PR?\n\nThis PR replaces the two ad-hoc login surfaces with one dedicated login\npage.\n\n\u003cimg width\u003d\"725\" height\u003d\"658\" alt\u003d\"image\"\nsrc\u003d\"https://github.com/user-attachments/assets/689a778a-e874-4b8b-a977-9d19863a8a4c\"\n/\u003e\n\nBefore, a visitor could sign in from either the local form embedded as a\ncolumn in the **About** page, or the Google button sitting in the\n**dashboard navbar** — the latter wired directly into\n`DashboardComponent`, which subscribed to `SocialAuthService.authState`,\nexchanged the id token, and navigated as a side concern of rendering the\napp chrome. `AuthGuardService` and the 401 interceptor both had to\nredirect to `/about` because there was nowhere better to send anyone.\n\n\u003cimg width\u003d\"1225\" height\u003d\"722\" alt\u003d\"image\"\nsrc\u003d\"https://github.com/user-attachments/assets/16d877e2-f8e8-4e50-8312-7c9f30afeaa2\"\n/\u003e\n\nAfter, there is a single `/login` page and everything points at it.\n\n**New**\n\n- `TexeraLoginComponent` (`frontend/src/app/hub/component/login/`) — a\ncentred full-page card with tabbed local **Sign In** / **Sign Up** plus\na `social-buttons` block for the Google button. The tabs render only\nwhen `localLogin` is enabled and the Google button only when\n`googleLogin` is enabled, so a deployment with one provider disabled\ngets a coherent page rather than a dead one. Adding another provider\nmeans one more button in that block, not another login surface. The\ncomponent owns the Google `authState` subscription, the id-token\nexchange, and post-login navigation; it filters `null` out of\n`authState` because that subject is a `ReplaySubject` and logout pushes\na stale `null` that would otherwise replay into a fresh subscription. It\nalso keeps the previous form\u0027s behaviour of prefilling\n`defaultLocalUser` credentials in local dev.\n- `GuestGuardService` — the mirror of `AuthGuardService`. It keeps an\nalready-signed-in user off `/login`, sending them to their `returnUrl`\nwhen one survived the round trip and to their workflows otherwise.\n- The `login` route is registered at the top level of\n`app-routing.module.ts`, a sibling of the `DashboardComponent` shell, so\nit renders in the root outlet without the navbar and sidebar.\n\n**Changed**\n\n- `AuthGuardService` and `UnauthorizedHttpInterceptor` now navigate to\n`LOGIN` instead of `ABOUT`; the existing `returnUrl` handling is\nunchanged.\n- `DashboardComponent` drops `SocialAuthService`,\n`GoogleSigninButtonModule`, and the `authState` login flow. Logged-out\nvisitors get a **Sign in** link to `/login` in the navbar slot the user\nicon occupies once signed in, styled to read as an ng-zorro primary\nbutton.\n- `AboutComponent` is now static marketing copy — with the login form\ngone it has no auth state left to track, so `OnInit`, `UserService`, and\nthe `isLogin$` subject were removed.\n\n**Removed**\n\n- `hub/component/about/local-login/` (component, template, styles, spec)\nand its `app.module.ts` declaration.\n\n### Any related issues, documentation, discussions?\n\nCloses #7340\nDiscussion #6717\n\nThe page layout and styling were designed in Figma first and transcribed\ninto the implementation here.\n\n### How was this PR tested?\n\nNew and updated Angular unit specs, run with the frontend unit suite:\n\n- `texera-login.component.spec.ts` (new, 19 cases) — `defaultLocalUser`\nprefill and the empty-config case; mode switching clearing the error\nmessage; the confirm-password validator firing only in sign-up mode;\nsign-in validation short-circuits for a blank username and a short\npassword; `UserService.login` called with a trimmed username; navigation\nto `USER_WORKFLOW` and to `returnUrl`; login failure surfacing a message\nwithout navigating, including the fallback when the error carries none;\nregistration rejecting a malformed email and mismatched passwords,\ncalling `UserService.register`, and notifying on success; the Google\n`authState` path handing the id token to `googleLogin` and navigating,\nignoring a `null` state, and notifying without navigating when the\nexchange fails.\n- `guest-guard.service.spec.ts` (new, 3 cases) — a logged-out visitor is\nallowed onto `/login`; a signed-in user is redirected to their\nworkflows; a `returnUrl` is honoured when present.\n- `auth-guard.service.spec.ts` and\n`unauthorized-http-interceptor.service.spec.ts` — updated to assert the\nredirect target is `LOGIN`.\n- `dashboard.component.spec.ts` — asserts the navbar renders a sign-in\nlink rather than a provider button when logged out, and neither when\nlogged in.\n- `about.component.spec.ts` — trimmed to the static component, with a\ncase asserting it no longer embeds a login form.\n\nEvery spec covering the files this PR touches passes. Not covered by\nunit tests, and worth exercising by hand on review: the real Google\nsign-in round trip against a configured client id, and the page\u0027s\nappearance with `localLogin` / `googleLogin` toggled independently.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored. The design was produced in Figma by a human author and\ntranscribed into this\nimplementation with assistance from Claude Opus 4.8.\n\nGenerated-by: Claude Opus 4.8"
    },
    {
      "commit": "a7f4386ba7ccb58155e44f79c8e10a25e60d2208",
      "tree": "cfa38ec8103c0510788dcbf9c7a3e4fdf54fb657",
      "parents": [
        "8aec22903261ddc69d43fe60def80e9b08547aa1"
      ],
      "author": {
        "name": "carloea2",
        "email": "carloea2@uci.edu",
        "time": "Mon Aug 10 11:35:13 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 18:35:13 2026 +0000"
      },
      "message": "feat(udf): enable Python UDF UI parameters end to end (#5912)\n\n### What changes were proposed in this PR?\n\nThis PR wires the existing Python UDF UI parameter support into the\nend-to-end execution path.\n\nIt changes:\n\n| Area | Change |\n| --- | --- |\n| Python UDF descriptors | Adds the `uiParameters` property to Python\nUDF, dual-input Python UDF, and Python UDF source operators. |\n| Execution wiring | Applies `PythonUdfUiParameterInjector.inject(...)`\nbefore creating Python physical operators. |\n| Frontend wiring | Connects the existing UI-parameter sync service to\nthe code editor and property editor, and renders `uiParameters` with the\nexisting UI-parameter editor. |\n| Operator templates | Adds commented `UiParameter` examples to Python\nUDF templates. |\n\n### Any related issues, documentation, discussions?\n\nPart of the Python UDF UI parameter feature split from\n`feat/ui-parameter`.\n\nRelated tracking issue / stack: #5044\n\nStack order:\n\n1. Frontend UI parameter building blocks: #5043\n2. Scala backend injection model: #5141\n3. Python runtime support: #5603\n4. End-to-end execution wiring: this PR\n\n### How was this PR tested?\nManually +\n\nCommands run:\n\n```bash\nsbt --no-server scalafmtAll scalafixAll\nsbt --no-server scalafmtCheckAll \"scalafixAll --check\"\n\ncd amber\nruff check src/main/python src/test/python\nruff format --check src/main/python src/test/python\ncd ..\n\nsbt --no-server \"WorkflowExecutionService / Test / testOnly org.apache.texera.amber.engine.architecture.pythonworker.PythonWorkflowWorkerStartupConfigSpec\"\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Me"
    },
    {
      "commit": "8aec22903261ddc69d43fe60def80e9b08547aa1",
      "tree": "dc4f9d6811f0a4de76819617ae0f46aa4669fc89",
      "parents": [
        "29d7cd6cff43542d11effd970ecfc9f1ba78ce11"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 10:30:02 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 17:30:02 2026 +0000"
      },
      "message": "test(computing-unit): cover the pod lookup, creation and deletion paths (#7511)\n\n### What changes were proposed in this PR?\n\nThe spec covered the pure transforms and the namespace-wide wrappers and\nstopped. The single-pod\nhalf of the class — `getPodByName`, `podExists`, `getPodLimits`,\n`createPod`, `deletePod` and the\npod URI — was untested, which is 42 of the file\u0027s 62 lines.\n\nNone of it needs a cluster: the fabric8 client is already a constructor\nparameter, so the existing\nMockito fixture extends to the rest of the fluent chain, with the pod\nthat `createPod` builds\ncaptured and inspected rather than sent anywhere.\n\nAdds 8 tests. The three that matter:\n\n- **the guard that refuses to overwrite a live pod** — creating over a\nrunning unit would detach it\n  from its owner;\n- **the `Option(...)` wrapper around the by-name lookup** — fabric8\nreturns `null` for an absent\npod rather than throwing, so the wrapper is all that stands between a\ncaller and an NPE;\n- **the shared-memory volume appearing only when a size is requested** —\n`/dev/shm` defaults to\n64 Mi, too small for the Python workers, and the volume must not appear\nwhen unrequested.\n\nAlso covered: the pod URI\u0027s service and namespace segments, the first\ncontainer\u0027s resource limits\nand the empty-map fallback, env values reaching the container as\nstrings, and `deletePod` targeting\nthe cuid\u0027s own pod.\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| pod name loses the cuid suffix | red |\n| URI drops the namespace segment | red |\n| `getPodByName` no longer null-guards | red |\n| `createPod` overwrites an existing pod | red |\n| cpu limit written from the memory value | red |\n| pod hostname is not the pod name | red |\n| `deletePod` targets a fixed cuid | red |\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7510\n\n### How was this PR tested?\n\n```\nsbt \"ComputingUnitManagingService/testOnly org.apache.texera.service.util.KubernetesClientSpec\"\n```\n\n```\n[info] Total number of tests run: 16\n[info] Tests: succeeded 16, failed 0, canceled 0, ignored 0, pending 0\n```\n\n8 new on top of the existing 8. `Test/scalafmtCheck` and `Test/scalafix\n--check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "29d7cd6cff43542d11effd970ecfc9f1ba78ce11",
      "tree": "805c2868f6dbe240d23fd9aa65b2432d2f4fe214",
      "parents": [
        "a61e1ee4a8b08f196cf509171d6372f7ab5895b8"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 10:05:10 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 17:05:10 2026 +0000"
      },
      "message": "test(frontend): cover the joint graph wrapper\u0027s layout and co-editor paths (#7509)\n\n### What changes were proposed in this PR?\n\n`joint-graph-wrapper.ts` sat at 76.4% lines and **50.6% branches**. The\nbranch number is the one\nthat mattered — half its conditions had only ever been taken one way.\n\nAdds 20 tests to the existing spec, appended as new blocks rather than\nedits so a rebase stays\ncheap (#6489 also touches this file). Covered: absolute positioning, the\nlink-cell change stream,\nauto layout, the co-editor presence rings including re-padding when one\nis deleted, the editing\nbanner, and the guard clauses for missing and wrong-typed cells.\n\n| | Before | After |\n|---|---|---|\n| Lines | 220/288 (76.4%) | **282/288 (97.91%)** |\n| Branches | 43/85 (50.6%) | **82/85 (96.47%)** |\n| Functions | 98/111 (88.3%) | 107/111 (96.39%) |\n\n### Verification\n\n46 mutations were applied and reverted, 45 red on the first pass. One\nsurvived — the\n`currentStrokeIds.includes(highlightIdToDelete)` guard — and the test\nwas strengthened to assert\nring **order** after a ghost delete, which kills it.\n\nReview then found two more problems, both fixed:\n\n- **A test whose name outran its assertions.** `\"removeCurrentEditing\nhides the banner and stops\nthe animation\"` could not fail on the second half:\n`removeCurrentEditing` blanks the banner text\nfirst, so the interval body\u0027s ownership check is permanently false and\nadvancing the timers is a\nno-op whether or not the interval was cleared. `clearInterval` is\nalready pinned by a\npre-existing test, so the unfalsifiable half was removed rather than\npropped up.\n- **A comment that misdescribed its own branch.** It claimed a link\nexercised the `|| 0` fallback in\n`getCellLayer`; a link\u0027s `z` is explicitly 0, so it only proves a\npresent zero survives.\n\n### Deliberately not included\n\n`getCellLayer`\u0027s `|| 0` fallback (line 752) is **unreachable**, and no\ntest pins it. Mutating it to\n`?? -1` survives, and the reason is structural rather than a missing\ntest: joint\u0027s `Graph.addCell`\nsets `z \u003d maxZIndex() + 1` on any cell that arrives without one, and\n`getCellLayer` throws for a\ncell that is not in the graph — so `attributes.z` is never `undefined`\nwhere it is read. Deleting\nthe `|| 0` outright does not compile (`z` is `number | undefined`), so\nit is load-bearing for typing\nonly. That is recorded in the spec so the next reader does not re-derive\nit.\n\nAlso left alone: the link-breakpoint members.\n`jointLinkBreakpointShowStream` and\n`jointLinkBreakpointHideStream` are private Subjects never `.next()`-ed\nanywhere in `frontend/src`,\nand `linksWithBreakpoints` is declared and read but never written.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7508\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/joint-graph-wrapper.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  67 passed (67)\n```\n\n20 new on top of the existing 47. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "a61e1ee4a8b08f196cf509171d6372f7ab5895b8",
      "tree": "cfb2e642c48e9a61bb0ae9aacc83574ed5216211",
      "parents": [
        "42d08a3701cd06542bcfa92728116302723b2536"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Mon Aug 10 09:43:43 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 16:43:43 2026 +0000"
      },
      "message": "test(agent-service): pin the context serializer and the execution tools (#7505)\n\n### What changes were proposed in this PR?\n\n`context-utils.ts` builds the prompt the agent reasons over and\n`workflow-execution-tools.ts` turns\nan execution result into the table it reads back. Both looked reasonably\ncovered and were not:\n`bun` credits a whole function body once entered, so blocks inside\n`jsonToTableFormat` and\n`executeOperatorAndFormat` counted as covered while nothing asserted\nthem.\n\nAdds 15 tests across the two existing specs (no new spec files — one\nspec per source class, both\nalready existed).\n\n| File | Before | After |\n|---|---|---|\n| `context-utils.ts` | 60.00% funcs / 77.83% lines | **100% / 100%** |\n| `workflow-execution-tools.ts` | 58.97% funcs / 91.24% lines | 85.71% /\n95.16% |\n\n**Ten of the killed mutations target lines `bun` already called\ncovered** — the DAG topological\nordering and its target-rank tie-break, port-ordinal mapping, the\n`NULL`/`null`/`undefined`/object\ncell rendering, the row-gap ellipsis, the leading-tab header, and the\nschema-violation messages.\nThe file percentage barely moves for those; the pinning is the point.\n\n### Verification\n\n45 mutations were applied to the production files and reverted, each\nrevert confirmed with\n`git diff --quiet` before the next. All 45 turned the suite red.\n\nAn adversarial re-check then found **two assertions that were vacuous\nanyway**, which is the part\nworth reporting:\n\n| Survivor | Why it passed | Fix |\n|---|---|---|\n| `Math.ceil` → `Math.round` on the execution timeout | the fixture was\n`4500 ms`, and `ceil(4.5) \u003d\u003d round(4.5) \u003d\u003d 5`, so the assertion\ncommented \"rounds up\" proved nothing | fixture changed to `4200 ms`,\nwhich separates ceil (5) from round and floor (4) |\n| `getConfig()` hoisted out of the `execute` closure | the test invoked\nthe tool once, so `toHaveBeenCalledTimes(1)` holds whether the config is\nresolved per invocation or captured once at construction | invoke twice\nwith the workflow id changing in between, and assert the second request\nURL reflects the second config |\n\nBoth mutations are now red, and so is `Math.floor`. Production diff\nempty.\n\n### Deliberately not included\n\nThree regions of `workflow-execution-tools.ts` are left uncovered\nbecause they are dead, confirmed\nby inserting `throw new Error(...)` at the top of each and running the\nwhole 273-test module — all\nstill passed, so nothing reaches them:\n\n- `formatWorkflowValidationErrors` (169–178) — no call site.\n- lines 221–226 and 229–233.\n\nTesting them would cement code that should be deleted instead.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7504\n\n### How was this PR tested?\n\n```\nbun test\n```\n\n```\n 273 pass\n 0 fail\n```\n\n15 new on top of the existing 258. `bun run typecheck` and `bun run\nformat:check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "42d08a3701cd06542bcfa92728116302723b2536",
      "tree": "7f709a6ed483da1d2d9843406108ee658fd81e77",
      "parents": [
        "d2ef447ff7eb3a77bdcd66952926a5f2ad43c53f"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 22:28:45 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 05:28:45 2026 +0000"
      },
      "message": "test(frontend): cover the remaining branches in three dashboard components (#7503)\n\n### What changes were proposed in this PR?\n\nCovers the branches the three specs never reached. 22 new tests; every\nfunction in all\nthree files is now executed.\n\n| file | statements | branches | functions |\n| --- | --- | --- | --- |\n| `user-computing-unit.component.ts` | 37/37 | 12/12 | 11/11 |\n| `user-dataset-file-renderer.component.ts` | 142/142 | 65/68 | 25/25 |\n| `files-uploader.component.ts` | 139/140 | 78/82 | 37/37 |\n\n**UserComputingUnitComponent** — the session subscription updating\n`isLogin`/`currentUid`,\nthe mapping of fetched units into dashboard entries, the 1s poller (it\nrefreshes on each\ntick and stops once the component is destroyed), and both arms of\n`terminateComputingUnit`.\n\nThe poll test calls `ngOnInit()` directly rather than `detectChanges()`:\nthe fixture\u0027s\nNgZone is created outside the `fakeAsync` zone, so a poll scheduled\nthrough it lands on\nthe real timer queue where `tick()` cannot drive it.\n`discardPeriodicTasks()` drops the\nunbounded interval, and `fixture.destroy()` in `afterEach` keeps it from\nticking into a\nlater test.\n\n**UserDatasetFileRendererComponent** — the spreadsheet branch\n(previously unhit in full),\nthe CSV empty-result and read-failure arms, and the guard that stops a\nfetch when the\ndataset ids are missing.\n\nThe spreadsheet tests build a real `.xlsx` with JSZip (already a\ndependency, and already\nused this way in `user-workflow.component.spec.ts`) and run the real\n`read-excel-file`\nrather than mocking the module; one workbook leaves a gap in a row so\nboth arms of the\ncell-to-string mapping run. jsdom\u0027s `Blob` has no `arrayBuffer()`, which\nis how\n`read-excel-file` reads its input, so the helper attaches the buffer it\njust built to that\none blob instead of patching `Blob.prototype`. For CSV, `FileReader` is\nreplaced with a\nfake that settles on a microtask, which is what makes the empty-result\nand error arms\ndeterministic — `Papa.parse` cannot be spied here (the existing spec\ndocuments why).\n\n**FilesUploaderComponent** — the drop paths that never yield an\nuploadable file (oversized\nfile, dropped directory, unreadable entry, including the singular/plural\nfailure banner),\nthe lookup paths (no dataset context, failed lookup, null result, and an\nunexpected failure\nof the whole drop with and without an error message), the fallback used\nwhen a conflicting\npath ends in a separator, the settings-request failure the constructor\nswallows, and the\nteardown that stops a late setting reaching a destroyed component.\n\nNo production code was changed.\n\n### Coverage that is not reachable\n\nThree branches and one statement stay uncovered because no test can\nreach them:\n\n- `user-dataset-file-renderer.component.ts:203` and `:223` — the\n`?? this.DEFAULT_MAX_SIZE` / `|| this.DEFAULT_MAX_SIZE` fallbacks. Both\nare reached only\nafter `isPreviewSupported` has confirmed via `hasOwnProperty` that the\nkey exists in\n`MIME_TYPE_SIZE_LIMITS_MB`, and every value in that map is a positive\nnumber, so neither\n  fallback can be taken.\n- `user-dataset-file-renderer.component.ts:372` — `if (cell !\u003d \"\")`\ninside\n`for (const cell in row)`. `for...in` yields index strings (\"0\", \"1\",\n…), which are never\n`\"\"`, so the condition is always true and the \"filter out all empty row\"\nstep filters\n  nothing. That is a defect rather than a coverage gap.\n- `files-uploader.component.ts:58` — a statement whose source range runs\nbackwards\n(`58:35 -\u003e 50:None`) into the `@Component` decorator: the\ncompiler-emitted `ngDevMode`\nguard on the class declaration, not application code. The one genuinely\nreachable gap\nattributed near it — the constructor\u0027s `error: () \u003d\u003e {}` arm — is now\ncovered, taking\n  function coverage to 37/37.\n\n- `user-dataset-file-renderer.component.ts` sets `isLoading \u003d true`\nimmediately above the\n`did \u0026\u0026 dvid \u0026\u0026 filePath` guard and never clears it when that guard\nfails, so a renderer\ngiven a `filePath` before its dataset ids shows a spinner that never\nstops. The id-guard\ntest pins this with a comment saying it characterizes a defect and what\nto flip once it\n  is fixed.\n\n### Defects worth recording\n\n`getMimeType` uppercases a file\u0027s extension and looks it up as a **key**\nof `MIME_TYPES`.\nThe Excel key is `MSEXCEL`, so only a file named `*.msexcel` resolves to\n`application/vnd.ms-excel`; a real `.xlsx` or `.xls` falls through to\n`OCTET_STREAM` and is\nrejected as \"preview unsupported\", which makes the whole spreadsheet\nbranch dead for real\nspreadsheets. `.jpg` has the same problem (the key is `JPEG`). The new\ntests use the suffix\nthe code actually accepts, with a comment saying so, rather than\nasserting an intent the\ncode does not implement.\n\n### Any related issues, documentation, discussions?\n\nCloses #7497.\n\n### How was this PR tested?\n\n`ng test --watch\u003dfalse` over the three specs — 86 passed (64 existing +\n22 new), run 3x for\ndeterminism. Coverage (`--coverage`) gives the table above. The failure\npath was verified by\nbreaking one assertion in each of the three specs (red, non-zero exit)\nand restoring them;\neslint and prettier are clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "d2ef447ff7eb3a77bdcd66952926a5f2ad43c53f",
      "tree": "47faf526838f37ee9aa1f950da3ba0263d56a9dc",
      "parents": [
        "b72fb80e57aafd8c6f896ffb948686c78b060678"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 22:28:38 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 05:28:38 2026 +0000"
      },
      "message": "test(frontend): render four component templates for coverage (#7501)\n\n### What changes were proposed in this PR?\n\nExtends four component specs so their templates actually render,\ncovering markup\nthat the existing tests never executed (they drove the classes\ndirectly). No\nproduction code was changed.\n\n**`MarkdownDescriptionComponent`** (+5) — clicking the Edit action\nenters edit\nmode and renders the edit arm; the `[innerHTML]` block renders the\nparsed\nmarkdown; the `#noDescription` fallback renders when there is nothing to\nshow;\nthe view-more button toggles both ways (label and chevron are driven by\nthe same\nflag); and the control is omitted when the description does not\noverflow.\n\n**`PresetWrapperComponent`** (+5) — the save button renders and saves;\nthe\ndropdown\u0027s `*ngFor` list is populated per preset with the\ntitle/description the\nrow interpolations render; the empty-list arm; and the `applyPreset` /\n`deletePreset` binding targets.\n\n**`PropertyEditorComponent`** (+2) — the docked collapse item closes the\npanel and\nthe collapsed item reopens it, so both arms of the `*ngIf` pair and both\n`(click)`\nbindings execute.\n\n**`AdminExecutionComponent`** (+3) — a seeded execution renders one row\nwhose\ncells contain `maxStringLength(...)` and `convertSecondsToTime(...)`\noutput; the\n\"Not Available\" arm renders for a negative execution time; and the kill\ncontrol\nroutes the workflow id.\n\nTwo behaviours worth noting for future template specs, recorded in\ncomments:\n\n- `ngOnInit` refills the list-backed state from the service, so rows\nmust be fed\nthrough the service stub rather than assigned afterwards (the fetch\nwould\n  overwrite them).\n- `nz-dropdown`\u0027s menu only mounts into a CDK overlay on a real user\nopen, which\njsdom does not drive. Rather than asserting on markup that cannot render\nthere\n(which would be brittle), those tests assert the list the `*ngFor` is\nbound to\nand the interpolations/handlers each row uses. `nz-table` also renders\nan\n  internal measure row, which the row helper filters out.\n\nPer the issue\u0027s determinism constraints: no fake timers are introduced,\nno\ndate/time string is asserted, and nothing asserts layout or geometry.\n\n### Any related issues, documentation, discussions?\n\nCloses #7496\n\n### How was this PR tested?\n\nExtended unit tests, run locally in `frontend/` (all green; failure\npaths were\nverified by breaking assertions to confirm the suites go red):\n\n```\nng test --watch\u003dfalse --include .../markdown-description.component.spec.ts   # 24 passed\nng test --watch\u003dfalse --include .../preset-wrapper.component.spec.ts         # 29 passed\nng test --watch\u003dfalse --include .../property-editor.component.spec.ts        # 22 passed\nng test --watch\u003dfalse --include .../admin-execution.component.spec.ts        # 42 passed\nprettier --write \u003cspecs\u003e   # clean\neslint  \u003cspecs\u003e            # clean\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "b72fb80e57aafd8c6f896ffb948686c78b060678",
      "tree": "c294c22c39fa536b444c4917041571bdba08b7d4",
      "parents": [
        "d1ac8dc3b76d3248bebc5c289ece6aa8c84f0766"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Mon Aug 10 06:14:16 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 05:14:16 2026 +0000"
      },
      "message": "chore(deps, agent-service): update dependency tsx to v4.23.12 (#7499)\n\nThis PR contains the following updates:\n\n| Package | Change |\n[Age](https://docs.renovatebot.com/merge-confidence/) |\n[Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n| [tsx](https://tsx.hirok.io)\n([source](https://redirect.github.com/privatenumber/tsx)) | [`4.23.11` →\n`4.23.12`](https://renovatebot.com/diffs/npm/tsx/4.23.11/4.23.12) |\n![age](https://developer.mend.io/api/mc/badges/age/npm/tsx/4.23.12?slim\u003dtrue)\n|\n![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tsx/4.23.11/4.23.12?slim\u003dtrue)\n|\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Release Notes\n\n\u003cdetails\u003e\n\u003csummary\u003eprivatenumber/tsx (tsx)\u003c/summary\u003e\n\n###\n[`v4.23.12`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.23.12)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.11...v4.23.12)\n\n##### Bug Fixes\n\n- shim `import.meta` when tokens are split by comments or newlines\n([#\u0026#8203;829](https://redirect.github.com/privatenumber/tsx/issues/829))\n([ed9d330](https://redirect.github.com/privatenumber/tsx/commit/ed9d33046a135de13a35fdfce12368b79d1b1518)),\ncloses\n[#\u0026#8203;828](https://redirect.github.com/privatenumber/tsx/issues/828)\n\n***\n\nThis release is also available on:\n\n- [npm package (@\u0026#8203;latest\ndist-tag)](https://www.npmjs.com/package/tsx/v/4.23.12)\n\n\u003c/details\u003e\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n🔕 **Ignore**: Close this PR and you won\u0027t be reminded about this update\nagain.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "d1ac8dc3b76d3248bebc5c289ece6aa8c84f0766",
      "tree": "d2174aa4845ac6ce8b5b319cd54af1810ba539fb",
      "parents": [
        "363e0ff96477482160c41d0b3a4181ef5b0cdc80"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 21:52:52 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 04:52:52 2026 +0000"
      },
      "message": "fix(amber): pass unstamped boundary states through LoopEnd instead of consuming them (#6913)\n\n### What changes were proposed in this PR?\n\nFollow-up to #6661, addressing [this review\ncomment](https://github.com/apache/texera/pull/6661#discussion_r3648708075):\na loop-body operator that emits its own boundary state\n(`produce_state_on_start/finish` — a public API on both engine sides)\nsends it with the \"no loop\" envelope (counter `0`, `loop_start_id \"\"`).\nThe LoopEnd matching branch treated **every** counter-0 frame as the\nloop\u0027s own boundary state:\n\n```\nLoopStart ──(0, LS-id)──▶ stateful body op ──▶ LoopEnd\n                             │ produce_state_on_finish\n                             └──(0, \"\")────────▶ LoopEnd   ← arrives AFTER the loop state\n```\n\nConsuming the unstamped state (1) clobbers the captured back-jump id\nwith `\"\"` → `no loop-back state URI configured for LoopStart \u0027\u0027`, and\n(2) hands `run_update` a State with no `table` payload → `KeyError`.\nEither way the loop breaks. The reviewer reasoned this for a stateful\nJVM operator; it is language-independent (a Python UDF hits the\nidentical path — no JVM built-in currently overrides\n`produceStateOnFinish`, so the Python UDF is also the practical repro).\n\n**Fix (consumer-side).** A real loop state is always stamped — the\nmatching LoopStart stamps its own id on every iteration\u0027s output state —\nso the LoopEnd runtime now keys on the stamp:\n\n| Frame at LoopEnd (counter 0) | before | after |\n|---|---|---|\n| stamped (`loop_start_id` set) | consume + capture id | unchanged |\n| unstamped (`\"\"`) | consume → id clobber / `KeyError` | forward\ndownstream unchanged, skip the operator (default pass-through\nsemantics), captured id untouched |\n\n**Keeping the loud failure.** Forwarding unstamped frames also swallows\nthe symptom of the bug class #6660/#6661 fixed: a hop that blanks the\nenvelope makes the loop\u0027s *own* state arrive unstamped, and forwarding\nit leaves `_loop_table` `None` → `condition()` returns `False` → the\nloop stops after one iteration and reports **success with a wrong row\ncount**. So a Loop End that forwarded an unstamped state and never took\na stamped one now raises:\n\n```\nLoop End received a loop-boundary state with no LoopStart stamp and never\nreceived its own (stamped) loop state: the loop envelope was lost upstream,\nso this loop would silently stop after one iteration\n```\n\nThree properties of where that check lives:\n\n- **`_process_end_channel`, not `complete()`** — `complete()` runs after\n`port_completed` has gone out for the input port and every output port,\nand region completion is port-based, so a raise there would be reported\nonly once the coordinator already considers the region done.\n- **Order-independent** — the body operator\u0027s state may arrive before or\nafter the loop\u0027s; `EndChannel` is `PORT_ALIGNMENT`, so the port is\ndrained by then.\n- **Reads nothing out of the `State`** — deliberately not keyed on the\nreserved `table` key, which #6971 removes from the loop state (and which\nan ordinary body UDF may legitimately emit), so the guard cannot rot\ngreen.\n\nIt is narrow on purpose — *forwarded an unstamped state* **and** *never\ntook a stamped one*. A Loop End completing without any matching state is\nlegal (`LoopEndOperator.eval_condition`\u0027s `_loop_table` guard), so only\npositive evidence of an unstamped boundary state counts.\n\nAlso documents why a Loop **Start** must do the opposite — MERGE an\nunstamped counter-0 state rather than forward it: the back-edge writes\nthe next iteration\u0027s variables to the Loop Start\u0027s own input-port state\nURI with that same \"no loop\" envelope (`State.to_tuple(0)`), so a Loop\nStart cannot tell its own state from an upstream operator\u0027s, while a\nLoop End can. The key-collision hazard that follows from the merge is\nfiled as #7248.\n\n### Any related issues, documentation, discussions?\n\nFollow-up to #6661 (review discussion r3648708075). Related engine\ncontext: #6660. Follow-up filed: #7248.\n\n### How was this PR tested?\n\n- **Unit** (`test_main_loop.py`), all verified red before the\ncorresponding change:\n- an unstamped counter-0 frame at a LoopEnd is forwarded with its\nenvelope unchanged, the operator is not invoked, the captured back-jump\nid is not clobbered, and it does not count as taking the loop\u0027s own\nstate;\n- a LoopEnd that only ever saw an unstamped state reports the error from\n`_process_end_channel` and sends **no** `port_completed`, so the region\nis held;\n- the legitimate shape (body-operator state *plus* the loop\u0027s own\nstamped state) stays silent in **both** arrival orders;\n- an unstamped counter-0 frame at a Loop **Start** is merged, not\nforwarded.\n- **E2E** (`LoopIntegrationSpec`, CI-only): `TextInput → LoopStart →\nstateful Python UDF → LoopEnd` where the UDF emits boundary state via\n`produce_state_on_finish` — it crashes without this fix and completes\nexactly 3 iterations with it.\n- Full pyamber suite, `scalafmtCheckAll` + `scalafixAll --check` + full\ntest-compile + ruff format/check pass locally (Java 17).\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nCo-authored-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e"
    },
    {
      "commit": "363e0ff96477482160c41d0b3a4181ef5b0cdc80",
      "tree": "e917962a3c636d8e68b8d7cd81c93c12086cf1d6",
      "parents": [
        "91235fbdb57768c880c0e043d4cb891283e225f1"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Mon Aug 10 05:25:20 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 04:25:20 2026 +0000"
      },
      "message": "chore(deps, amber): update dependency org.scala-lang.modules:scala-collection-contrib to v0.4.0 (#7492)\n\nThis PR contains the following updates:\n\n| Package | Update | Change |\n|---|---|---|\n|\n[org.scala-lang.modules:scala-collection-contrib](http://www.scala-lang.org/)\n([source](https://redirect.github.com/scala/scala-collection-contrib)) |\nminor | `0.3.0` → `0.4.0` |\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Release Notes\n\n\u003cdetails\u003e\n\u003csummary\u003escala/scala-collection-contrib\n(org.scala-lang.modules:scala-collection-contrib)\u003c/summary\u003e\n\n###\n[`v0.4.0`](https://redirect.github.com/scala/scala-collection-contrib/releases/tag/v0.4.0):\n0.4.0\n\n[Compare\nSource](https://redirect.github.com/scala/scala-collection-contrib/compare/v0.3.0...v0.4.0)\n\n#### Changes\n\n- Support Scala Native 0.5:\n- Update auxlib, clib, javalib, junit-plugin, ... to 0.5.3 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;248](https://redirect.github.com/scala/scala-collection-contrib/pull/248)\n- Update auxlib, clib, javalib, junit-plugin, ... to 0.5.4 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;249](https://redirect.github.com/scala/scala-collection-contrib/pull/249)\n- Update auxlib, clib, javalib, junit-plugin, ... to 0.5.5 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;253](https://redirect.github.com/scala/scala-collection-contrib/pull/253)\n- Issue 239 Fix by\n[@\u0026#8203;sageserpent-open](https://redirect.github.com/sageserpent-open)\nin\n[#\u0026#8203;244](https://redirect.github.com/scala/scala-collection-contrib/pull/244)\n\n#### Chores\n\n- Add java 21 to build matrix by\n[@\u0026#8203;Philippus](https://redirect.github.com/Philippus) in\n[#\u0026#8203;236](https://redirect.github.com/scala/scala-collection-contrib/pull/236)\n- Improvements to the Scala 3 crossbuild by\n[@\u0026#8203;som-snytt](https://redirect.github.com/som-snytt) in\n[#\u0026#8203;240](https://redirect.github.com/scala/scala-collection-contrib/pull/240)\n- Remove junit -q parameter by\n[@\u0026#8203;Philippus](https://redirect.github.com/Philippus) in\n[#\u0026#8203;243](https://redirect.github.com/scala/scala-collection-contrib/pull/243)\n- Update checkout and setup-java github actions to v4 by\n[@\u0026#8203;Philippus](https://redirect.github.com/Philippus) in\n[#\u0026#8203;235](https://redirect.github.com/scala/scala-collection-contrib/pull/235)\n- Update junit-plugin, junit-runtime, ... to 0.4.10 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;201](https://redirect.github.com/scala/scala-collection-contrib/pull/201)\n- Update junit-plugin, junit-runtime, ... to 0.4.12 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;204](https://redirect.github.com/scala/scala-collection-contrib/pull/204)\n- Update junit-plugin, junit-runtime, ... to 0.4.14 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;211](https://redirect.github.com/scala/scala-collection-contrib/pull/211)\n- Update junit-plugin, junit-runtime, ... to 0.4.15 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;221](https://redirect.github.com/scala/scala-collection-contrib/pull/221)\n- Update junit-plugin, junit-runtime, ... to 0.4.16 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;226](https://redirect.github.com/scala/scala-collection-contrib/pull/226)\n- Update junit-plugin, junit-runtime, ... to 0.4.17 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;230](https://redirect.github.com/scala/scala-collection-contrib/pull/230)\n- Update junit-plugin, junit-runtime, ... to 0.4.9 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;195](https://redirect.github.com/scala/scala-collection-contrib/pull/195)\n- Update junit-plugin, nscplugin, ... to 0.5.1 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;242](https://redirect.github.com/scala/scala-collection-contrib/pull/242)\n- Update sbt to 1.7.3 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;191](https://redirect.github.com/scala/scala-collection-contrib/pull/191)\n- Update sbt to 1.8.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;196](https://redirect.github.com/scala/scala-collection-contrib/pull/196)\n- Update sbt to 1.8.2 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;197](https://redirect.github.com/scala/scala-collection-contrib/pull/197)\n- Update sbt to 1.8.3 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;208](https://redirect.github.com/scala/scala-collection-contrib/pull/208)\n- Update sbt to 1.9.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;210](https://redirect.github.com/scala/scala-collection-contrib/pull/210)\n- Update sbt to 1.9.1 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;214](https://redirect.github.com/scala/scala-collection-contrib/pull/214)\n- Update sbt to 1.9.3 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;219](https://redirect.github.com/scala/scala-collection-contrib/pull/219)\n- Update sbt to 1.9.4 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;220](https://redirect.github.com/scala/scala-collection-contrib/pull/220)\n- Update sbt to 1.9.6 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;224](https://redirect.github.com/scala/scala-collection-contrib/pull/224)\n- Update sbt to 1.9.7 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;227](https://redirect.github.com/scala/scala-collection-contrib/pull/227)\n- Update sbt to 1.9.8 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;229](https://redirect.github.com/scala/scala-collection-contrib/pull/229)\n- Update sbt to 1.9.9 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;232](https://redirect.github.com/scala/scala-collection-contrib/pull/232)\n- Update sbt to 1.10.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;246](https://redirect.github.com/scala/scala-collection-contrib/pull/246)\n- Update sbt to 1.10.1 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;250](https://redirect.github.com/scala/scala-collection-contrib/pull/250)\n- Update sbt to 1.10.2 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;254](https://redirect.github.com/scala/scala-collection-contrib/pull/254)\n- Update sbt-scala-module to 3.1.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;217](https://redirect.github.com/scala/scala-collection-contrib/pull/217)\n- Update sbt-scala-native-crossproject, ... to 1.3.1 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;207](https://redirect.github.com/scala/scala-collection-contrib/pull/207)\n- Update sbt-scala-native-crossproject, ... to 1.3.2 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;216](https://redirect.github.com/scala/scala-collection-contrib/pull/216)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.12.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;194](https://redirect.github.com/scala/scala-collection-contrib/pull/194)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.13.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;200](https://redirect.github.com/scala/scala-collection-contrib/pull/200)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.13.1 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;206](https://redirect.github.com/scala/scala-collection-contrib/pull/206)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.13.2 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;213](https://redirect.github.com/scala/scala-collection-contrib/pull/213)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.14.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;225](https://redirect.github.com/scala/scala-collection-contrib/pull/225)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.15.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;228](https://redirect.github.com/scala/scala-collection-contrib/pull/228)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.16.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;237](https://redirect.github.com/scala/scala-collection-contrib/pull/237)\n- Update sbt-scalajs, scalajs-compiler, ... to 1.17.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;256](https://redirect.github.com/scala/scala-collection-contrib/pull/256)\n- Update scala-library to 2.13.11 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;212](https://redirect.github.com/scala/scala-collection-contrib/pull/212)\n- Update scala-library to 2.13.12 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;223](https://redirect.github.com/scala/scala-collection-contrib/pull/223)\n- Update scala-library to 2.13.13 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;233](https://redirect.github.com/scala/scala-collection-contrib/pull/233)\n- Update scala-library to 2.13.14 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;245](https://redirect.github.com/scala/scala-collection-contrib/pull/245)\n- Update scala-library to 2.13.15 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;255](https://redirect.github.com/scala/scala-collection-contrib/pull/255)\n- Update scala3-library, ... to 3.2.2 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;202](https://redirect.github.com/scala/scala-collection-contrib/pull/202)\n- Update scala3-library, ... to 3.3.0 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;209](https://redirect.github.com/scala/scala-collection-contrib/pull/209)\n- Update scala3-library, ... to 3.3.1 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;222](https://redirect.github.com/scala/scala-collection-contrib/pull/222)\n- Update scala3-library, ... to 3.3.3 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;234](https://redirect.github.com/scala/scala-collection-contrib/pull/234)\n- Update scala3-library, ... to 3.3.4 by\n[@\u0026#8203;scala-steward](https://redirect.github.com/scala-steward) in\n[#\u0026#8203;257](https://redirect.github.com/scala/scala-collection-contrib/pull/257)\n- copyright 2023 by\n[@\u0026#8203;SethTisue](https://redirect.github.com/SethTisue) in\n[#\u0026#8203;198](https://redirect.github.com/scala/scala-collection-contrib/pull/198)\n- copyright 2024 by\n[@\u0026#8203;SethTisue](https://redirect.github.com/SethTisue) in\n[#\u0026#8203;258](https://redirect.github.com/scala/scala-collection-contrib/pull/258)\n- test Scaladoc generation in CI by\n[@\u0026#8203;SethTisue](https://redirect.github.com/SethTisue) in\n[#\u0026#8203;259](https://redirect.github.com/scala/scala-collection-contrib/pull/259)\n\n#### New Contributors\n\n-\n[@\u0026#8203;sageserpent-open](https://redirect.github.com/sageserpent-open)\nmade their first contribution in\n[#\u0026#8203;244](https://redirect.github.com/scala/scala-collection-contrib/pull/244)\n\n**Full Changelog**:\n\u003chttps://github.com/scala/scala-collection-contrib/compare/v0.3.0...v0.4.0\u003e\n\n\u003c/details\u003e\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n🔕 **Ignore**: Close this PR and you won\u0027t be reminded about this update\nagain.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\n---------\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "91235fbdb57768c880c0e043d4cb891283e225f1",
      "tree": "2799afce535865460a2a21c838c858519881ed1c",
      "parents": [
        "8982803165bbf2ace67ec9635b258a16649e17ce"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Sun Aug 09 19:39:03 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 02:39:03 2026 +0000"
      },
      "message": "fix(workflow-operator): Text Input operator using offset with an empty limit emits no rows (#7347)\n\n### What changes were proposed in this PR?\n\n`TextInputSourceOpExec` computed its line window as `slice(offset,\noffset + limit.getOrElse(Int.MaxValue))`. With an Offset set and the\nLimit left empty, the addition overflows `Int` to a negative bound,\nwhich Scala 2.13\u0027s `Iterator.slice` clamps to 0 and then returns an\nempty iterator — so the operator silently emitted **zero rows** while\nthe workflow reported success. Any Offset ≥ 1 with an empty Limit is\naffected, and an explicit large Limit (e.g. `Int.MaxValue`) overflows\nthe same way. This contradicts the Limit property\u0027s own description,\n\"Leave empty to read all lines.\"\n\nThis PR replaces the slice with `drop(offset)` + `take(limit)`, the same\nidiom the CSV, Arrow, and JSONL scan sources already use. There is no\naddition, so nothing can overflow; every configuration that previously\nworked is unchanged (verified case-by-case, including negative offsets\nand `isSingle` attribute types, which keep ignoring offset/limit as\ndocumented).\n\n**Before the fix (current `main`)** — Offset \u003d 1, Limit left empty,\nfive-line input `a b c d e`: the result is an empty set even though the\nworkflow completes successfully. Expected: the four rows `b, c, d, e`.\n\n\u003cimg width\u003d\"1349\" height\u003d\"839\" alt\u003d\"Screenshot 2026-08-05 at 2 21 56 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/107a06a0-f0f3-4d4c-bf13-0357420ca6cb\"\n/\u003e\n\n**Control on the same build** — Offset \u003d 0, Limit left empty returns all\nfive rows:\n\n\u003cimg width\u003d\"1344\" height\u003d\"841\" alt\u003d\"Screenshot 2026-08-05 at 2 22 05 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/9acdd769-1762-44d4-8386-a6ca16a78d0d\"\n/\u003e\n\n\n### Any related issues, documentation, discussions?\n\nCloses #7346.\n\nSame class of defect as #7245 (JSONL File Scan dropping rows when Offset\nis set), which was fixed by #7247.\n\n### How was this PR tested?\n\nTDD: the regression tests were written first and confirmed to fail on\nthe unfixed code — the offset-without-limit case and the\noffset-with-`Int.MaxValue`-limit case both produced empty output — then\nthe fix was applied and all tests pass.\n\nSeven new cases were added to `TextInputSourceOpDescSpec` (the spec that\nalready exercises `produceTuple()`): offset without limit, offset with\nan `Int.MaxValue` limit, offset+limit window, limit only, offset at/past\nthe end of the input, negative offset treated as zero, and\n`SINGLE_STRING` ignoring offset/limit (documented behavior, pinned).\n\n```bash\nsbt \"WorkflowOperator/testOnly org.apache.texera.amber.operator.source.scan.text.TextInputSourceOpDescSpec\"\n# 17 tests, all passed (10 pre-existing + 7 new)\n\nsbt \"WorkflowOperator/testOnly org.apache.texera.amber.operator.source.scan.*\"\n# 17 suites, 123 tests, all passed\n\nsbt \"WorkflowOperator/scalafixAll --check\"\n# passed, no lint issues\n\nsbt scalafmtCheckAll\n# passed, no mis-formatted files\n```\n\nAlso verified manually in the UI with the same two-operator workflow\nshown in the screenshots above:\n\u003cimg width\u003d\"1131\" height\u003d\"760\" alt\u003d\"Screenshot 2026-08-05 at 5 15 55 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/28e639df-0888-4793-a3a3-ffe9c37d07c8\"\n/\u003e\n\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Fable 5)\n\nCo-authored-by: Claude Fable 5 \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "8982803165bbf2ace67ec9635b258a16649e17ce",
      "tree": "ccf8081cae2e508545c94de7fb5132184b8eb741",
      "parents": [
        "88ca47f2f4d4ae26535012951b9c64cb9af3c91c"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Sun Aug 09 19:26:36 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 02:26:36 2026 +0000"
      },
      "message": "fix(workflow-operator): File Scan operator using offset with an empty limit emits no rows (#7348)\n\n### What changes were proposed in this PR?\n\n`FileScanUtils.createTuplesFromFile` computed the end of its line slice\nas `offset + limit.getOrElse(Int.MaxValue)`. With Offset \u003e\u003d 1 and Limit\nleft empty, the addition overflows `Int` to a negative bound, and\n`Iterator.slice` clamps a negative bound to 0 and returns an empty\niterator. The File Scan operator therefore emitted **zero rows,\nsilently, with the workflow reporting success**. Both `FileScan` and\n`FileScanOp` delegate to this helper, so both were affected.\n\n**Before the fix (current `main`)**——**Offset \u003d 1, Limit left empty —\nzero rows (\"Empty result set\") while the run reports success:**\n\u003cimg width\u003d\"1344\" height\u003d\"869\" alt\u003d\"Screenshot 2026-08-05 at 2 19 40 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/28c628b5-2a71-47a4-bf78-f790c9b113c0\"\n/\u003e\n\n**Control: Offset \u003d 0, Limit left empty, same file — all five rows:**\n\u003cimg width\u003d\"1340\" height\u003d\"869\" alt\u003d\"Screenshot 2026-08-05 at 2 19 47 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/cd747eee-b931-4e31-8399-ad666881e1cf\"\n/\u003e\n\nThe fix replaces the slice arithmetic with `drop(offset)` plus an\noptional `take(limit)` — the shape `CSVScanSourceOpExec` and\n`ArrowSourceOpExec` already use — so \"no limit\" is expressed by not\nbounding the iterator rather than by a sentinel value that arithmetic\ncan overflow. Offset and limit still apply per extracted zip entry\n(unchanged behavior, now pinned by a test).\n\n### Any related issues, documentation, discussions?\n\nCloses #7345\n\nSame bug class as #7245 (JSONL scan, fixed by #7247).\n\n### How was this PR tested?\n\nTDD: the regression tests were written first and confirmed to fail on\nthe unfixed code — the four offset-without-limit cases all produced\nempty output (e.g. `List() did not equal List(\"l2\", \"l3\", \"l4\", \"l5\")`)\n— then the fix was applied and all tests pass.\n\nTen new cases were added across the three File Scan specs: eight in\n`FileScanUtilsSpec` (offset without limit — the regression, offset 0,\noffset with limit, limit only, offset past EOF, offset with an\n`Int.MaxValue` limit, per-zip-entry offset with `extract \u003d true`, and\n`isSingle` types ignoring offset/limit — documented behavior, pinned),\nplus one operator-level offset-without-limit case each in\n`FileScanSourceOpDescSpec` (source operator) and `FileScanOpDescSpec`\n(input-port operator), since both operators delegate to the same helper.\n\nTDD: the regression tests were written first and confirmed to fail on\nthe unfixed code — the four offset-without-limit cases all produced\nempty output (e.g. `List() did not equal List(\"l2\", \"l3\", \"l4\", \"l5\")`)\n— then the fix was applied and all tests pass.\n\nTen new cases were added across the three File Scan specs: eight in\n`FileScanUtilsSpec` (offset without limit — the regression, offset 0,\noffset with limit, limit only, offset past EOF, offset with an\n`Int.MaxValue` limit, per-zip-entry offset with `extract \u003d true`, and\n`isSingle` types ignoring offset/limit — documented behavior, pinned),\nplus one operator-level offset-without-limit case each in\n`FileScanSourceOpDescSpec` (source operator) and `FileScanOpDescSpec`\n(input-port operator), since both operators delegate to the same helper.\n\n```bash\nsbt \"WorkflowOperator/testOnly org.apache.texera.amber.operator.source.scan.file.FileScanUtilsSpec org.apache.texera.amber.operator.source.scan.file.FileScanSourceOpDescSpec org.apache.texera.amber.operator.source.scan.file.FileScanOpDescSpec\"\n# 29 tests, all passed (19 pre-existing + 10 new)\n\nsbt \"WorkflowOperator/scalafixAll --check\"\n# passed, no lint issues\n\nsbt \"WorkflowOperator/scalafmtCheck\" \"WorkflowOperator/Test/scalafmtCheck\"\n# passed, no mis-formatted files\n\nsbt WorkflowOperator/test\n# full module: 2050 tests in 283 suites, all passed\n```\n\nAlso verified manually in the UI with the same two-operator workflow\nshown in the screenshots above:\n\u003cimg width\u003d\"1133\" height\u003d\"762\" alt\u003d\"Screenshot 2026-08-05 at 5 20 41 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/fe2e3098-ddf4-4787-a611-fcbb3b61e19d\"\n/\u003e\n\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Claude Fable 5)"
    },
    {
      "commit": "88ca47f2f4d4ae26535012951b9c64cb9af3c91c",
      "tree": "c4c7e140087dd120fb2cd1462a5217513c2df71d",
      "parents": [
        "aa791a47be922eedd95098b390223726178bfd93"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 18:57:22 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:57:22 2026 +0000"
      },
      "message": "test(amber): replace commented-out PythonWorkflowWorkerSpec with pythonworker proxy unit tests (#7488)\n\n### What changes were proposed in this PR?\n\n#7447 proposed deleting `PythonWorkflowWorkerSpec.scala`, which has been\nfully commented out for years and no longer compiles against today\u0027s\nAPIs. Following the review feedback there\n(https://github.com/apache/texera/pull/7447#issuecomment-5234671357),\nthis PR replaces the dead file with real unit tests instead of only\ndeleting it.\n\nThe commented-out spec drove `PythonWorkflowWorker` end-to-end, which\nneeds a live Python process — that path is covered by the e2e tests.\nWhat can be unit-tested without Python is the JVM side of the JVM↔Python\nArrow Flight bridge, which had no coverage until now:\n\n```\n                     JVM                                     Python\n  ┌───────────────────────────────────────┐\n  │ PythonWorkflowWorker (actor)          │      e2e-tested only (needs Python)\n  │  ├─ PythonProxyClient ──── Flight ────┼────▶ network_receiver.py\n  │  │    PythonProxyClientSpec: fake     │\n  │  │    Python Flight server in Scala   │\n  │  └─ PythonProxyServer ◀─── Flight ────┼───── network_sender.py\n  │       PythonProxyServerSpec: test     │\n  │       plays the Python Flight client  │\n  └───────────────────────────────────────┘\n```\n\n| New spec | Subject | Behavior pinned down |\n|---|---|---|\n| `PythonProxyServerSpec` | `PythonProxyServer` / `AmberProducer` |\n`handshake` completes the port promise and replies `ok`; `control`\nactions route `ControlInvocation` / `ReturnInvocation` to the output\ngateway on the control channel and ack with a little-endian credit\nvalue; `Data` / `State` / `ECM` puts are reassembled into `DataFrame` /\n`StateFrame` (loop envelope preserved) / `EmbeddedControlMessage` and\nacked with credits |\n| `PythonProxyClientSpec` | `PythonProxyClient` | heartbeat handshake\nhappens before the queue is drained; queued `ControlInvocation` /\n`ReturnInvocation` / actor commands arrive as `control` / `actor`\nactions with intact protobuf payloads; `DataFrame` / `StateFrame` / ECM\nputs arrive under the right `PythonDataHeader` with tuples, loop\nenvelope, and bytes intact; queue-size acks update `getQueuedCredit`;\nconnection retries abort with `WorkflowRuntimeException` (no server\nlistening, non-`ack` heartbeat); `close()` before any connection does\nnot throw |\n\nBoth specs stand in for the Python worker with plain Arrow Flight\ncomponents (`FlightClient` / `NoOpFlightProducer`), so no Python process\nis involved. Together with the existing `WorkerBatchInternalQueueSpec`\nand `PythonWorkflowWorkerStartupConfigSpec`, every class in the\n`pythonworker` package except the actor itself now has unit coverage.\n\nThe commented-out `PythonWorkflowWorkerSpec.scala` is removed,\nsuperseded by these tests.\n\n### Any related issues, documentation, discussions?\n\nSupersedes #7447.\n\n### How was this PR tested?\n\nThis PR is tests-only. Both new specs pass locally:\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.pythonworker.PythonProxyServerSpec org.apache.texera.amber.engine.architecture.pythonworker.PythonProxyClientSpec\"\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Fable 5)"
    },
    {
      "commit": "aa791a47be922eedd95098b390223726178bfd93",
      "tree": "8b24f350997cb1b549bc475b25a6529583942055",
      "parents": [
        "dccb364f3add0afe41a1091f5f0b1874bea094fb"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Mon Aug 10 02:51:10 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:51:10 2026 +0000"
      },
      "message": "chore(deps, amber): update dependency io.github.kostaskougios:cloning to v1.13.0-jdk8 (#7490)\n\nThis PR contains the following updates:\n\n| Package | Update | Change |\n|---|---|---|\n|\n[io.github.kostaskougios:cloning](https://redirect.github.com/kostaskougios/cloning)\n| minor | `1.10.3` → `1.13.0-jdk8` |\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n🔕 **Ignore**: Close this PR and you won\u0027t be reminded about this update\nagain.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\n---------\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "dccb364f3add0afe41a1091f5f0b1874bea094fb",
      "tree": "5e4ac8768ec7aa5419ad0654ea4a399585f962f9",
      "parents": [
        "e328232b436b3c57936f1ef8618a14b5e87ba559"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Mon Aug 10 02:51:05 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:51:05 2026 +0000"
      },
      "message": "chore(deps, amber): update dependency io.dropwizard-bundles:dropwizard-redirect-bundle to v1.3.5 (#7489)\n\nThis PR contains the following updates:\n\n| Package | Update | Change |\n|---|---|---|\n|\n[io.dropwizard-bundles:dropwizard-redirect-bundle](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle)\n| minor | `1.0.5` → `1.3.5` |\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Release Notes\n\n\u003cdetails\u003e\n\u003csummary\u003edropwizard-bundles/dropwizard-redirect-bundle\n(io.dropwizard-bundles:dropwizard-redirect-bundle)\u003c/summary\u003e\n\n###\n[`v1.3.5`](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle/compare/v1.2.2...v1.3.5)\n\n[Compare\nSource](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle/compare/v1.2.2...v1.3.5)\n\n###\n[`v1.2.2`](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle/compare/v1.1.4...v1.2.2)\n\n[Compare\nSource](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle/compare/v1.1.4...v1.2.2)\n\n###\n[`v1.1.4`](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle/compare/v1.0.5...v1.1.4)\n\n[Compare\nSource](https://redirect.github.com/dropwizard-bundles/dropwizard-redirect-bundle/compare/v1.0.5...v1.1.4)\n\n\u003c/details\u003e\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n🔕 **Ignore**: Close this PR and you won\u0027t be reminded about this update\nagain.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\n---------\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "e328232b436b3c57936f1ef8618a14b5e87ba559",
      "tree": "87dc5b6599af9518593cdac056988a3a49d591fe",
      "parents": [
        "fceef70e32260c9dc29762a2f70d87f8fef03f3b"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 18:48:03 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:48:03 2026 +0000"
      },
      "message": "test(agent-service): cover the auth, workflow, and backend API clients (#7384)\n\n### What changes were proposed in this PR?\n\nThree of the four API clients under `agent-service/src/api` had no spec.\n`auth-api.ts` is the one that decides whether a request is authenticated\nat all, and none of its decisions were pinned.\n\nAdds 30 tests across three spec files, following the `fetch`-spy pattern\nalready established by `compile-api.spec.ts`.\n\n**auth-api** — several of these are policy choices that read like\noversights, so the tests state the intent rather than just the\nbehaviour:\n\n| Input | Result |\n|---|---|\n| token with no `exp` | valid — tokens minted without an expiry never\nexpire |\n| malformed token | invalid — the decode error is swallowed and reported\nas expired, not thrown |\n| payload with no `role` | `REGULAR`, so absent means least privilege |\n| `bearer` / `BEARER` | accepted; the scheme is matched\ncase-insensitively |\n| two-segment token whose payload parses | rejected |\n\n**workflow-api** — the workflow `content` round-trips as a nested JSON\n**string**: the request sends `JSON.stringify(content)` and the response\nis re-parsed when it comes back as a string. Sending the object directly\nis the obvious-looking mistake and the backend rejects it, so both\ndirections are pinned, along with the empty-description default and the\nerror text on a refused save or a missing workflow.\n\n**backend-api** — the endpoint set, the defensive copy of the\nmodule-level config, and the two failure paths of the metadata fetch.\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| default a missing role to `ADMIN` | red |\n| remove the three-segment check | red |\n| treat a token with no `exp` as expired | red |\n| compare `exp` as milliseconds instead of seconds | red |\n| make the Bearer scheme case-sensitive | red |\n| report a malformed token as valid | red |\n| send `content` as a nested object | red |\n| drop the empty-description default | red |\n| stop re-parsing a stringified response `content` | red |\n| drop the wid from the retrieve URL | red |\n| return the shared config by reference | red |\n\nThe three-segment mutation initially **survived**: the test used\n`\"only.two\"`, whose payload fails `JSON.parse` regardless, so the\nsegment check was never actually exercised. Replaced with a two-segment\ntoken carrying a valid payload — an unsigned token — which is the case\nthe check exists for.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7381\n\n### How was this PR tested?\n\n```\nbun test\n```\n\n```\n 232 pass\n 0 fail\nRan 232 tests across 18 files.\n```\n\n`bun run typecheck` and `bun run format:check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "fceef70e32260c9dc29762a2f70d87f8fef03f3b",
      "tree": "c26d114644d96b98a5df5cf17df20fd5a2d366a1",
      "parents": [
        "306944a3ecc3466cc514cd0d8c1f8711d0f4dbe0"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Mon Aug 10 02:36:48 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:36:48 2026 +0000"
      },
      "message": "chore(deps, agent-service): update agent-service patch updates (#7482)\n\nThis PR contains the following updates:\n\n| Package | Change |\n[Age](https://docs.renovatebot.com/merge-confidence/) |\n[Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n| [@ai-sdk/openai](https://ai-sdk.dev/docs)\n([source](https://redirect.github.com/vercel/ai/tree/HEAD/packages/openai))\n| [`4.0.27` →\n`4.0.36`](https://renovatebot.com/diffs/npm/@ai-sdk%2fopenai/4.0.27/4.0.36)\n|\n![age](https://developer.mend.io/api/mc/badges/age/npm/@ai-sdk%2fopenai/4.0.36?slim\u003dtrue)\n|\n![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@ai-sdk%2fopenai/4.0.27/4.0.36?slim\u003dtrue)\n|\n| [ai](https://ai-sdk.dev/docs)\n([source](https://redirect.github.com/vercel/ai/tree/HEAD/packages/ai))\n| [`7.0.48` →\n`7.0.58`](https://renovatebot.com/diffs/npm/ai/7.0.48/7.0.58) |\n![age](https://developer.mend.io/api/mc/badges/age/npm/ai/7.0.58?slim\u003dtrue)\n|\n![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/ai/7.0.48/7.0.58?slim\u003dtrue)\n|\n| [tsx](https://tsx.hirok.io)\n([source](https://redirect.github.com/privatenumber/tsx)) | [`4.23.5` →\n`4.23.11`](https://renovatebot.com/diffs/npm/tsx/4.23.5/4.23.11) |\n![age](https://developer.mend.io/api/mc/badges/age/npm/tsx/4.23.11?slim\u003dtrue)\n|\n![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tsx/4.23.5/4.23.11?slim\u003dtrue)\n|\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Release Notes\n\n\u003cdetails\u003e\n\u003csummary\u003evercel/ai (@\u0026#8203;ai-sdk/openai)\u003c/summary\u003e\n\n###\n[`v4.0.36`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4036)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.35...@ai-sdk/openai@4.0.36)\n\n##### Patch Changes\n\n- [`6157098`](https://redirect.github.com/vercel/ai/commit/6157098):\nfix(openai): serialize tool text outputs when an output schema is\nconfigured\n- [`4cd4548`](https://redirect.github.com/vercel/ai/commit/4cd4548):\nAccept `serviceTier: \u0027fast\u0027` on OpenAI chat and responses models. OpenAI\nrenamed priority processing to Fast mode and accepts `service_tier:\n\u0027fast\u0027` and `\u0027priority\u0027` interchangeably, so `\u0027fast\u0027` is now passed\nthrough verbatim and gated on the same model capability as `\u0027priority\u0027`.\n- Updated dependencies\n\\[[`ad6a650`](https://redirect.github.com/vercel/ai/commit/ad6a650)]\n- Updated dependencies\n\\[[`81cd026`](https://redirect.github.com/vercel/ai/commit/81cd026)]\n-\n[@\u0026#8203;ai-sdk/provider](https://redirect.github.com/ai-sdk/provider)@\u0026#8203;4.0.7\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.25\n\n###\n[`v4.0.35`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4035)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.34...@ai-sdk/openai@4.0.35)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`1937bef`](https://redirect.github.com/vercel/ai/commit/1937bef)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.24\n\n###\n[`v4.0.34`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4034)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.33...@ai-sdk/openai@4.0.34)\n\n##### Patch Changes\n\n- [`73d48d0`](https://redirect.github.com/vercel/ai/commit/73d48d0):\nfix(provider/openai): correlate rotating Responses API item IDs by\noutput index\n- [`bbd9b31`](https://redirect.github.com/vercel/ai/commit/bbd9b31):\nchore: rename `*TranslationModel` and its related types to\n`*SpeechTranslationModel` for consistency\n\n###\n[`v4.0.33`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4033)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.32...@ai-sdk/openai@4.0.33)\n\n##### Patch Changes\n\n- [`e6a93c4`](https://redirect.github.com/vercel/ai/commit/e6a93c4):\nfeat(openai): support batch APIs with experimental\\_startTextBatch\n\n###\n[`v4.0.32`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4032)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.31...@ai-sdk/openai@4.0.32)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`3469d0c`](https://redirect.github.com/vercel/ai/commit/3469d0c)]\n-\n[@\u0026#8203;ai-sdk/provider](https://redirect.github.com/ai-sdk/provider)@\u0026#8203;4.0.6\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.23\n\n###\n[`v4.0.31`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4031)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.30...@ai-sdk/openai@4.0.31)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`2b60826`](https://redirect.github.com/vercel/ai/commit/2b60826)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.22\n\n###\n[`v4.0.30`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4030)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.29...@ai-sdk/openai@4.0.30)\n\n##### Patch Changes\n\n- [`1bec07d`](https://redirect.github.com/vercel/ai/commit/1bec07d): Fix\nstreamed tool calls with non-zero, non-contiguous, reused, or missing\nindexes.\n- Updated dependencies\n\\[[`1bec07d`](https://redirect.github.com/vercel/ai/commit/1bec07d)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.21\n\n###\n[`v4.0.29`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4029)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.28...@ai-sdk/openai@4.0.29)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`160ccdb`](https://redirect.github.com/vercel/ai/commit/160ccdb)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.20\n\n###\n[`v4.0.28`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/openai/CHANGELOG.md#4028)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/@ai-sdk/openai@4.0.27...@ai-sdk/openai@4.0.28)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`79e133c`](https://redirect.github.com/vercel/ai/commit/79e133c)]\n-\n[@\u0026#8203;ai-sdk/provider](https://redirect.github.com/ai-sdk/provider)@\u0026#8203;4.0.5\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.19\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003evercel/ai (ai)\u003c/summary\u003e\n\n###\n[`v7.0.58`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7058)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.57...ai@7.0.58)\n\n##### Patch Changes\n\n- [`72ad23f`](https://redirect.github.com/vercel/ai/commit/72ad23f):\nRespect ToolLoopAgent timeouts configured in agent settings.\n\n- [`ad6a650`](https://redirect.github.com/vercel/ai/commit/ad6a650):\nfeat(video): allow `aspectRatio: \u0027adaptive\u0027` on `generateVideo`\n\nSome video models derive the output ratio from the input and reject\nexplicit\n`{width}:{height}` values — BytePlus Seedance 2.5 does this for\nfirst-frame,\n  first-and-last-frame, editing, and extension tasks. `aspectRatio` on\n  `VideoModelV3CallOptions`, `VideoModelV4CallOptions`, and\n`experimental_generateVideo` is now `` `${number}:${number}` |\n\u0027adaptive\u0027 ``, so\nthose calls no longer need a type assertion. Support is\nprovider-specific.\n\n- [`81cd026`](https://redirect.github.com/vercel/ai/commit/81cd026):\nReduce bundle size by making internal Zod v4 imports tree-shakeable.\n\n- Updated dependencies\n\\[[`c477556`](https://redirect.github.com/vercel/ai/commit/c477556)]\n\n- Updated dependencies\n\\[[`ad6a650`](https://redirect.github.com/vercel/ai/commit/ad6a650)]\n\n- Updated dependencies\n\\[[`81cd026`](https://redirect.github.com/vercel/ai/commit/81cd026)]\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.46\n-\n[@\u0026#8203;ai-sdk/provider](https://redirect.github.com/ai-sdk/provider)@\u0026#8203;4.0.7\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.25\n\n###\n[`v7.0.57`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7057)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.56...ai@7.0.57)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`1937bef`](https://redirect.github.com/vercel/ai/commit/1937bef)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.24\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.45\n\n###\n[`v7.0.56`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7056)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.55...ai@7.0.56)\n\n##### Patch Changes\n\n- [`25c9120`](https://redirect.github.com/vercel/ai/commit/25c9120):\nExpose provider metadata on language-model-call end callbacks and\ntelemetry spans.\n\n- [`89080c8`](https://redirect.github.com/vercel/ai/commit/89080c8): fix\n(ai/gateway): make retried `doStart` calls idempotent\n\n`generateVideo` retries `doStart`, which creates a billable generation,\nso a\n  retry after a lost response could start a second one. It now mints one\nidempotency token per logical start — outside the retry closure — and\nforwards it\nas an `idempotency-key` header, so a provider that deduplicates (the\nVercel AI\nGateway does) sees the same key on every attempt. `GatewayVideoModel`\nsimply\nforwards the caller\u0027s headers rather than inferring retry identity from\nan\n  options object, which would collide across unrelated calls.\n\n- [`79d6195`](https://redirect.github.com/vercel/ai/commit/79d6195):\nStop pending and active resumed chat streams after cancellation, and\nprevent\n  overlapping resumptions from applying stale updates.\n\n- Updated dependencies\n\\[[`89080c8`](https://redirect.github.com/vercel/ai/commit/89080c8)]\n\n- Updated dependencies\n\\[[`89080c8`](https://redirect.github.com/vercel/ai/commit/89080c8)]\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.44\n\n###\n[`v7.0.55`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7055)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.54...ai@7.0.55)\n\n##### Patch Changes\n\n- [`3469d0c`](https://redirect.github.com/vercel/ai/commit/3469d0c):\nfeat: add batch APIs\n- Updated dependencies\n\\[[`3469d0c`](https://redirect.github.com/vercel/ai/commit/3469d0c)]\n-\n[@\u0026#8203;ai-sdk/provider](https://redirect.github.com/ai-sdk/provider)@\u0026#8203;4.0.6\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.43\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.23\n\n###\n[`v7.0.54`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7054)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.52...ai@7.0.54)\n\n##### Patch Changes\n\n- [`a6b17a2`](https://redirect.github.com/vercel/ai/commit/a6b17a2):\nAllow `ToolLoopAgent` `prepareCall` callbacks to read and override the\ntop-level `reasoning` option.\n- [`5615eb7`](https://redirect.github.com/vercel/ai/commit/5615eb7): Add\n`defaultInstructionsMiddleware` for applying default language model\ninstructions while preserving call-level overrides.\n- [`36a3ff6`](https://redirect.github.com/vercel/ai/commit/36a3ff6):\nPreserve preceding assistant messages when regenerating a response.\n\n###\n[`v7.0.52`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7052)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.51...ai@7.0.52)\n\n##### Patch Changes\n\n- [`3836a85`](https://redirect.github.com/vercel/ai/commit/3836a85):\nSkip re-validating tool input for terminal output-available UI message\nparts.\n- Updated dependencies\n\\[[`1bec07d`](https://redirect.github.com/vercel/ai/commit/1bec07d)]\n- Updated dependencies\n\\[[`53c326e`](https://redirect.github.com/vercel/ai/commit/53c326e)]\n- Updated dependencies\n\\[[`d765f82`](https://redirect.github.com/vercel/ai/commit/d765f82)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.21\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.41\n\n###\n[`v7.0.51`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7051)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.50...ai@7.0.51)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`160ccdb`](https://redirect.github.com/vercel/ai/commit/160ccdb)]\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.20\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.40\n\n###\n[`v7.0.50`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7050)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.49...ai@7.0.50)\n\n##### Patch Changes\n\n- [`79e133c`](https://redirect.github.com/vercel/ai/commit/79e133c):\nasync APIs for generateVideo (poll, webhook)\n\n  Adds an asynchronous start/status flow to the experimental video model\ninterface (`VideoModelV4`): models may now implement `doStart`,\n`doStatus`,\nand `handleWebhookOption` instead of (or in addition to) `doGenerate`,\nand\n  `experimental_generateVideo` accepts `poll` and `webhook` options to\norchestrate completion via polling or webhooks. Polling configuration\ncan use\n  a custom delay implementation for durable workflow compatibility.\n\n- [`da64b51`](https://redirect.github.com/vercel/ai/commit/da64b51):\nfeat(code-mode): simplify tool caller configuration\n\n- Updated dependencies\n\\[[`79e133c`](https://redirect.github.com/vercel/ai/commit/79e133c)]\n-\n[@\u0026#8203;ai-sdk/provider](https://redirect.github.com/ai-sdk/provider)@\u0026#8203;4.0.5\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.39\n-\n[@\u0026#8203;ai-sdk/provider-utils](https://redirect.github.com/ai-sdk/provider-utils)@\u0026#8203;5.0.19\n\n###\n[`v7.0.49`](https://redirect.github.com/vercel/ai/blob/HEAD/packages/ai/CHANGELOG.md#7049)\n\n[Compare\nSource](https://redirect.github.com/vercel/ai/compare/ai@7.0.48...ai@7.0.49)\n\n##### Patch Changes\n\n- Updated dependencies\n\\[[`fb6d2f8`](https://redirect.github.com/vercel/ai/commit/fb6d2f8)]\n-\n[@\u0026#8203;ai-sdk/gateway](https://redirect.github.com/ai-sdk/gateway)@\u0026#8203;4.0.38\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eprivatenumber/tsx (tsx)\u003c/summary\u003e\n\n###\n[`v4.23.11`](https://redirect.github.com/privatenumber/tsx/compare/v4.23.10...bd3bc6448e957c1172eb91a0584ec7fec2d6a7ad)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.10...v4.23.11)\n\n###\n[`v4.23.10`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.23.10)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.9...v4.23.10)\n\n##### Bug Fixes\n\n- support nyc coverage discovery\n([#\u0026#8203;710](https://redirect.github.com/privatenumber/tsx/issues/710))\n([ec1bcd5](https://redirect.github.com/privatenumber/tsx/commit/ec1bcd5f711e5159b67cb0aea211f06cf2cfce8a))\n\n***\n\nThis release is also available on:\n\n- [npm package (@\u0026#8203;latest\ndist-tag)](https://www.npmjs.com/package/tsx/v/4.23.10)\n\n###\n[`v4.23.9`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.23.9)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.8...v4.23.9)\n\n##### Bug Fixes\n\n- map Node test locations\n([2f55884](https://redirect.github.com/privatenumber/tsx/commit/2f55884195a8c745fbe64a0288de69bc062ed876))\n- support data URLs in tsImport\n([b94f46f](https://redirect.github.com/privatenumber/tsx/commit/b94f46f6b6a7e6dc575624b0ecc7124318723056))\n\n***\n\nThis release is also available on:\n\n- [npm package (@\u0026#8203;latest\ndist-tag)](https://www.npmjs.com/package/tsx/v/4.23.9)\n\n###\n[`v4.23.8`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.23.8)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.7...v4.23.8)\n\n##### Bug Fixes\n\n- preserve package subpath resolution\n([be1315e](https://redirect.github.com/privatenumber/tsx/commit/be1315e3f31835f010fd75689b60a8ef9d7c4c88))\n- preserve typeless ESM dependency exports\n([70dfc5e](https://redirect.github.com/privatenumber/tsx/commit/70dfc5e3db899f93701823f2ba9c0579269d0015))\n\n***\n\nThis release is also available on:\n\n- [npm package (@\u0026#8203;latest\ndist-tag)](https://www.npmjs.com/package/tsx/v/4.23.8)\n\n###\n[`v4.23.7`](https://redirect.github.com/privatenumber/tsx/releases/tag/v4.23.7)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.6...v4.23.7)\n\n##### Bug Fixes\n\n- prevent tsImport cache collisions\n([4e5a138](https://redirect.github.com/privatenumber/tsx/commit/4e5a1387ac16570432d16ef41efd8904d38e660d))\n\n***\n\nThis release is also available on:\n\n- [npm package (@\u0026#8203;latest\ndist-tag)](https://www.npmjs.com/package/tsx/v/4.23.7)\n\n###\n[`v4.23.6`](https://redirect.github.com/privatenumber/tsx/compare/v4.23.5...205868f95334d87b398e0bc2eda5792b78e2fbd2)\n\n[Compare\nSource](https://redirect.github.com/privatenumber/tsx/compare/v4.23.5...v4.23.6)\n\n\u003c/details\u003e\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n👻 **Immortal**: This PR will be recreated if closed unmerged. Get\n[config\nhelp](https://redirect.github.com/renovatebot/renovate/discussions) if\nthat\u0027s undesired.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\n---------\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "306944a3ecc3466cc514cd0d8c1f8711d0f4dbe0",
      "tree": "4521d24aea30de1a67fd95909bbd2c37ecfaf7f8",
      "parents": [
        "97cb8cf699e676e7d9ee1ca643da58d0b3bc8b84"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 18:17:13 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:17:13 2026 +0000"
      },
      "message": "test(frontend): drive the virtual-environment socket (#7480)\n\n### What changes were proposed in this PR?\n\nThe PVE block is the largest uncovered region in this component, and the\nexisting suite stops exactly at its seams: it stubs `runPveWebSocket`\nand `deleteUserPackages` so it can assert name validation without\nopening a socket. These drive the other side of those seams.\n\nAdds 9 tests using a stand-in `WebSocket`, so `onmessage` and `onerror`\ncan be fired by hand. Covered: the socket opening and locking the card,\nthe name being trimmed before it reaches the URL, server lines appending\nto the pip output, the `__DONE__` sentinel closing the socket and\nclearing installing without printing itself, a dropped connection\nsurfacing as output rather than a hang, a still-open socket being closed\nbefore another starts, and the create path chaining delete-then-install.\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| name not trimmed for the socket URL | red |\n| previous socket left open | red |\n| card not locked while installing | red |\n| sentinel not recognised | red |\n| done leaves installing set | red |\n| done does not close the socket | red |\n| done skips the continuation | red |\n| error not surfaced in the output | red |\n| error leaves the card installing | red |\n\nThe \"done leaves installing set\" mutation **survived a first pass**, and\nthe reason is worth recording: the test let the real delete/install\ncontinuation run, which resets `isInstalling` downstream — so it was\nobserving the continuation\u0027s state, not the sentinel branch\u0027s. Stubbing\nthe continuation is what makes the test discriminate, and that is\ncommented in the spec.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7477\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/computing-unit-selection.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  109 passed (109)\n```\n\n9 new on top of the existing 100. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "97cb8cf699e676e7d9ee1ca643da58d0b3bc8b84",
      "tree": "c68142203664b8dedefbbddbc449e3bdcd55e51a",
      "parents": [
        "ca41bdd0cd1c99a164868afe6b0dce2d4c502105"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 18:16:43 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:16:43 2026 +0000"
      },
      "message": "test(frontend): render the quota page\u0027s result cache tab (#7437)\n\n### What changes were proposed in this PR?\n\nThe quota page\u0027s Result Cache tab is never rendered by its spec, which\ndrives the quota data and its charts only.\n\nAdds 5 tests. The reported cache size is the centrepiece:\n\n```html\n{{ formatSize(execution.resultBytes + execution.logBytes + execution.runTimeStatsBytes) }}\n```\n\nThree separate byte counts added together. A dropped or double-counted\nterm still produces a plausible-looking size and nothing else in the\nsuite would notice, so the fixture uses distinct powers of two — any\nsuch slip lands on a different total rather than coincidentally\nmatching.\n\nAlso covered: one collapse panel per workflow headed by its name, the\nexecutions listed under the opened workflow, the delete button carrying\nthe row\u0027s **execution** id rather than the workflow id, and the table\npaging rather than listing everything.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| cache size drops `logBytes` | red |\n| cache size drops runtime statistics | red |\n| cache size double-counts `resultBytes` | red |\n| delete passes the workflow id | red |\n| panel header shows the id | red |\n| execution-id column shows the name | red |\n| pagination widened | red |\n| rows read the raw list instead of the page | red |\n\n`ngOnInit` resets `workflows`, so the first change-detection cycle runs\nbefore the fixture data is assigned; that is commented in the spec.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7434\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/user-quota.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  16 passed (16)\n```\n\n5 new on top of the existing 11. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nSigned-off-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "ca41bdd0cd1c99a164868afe6b0dce2d4c502105",
      "tree": "922c0359399a05a465fc7cabf6a4256ddca6d5dd",
      "parents": [
        "bbd5c976d7512f796251e5d5a8ca1495e5b3756f"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 18:16:23 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 01:16:23 2026 +0000"
      },
      "message": "test(amber): pin the dataset search\u0027s access-control branches (#7479)\n\n### What changes were proposed in this PR?\n\nEvery member of `DatasetSearchQueryBuilder` is `override protected`, so\nnothing is directly callable. The one public route in is the trait\u0027s\n`final constructQuery`, and what it returns can be rendered to SQL and\ninspected without ever executing it.\n\nThat reaches the part of the file with real consequences: **which\ndatasets a caller is allowed to see.**\n\nAdds 9 tests. The one that matters most is the grant join\u0027s scoping\npredicate — without `.eq(uid)` the `UID.isNotNull` check below is\nsatisfied by any user\u0027s grant row, which hands the caller every shared\ndataset in the system. An anonymous caller must see public datasets only\nand match no grant row at all; a private-only search must not leak\npublic datasets in.\n\nAlso covers the keyword split, `selectDistinct` being the sole dedup\n(this builder alone has no `GROUP BY`, so the DISTINCT is all that\ncollapses the rows the access join multiplies out), and the `\u0027dataset\u0027`\nliteral that `DashboardResource` dispatches on with no default branch.\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| grant join not scoped to the caller | red |\n| anonymous caller matches any grant row | red |\n| anonymous arm drops the public restriction | red |\n| private-only search leaks public datasets | red |\n| `includePublic` arm narrowed to public only | red |\n| keyword splitting removed | red |\n| a `GROUP BY` is introduced | red |\n| resource type mis-tagged | red |\n\n`toEntryImpl` is deliberately left uncovered — it is ~80% of this file\u0027s\nuncovered lines and sits behind a live LakeFS call with no mockable\nseam, so reaching it would need a source change rather than a test. That\nis stated in the spec\u0027s header so the next reader does not re-derive it.\n\n`MockTexeraDB` is initialized only because `SearchQueryBuilder.context`\nreads `SqlServer.getInstance()`; no query is run against the database.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7476\n\n### How was this PR tested?\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.web.resource.dashboard.DatasetSearchQueryBuilderSpec\"\n```\n\n```\n[info] Tests: succeeded 9, failed 0, canceled 0, ignored 0, pending 0\n[info] All tests passed.\n```\n\n`Test/scalafmtCheck` and `Test/scalafix --check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "bbd5c976d7512f796251e5d5a8ca1495e5b3756f",
      "tree": "fdddf5ff91549133617b37b8647f2fd8535e1ecc",
      "parents": [
        "6790bf1765cae3a1881bc16607a5966dec3107f0"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 17:59:23 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 00:59:23 2026 +0000"
      },
      "message": "test(frontend): render the error frame\u0027s grouping and operator jump (#7442)\n\n### What changes were proposed in this PR?\n\nThe suite builds the category map and never renders it, so everything\nthe template decides was unpinned.\n\nAdds 10 tests. The one with real teeth is the jump-to-operator shortcut,\nguarded by two conditions: it is withheld for the `unknown operator`\nsentinel, which would navigate the canvas to nothing, and for the\noperator already being shown, where it would be a no-op. Its click also\nstops propagation — the icon sits in the collapse header and would\notherwise toggle the panel underneath the user.\n\nAlso covers the all-operators banner appearing only for an unscoped\nframe, the empty state appearing only when there is nothing to report,\nthe grouping into category headings, and the message heading the panel\nwith the details in its body.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| show the all-operators banner always | red |\n| show the empty state always | red |\n| head the category with its size instead of its name | red |\n| head the panel with the details | red |\n| put the message in the body | red |\n| offer the jump for the unknown-operator sentinel | red |\n| offer the jump for the operator already shown | red |\n| jump to the frame\u0027s operator instead of the error\u0027s | red |\n| drop `stopPropagation` from the jump | red |\n\nThe empty-state mutation **survived its first run**: the test asserted\nthe message appears with no errors but never that it disappears once\nthere are some. It now checks both directions.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7439\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/error-frame.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  17 passed (17)\n```\n\n10 new on top of the existing 7. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nSigned-off-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "6790bf1765cae3a1881bc16607a5966dec3107f0",
      "tree": "eff1f2445f3612d1ba52156b9b0cbc7b303d4b3e",
      "parents": [
        "5482f7769bd9706440c9c027a60ea89e82f270af"
      ],
      "author": {
        "name": "Mend Renovate",
        "email": "bot@renovateapp.com",
        "time": "Mon Aug 10 01:35:47 2026 +0100"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 00:35:47 2026 +0000"
      },
      "message": "chore(deps, pyright-language-service): update dependency ws to v8.21.3 (#7483)\n\nThis PR contains the following updates:\n\n| Package | Change |\n[Age](https://docs.renovatebot.com/merge-confidence/) |\n[Confidence](https://docs.renovatebot.com/merge-confidence/) |\n|---|---|---|---|\n| [ws](https://redirect.github.com/websockets/ws) | [`8.21.1` →\n`8.21.3`](https://renovatebot.com/diffs/npm/ws/8.21.1/8.21.3) |\n![age](https://developer.mend.io/api/mc/badges/age/npm/ws/8.21.3?slim\u003dtrue)\n|\n![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/ws/8.21.1/8.21.3?slim\u003dtrue)\n|\n\n---\n\n\u003e [!WARNING]\n\u003e Some dependencies could not be looked up. Check the [Dependency\nDashboard](../issues/6912) for more information.\n\n---\n\n### Release Notes\n\n\u003cdetails\u003e\n\u003csummary\u003ewebsockets/ws (ws)\u003c/summary\u003e\n\n###\n[`v8.21.3`](https://redirect.github.com/websockets/ws/releases/tag/8.21.3)\n\n[Compare\nSource](https://redirect.github.com/websockets/ws/compare/8.21.2...8.21.3)\n\n### Bug fixes\n\n- The server now correctly rejects permessage-deflate offers if the\nincoming\n`client_max_window_bits` parameter value is smaller than its configured\n`clientMaxWindowBits`\n([`e97a20e`](https://redirect.github.com/websockets/ws/commit/e97a20ea)).\n\n###\n[`v8.21.2`](https://redirect.github.com/websockets/ws/releases/tag/8.21.2)\n\n[Compare\nSource](https://redirect.github.com/websockets/ws/compare/8.21.1...8.21.2)\n\n##### Bug fixes\n\n- Fixed a test for [CITGM][]\n([`2eb3be0`](https://redirect.github.com/websockets/ws/commit/2eb3be0b)).\n\n[CITGM]: https://redirect.github.com/nodejs/citgm\n\n\u003c/details\u003e\n\n---\n\n### Configuration\n\n📅 **Schedule**: (in timezone Etc/UTC)\n\n- Branch creation\n  - \"before 8am on monday\"\n- Automerge\n  - At any time (no schedule defined)\n\n🚦 **Automerge**: Disabled by config. Please merge this manually once you\nare satisfied.\n\n♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the\nrebase/retry checkbox.\n\n🔕 **Ignore**: Close this PR and you won\u0027t be reminded about this update\nagain.\n\n---\n\n- [ ] \u003c!-- rebase-check --\u003eIf you want to rebase/retry this PR, check\nthis box\n\n---\n\nThis PR was generated by [Mend Renovate](https://mend.io/renovate/).\nView the [repository job\nlog](https://developer.mend.io/github/apache/texera).\n\n\u003c!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19--\u003e\n\nCo-authored-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e"
    },
    {
      "commit": "5482f7769bd9706440c9c027a60ea89e82f270af",
      "tree": "9ab45f1bc34b0b125c3c854ab9b79b751183b102",
      "parents": [
        "5914ae077fee211ba89af55ac7fea86bde2e0b72"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 17:33:16 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 00:33:16 2026 +0000"
      },
      "message": "test(frontend): cover the link-breakpoint handlers in the workflow editor (#7481)\n\n### What changes were proposed in this PR?\n\n`handleLinkBreakpoint()` and the four handlers it installs have never\nrun in any test. The guard at\n`workflow-editor.component.ts:202` needs `linkBreakpointEnabled` **and**\n`getHighlightingEnabled()`,\nand both default to false under test — `MockGuiConfigService` for the\nfirst, `WorkflowActionService`\u0027s\nprivate field for the second. `gui.conf` ships `link-breakpoint-enabled\n\u003d true`, so the block is a\nshipped feature with no coverage rather than dead code.\n\nAdds 5 tests in a new `describe` that sets both flags before the first\nchange-detection cycle\n(`ngAfterViewInit` reads them once, when it decides whether to install\nthe handlers at all) and then\ndrives the handlers through the paper:\n\n| Test | What it pins |\n|---|---|\n| tool attached, hidden | a new link gets a breakpoint tool, and it\nstays out of sight until wanted |\n| breakpoint click highlights | clicking the button highlights that link\n|\n| shift-click unhighlights | a second shift-click removes an\nalready-selected link |\n| shift reaches multi-select | the modifier is carried into multi-select\nmode |\n| show/hide streams | both streams reach the link view, in that order |\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| tool never attached | red |\n| tool left visible | red |\n| shift not carried into multi-select | red |\n| re-highlights instead of unhighlighting | red |\n| show/hide streams swapped | red |\n| breakpoint handlers never installed | red |\n\nTwo of these needed the test strengthened before they died:\n\n- **show/hide swapped** initially survived — wiring each handler to the\nother\u0027s stream still calls\n`showTools` and `hideTools` once each. The test now asserts call order.\n- **shift not carried into multi-select** is routed through the\nunhighlight branch on purpose.\n`WorkflowActionService.highlightLinks` sets multi-select itself, so on\nthe highlight branch the\nhandler\u0027s own `setMultiSelectMode` is unobservable; `unhighlightLinks`\ndoes not touch it.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7478\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/workflow-editor.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  62 passed (62)\n```\n\n5 new on top of the existing 57. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "5914ae077fee211ba89af55ac7fea86bde2e0b72",
      "tree": "aa156466a2ac967097db9d64011e0e4d32cb15df",
      "parents": [
        "ae3ad45c45712e22625a5e30516cc1a31df8c5de"
      ],
      "author": {
        "name": "Kary Zheng",
        "email": "150742834+kz930@users.noreply.github.com",
        "time": "Sun Aug 09 17:11:54 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 10 00:11:54 2026 +0000"
      },
      "message": "feat(workflow-operator): stop forcing a color column on every Bubble Chart (#7396)\n\n### What changes were proposed in this PR?\n\nBubble Chart\u0027s Color-Column was declared `required \u003d true` with\n`@NotNull`, but the generated Python reads it only inside the Enable\nColor branch. The effect was that a freshly dropped Bubble Chart stayed\ninvalid until the user picked a color column, even when they wanted\nplain bubbles — and the column they picked was then never used.\n\nThis PR makes the field optional and puts it behind the toggle via\n`toggleHidden`, so it disappears from the panel when Enable Color is\noff. That matches Ternary Plot, which has the same toggle-plus-column\npair and already declares its color field optional.\n\nThe color decision also moves out of the generated Python and into\nScala. The old template emitted an `if \u0027...\u0027 \u003d\u003d \u0027true\u0027:` comparison over\na Scala Boolean; it is now a `colorArg` computed at build time, guarded\non both the toggle and the column being non-empty. That second half\nmatters: with the required flag gone, an empty column would otherwise\nreach `px.scatter(color\u003d\u0027\u0027)`, which plotly rejects — the same failure\nfixed for Bar Chart in #6792.\n\nBehavior for existing workflows is unchanged. `enableColor` keeps its\nmeaning, so no saved chart changes appearance.\n\nThe operator reference page is updated to match the new requirement and\ndescription.\n\n### Any related issues, documentation, discussions?\n\nCloses #7395\n\n### How was this PR tested?\n\nExisting `BubbleChartOpDescSpec` passes unchanged, including the\nassertion that pins the no-color output line. Three cases were added to\nit, covering the toggle-and-column matrix: enabled with a column chosen\n(color is emitted), enabled with no column (color is omitted rather than\nemitted empty), and disabled with a column chosen (the column is not\nemitted).\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)\n\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e"
    },
    {
      "commit": "ae3ad45c45712e22625a5e30516cc1a31df8c5de",
      "tree": "43828dce3aba686110a7a089bbca0daf1e3072d8",
      "parents": [
        "08a2eac8eb7151eaac33b18cd8a47a20599e5fa7"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 16:57:35 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:57:35 2026 +0000"
      },
      "message": "test(frontend): render the dataset list item\u0027s permission gates (#7443)\n\n### What changes were proposed in this PR?\n\nWhether this row offers any editing is decided in the template by\n**two** conditions, not one:\n\n```html\n*ngIf\u003d\"editable \u0026\u0026 entry.accessPrivilege \u003d\u003d\u003d \u0027WRITE\u0027\"\n```\n\nThe list being editable is not on its own permission to change someone\nelse\u0027s dataset. The existing suite exercises the component\u0027s methods and\nnever renders, so neither condition was pinned.\n\nAdds 8 tests covering both halves independently — a reader on an\neditable list gets no rename or add-description control, and neither\ndoes a writer on a non-editable list — plus the same pair guarding the\ninline description, the owner and shared-access markers being mutually\nexclusive, the shared marker naming the privilege held, and the rename\ninput being seeded from the dataset\u0027s name.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| rename gate drops the WRITE check | red |\n| rename gate drops the editable check | red |\n| description gate drops the WRITE check | red |\n| inline description gate drops the WRITE check | red |\n| show the owner marker to everyone | red |\n| show the shared marker to the owner too | red |\n| invert the name / edit-input branch | red |\n| seed the rename input from the description | red |\n\nTesting both halves separately is the point: dropping either condition\nalone still leaves a single-condition test passing.\n\nThe shared-marker mutation **survived its first run** — the owner test\nasserted its own marker was present but not that the shared one was\nabsent. It is now exclusive.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7440\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/user-dataset-list-item.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  28 passed (28)\n```\n\n8 new on top of the existing 20. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "08a2eac8eb7151eaac33b18cd8a47a20599e5fa7",
      "tree": "bd1e834defe396dea7bb7387504f547c0886de7d",
      "parents": [
        "12eaccbb24884fccf1dba26d15fff7ceb1db4aba"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 16:49:50 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:49:50 2026 +0000"
      },
      "message": "test(amber): cover ExecutionConsoleService\u0027s console routing and debug commands (#7441)\n\n### What changes were proposed in this PR?\n\nThe suite covered the `ConsoleMessageProcessor` object; the service\nclass around it was untouched. That class owns the console diff the\nfrontend is driven from, the worker-to-operator keying that decides\nwhere a message lands, and the websocket handler behind the debugger.\n\nConverts the spec to a TestKit suite and adds 8 tests:\n\n- a **debugger** message is never truncated, while an ordinary one still\nis — the debugger\u0027s output is the frame the user asked to see\n- the diff reports **only messages added since the last state**; the\nfrontend appends what it is sent, so emitting the whole buffer would\nduplicate every earlier line on each update\n- a console message is filed under the **logical** operator id — the\nworker id carries the physical layer and worker index, and anything else\nstrands the output where the frontend will not look for it\n- a debug command is attributed to `USER-\u003cuid\u003e`, falls back to\n`USER-UNKNOWN` with no session user, is filed under the operator rather\nthan the worker, and is forwarded to the coordinator with the worker it\nnames\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| truncate debugger messages too | red |\n| send the whole console buffer instead of the diff | red |\n| file the message under the physical op id | red |\n| file the message under the raw worker id | red |\n| attribute every debug command to a constant | red |\n| file the debug command under the worker | red |\n| forward the wrong id to the coordinator | red |\n| drop the command from the message title | red |\n\nEverything runs on an empty-plan `AmberClient` with a mocked\ncoordinator: no engine, database or Iceberg storage. The Iceberg-backed\nwriter path (`getOrCreateWriter` and the execution-state commit loop) is\n`private` and storage-bound; it is left uncovered rather than padded\nwith a no-throw test, and the spec says so.\n\nOne note recorded in the spec: the console store\u0027s event observable\nreplays on subscribe, so the diff test subscribes first and asserts on\nthe batch published for the second message.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7438\n\n### How was this PR tested?\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.web.service.ExecutionConsoleServiceSpec\"\n```\n\n```\n[info] Tests: succeeded 13, failed 0, canceled 0, ignored 0, pending 0\n[info] All tests passed.\n```\n\n8 new on top of the existing 5. `Test/scalafmtCheck` and `Test/scalafix\n--check` both pass.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nSigned-off-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "12eaccbb24884fccf1dba26d15fff7ceb1db4aba",
      "tree": "fe2cbe912d091d7fc3f0fada60d3643ee182ef78",
      "parents": [
        "ab4d25eb16fdd4b1b4ac74a890ea3eaba62b5e0a"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Sun Aug 09 16:13:23 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:13:23 2026 +0000"
      },
      "message": "test(amber): add unit test coverage for CoordinatorTimerService (#7312)\n\n### What changes were proposed in this PR?\n\nAdds `CoordinatorTimerServiceSpec` (new, 13 tests) for\n`amber/src/main/scala/org/apache/texera/amber/engine/architecture/coordinator/CoordinatorTimerService.scala`,\nwhich had no spec.\n\nNo production code is changed.\n\nThe spec substitutes a `PekkoActorService` that records\n`sendToSelfWithFixedDelay` requests instead of registering real\nrepeating timers, and returns a fresh recording `Cancellable` per call.\nA real `ActorContext` comes from a minimal Pekko TestKit actor, since\n`PekkoActorService` dereferences `self`/`dispatcher` eagerly and there\nis no Mockito in the amber test tree. Every timing decision the class\nmakes is taken synchronously at the `enable`/`disable` call, so the\nsuite needs no real timers and no sleeps.\n\nCovered:\n\n- **Scheduling decision** — an unconfigured interval schedules nothing;\na configured one schedules exactly once with initial delay 0, the\nconfigured period, and a `ControlInvocation` of\n`METHOD_COORDINATOR_INITIATE_QUERY_STATISTICS` carrying\n`QueryStatisticsRequest(Seq.empty, target)` and `AsyncRPCContext(SELF,\nSELF)`.\n- **The two entry points do not cross** — `enableStatusUpdate` uses\n`statusUpdateIntervalMs` with `UI_ONLY`,\n`enableRuntimeStatisticsCollection` uses\n`runtimeStatisticsPersistenceIntervalMs` with `PERSISTENCE_ONLY`,\nasserted separately and with distinct intervals; an asymmetric config\n(only one interval set) leaves the other timer unscheduled.\n- **Idempotence** — a second `enable` while the timer runs adds no\nschedule and keeps the same `Cancellable` instance.\n- **Disable** — cancels the handle and resets it to `None`, including\nwhen `cancel()` returns `false` (the return value is discarded by\n`disableTimer`); a second disable and a disable of a never-enabled timer\nare both no-ops.\n- **Restart and lifecycle** — a disabled timer can be enabled again, for\nboth timers; a full pause-resume cycle re-schedules both with their own\ntarget and interval.\n- **Independence** — disabling one timer leaves the other\u0027s handle\ninstalled and un-cancelled, in both directions.\n\n### Any related issues, documentation, discussions?\n\nCloses #7311.\n\n### How was this PR tested?\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.coordinator.CoordinatorTimerServiceSpec\"\n# 13 tests, all passed (~0.6 s)\n\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.amber.engine.architecture.coordinator.*\"\n# 18 suites, 146 tests, all passed — the new top-level test helpers do not clash with the neighboring specs\n\nsbt \"WorkflowExecutionService/Test/scalafmtCheck\"\n# 173 sources, clean\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nCo-authored by: Claude Code (Fable 5)"
    },
    {
      "commit": "ab4d25eb16fdd4b1b4ac74a890ea3eaba62b5e0a",
      "tree": "a0ca74b61137f136fac30669c525656ed14487df",
      "parents": [
        "dafccec7990fb3aec6b2b07b919051eccc115176"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 16:09:34 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:09:34 2026 +0000"
      },
      "message": "test(frontend): cover HuggingFaceImageUploadComponent template preview and error states (#7470)\n\n### What changes were proposed in this PR?\n\nExtends `HuggingFaceImageUploadComponent`\u0027s spec to render the template.\nThe\nclass file is already at 100%, but the existing tests only drive the\nhandlers\ndirectly, so the preview panel never rendered and\n`hugging-face-image-upload.component.html` sat at ~32%.\n\n7 added tests render the component and assert on the DOM:\n\n- No preview panel while no image is selected.\n- The preview `\u003cimg\u003e` is bound to the stored data URL (`src`, `alt`).\n- The panel\u0027s label falls back to `\"Uploaded image\"` when no file name\nis known, and shows the selected file name once one is.\n- The **Clear** button clears the control and removes the panel.\n- The error block renders the current `errorMessage`.\n- A `change` event with no file selected leaves the control untouched —\nthis also covers the file input\u0027s `(change)` binding while staying fully\nsynchronous (the guard returns before any `FileReader`/canvas work).\n\nThis lifts the template from **~32% to 100% statements**. Branches land\nat 50%,\nwhich is the maximum reachable — see below.\n\n**The `\"Selected image\"` fallback is unreachable.** The issue asks for a\ntest\nwhere `displayFileName` is empty so `{{ displayFileName || \"Selected\nimage\" }}`\nrenders the fallback, but that state cannot occur:\n\n- the panel only renders when `previewSrc` is truthy, which requires\n`hasImage`;\n- `displayFileName` returns `fileName` when set, otherwise `\"Uploaded\nimage\"` when `hasImage` — so with `hasImage` true it is never empty.\n\nSo whenever the fallback could be shown, the left-hand side is already\ntruthy. I\ndid not force it with a fabricated getter override, since that would\nassert a\nstate the component cannot reach. If desired, the template could simply\nbecome\n`{{ displayFileName }}` in a follow-up — left out here because this\nchange is\ntest-only.\n\n**Determinism:** no fake timers and no async image pipeline in the added\ntests\n(the no-file `change` path returns synchronously); no layout/geometry\nassertions.\nNo production code was changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7467\n\n### How was this PR tested?\n\nExtended unit tests, run locally in `frontend/`:\n\n```\nng test --watch\u003dfalse --include src/app/workspace/component/hugging-face-image-upload/hugging-face-image-upload.component.spec.ts\n# Test Files 1 passed (1) | Tests 42 passed (42)   — 3 consecutive runs, 0 flakes\n# hugging-face-image-upload.component.html: ~32% -\u003e 100% statements\nprettier --write \u003cspec\u003e   # formatted\neslint  \u003cspec\u003e            # clean\n```\n\nThe failure path was verified by deliberately breaking a new assertion\nand\nconfirming the suite exits non-zero.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "dafccec7990fb3aec6b2b07b919051eccc115176",
      "tree": "514b8e8756f136fc6c6719780fa266a8b6c3f3c5",
      "parents": [
        "f00b4ca9a8fa52bd7892b3f50619e2bfffb80936"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 16:09:25 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:09:25 2026 +0000"
      },
      "message": "test(frontend): extend DatasetFileSelectorComponent template coverage (#7472)\n\n### What changes were proposed in this PR?\n\nThe existing tests call `onClickOpenFileSelectionModal` directly, so the\ntemplate\nhad never been rendered — it sat at 1/10 statements. Adds 6 tests that\nrender it in\neach state it switches on, taking `dataset-file-selector.component.html`\nto 10/10\nwith no uncovered branches (and the class to 16/16, its last branch\nbeing the\ncomponent\u0027s own instantiation).\n\n- **enabled, with a path** — the path is shown and the Select File\nbutton is offered.\n- **enabled, no path yet** — the input is withheld until there is\nsomething to show;\n  only the button renders.\n- **disabled** — no picker to write the path, so the empty input is\nshown instead and\n  the button is gone.\n- **the button** — clicking it opens the selection modal; triggering it\nwhile the flag\nis off does not, which is what the handler\u0027s own `isFileSelectionEnabled\n\u0026\u0026` guard is\nfor (the `*ngIf` normally removes the button, so the test disables the\nflag without\n  re-rendering to reach that guard).\n\nThe GUI-config double moved from an inline provider literal to a\nvariable so a test\ncan flip `selectingFilesFromDatasetsEnabled`; its default is unchanged.\nNo production\ncode was changed.\n\n**One test pins a defect rather than the intent.**\n`[readOnly]\u003d\"isFileSelectionEnabled\"`\ndoes not make the input read-only: the camelCase name misses\n`NzInputDirective`\u0027s\n`readonly` input, so it lands on the DOM property, and the directive\u0027s\n`[attr.readonly]\u003d\"readonly() || null\"` host binding then clears the\nattribute and\nresets the property. Verified both ways locally — with `[readOnly]` the\nrendered input\nreports `readOnly: false, attr: null`; renaming it to `[readonly]` gives\n`readOnly: true, attr: true`. So the path the picker is meant to own can\ncurrently be\ntyped over. The test asserts the real behaviour with a comment saying\nwhat to flip when\nthe one-word fix lands; the fix itself is a production change and out of\nscope for a\ncoverage PR.\n\n### Any related issues, documentation, discussions?\n\nCloses #7466.\n\n### How was this PR tested?\n\n`ng test --watch\u003dfalse --include\nsrc/app/workspace/component/dataset-file-selector/dataset-file-selector.component.spec.ts`\n— 11 passed (5 existing + 6 new), run 3x for determinism. Coverage\n(`--coverage`)\nconfirms `dataset-file-selector.component.html` at 10/10 statements with\nno uncovered\nbranches. The failure path was verified by breaking an assertion (red,\nnon-zero exit);\neslint and prettier are clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "f00b4ca9a8fa52bd7892b3f50619e2bfffb80936",
      "tree": "6fff75b763440e92a949a62fa63c1202981c0ef0",
      "parents": [
        "3ef7a52b65544cd61b79f9521d3e34191ca4a7cf"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 16:09:15 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:09:15 2026 +0000"
      },
      "message": "test(frontend): extend TimeTravelComponent template coverage (#7471)\n\n### What changes were proposed in this PR?\n\nExtends `time-travel.component.spec.ts` to render the execution table.\nThe class\nwas already ~92% covered but the template sat at ~42% — the existing\ntests call\nthe class methods directly and never render a row. Adds 6 DOM-driven\ntests:\n\n- **Rows** — one `\u003ctr\u003e` per execution with its eid cell and a\nstarting-time cell;\n  no execution rows when the list is empty.\n- **Expand / collapse** — clicking a row expands the `*ngIf` detail row\nand a\n  second click collapses it.\n- **Interaction list** — the expanded row renders one button per entry\nof\n  `interactionHistories[eId]` with its label.\n- **Click wiring** — an interaction button passes the row\u0027s `vId`/`eId`\nand the\n  interaction to `onInteractionClick`.\n- **Disabled binding** — only the interaction already reverted to is\ndisabled.\n\nThis takes the template from 8/19 to **19/19 instrumented lines\n(100%)**.\n\nPer the issue\u0027s determinism note the starting-time cell is rendered but\nits\nformatted text is not asserted (it is timezone-dependent); the test only\nchecks\nthe pipe produced output. Execution rows are counted by their two data\ncells\nrather than a raw `tbody tr` count, so the nz-table empty placeholder\nand the\ncolspan detail row don\u0027t skew the count. No production code was changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7468.\n\n### How was this PR tested?\n\n`ng test --watch\u003dfalse --include\nsrc/app/workspace/component/left-panel/time-travel/time-travel.component.spec.ts`\n— 18 passed (12 existing + 6 new). Template coverage confirmed at 19/19\nlines via the lcov report. `eslint` and `prettier --check` clean.\nFailure path verified by breaking a new assertion (→ non-zero exit) and\nrestoring.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "3ef7a52b65544cd61b79f9521d3e34191ca4a7cf",
      "tree": "e9a24fb21f59eb813a561ab07156a5db6f8a3217",
      "parents": [
        "114a6100b53c1191a77b23b9b11221fd6607fef1"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 16:06:38 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 23:06:38 2026 +0000"
      },
      "message": "test(frontend): render the TypeCastingDisplay schema table for coverage (#7469)\n\n### What changes were proposed in this PR?\n\nExtends the existing `TypeCastingDisplayComponent` spec so the schema\ntable\nactually renders, covering the template that was previously never\nexecuted\n\n(`frontend/src/app/workspace/component/property-editor/typecasting-display/type-casting-display.component.html`).\nNo production code was changed.\n\n4 tests cover every branch of the template:\n\n- the outer `*ngIf` — no `nz-table` is rendered while the type-casting\n  information is hidden;\n- the header cells (`Attribute Name` / `Attribute Type`);\n- the table\u0027s no-data arm for an empty schema;\n- the `*ngFor` row — one row per attribute, asserting each row\u0027s name\nand type\ncell text against the seeded schema (mixed `long` / `string` /\n`double`).\n\nOne note on the empty-schema case: `nz-table` renders a single\nplaceholder row\nrather than no rows at all. The test asserts the *shape* of that arm\n(one row\nwith one spanning cell) instead of the placeholder\u0027s text, which comes\nfrom the\nactive locale bundle and would make the assertion brittle.\n\nPer the usual constraints: no fake timers, and no layout or geometry\nassertions.\n\n### Any related issues, documentation, discussions?\n\nCloses #7465\n\n### How was this PR tested?\n\nExtended unit tests, run locally in `frontend/` (all green; the failure\npath was\nverified by breaking an assertion to confirm the suite goes red):\n\n```\nng test --watch\u003dfalse --include src/app/workspace/component/property-editor/typecasting-display/type-casting-display.component.spec.ts\n# Test Files 1 passed (1) | Tests 16 passed (16)\nprettier --write \u003cspec\u003e   # clean\neslint  \u003cspec\u003e            # clean\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "114a6100b53c1191a77b23b9b11221fd6607fef1",
      "tree": "427021645a92f8ccec0a914d6eca6eeb9d7c1e06",
      "parents": [
        "e30eb17518dec86b522a2715f6b73c431ed39097"
      ],
      "author": {
        "name": "Yicong Huang",
        "email": "17627829+Yicong-Huang@users.noreply.github.com",
        "time": "Sun Aug 09 09:40:04 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 16:40:04 2026 +0000"
      },
      "message": "docs: define how to pick a PR title\u0027s type and scope (#7427)\n\n### What changes were proposed in this PR?\n\n`CONTRIBUTING.md` requires Conventional Commits but never says how to\npick the type or scope, so recurring cases get decided ad hoc. This\nwrites the convention down:\n\n- **Scope** names the module the change lands in (`amber`, `pyamber`,\n`frontend`, …), not an informal synonym; a cross-module PR is scoped to\nthe module carrying the substantive change.\n- **Type follows the behavior**, not the diff size:\n  - worked before, broken now → `fix`\n- adding or removing a functionality, or reworking one so that\nuser-facing behavior intentionally changes → `feat`\n  - leaves the user-facing behavior unchanged → `refactor`\n\nA `refactor` keeps user-facing API tests passing untouched; tests\nmirroring internals may be rewritten with the code. Behavior is defined\nby the code, so implementing something the docs claimed but never had is\na `feat`.\n- **Tests**: a test-only PR is `test(\u003cmodule\u003e)`; repairing a broken or\nflaky test is `fix(test, \u003cmodule\u003e)`.\n- **Dependencies**: `fix(deps, \u003cmodule\u003e)` when the bump patches a CVE,\n`chore(deps, \u003cmodule\u003e)` otherwise. GitHub Actions bumps take `ci` as\ntheir module (`chore(deps, ci)`); a bare `ci:` is for hand-written CI\nand workflow changes.\n- **Backports**: a release-branch PR appends the version as the last\nscope component, e.g. `fix(deps, frontend, v1.2): ...`.\n\nOn dependency bumps this documents what the automation already does\nrather than changing it: `.github/renovate.json5` types every routine\nbump as `chore(...)` and reserves `fix(...)` for `vulnerabilityAlerts`,\nand it opens GitHub Actions bumps as `chore(deps, ci)` where the docs\nsaid `ci:`. The old runtime-vs-toolchain wording governed only\nhand-written titles and disagreed with the bot on both counts; the docs\nnow follow it.\n\n### Any related issues, documentation, discussions?\n\nCloses #7393\n\n### How was this PR tested?\n\n- Documentation only — no code path changes.\n- Verified the new title forms pass the CI type gate and the review-time\ntitle check, both on `main` and with a version scope on `release/v1.2`.\n- Cross-checked every rule against the automation that consumes titles:\n`.github/renovate.json5`, `backport-auto-label.yml`, and\n`direct-backport-push.yml`\u0027s title rewriter, which already emits the\ndocumented backport form.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)\n\n---------\n\nSigned-off-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e\nCo-authored-by: Claude Opus 5 (1M context) \u003cnoreply@anthropic.com\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "e30eb17518dec86b522a2715f6b73c431ed39097",
      "tree": "c6c91369acc0ac1628a2a57d61174b96fa70a84c",
      "parents": [
        "307dfc4cbaa66302caa1a9b254d6d5743deed4d4"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sun Aug 09 07:56:35 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 14:56:35 2026 +0000"
      },
      "message": "feat(storage): add the user_warehouse table schema (#7386)\n\n### What changes were proposed in this PR?\n\nAdds the `user_warehouse` table (umbrella #6870): one row per warehouse\na user registers. The DDL below is the full shape — base columns only;\nthe assume-role (BYO-S3) columns come in a later change.\n\n```sql\nCREATE TABLE IF NOT EXISTS user_warehouse\n(\n    whid                    SERIAL PRIMARY KEY,\n    uid                     INT          NOT NULL,\n    name                    VARCHAR(128) NOT NULL,\n    warehouse_name          VARCHAR(255) NOT NULL UNIQUE,\n    lakekeeper_warehouse_id UUID,\n    flavor                  VARCHAR(32)  NOT NULL,\n    s3_bucket               VARCHAR(255),\n    s3_endpoint             VARCHAR(255),\n    s3_region               VARCHAR(64),\n    created_at              TIMESTAMPTZ  NOT NULL DEFAULT now(),\n    UNIQUE (uid, name),\n    FOREIGN KEY (uid) REFERENCES \"user\" (uid) ON DELETE CASCADE\n);\n```\n\nSchema only — nothing reads or writes the table yet. The DDL, the\nincremental migration (`sql/updates/32.sql`), and the changelog\nregistration ship together; jOOQ classes are generated from the live\ndatabase at build time as usual.\n\n### Any related issues, documentation, discussions?\n\nCloses #6931. Part of #6870 (design discussions #5293 and #6040).\n\n### How was this PR tested?\n\nA new `UserWarehouseSpec` (MockTexeraDB, embedded Postgres) pins the\nDDL\u0027s structural properties against the generated jOOQ classes:\ninsert/read-back of a registered warehouse, the per-user name\nuniqueness, and the ownership cascade. Verified locally with `sbt\n\"DAO/testOnly *UserWarehouseSpec\"` plus scalafmt/scalafix; the cascade\ncase was deliberately broken once to confirm it fails red.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (claude-fable-5)"
    },
    {
      "commit": "307dfc4cbaa66302caa1a9b254d6d5743deed4d4",
      "tree": "006eadecef46cdb271d118026a2bc7564e206060",
      "parents": [
        "16463d53d587d3cdb5efc08671a4d34ef8ba212c"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 07:40:15 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 14:40:15 2026 +0000"
      },
      "message": "test(frontend): render the dataset explorer\u0027s toolbar and upload panel (#7435)\n\n### What changes were proposed in this PR?\n\nThe dataset explorer\u0027s toolbar and upload panel are template-only, and\nthe suite around them drives component state without asserting on what\nreaches the screen.\n\nAdds 14 tests. The download gating is the part that matters — both the\nper-file and whole-version downloads are guarded by `!isLogin ||\n!isDownloadAllowed()`, and each half is pinned separately, since being\nsigned in is not on its own permission to copy someone else\u0027s\nnon-downloadable dataset.\n\nAlso covered: exactly one of Maximize/Minimize showing, so the user\nalways has a way back; the copy-path control appearing only once a file\nis on screen; the file size and version creation time appearing only\nwhen known; and the upload panel reporting no statistics while\ninitializing, live speed and both timings while running, and a single\ntotal once finished or aborted.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| file download ignores `isLogin` | red |\n| file download ignores `isDownloadAllowed()` | red |\n| whole-version download ungated | red |\n| Maximize shown regardless of state | red |\n| Minimize shown regardless of state | red |\n| copy-path always offered | red |\n| file-size block always rendered | red |\n| creation-time row always rendered | red |\n| statistics shown while still initializing | red |\n| live figures kept after finishing | red |\n| total time shown only when finished, not when aborted | red |\n\nTwo structural notes are commented in the spec, since both cost a\ndebugging round:\n\n- `nz-tabs` only instantiates the active tab, and this toolbar lives in\nthe second one, so nothing in it exists until that tab is selected.\n- The upload panel is gated on the separate `activeUploads` counter\nrather than on `uploadTasks`, and ng-zorro collapses it by default.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7432\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/dataset-detail.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  129 passed (129)\n```\n\n14 new on top of the existing 115. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nSigned-off-by: Meng Wang \u003cmengw15@uci.edu\u003e\nCo-authored-by: Meng Wang \u003cmengw15@uci.edu\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "16463d53d587d3cdb5efc08671a4d34ef8ba212c",
      "tree": "d2ac26d134d809d6c1bb2ad2da1dbc1ac8ac7088",
      "parents": [
        "e03d97108ddd47befc78a87f467f781dd50a56e6"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 07:29:49 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 14:29:49 2026 +0000"
      },
      "message": "test(frontend): render the drag-and-drop repeat section\u0027s rows (#7436)\n\n### What changes were proposed in this PR?\n\nThe existing suite drives `onDrop` directly and never renders, so\neverything the template owns was unpinned.\n\nAdds 8 tests. The remove index is the one that matters: it comes from\nthe `ngFor` loop variable, and a fixed or off-by-one index deletes\nsomeone else\u0027s row while every row looks identical on screen. Also\ncovered: one row per entry, the drag handle, the add button\u0027s wiring,\nits label falling back to `\"Add\"`, and the add button locking for a\ndisabled section.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| remove uses a fixed index | red |\n| add button unwired | red |\n| add label ignores the field\u0027s own | red |\n| add label loses its default | red |\n| add button never disabled | red |\n| only the first row rendered | red |\n| drag handle removed | red |\n\nThe drag-handle test **survived its first mutation**: it asserted the\n`.drag-handle` class, which is styling and survives `cdkDragHandle`\nbeing dropped — leaving the row undraggable with the test still green.\nIt now asserts the directive.\n\n### A production bug this surfaced\n\nThe per-row remove button\u0027s `[disabled]` guard never takes effect. The\nrows are `*ngFor\u003d\"let field of field.fieldGroup\"`, which **shadows** the\ncomponent\u0027s `field`, so inside a row `field.templateOptions?.disabled`\nreads the sub-field\u0027s options and is always `undefined`. The add button,\noutside the loop, reads the same expression correctly and does disable.\n\nFiled as #7431. This PR deliberately asserts the add button\u0027s gating and\n**not** the remove buttons\u0027, so the current behaviour is not cemented\nbefore the fix.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7433\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/repeat-dnd.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  12 passed (12)\n```\n\n8 new on top of the existing 4. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "e03d97108ddd47befc78a87f467f781dd50a56e6",
      "tree": "695532d3be6c69bfe4b923e9dffd924bd6344ce1",
      "parents": [
        "fb1a5c4255f03e195e4ff36821d29acb71348071"
      ],
      "author": {
        "name": "Ghulam Mustafa",
        "email": "138971833+Musxeto@users.noreply.github.com",
        "time": "Sun Aug 09 16:26:22 2026 +0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 11:26:22 2026 +0000"
      },
      "message": "refactor(agent-service): remove unused targetOperatorId from toLogicalPlan (#7430)\n\n### What changes were proposed in this PR?\nIt Refactors `WorkflowState.toLogicalPlan()` by removing the unused\n`targetOperatorId` parameter.\n\nThe parameter was never referenced in the method (it always built the\nwhole-graph plan) and the only caller (`texera-agent.ts`) passed no\narguments to it. The need to fetch a sub-graph of a target is already\nproperly served by `getSubDAG(targetOperatorId)`.\n \n### Any related issues, documentation, discussions?\nCloses #7170\n\n### How was this PR tested?\nRun the TypeScript compiler checks and existing agent-service unit tests\nto verify no callers or types were broken.\n\n### Was this PR authored or co-authored using generative AI tooling?\nGenerated-by: Gemini 3.1 Pro (High)"
    },
    {
      "commit": "fb1a5c4255f03e195e4ff36821d29acb71348071",
      "tree": "6d9dd16b404bd915359e6f64d851e747d83db2ba",
      "parents": [
        "f9deb66dcccfb3b5994be659350021c2e0aa8e06"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 02:27:00 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 09:27:00 2026 +0000"
      },
      "message": "test(frontend): cover the debugger\u0027s breakpoint gutter (#7425)\n\n### What changes were proposed in this PR?\n\n`setupMonacoBreakpointMethods` was the component\u0027s one uncovered block.\nThe existing suite stubs it out — with a comment saying so — because the\nminimal editor mock cannot back a real `MonacoBreakpoint`, so neither of\nthe two overrides it installs was exercised.\n\nAdds 13 tests over both.\n\n**The glyph override** decides what the gutter shows:\n\n```\nexists \u0026\u0026 condition present   -\u003e  monaco-conditional-breakpoint\nexists \u0026\u0026 no condition        -\u003e  monaco-breakpoint\nhovering only                 -\u003e  monaco-hover-breakpoint\n```\n\nCovered including the `Boolean(condition?.trim())` guard — a condition\nleft as whitespace must render as an ordinary breakpoint rather than\nclaiming a condition the debugger will not apply — and the lookup\nhappening at `range.startLineNumber`, since reading `endLineNumber`\nwould attribute another line\u0027s condition to this glyph.\n\n**The mouse-down override** replaces the library\u0027s own handler. The\n`dispose()` before re-registering is load-bearing: two live handlers\nwould add and immediately remove a breakpoint on a single click. A left\nclick toggles; a right click opens the condition input instead of\ntoggling, and only for a line that already has a breakpoint; clicks\nbelow the last line and outside the gutter do nothing.\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| treat a blank condition as a condition | red |\n| read the condition from the range\u0027s end line | red |\n| key the condition lookup to a fixed operator | red |\n| swap the conditional and plain glyphs | red |\n| swap the exists and hover arms | red |\n| skip disposing the previous mouse-down handler | red |\n| drop the gutter target-type check | red |\n| drop the after-lines guard | red |\n| invert the left/right button branch | red |\n\nThe stand-in editor is a `Proxy` that answers any unstubbed `on*`\nlistener with an inert disposable, so the spec does not have to track\nwhich events `monaco-breakpoints` subscribes to — the first attempt\nfailed on `onDidChangeCursorPosition`, and guessing at the rest would\nhave been fragile.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7422\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/code-debugger.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  29 passed (29)\n```\n\n13 new on top of the existing 16. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "f9deb66dcccfb3b5994be659350021c2e0aa8e06",
      "tree": "c501579a339ab961b8b8684174979fe00d736ecb",
      "parents": [
        "1e899aa4949c5307a8f016681cc2892b44d438c7"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 02:18:12 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 09:18:12 2026 +0000"
      },
      "message": "test(frontend): render the workflow list item\u0027s editing gates and row actions (#7424)\n\n### What changes were proposed in this PR?\n\nThe existing suite calls the component\u0027s methods directly, so the\ntemplate\u0027s own decisions were never rendered: which control a click\nreaches, what value an edit forwards, and which actions a row offers.\n\nAdds 13 tests. The ones that carry real weight:\n\n- **Renaming forwards the text that was typed.** The input is seeded\nwith the current name, so binding `workflow.name` instead would look\nright on screen while silently discarding every rename.\n- **The inline description gate is `editingDescription \u003d editable`.**\nWithout it a shared read-only row opens an editor whose save the backend\nthen rejects.\n- **The shared-access tooltip composes `accessLevel` then `ownerName`,**\nand is shown only to a non-owner.\n- **The per-tag remove passes the `ngFor` loop variable,** not the\ncomponent\u0027s `pid`.\n- **Duplicate and delete stay on their own outputs,** and delete is\ndisabled for a non-owner.\n- **The executions action appears only when execution tracking is\nconfigured on.**\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| rename forwards the old name instead of the typed one | red |\n| drop the read-only gate on inline description editing | red |\n| swap the two interpolations in the shared-access tooltip | red |\n| show the shared-access marker to the owner too | red |\n| pass the component\u0027s `pid` to the per-tag remove | red |\n| stop disabling delete for a non-owner | red |\n| always show the executions action | red |\n| make duplicate emit `deleted` | red |\n| invert the avatar indent | red |\n| invert the light/dark tag arms | red |\n| invert the tag text colour | red |\n\nThe light/dark test **survived its first mutation**: inverting both arms\nmerely swaps which tag gets which class, so an assertion that \"both\nclasses appear somewhere\" cannot see it. It now checks each tag\nindividually, and both that mutation and the text-colour one fail.\n\nThree things worth recording, all commented in the spec:\n\n- ng-zorro consumes the `nz-tooltip` attribute, and an interpolated\ntitle is a property binding that never reaches the DOM at all. Elements\nare located through `NzTooltipDirective` and its `directiveTitle`; an\nattribute selector finds nothing.\n- `StubWorkflowPersistService` does not declare `updateWorkflowName`, so\nit cannot be spied on — the suite supplies its own persist stub.\n- The project colours are supplied locally. The shared\n`testUserProjects` fixture stores colours that already carry a `\u0027#\u0027`\nwhile the template prepends one, so every tag fails the format check and\ntakes the dark arm, leaving the light arm unreachable.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7421\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/user-workflow-list-item.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  28 passed (28)\n```\n\n13 new on top of the existing 15. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nSigned-off-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "1e899aa4949c5307a8f016681cc2892b44d438c7",
      "tree": "85792c4593f68f1b82709733259f55bcad8148bd",
      "parents": [
        "35346629ce00493927556df92fc839cb79b78dfa"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sun Aug 09 02:17:13 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Aug 09 09:17:13 2026 +0000"
      },
      "message": "test(frontend): pin the admin settings form\u0027s wiring (#7426)\n\n### What changes were proposed in this PR?\n\nThe settings form is four near-identical Save/Reset cards, three\nnear-identical upload blocks, and twelve sidebar switches. All 31 of its\ntemplate listeners and all 34 of its branches were unhit, because the\nexisting suite calls the component\u0027s methods directly and never renders\nan interaction.\n\nThe realistic defect in a template shaped like this is cross-wiring from\ncopy-paste, and two switch keys are one character apart:\n\n- `workflow_enabled` vs `workflows_enabled`\n- `dataset_enabled` vs `datasets_enabled`\n\nA swap between either pair is invisible on screen and silently toggles\nthe wrong sidebar entry.\n\nAdds 12 tests. The central one walks the twelve switches in template\norder and asserts each flips **exactly one** setting and no other — that\nis what catches a swap between the confusable pairs. Alongside it:\n\n- the Hub children locked until Hub is on, and the Your Work children\nuntil Your Work is on\n- the three section switches never locked, since locking one behind\nitself would make it impossible to switch back on\n- each of the five number inputs owning its own field\n- each card\u0027s Save and Reset reaching that card\u0027s own handler\n- each \"Choose a …\" button opening its own hidden input, and each file\ninput tagging its change with its own setting key\n- the previews rendering only for images that have been chosen\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| make the `workflows` switch write `workflow_enabled` | red |\n| make the `datasets` switch write `dataset_enabled` | red |\n| gate a Hub child on Your Work instead | red |\n| gate About on Hub | red |\n| gate the Hub section on itself | red |\n| point the tabs Save at the dataset handler | red |\n| point the csv Reset at the branding handler | red |\n| make the logo picker open the favicon input | red |\n| tag the mini-logo change as `logo` | red |\n| make the chunk-size input write `maxFileSizeMiB` | red |\n| render the logo preview unconditionally | red |\n| make the mini-logo preview show the logo | red |\n\nThe preview mutation **survived its first run**: the test set\n`logoData`, so removing that image\u0027s `*ngIf` changed nothing. A no-data\ncase now covers it — without the guard a card renders a broken image on\nfirst load.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7423\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/admin-settings.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  36 passed (36)\n```\n\n12 new on top of the existing 24. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)\n\n---------\n\nSigned-off-by: Xinyuan Lin \u003cxinyual3@uci.edu\u003e\nCo-authored-by: Copilot Autofix powered by AI \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "35346629ce00493927556df92fc839cb79b78dfa",
      "tree": "676131c91960f1b256d7fd3929932b76235264c3",
      "parents": [
        "96ed553760a299f2031f4cd83c024e9327cb5346"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sat Aug 08 04:52:20 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 11:52:20 2026 +0000"
      },
      "message": "test(frontend): extend UserProjectListItemComponent template coverage (#7418)\n\n### What changes were proposed in this PR?\n\nRebased onto `main` after #7415 landed on the same file, and reduced to\nwhat that\nPR left uncovered. #7415 pins what each template branch *looks like* by\nputting the\ncomponent into the state directly; this PR pins the wiring that produces\nthose\nstates, so a control losing its handler fails here. Together they take\n`user-project-list-item.component.html` to 100% (110/110 statements, no\nuncovered\nbranches — it was 77/110 after #7415).\n\n8 new tests:\n\n- **colour panel** — the `[(colorPicker)]` / `(colorPickerSelect)`\noutputs, and the\n`cpExtraTemplate` menu, whose markup exists only while the picker is\nopen: its\nSave action, and its Delete action in both states (disabled while the\nproject has\nno colour, enabled and wired once one is set). None of this was\npreviously\n  rendered — it is the bulk of the gap #7410 describes.\n- **name** — the edit button opens the input, `keyup.enter` saves,\n`focusout` closes.\n- **description** — the expand/collapse controls, the edit button,\n`focusout`\n  saving, and the suffix save icon closing the editor.\n- **actions** — the share button and the delete popconfirm\u0027s\n`nzOnConfirm`.\n- three class-level gaps: the `entry` getter\u0027s guard, `ngOnInit`\nadopting a stored\ncolour, and `updateProjectColor` skipping the service when the colour is\n  unchanged (class 63/67 -\u003e 66/67).\n\nThis block queries with `By.css` + `triggerEventHandler` rather than\n`querySelector`: `nzOnConfirm`, `keyup.enter` and `colorPickerSelect`\nare directive\noutputs, not DOM events, so a native dispatch cannot reach them. #7415\u0027s\n`MarkdownModule.forRoot()` is kept as-is. No production code was\nchanged.\n\nTests that #7415 already covers (the creation date, the `editable`\ngating, the\nread-only delete branch) were dropped from this PR rather than\nduplicated.\n\nOne statement stays uncovered: the `if (!this.entry) throw` guard inside\n`saveProjectName`\u0027s subscribe. The `entry` getter already throws when no\nentry was\nprovided, so that branch cannot be reached — it is dead code rather than\na coverage\ngap, and removing it felt out of scope for a test-only PR.\n\n### Any related issues, documentation, discussions?\n\nCloses #7410. Builds on #7415 (#7412), which covers the same template\nfrom the\nrendering side.\n\n### How was this PR tested?\n\n`ng test --watch\u003dfalse --include\nsrc/app/dashboard/component/user/user-project/user-project-list-item/user-project-list-item.component.spec.ts`\n— 28 passed (20 existing + 8 new), run 3x for determinism. Coverage\n(`--coverage`)\nconfirms `user-project-list-item.component.html` at 110/110 statements\nwith no\nuncovered branches, and the class at 66/67. The failure path was\nverified by\nbreaking an assertion (red, non-zero exit); eslint and prettier are\nclean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "96ed553760a299f2031f4cd83c024e9327cb5346",
      "tree": "027996cfcaf76e0710090b49d96679bcdac81fe8",
      "parents": [
        "97dac3c2db0055a5bb98a23d6741ace3fc106742"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Sat Aug 08 04:13:59 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 11:13:59 2026 +0000"
      },
      "message": "test(frontend): render DatasetDetailComponent template branches for coverage (#7419)\n\n### What changes were proposed in this PR?\n\nExtends the existing `DatasetDetailComponent` spec so the detail view\u0027s\nmarkup\nactually renders, covering template branches that were previously never\nexecuted\n\n(`frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.html`).\nThe spec previously drove the class directly and never queried the DOM.\nNo\nproduction code was changed.\n\n9 tests drive the template through the DOM:\n\n- **Like tag** — likes when logged in, unlikes when already liked, and\nstays\n  inert (with the `disabled` class) when logged out, exercising the\n  `(click)\u003d\"isLogin \u0026\u0026 toggleLike()\"` guard.\n- **Cover image** — the `*ngIf` omits the `\u003cimg\u003e` without a cover URL\nand the\n  `[src]` binding renders it when one is present.\n- **Right bar** — both arms of the collapse/restore `*ngIf` pair are\nclicked.\n- **Settings tab** — the dataset-name `[(ngModel)]` input renders and\nits Save\nbutton routes to the service; both `nz-switch` toggles are present and\ntheir\nchange handlers reach `updateDatasetPublicity` /\n`updateDatasetDownloadable`.\n- **Contributors** — the `*ngFor` renders the seeded contributor rows.\n\nThree component behaviours the tests had to account for, noted in\ncomments so the\nsetup isn\u0027t mistaken for boilerplate:\n\n- `toggleLike()` early-returns unless `currentUid` is set — the spec\u0027s\nexisting\n`login()` helper supplies it (the stub user service emits before the\ncomponent\n  subscribes).\n- `ngOnInit`\u0027s subscriptions reset fields such as `coverImageUrl`, so\nthe helper\nruns one change-detection pass first, then applies the test state, then\nrenders.\n- `nz-tabs` only renders the active tab, and the Settings tab is\nadditionally\nbehind `*ngIf\u003d\"userHasWriteAccess()\"`, so an `openTab()` helper switches\ntabs\n  and the access level is seeded.\n\nPer the issue\u0027s determinism constraints: no fake timers are introduced,\nno\ndate/time string is asserted, and no layout or geometry is asserted.\n\n### Any related issues, documentation, discussions?\n\nCloses #7409\n\n### How was this PR tested?\n\nExtended unit tests, run locally in `frontend/` (all green; the failure\npath was\nverified by breaking an assertion to confirm the suite goes red):\n\n```\nng test --watch\u003dfalse --include src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.spec.ts\n# Test Files 1 passed (1) | Tests 104 passed (104)\nprettier --write \u003cspec\u003e   # clean\neslint  \u003cspec\u003e            # clean\n```\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "97dac3c2db0055a5bb98a23d6741ace3fc106742",
      "tree": "b3ba88df5e793511e3d2db65b4ee4393f855770b",
      "parents": [
        "69c7391a5f613b165ce7276f81811a98de48c442"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sat Aug 08 00:24:58 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 07:24:58 2026 +0000"
      },
      "message": "test(frontend): render the project list item\u0027s permission and description rules (#7415)\n\n### What changes were proposed in this PR?\n\n`UserProjectListItemComponent` decides in its template what a viewer may\ntouch, and none of it was rendered — the existing specs call the save\nand colour methods directly.\n\nAdds 8 tests. The one that matters most is the `editable` gating: a\nproject the viewer only holds READ on must not be offered the rename,\nadd-description, share or delete controls, and that decision lives\nentirely in two `*ngIf\u003d\"editable\"` guards plus one on the action list.\n\nAlso covered: the name/edit-input swap, the description starting\ncollapsed and expanding on request, the `trim()` guard that stops a\nwhitespace-only description rendering an empty expander, the character\ncounter, the save icon appearing only once the text actually differs,\nand the creation-date format.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| show the rename button to a read-only viewer | red |\n| show the share/delete actions to a read-only viewer | red |\n| invert the name / edit-input branch | red |\n| drop the collapse guard | red |\n| drop the whitespace `trim()` guard | red |\n| always show the save icon | red |\n| count characters against the max instead of the text | red |\n| change the creation-date format | red |\n\nTwo things worth recording:\n\n- `MarkdownModule.forRoot()` joins the TestBed. An expanded description\nrenders a `\u003cmarkdown\u003e` element, and no existing test reached that path,\nso `MarkdownService` had never been needed.\n- `descriptionCollapsed` defaults to **true**. My first version of the\ncollapse test asserted the opposite and failed, which also revealed that\nthe whitespace test would have passed vacuously — collapsed hides the\nblock regardless. It now expands first, so the `trim()` guard is the\nonly thing left doing the work.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7412\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/user-project-list-item.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  18 passed (18)\n```\n\n8 new on top of the existing 10. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "69c7391a5f613b165ce7276f81811a98de48c442",
      "tree": "dd99182c28b4cf4ce536ebc1c98bbb3ec36a46c3",
      "parents": [
        "fe89db4315c4b23c04ae06160030566ce8410281"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sat Aug 08 00:24:55 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 07:24:55 2026 +0000"
      },
      "message": "test(frontend): render the dataset page\u0027s view toggle and results wiring (#7417)\n\n### What changes were proposed in this PR?\n\n`UserDatasetComponent`\u0027s spec constructs the component with `new`, so\nits template had never been rendered and sat at 0%. That 0% is simply\n\"never mounted\" — not the instrumentation problem some other templates\nhave.\n\nAdds 8 tests that mount it for real:\n\n- the card/list toggle, and which button carries the `primary` highlight\n— the only way the user can tell which view they are in\n- the preference surviving into a freshly created component through\n`localStorage`\n- the view mode, `editable` and `isPrivateSearch` flags handed down to\n`texera-search-results`\n- `(sortMethodChange)\u003d\"sortMethod \u003d $event; search()\"` — an inline\nstatement doing two things, where dropping either leaves the list in the\nprevious order\n- the execution-time sort options being withheld on a page whose entries\nnever execute\n- the create button being wired\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| pin the list button\u0027s highlight on | red |\n| key the card highlight off the wrong mode | red |\n| stop passing the view mode down | red |\n| mark the results list read-only | red |\n| turn off the private-search scope | red |\n| drop `search()` from the sort handler | red |\n| drop the assignment from the sort handler | red |\n| offer the execution-time sort option | red |\n| unwire the create button | red |\n| stop persisting the view preference | red |\n\nThree findings from getting it to run, all commented in the spec:\n\n- `viewType` defaults to **card**, not list, and is seeded from\n`localStorage` at construction — so it is cleared per test, or a view\nchosen by one test leaks into the next. That persistence turned out to\nbe worth a test of its own.\n- The sort button renders its own `\u003cbutton\u003e` into the same\n`nz-space-compact`, so a positional selector picks that up first. The\nview buttons are selected by their `title` attribute instead.\n- ng-zorro defaults to `zh-cn` and throws `NG0701` without locale data;\nthe TestBed provides `{ provide: NZ_I18N, useValue: en_US }`, matching\nthe sibling dashboard specs.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7414\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/user-dataset.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  26 passed (26)\n```\n\n8 new on top of the existing 18. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "fe89db4315c4b23c04ae06160030566ce8410281",
      "tree": "518e105d9f947aca34f4b246a6c22491f42c68df",
      "parents": [
        "c5c2c6f8c2aeb746929a5f56b9d36eaa0373848e"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Sat Aug 08 00:16:28 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 07:16:28 2026 +0000"
      },
      "message": "test(frontend): render the hub browse section\u0027s entity cards (#7408)\n\n### What changes were proposed in this PR?\n\nThe browse section\u0027s specs cover the route map and the cover-URL cache,\nbut no card had ever been rendered, so every per-entity binding and\nfallback in the template was unpinned. The template was at roughly\n**8%** of statements locally.\n\nAdds 8 tests over what the template decides on its own:\n\n- the section disappears entirely when it holds no entities\n- the heading, and one card per entity, with name and description\n- `{{ entity.description || \u0027No description available\u0027 }}` — an entity\npublished without a description would otherwise render an empty\nparagraph and collapse the card\n- `[src]\u003d\"getCoverImage(entity)\"` and the inline `(error)` handler that\nswaps in `defaultBackground`; a cached cover URL can still 404, and that\nhandler is the only thing standing between the user and a broken image\n- the avatar labelled with the entity id, and the owner name defaulting\nto empty\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| render the section even when empty | red |\n| drop the description fallback | red |\n| drop the owner-name fallback | red |\n| ignore the cover cache and always use the default | red |\n| remove the image error handler | red |\n| label the avatar with the name instead of the id | red |\n| show the description as the card title | red |\n| render only the first entity | red |\n\nLocal coverage for the component directory: **~8% → 94.73%** of\nstatements.\n\nThe real `UserService` is replaced with the shared `StubUserService`:\nthe embedded `texera-user-avatar` injects it, and the real one drags in\n`AuthService` and from there `JwtHelperService` and `NzModalService`.\nThe stub cuts that chain in one step.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7405\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/browse-section.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  17 passed (17)\n```\n\n8 new on top of the existing 9. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "c5c2c6f8c2aeb746929a5f56b9d36eaa0373848e",
      "tree": "521b9e93a44e2af70725a2abf83cc57a8d1f8cbd",
      "parents": [
        "a38bc6659d314b5cbbc32a2233934bb3e0d4ce37"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Sat Aug 08 00:06:27 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 07:06:27 2026 +0000"
      },
      "message": "test(amber): add unit tests cover ProjectSearchQueryBuilder (#7399)\n\n### What changes were proposed in this PR?\n\nAdds `ProjectSearchQueryBuilderSpec`, a connection-free unit spec for\nthe project arm of the unified dashboard search.\n`ProjectSearchQueryBuilder` was the only search query builder without\ntests — `WorkflowSearchQueryBuilderSpec` already exists, and\n`DatasetSearchQueryBuilder` is driven from `DatasetResourceSpec`.\n\nThe spec follows the same conventions as the sibling\n`WorkflowSearchQueryBuilderSpec` (in-memory jOOQ records rendered with\nthe Postgres dialect, no database connection) and covers the two members\nthe object widens from the trait\u0027s `protected` to public:\n\n**`toEntryImpl` — the record-to-DTO mapping (4 tests):** copies every\n`PROJECT` column into the `Project` POJO with distinct fixture values so\na wrong-column read cannot pass; passes NULL description/color through\n(the only two nullable project columns); tags the entry `resourceType \u003d\u003d\n\"project\"` with the `workflow`/`dataset` payload slots `None` (the\ndashboard dispatch matches on this value with no default branch, so\ndrift is a runtime `MatchError`); and produces an identical entry\nregardless of the caller\u0027s uid (the project arm computes no ownership\nflag).\n\n**`mappedResourceSchema` — the projection the union and dispatch depend\non (5 tests):** pins the inline `\u0027project\u0027` resourceType literal; pins\nthat `PROJECT.CREATION_TIME` is aliased as both the creation and\nlast-modified time — a deliberate alias (the project table has no\nlast-modified column) that keeps projects sortable by edit time instead\nof NULL-sinking; and pins the color, pid/ownerId, and name/description\nprojection slots.\n\n`constructFromClause`, `constructWhereClause`, and `getGroupByFields`\nstay `override protected` (Scala `protected` grants no same-package\naccess), so they are intentionally out of scope.\n\nEvery test was mutation-checked: 8 distinct hand-applied mutations of\nthe production object (literal changes, column swaps, dropped alias,\nempty-POJO copy, `project \u003d None`) each fail the intended test, with\nproduction sources restored afterwards. No production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7398\n\n### How was this PR tested?\n\nNine new tests; the spec is the only change:\n\n```\nsbt \"WorkflowExecutionService/testOnly org.apache.texera.web.resource.dashboard.ProjectSearchQueryBuilderSpec\"\n```\n\n```\n[info] Tests: succeeded 9, failed 0, canceled 0, ignored 0, pending 0\n[info] All tests passed.\n```\n\nThe file is formatted with the project\u0027s scalafmt (no diff on re-run).\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Fable 5)"
    },
    {
      "commit": "a38bc6659d314b5cbbc32a2233934bb3e0d4ce37",
      "tree": "28e309797dd485b26d8062c5eb041c5b18e93490",
      "parents": [
        "802a388d28befb53becb764aee1e0af5fff01117"
      ],
      "author": {
        "name": "Eugene Gu",
        "email": "eugenegujing@outlook.com",
        "time": "Sat Aug 08 00:05:56 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 07:05:56 2026 +0000"
      },
      "message": "test(amber): cover computing unit master args (#7400)\n\n### What changes were proposed in this PR?\n\nAdds focused unit coverage for computing-unit master command-line\nparsing, including empty input, mixed-case and repeated cluster flags,\nand malformed or unknown options.\n\n### Any related issues, documentation, discussions?\n\nCloses #7397\n\nMirrors the worker-side `ComputingUnitWorkerSpec` from #7192.\n\n### How was this PR tested?\n\n- `WorkflowExecutionService/testOnly\norg.apache.texera.web.ComputingUnitMasterSpec` — 10 passed.\n- `WorkflowExecutionService/testOnly\norg.apache.texera.web.ComputingUnitWorkerSpec` — 5 passed (neighbor spec\nunaffected).\n- `WorkflowExecutionService/Test/scalafmtCheck` and\n`WorkflowExecutionService/Test/scalafix --check` — clean.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Fable 5)"
    },
    {
      "commit": "802a388d28befb53becb764aee1e0af5fff01117",
      "tree": "08f40f0e3b72158820fbb5af03a2beef4baf6102",
      "parents": [
        "85c5fb2ec52b75a91d4915a61717ced425458a5e"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Fri Aug 07 22:03:54 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 05:03:54 2026 +0000"
      },
      "message": "test(frontend): cover aborting a dataset upload and its conflict retry (#7416)\n\n### What changes were proposed in this PR?\n\n`onClickAbortUploadProgress` was the largest uncovered block in\n`DatasetDetailComponent` and the one with the most ways to go wrong.\nAborting an in-flight upload has to survive the backend still finalizing\na previous attempt, so the abort is retried on 409:\n\n| Response | Behaviour |\n|---|---|\n| success | notify, report the abort |\n| 404 | already gone — report the abort, no error |\n| 409, attempt \u003c `ABORT_RETRY_MAX_ATTEMPTS` | retry after\n`ABORT_RETRY_BACKOFF_BASE_MS * (attempt + 1)` |\n| 409 at the limit, or any other status | give up, but still report the\nabort |\n\nAdds 9 tests over that ladder plus the surrounding bookkeeping: the\nabort flag on the request, the task moving to `aborted`, the progress\nsubscription being dropped so a late event cannot resurrect it, the\nconcurrency slot being released so a queued upload starts, and\n`cancelExistingUpload` delegating here for an upload still running. Both\nconstants are exported, so the backoff growth and the attempt bound are\nasserted rather than hard-coded.\n\n**Verified by mutation**, all reverted (production diff empty):\n\n| Mutation | Result |\n|---|---|\n| never retry on conflict | red |\n| make the retry unbounded | red |\n| use a constant backoff instead of a growing one | red |\n| skip the unsubscribe | red |\n| leave the task unmarked | red |\n| send the abort flag as false | red |\n| drop the `onUploadComplete()` that frees the slot | red |\n| remove the 404 early return | **survived** |\n| remove the `doneCalled` idempotence guard | **survived** |\n\nThe two survivors are reported rather than papered over, because they\nare informative:\n\n- **The 404 early return is behaviourally redundant.** Without it a 404\nfalls past the 409 check to the same `done()` at the bottom, so no input\ndistinguishes the two. The test still earns its place — it fails if 404\nis ever turned into an error path — but it does not pin the branch\nitself.\n- **The `doneCalled` guard is not reachable.** Exactly one of the\n`next`/404/fallback paths fires per response, and each retry replaces\nthe subscription, so `done()` is never invoked twice. It is defensive\ncode with no observable behaviour at this level.\n\nThe slot-release mutation survived my first pass too; unlike the other\ntwo that was a genuine gap, so I added the test that covers it.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7413\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/dataset-detail.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  104 passed (104)\n```\n\n9 new on top of the existing 95. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "85c5fb2ec52b75a91d4915a61717ced425458a5e",
      "tree": "6ddf9b502d45adfd01ec140b2107061f7777a719",
      "parents": [
        "2c57707a762486a7935860d8fee7b8eb0ff89a7e"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Fri Aug 07 22:02:17 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 05:02:17 2026 +0000"
      },
      "message": "test(frontend): cover UserComputingUnitListItemComponent template bindings (#7420)\n\n### What changes were proposed in this PR?\n\nExtends `UserComputingUnitListItemComponent`\u0027s spec to exercise the row\nthrough\nthe DOM. The class file is already at 100%, but the existing tests call\nthe\nhandlers directly and never click the row\u0027s buttons, so\n`user-computing-unit-list-item.component.html` sat at ~52%.\n\n10 added tests render the row and drive it via\n`fixture.debugElement.query(By.css(...))`:\n\n- **Buttons** — the rename button starts inline editing; clicking the\nunit name opens the metadata modal (`NzModalService.create` spied); the\ndelete button emits the `deleted` output.\n- **Inline rename** — `Escape` cancels and `Enter` confirms with the\ntyped value (both fired as real `KeyboardEvent`s), and a click inside\nthe input does not bubble to the row.\n- **Sharing** — the share button is omitted while\n`sharingComputingUnitEnabled` is off, and opens the share-access modal\nwhen it is on.\n- **Metrics popover** — the CPU/RAM rows render, and the GPU /\nJVM-memory / shared-memory rows appear only when those limits are set\n(covering both arms of their `*ngIf`s).\n\nThis lifts the template from **~52% to 100%** (statements *and*\nbranches); the\nclass stays at 100%.\n\nTwo things worth noting, both found by checking rather than assuming:\n\n- The `Escape`/`Enter` tests dispatch **real** `KeyboardEvent`s. With\n`triggerEventHandler(\"keydown.escape\", …)` the handler does fire\n(verified with a spy), but it bypasses Angular\u0027s key-filtering, so the\nreal dispatch is both more representative and what the coverage\nreflects.\n- The last uncovered line was reported as html:79, but reading the\ncoverage `statementMap` showed the uncovered statement actually spans to\n**line 84** — the input\u0027s `(click)\u003d\"$event.stopPropagation()\"`. That is\nwhat the added \"click does not bubble\" test covers.\n\n**Determinism:** the added tests introduce no *new* `vi.useFakeTimers()`\nusage\n(one pre-existing test in this file already uses fake timers; nothing\nwas added\non top) — the component\u0027s `setTimeout` never runs in a synchronous test\nbody, and\nlayering fake timers over zone.js\u0027s patched timers is Node-version\ndependent. No\nlayout/geometry assertions. Overlay contents are cleared in an\n`afterEach` so no\npopover DOM leaks into a later test (clearing `innerHTML` rather than\nremoving\nthe container, since CDK caches that element). The popover is\nopened synchronously via `.injector.get(NzPopoverDirective).show()` +\n`detectChanges()` — the pattern already used in\n`user-dataset-staged-objects-list.component.spec.ts` — and hidden again\nafterwards. The sharing flag is flipped through\n`TestBed.inject(GuiConfigService)`\n(the same DI instance the component holds, whose config object is\nper-instance),\nso nothing leaks between tests. No production code was changed.\n\n### Any related issues, documentation, discussions?\n\nCloses #7411\n\n### How was this PR tested?\n\nExtended unit tests, run locally in `frontend/`:\n\n```\nng test --watch\u003dfalse --include src/app/dashboard/component/user/user-computing-unit/user-computing-unit-list-item/user-computing-unit-list-item.component.spec.ts\n# Test Files 1 passed (1) | Tests 45 passed (45)   — 3 consecutive runs, 0 flakes\n# user-computing-unit-list-item.component.html: ~52% -\u003e 100% (statements \u0026 branches)\nprettier --write \u003cspec\u003e   # formatted\neslint  \u003cspec\u003e            # clean\n```\n\nThe failure path was verified by deliberately breaking a new assertion\nand\nconfirming the suite exits non-zero.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 4.8 [1M context])"
    },
    {
      "commit": "2c57707a762486a7935860d8fee7b8eb0ff89a7e",
      "tree": "058846664ff64264fd68a4244573d15680002493",
      "parents": [
        "dce17e8446358cabf6b8910705cd7a9c7737f159"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Fri Aug 07 18:31:43 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 01:31:43 2026 +0000"
      },
      "message": "test(frontend): render the version list\u0027s collapse and selection rules (#7407)\n\n### What changes were proposed in this PR?\n\nThe version list keeps its display rules in the template, and the spec\nnever rendered it — the existing tests drive `collapse()` and\n`getDisplayedVersionId()` directly. The template was at roughly **4%**\nof statements locally.\n\nThe rule worth pinning is the row predicate:\n\n```html\n\u003ctr *ngIf\u003d\"(!row.importance \u0026\u0026 row.expand) || row.importance\"\u003e\n```\n\nA minor version stays folded away until its important parent is expanded\n— that is the whole point of the collapse, and it exists only in the\ntemplate.\n\nAdds 9 tests: that predicate in both directions, the descending version\nnumbering, the `selected-row` highlight, the expand control appearing\nonly on important versions, the three arguments the timestamp button\npasses to `getVersion`, the date format, the column headings, and the\ntable being absent until versions load.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| make the row predicate always true | red |\n| drop `expand` from the predicate | red |\n| key `selected-row` off the row count instead of the index | red |\n| number versions by index instead of count − index | red |\n| hand `getVersion` a fixed index | red |\n| show the expand control on every row | red |\n| change the date format | red |\n| render the table before versions load | red |\n\nLocal coverage for the component directory: **~4% → 96.55%** of\nstatements.\n\nThe spec was already set up for this — it deliberately skips\n`detectChanges()` in `beforeEach` and notes that tests needing the\nrendered template should call it locally.\n\nOne gotcha worth recording: `nz-table` renders its own expand-icon\n`\u003cbutton\u003e`, so `querySelector(\"button\")` finds that rather than the\nversion link. The tests select `button.version-link`.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7404\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/versions-list.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  20 passed (20)\n```\n\n9 new on top of the existing 11. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "dce17e8446358cabf6b8910705cd7a9c7737f159",
      "tree": "6bece416cd76f59b208ee4df89ba15d84cb4019f",
      "parents": [
        "1362167975e93322282908bbfbe7ea8ac2c4d2fe"
      ],
      "author": {
        "name": "Xinyuan Lin",
        "email": "xinyual3@uci.edu",
        "time": "Fri Aug 07 18:31:40 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 01:31:40 2026 +0000"
      },
      "message": "test(frontend): render the dataset file preview\u0027s viewer branches (#7406)\n\n### What changes were proposed in this PR?\n\nThe file renderer\u0027s class was already at 91% locally, but its template\nwas at **25%** of statements. The template is a viewer switch — each\n`displayX` flag selects exactly one preview — and only the CSV path had\never been rendered.\n\nAdds 16 tests that drive each viewer and assert what actually reaches\nthe screen: the four status alerts (each excluding the others), the\nshared table for CSV and spreadsheets, image plus the click that opens\nthe full-size modal, video, audio, markdown, JSON, plain text, the empty\ninitial state, and the maximized height.\n\nIt also pins the `\u0026\u0026 safeFileURL` guards on the media branches. Those\nare load-bearing: the flag is set as soon as the MIME type is known\nwhile the object URL is built asynchronously, so rendering on the flag\nalone emits a source-less `\u003cimg\u003e`/`\u003cvideo\u003e`/`\u003caudio\u003e`.\n\n**Verified by mutation**, all reverted (template diff empty):\n\n| Mutation | Result |\n|---|---|\n| drop the `\u0026\u0026 safeFileURL` guard on the video branch | red |\n| drop the same guard on the image branch | red |\n| key the markdown branch off `displayJson` | red |\n| remove the image\u0027s click handler | red |\n| drop `displayXlsx` from the table guard | red |\n| reword the too-large message | red |\n| use 100% height when not maximized | red |\n\nLocal coverage for the component directory: **68.34% → 93.57%** of\nstatements.\n\nThree details are commented in the spec, each of which cost a debugging\nround:\n\n- The first `detectChanges()` runs `ngOnInit`, which inspects the empty\n`filePath` and settles on \"preview unsupported\"; flags set beforehand\nare silently overwritten. The helper clears state via the component\u0027s\nown `turnOffAllDisplay()` afterwards.\n- Binding `[src]` makes Angular call `DomSanitizer.sanitize`, which the\nexisting stub does not provide, so the new block supplies its own.\n- `\u003cmarkdown\u003e` needs `MarkdownModule.forRoot()`, following\n`agent-chat.component.spec.ts`.\n\nNo production file is touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7403\n\n### How was this PR tested?\n\n```\nnpx ng test --watch\u003dfalse --include\u003d\"**/user-dataset-file-renderer.component.spec.ts\"\n```\n\n```\n Test Files  1 passed (1)\n      Tests  48 passed (48)\n```\n\n16 new on top of the existing 32. `yarn format:ci` passes.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Opus 5)"
    },
    {
      "commit": "1362167975e93322282908bbfbe7ea8ac2c4d2fe",
      "tree": "4287ba27c5e01186cfea1ede9ef3d74059597b44",
      "parents": [
        "d2fe4ba34e0e76679eb14499c854d487ed953a09"
      ],
      "author": {
        "name": "Kary Zheng",
        "email": "150742834+kz930@users.noreply.github.com",
        "time": "Fri Aug 07 18:15:40 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 01:15:40 2026 +0000"
      },
      "message": "feat(visualization): declare the column types Wind Rose and Bubble Chart require (#7341)\n\n### What changes were proposed in this PR?\n\nWind Rose\u0027s radial value and Bubble Chart\u0027s z column are both consumed\nas magnitudes, and neither declared an `attributeTypeRules` entry, so\nthe property form offered every column and accepted a string one. Each\nnow declares `integer`, `long` or `double`, the way Range Slider\u0027s\ny-axis and Radar Chart\u0027s value columns already do.\n\u003cimg width\u003d\"1433\" height\u003d\"925\" alt\u003d\"Screenshot 2026-08-07 at 2 21 49 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/61e45feb-22ca-4b7d-b447-8785a4ad3695\"\n/\u003e\n\u003cimg width\u003d\"1432\" height\u003d\"920\" alt\u003d\"Screenshot 2026-08-07 at 2 23 46 PM\"\nsrc\u003d\"https://github.com/user-attachments/assets/7336c652-869f-4f92-a075-98b2b55a2c52\"\n/\u003e\n\n\nThe other pickers are deliberately left alone: Wind Rose\u0027s angle is a\ndirection label and Bubble Chart\u0027s x and y are positions, all of which\ntake any type the way a scatter plot\u0027s axes do.\n\n### Any related issues, documentation, discussions?\n\nCloses #7324. Same class of gap as #7250, which covered a different set\nof operators.\n\n### How was this PR tested?\n\nEach spec gains a case that generates its descriptor\u0027s schema and\nasserts the rule on it: keyed to `rColumn` and to `zValue`, each naming\na property the schema declares, each allowing exactly `integer`, `long`\nand `double`, and each stating that `string` is not among them. Reading\nthe annotation text would not have shown this — a key naming no property\nparses exactly as well and constrains nothing, which is what #7210\ncollected four instances of.\n\nRemoving either annotation leaves exactly those two cases failing. Each\nasserts the whole key set rather than the presence of its own key, so\nconstraining the angle or the two axes later would fail here too — those\nread as any type on purpose.\n\n```\nsbt \"WorkflowOperator/testOnly org.apache.texera.amber.operator.visualization.windRoseChart.WindRoseChartOpDescSpec org.apache.texera.amber.operator.visualization.bubbleChart.BubbleChartOpDescSpec\"\n```\n\nThirteen cases, all passing.\n\nThe behaviour each rule prevents was reproduced first: rendering the\nsame three-row frame with a numeric column and with a string one, Wind\nRose\u0027s `radialaxis.type` comes out `linear` with range 0 to 4.2 for the\nnumeric column and `category` with range -0.11 to 2.11 for the string\none — the wedges drawn at ordinal positions rather than lengths, with no\nerror — and this holds even when every value is a number written as\ntext. Bubble Chart raises `TypeError: unsupported operand type(s) for /:\n\u0027str\u0027 and \u0027int\u0027` on either.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (Claude Opus 5)\n\n---------\n\nCo-authored-by: Claude Opus 5 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "d2fe4ba34e0e76679eb14499c854d487ed953a09",
      "tree": "8788b689e5efe7174f4a2fc5c72723c32d20411a",
      "parents": [
        "a1e64cdd18bee57dcc0f143c2bc6fe9a8d6b2af6"
      ],
      "author": {
        "name": "Meng Wang",
        "email": "mengw15@uci.edu",
        "time": "Fri Aug 07 17:23:11 2026 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Aug 08 00:23:11 2026 +0000"
      },
      "message": "fix(pyamber, test): stabilize flaky AtomicInteger get_and_set deadlock test (#7295)\n\n### What changes were proposed in this PR?\n\n`test_get_and_set_does_not_deadlock_on_non_reentrant_lock` (added in\n#5010)\nwaited on an `Event` for a fixed 0.5s and then asserted `not\nworker.is_alive()`.\nThe worker sets that event *inside* `attempt()`, before the thread\nexits, so the\nassertion could fire while a perfectly correct `get_and_set` was still\ntearing\ndown — and if the worker didn\u0027t finish inside the 0.5s budget at all,\nthe assert\nfailed outright. Both are wall-clock races unrelated to the deadlock the\ntest\nguards, and both surface under CI load.\n\nReplaced the fixed window with `worker.join(timeout\u003d5)`. `join` returns\nonly\nonce the thread is really dead, which is the precondition `is_alive()`\nneeds, and\nit returns in microseconds on a correct implementation — so the timeout\ncosts\nnothing in practice while still letting a real deadlock keep the worker\nalive\npast it and trip the same assertion. The regression-detection intent is\nunchanged. Test-only change; no production code touched.\n\n### Any related issues, documentation, discussions?\n\nCloses #7294.\n\n### How was this PR tested?\n\n`pytest amber/src/test/python/core/util/test_atomic.py` locally on\nPython 3.12 —\n11 passed, run repeatedly, all green in ~0.6s per run (the join adds no\nmeasurable time).\n\nFailure path verified: temporarily reintroducing the #4794 deadlock in\n`AtomicInteger.get_and_set` (`old_value \u003d self.value` while holding the\nnon-reentrant lock) makes the test fail red with the same `assert not\nTrue` and\npytest exit code 1 after the 5s join timeout.\n\n`ruff check` and `ruff format --check` clean on the touched file.\n\n### Was this PR authored or co-authored using generative AI tooling?\n\nGenerated-by: Claude Code (claude-fable-5)\n\nCo-authored-by: Yicong Huang \u003c17627829+Yicong-Huang@users.noreply.github.com\u003e"
    }
  ],
  "next": "a1e64cdd18bee57dcc0f143c2bc6fe9a8d6b2af6"
}
