)]}'
{
  "log": [
    {
      "commit": "9799b263cb1b9ca5aa2bd0998739e284ec9d5daf",
      "tree": "3b1143b18f16c60230a5aad8ae86d2143bf8a780",
      "parents": [
        "2d14bb99bdf2091b4ff36edd5a623e12a93ead1c"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Tue Oct 27 20:40:06 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 27 20:40:06 2026 +0900"
      },
      "message": "[ZEPPELIN-6762] Fix truncated output alerts in the new UI\n\n### What is this PR for?\nFix the unstyled “Output is truncated” alert and its non-functional close button in the new UI.\n\nThe alert HTML generated by the server relies on Bootstrap styles and dismissal behavior, which the new UI does not provide. This PR adds light/dark theme styling and close-button handling for both Angular and React.\n\n### What type of PR is it?\nBug Fix\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-6762\n\n### How should this be tested?\n\nAutomated tests\n- Run the following commands from the repository root:\n\n```bash\ncd zeppelin-web-angular\nnpm run test:shell -- src/app/pages/workspace/share/result/result.component.spec.ts --maxWorkers\u003d1\nnpm --prefix projects/zeppelin-react test -- src/components/renderers/HTMLRenderer.spec.tsx --maxWorkers\u003d1\n```\n\nManual verification\n\n1. Create a notebook using the sh interpreter and run:\n  ```sh\n%sh\nfor i in $(seq 1 20000); do echo \"line_$i\"; done\n  ```\n2. Verify that the “Output is truncated” alert below the output has a background, border, and close button.\n3. Click × and verify that only the alert disappears; the output text should remain.\n4. Run the paragraph again. Verify that the alert reappears and can also be dismissed by focusing its close button and pressing Enter.\n5. Repeat in both light and dark themes.\n6. Open the same paragraph in the React Published view and repeat:\n  ```text\n/#/notebook/\u003cnoteId\u003e/paragraph/\u003cparagraphId\u003e?react\u003dtrue\n  ```\n\nTo verify the row-limit alert with a PostgreSQL JDBC interpreter, set zeppelin.jdbc.maxResult to 1000 and run:\n\n```sql\n%jdbc\nSELECT generate_series(1, 2000);\n```\n\nVerify that the row-limit alert following the table is styled correctly and can be dismissed.\n\n### Screenshots (if appropriate)\n**Angular dark theme**\n\n\u003cimg width\u003d\"1280\" height\u003d\"420\" alt\u003d\"zeppelin-6762-angular-dark\" src\u003d\"https://github.com/user-attachments/assets/22343a9e-9aa1-47d8-86a6-6320b3f1d675\" /\u003e\n\n**Angular light theme**\n\n\u003cimg width\u003d\"1280\" height\u003d\"420\" alt\u003d\"zeppelin-6762-angular-light\" src\u003d\"https://github.com/user-attachments/assets/3498ac84-d76f-4ffe-a831-12d9c7e6e5e6\" /\u003e\n\n**React dark theme**\n\n\u003cimg width\u003d\"1600\" height\u003d\"525\" alt\u003d\"zeppelin-6762-react-dark\" src\u003d\"https://github.com/user-attachments/assets/d7f85139-e1bf-425e-b189-ffba5de510c5\" /\u003e\n\n**React light theme**\n\n\u003cimg width\u003d\"1280\" height\u003d\"420\" alt\u003d\"zeppelin-6762-react-light\" src\u003d\"https://github.com/user-attachments/assets/243408ef-3ae0-411f-83e0-5839d123deff\" /\u003e\n\n### Questions:\n* Does the license files need to update? No.\n* Is there breaking changes for older versions? No.\n* Does this needs documentation? No.\n\n\nCloses #5591 from miinhho/ZEPPELIN-6762-truncated-output-alert.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "2d14bb99bdf2091b4ff36edd5a623e12a93ead1c",
      "tree": "042833bae55241983b4652b588fdb317329cad4b",
      "parents": [
        "5243b9b6978686f9f6c9c5214b517d1a28a3911c"
      ],
      "author": {
        "name": "SeungYoung Oh",
        "email": "seung-00@naver.com",
        "time": "Mon Oct 26 21:55:34 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 21:55:34 2026 +0900"
      },
      "message": "[ZEPPELIN-6759] Add get_paragraph tool to the AI assistant\n\n### What is this PR for?\nAdd a get_paragraph assistant tool to retrieve a paragraph’s code, execution status, and output.\n\n### What type of PR is it?\nFeature\n\n### Todos\n\n### What is the Jira issue?\n[[ZEPPELIN-6759]](https://issues.apache.org/jira/browse/ZEPPELIN-6759)\n\n### How should this be tested?\nRun GetParagraphToolTest, ListParagraphsToolTest, and AssistantTest.\n\n### Screenshots (if appropriate)\n\n### Questions:\n* Does the license files need to update? N\n* Is there breaking changes for older versions? N\n* Does this needs documentation? N\n\n\nCloses #5586 from seung-00/feature/ZEPPELIN-6759.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "5243b9b6978686f9f6c9c5214b517d1a28a3911c",
      "tree": "b0398ed9fed5e21973ebaa96128d0ddae27c4c52",
      "parents": [
        "65c12bf1b977dc4e1afdb6fa0934b8376f6abd00"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Mon Oct 26 21:54:58 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 26 21:54:58 2026 +0900"
      },
      "message": "[ZEPPELIN-6748] Assemble the fixture-backed Assistant conversation panel\n\n### What is this PR for?\n\nAssemble the existing Assistant components into a fixture-backed conversation panel, available in Storybook and in notebooks with `?reactAssistant\u003dtrue`.\n\nThe panel supports:\n- Creating conversations on the first send, selecting saved conversations, and confirming deletion.\n- Streaming answers with Markdown and tool activity, followed by history reconciliation.\n- Keeping each conversation’s draft and running answer separate when switching conversations.\n- Loading earlier history while preserving message identity and the reader’s scroll position.\n- Presenting creation, send, run, and history-loading failures through the existing error components.\n\nConversation state, run-event accumulation, history reconciliation, and React subscription have separate owners. The fixture accepts explicit seed data, a reference clock, and failure scenarios independently of Storybook.\n\n### What type of PR is it?\n\nFeature\n\n### What is the Jira issue?\n\n* https://issues.apache.org/jira/browse/ZEPPELIN-6748\n\n### How should this be tested?\n\n#### Unit and component tests\n\nFrom zeppelin-web-angular/projects/zeppelin-react:\n\n```bash\nnpm test -- \\\nsrc/pages/assistant-workspace \\\nsrc/entities/assistant/ui/AssistantAnswer.spec.tsx \\\n--maxWorkers\u003d1 --no-file-parallelism\n\nnpm run typecheck\nnpm run lint\n```\n\nThese tests cover run-event handling, conversation switching, stale responses, history reconciliation, fixture behavior, deletion confirmation, and answer rendering across state transitions.\n\n#### Notebook E2E tests\n\nStart the Zeppelin backend on localhost:8080, then run from zeppelin-web-angular:\n\n```bash\nnpm run e2e -- e2e/tests/notebook/assistant\n```\n\nThe conversation scenarios check:\n- Streaming a new answer, preserving its DOM through completion, and restoring saved history.\n- Switching away from an active conversation without mixing drafts or results.\n- Loading earlier history and joining a split answer without replacing the later answer.\n\n#### Manual verification\n\n1. Open a notebook with ?reactAssistant\u003dtrue and open the Assistant sidebar.\n2. Send a question and observe the streaming answer, tool activity, and completed Markdown table.\n3. Send in one conversation, switch to another, and return to verify that the draft and answer remain associated with the correct conversation.\n4. Open Revenue analysis and scroll to the top to load earlier messages.\n5. Use the panel stories to exercise creation failure, rejected sends, unknown acceptance, and accepted-run failure.\n\nTo open the stories, run from zeppelin-web-angular/projects/zeppelin-react:\n\n```bash\nnpm run storybook\n```\n\nOpen Assistant / ConversationPanel.\n\n### Screenshots (if appropriate)\n\u003cimg width\u003d\"396\" height\u003d\"624\" alt\u003d\"Screenshot 2026-10-21 101119\" src\u003d\"https://github.com/user-attachments/assets/314b72b4-f39a-412e-8131-6767de3afdba\" /\u003e\n\n\n### Questions:\n\n- Does the license files need to update? No.\n- Is there breaking changes for older versions? No.\n- Does this needs documentation? No.\n\nCloses #5578 from miinhho/ZEPPELIN-6748-fixture-panel.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "65c12bf1b977dc4e1afdb6fa0934b8376f6abd00",
      "tree": "7d14bfc516eedb972252b83afff80e914d71d1da",
      "parents": [
        "d8da8f387d315f195224b9ae6f487f2c09a88ce1"
      ],
      "author": {
        "name": "ChanHo Lee",
        "email": "chanholee@apache.org",
        "time": "Sat Oct 24 23:41:39 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 23:41:39 2026 +0900"
      },
      "message": "[HOTFIX] Update remaining Node.js toolchains to 22.23.4\n\n### What is this PR for?\n\nFollow up on #5587 by updating the remaining Node.js toolchains to patched releases. The [October 2026 Node.js security release](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases#nodejs-brotli-decoder-out-of-bounds-write-permits-remote-code-execution-cve-2026-111497---high) addresses the Brotli decoder vulnerability CVE-2026-111497.\n\n- Upgrade Classic UI builds from Node.js 16.20.2 to 22.23.4, aligning Maven, nvm, and package engine metadata.\n- Upgrade Helium bundle generation from Node.js 16.16.0 to 22.23.4.\n- Restrict the Angular/React frontend engine range to patched release lines: `^22.23.4 || ^24.22.1 || \u003e\u003d26.12.1`.\n\nThe existing Classic npm 8.19.4 and Helium npm 8.11.0/Yarn 1.22.0 versions are retained. Application code and dependency resolutions are unchanged apart from the Node.js version selection and engine metadata.\n\nClassic uses Node.js during development and builds; Helium also invokes Node.js on the server to install packages and generate bundles. This updates those toolchains without claiming a confirmed remotely exploitable Zeppelin attack path.\n\n### What type of PR is it?\n\nBug Fix\n\n### Todos\n\n- [x] Validate Classic UI builds and tests on Node.js 22.23.4\n- [x] Validate Helium installation, bundle generation, rendering, and cache reuse\n- [x] Validate integration with the #5587 frontend toolchain\n- [ ] Confirm GitHub Actions results\n\n### What is the Jira issue?\n\nN/A\n\n### How should this be tested?\n\nFrontend:\n- Clean installation with Node.js 22.23.4 and npm 11.21.1.\n- React tests: 262 passed.\n- React typecheck and React/Angular production builds passed.\n- Existing braces security patch applied successfully.\n\nClassic UI:\n- Production build and 194 browser unit tests passed.\n- Browser checks covered notebook editing, execution, table/chart rendering, search/replace, and interpreter permission settings.\n- The development server connected to the backend successfully.\n\nHelium:\n- Five Helium tests passed, and the server reactor build passed with JDK 11.\n- Installed and enabled the horizontalbar example, generated its bundle with Node.js 22.23.4, and verified the SVG chart and values in a notebook.\n- On Linux x86-64, verified automatic replacement of an existing Node.js 16.16.0 installation, bundle loading, forced rebuild, and reuse after server restart.\n- The Markdown Spell example installed, bundled, and rendered, but result persistence encountered an existing Java ClassCastException. Equivalent bundles built with Node.js 16.20.2 and 22.23.4 were byte-identical.\n\nThe browser checks also identified an existing Monaco icon font loading error, reproduced with a Node.js 22.21.1 comparison build. These existing issues are outside this change.\n\nThe retained Node.js changes are identical to the previously validated versions. After integration with #5587, installation, React tests, typecheck, and frontend builds were repeated. The source tree was unchanged by rebasing onto the merged #5587 commit. The full E2E suite, Storybook build, and final WAR/container packaging were not rerun.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No.\n* Is there breaking changes for older versions? Builds require a patched Node.js release. Maven downloads Node.js 22.23.4 for Classic UI builds, and Helium installs that version for bundle generation.\n* Does this needs documentation? Yes; the Classic UI Local Development instructions now point to the Node.js version pinned in `.nvmrc`.\n\n\nCloses #5588 from tbonelee/fix/brotli-security-after-5587.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "d8da8f387d315f195224b9ae6f487f2c09a88ce1",
      "tree": "d13a02a45a7998e0076a66f3295e19fb4e09f90e",
      "parents": [
        "0a9c4ed53460c9bc23285cc853f2b7e3a860b82d"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sat Oct 24 22:28:45 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 22:28:45 2026 +0900"
      },
      "message": "[MINOR] Refresh frontend Node.js and audit dependencies\n\n### What is this PR for?\n\nUpdate the Angular/React frontend toolchain to [Node.js 22.23.4](https://github.com/nodejs/node/releases/tag/v22.23.4) for upstream security fixes, including DNS null-byte input validation (CVE-2026-105482) and `realpathSync` permission-model checks (CVE-2026-106073). Pin npm 11.21.1 in Maven and both audit workflows to avoid the npm 10.9.4 `edgesOut` crash in the [scheduled audit remediation job](https://github.com/apache/zeppelin/actions/runs/40054980691/job/120755869155).\n\nUpdate Storybook to 10.6.3, Vitest to 4.1.12, and vulnerable transitive dependencies. Keep the existing audit policy and braces patch verification. Retain npm debug logs for three days on failure to diagnose internal errors such as `edgesOut`.\n\nThe Angular root audit exclusion and classic UI Node.js versions remain outside this change.\n\n### What type of PR is it?\n\nBug Fix\n\n### Todos\n\n* [x] Verify clean installs, audit remediation, tests, and builds locally\n* [x] Confirm GitHub Actions checks\n\n### What is the Jira issue?\n\nN/A\n\n### How should this be tested?\n\nUse Node.js 22.23.4 and npm 11.21.1. From `zeppelin-web-angular/`:\n\n```bash\nnpm ci --ignore-scripts --no-audit\nnpm run build:projects\n```\n\nThen, from `zeppelin-web-angular/projects/zeppelin-react/`:\n\n```bash\nnpm ci --ignore-scripts --no-audit\nnpm run apply:patches\nnpm run audit\nnpm audit fix --package-lock-only --ignore-scripts --audit-level\u003dhigh\nnpm run lint\nnpm test\nnpm run typecheck\nnpm run build\n```\n\nLocal checks passed: React audit, 262 tests, lint, typecheck, builds, and Maven toolchain installation. GitHub CI and the Docker documentation build remain unverified.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? Yes\n\n\nCloses #5587 from voidmatcha/fix/node-npm-audit-security.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "0a9c4ed53460c9bc23285cc853f2b7e3a860b82d",
      "tree": "6f57d38fb2b9a40090e55a8a13b9a144cba8a220",
      "parents": [
        "614baac84668a7c880161b8df8f1d575be4d8aa2"
      ],
      "author": {
        "name": "Lee SuJung",
        "email": "153787023+xhaktm00@users.noreply.github.com",
        "time": "Sat Oct 24 11:00:15 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 11:00:15 2026 +0900"
      },
      "message": "[ZEPPELIN-6673] Capture notebook permission, authentication, and shell error-handling fixtures\n\n### What is this PR for?\n\nCapture how the server and the Angular shell behave around note permissions, sign-in and session expiry, so that ZEPPELIN-6727 can check its consumer against recorded behavior instead of rules copied from client code. This PR records behavior only. It does not change server, shell or Core code.\n\n**Recording.** `createLifecycleRecorder(metadata, { authentication: true })` also records `/api/security/ticket`, `/api/login` and `/api/login/logout`. Each redirect hop is recorded as its own request with its `location` and no body, and names the request it was redirected from in `redirectedFrom`, because logout cycles overlap and request order alone cannot pair them. A failed sign-in request becomes a `failed` record, while a failed notebook request still fails capture. `writeWithoutAccountNames` moves unchanged from `read-fixtures.spec.ts` (ZEPPELIN-6737) to `lifecycle/capture.ts`, so both capture specs replace account names with `\u003cuser\u003e`.\n\n**Captures.** `notebook-auth-fixtures.spec.ts` records 12 rows into `e2e/fixtures/notebook-auth/` with a manifest, and `notebook-auth-captures.test.mjs` checks the inventory, provenance, redaction and each row\u0027s behavior. The shell rows are replayed through the production `AppHttpInterceptor` and `AppMessageInterceptor`.\n\n#### Captured behavior\n\n| Fixture | Behavior |\n| --- | --- |\n| `acl-write.json` | Owner permission write `200`, non-owner `403` |\n| `acl-write-role-owner.json` | The same when the owner is named only by a role |\n| `acl-write-unauthenticated.json` | No session: `302` to `/api/login`, which answers `405` |\n| `acl-write-anonymous.json` | Anonymous server: the write succeeds (`200`) |\n| `rest-401-logout.json` | Signed-in logout: `401` with no `Location` |\n| `rest-401-with-location.json` | Skipped, no file: this server never sends `401` with `Location` (needs an SSO realm such as Knox) |\n| `http-session-expired.json` | HTTP session expired while the WebSocket still works; one logout per `405` on a request that is not the logout |\n| `ws-global-auth-info.json` | `AUTH_INFO` without msgId; later reads on the same socket succeed |\n| `ws-global-error-info.json` | `ERROR_INFO` without msgId |\n| `ws-read-correlation.json` | Read failures carry their request msgId next to an unrelated global `ERROR_INFO` |\n| `ws-session-logout.json` | After a logout, a command on the old ticket is dropped; once the account signs in again it is answered with `SESSION_LOGOUT` (no msgId) |\n| `session-expiry-server-restart.json` | The same after a server restart |\n\n#### Points for review\n\n* **Recorder contract change**: `location` now survives header filtering in both fixture formats, reduced to its path (no host, query or path parameters; an unparseable value is dropped). `failed` records are accepted only in lifecycle captures, and lifecycle replay rejects a capture containing sign-in requests, `failed` records or `location`. The README is updated in the same PR, as in ZEPPELIN-6672 and ZEPPELIN-6737.\n* **401 with Location**: with that row skipped, the shell\u0027s redirect branch is covered by a synthetic test that says so.\n* **Restart row**: after the in-test restart, the UI sign-in in global setup failed repeatedly on the restarted server. Starting a new server from the shell made it pass. The cause is not found; the README says to run the restart row last and restart the server from the shell before capturing again.\n* **Read fixtures** (ZEPPELIN-6737, recaptured from Apache master): the WebSocket messages and record counts are unchanged. Besides new IDs and timestamps, the permissions REST responses now arrive before the `NOTE`, `ERROR_INFO` and `AUTH_INFO` frames they used to follow. Order between REST and WebSocket is not defined, and the read replay passes.\n* **Handoff table** (README): \"Behavior owner\" is who handles the behavior (Server, Angular shell, Core). It is not `metadata.owner`, the package that keeps the capture. `SESSION_LOGOUT` belongs to the Angular shell (session foundation) and nothing handles it yet.\n* **Pre-existing**: `read-fixtures.spec.ts:57` has a TypeScript conversion error that was hidden because that spec is not in the core-contract tsconfig. This PR does not add it there.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] - Record sign-in requests and redirect hops in lifecycle captures behind an opt-in option\n* [x] - Capture permission, authentication and session-expiry fixtures with an inventory test\n* [x] - Replay the captured shell signals through the production interceptors\n* [x] - Recapture the ZEPPELIN-6737 read fixtures from Apache master\n* [x] - Document the capture procedure and the ZEPPELIN-6727 handoff\n\n### What is the Jira issue?\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6673\n\n### How should this be tested?\n\nFrom `zeppelin-web-angular`:\n\n```bash\nnpm run check:core-contract-fixtures  # 175 tests: 174 passed, 1 skipped (the 401 with Location row)\nnpm run test:shell                    # 318 passed\n```\n\nBreaking each new recorder and validation rule (18 changes), each inventory assertion against the captures (10 changes) and each interceptor branch the replay covers made a test fail. The \"no reply in between\" check of the `SESSION_LOGOUT` rows was confirmed only indirectly.\n\nCaptures were taken against Apache master `bf658867be1067a208d3b41cd07cb0a3feb4ef06`, built in a separate clone with `capture/server.sh` as the README describes:\n\n* authenticated (`--mode auth`): 11 supported, 1 skipped\n* anonymous: `acl-write-anonymous.json`\n* read fixtures: `read-fixtures` in anonymous and authenticated mode, both passed\n\nNot run locally: `npm run e2e:core-contract` and the full E2E suite, Firefox and WebKit.\n\n### Screenshots (if appropriate)\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No. Recording without the new option is unchanged.\n* Does this needs documentation? The captures, the procedure and the handoff are documented in the core-contract README.\n\nCloses #5581 from xhaktm00/ZEPPELIN-6673.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "614baac84668a7c880161b8df8f1d575be4d8aa2",
      "tree": "5f51e6f20950cc0ba3e982227b14f5bd1e649fb6",
      "parents": [
        "81e5de88d07270b950c056fe0f2628efcfa0feac"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Sat Oct 24 10:59:52 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 24 10:59:52 2026 +0900"
      },
      "message": "[ZEPPELIN-6731] Fix LdapRealm login failure caused by unsupported SHA-1 hashing after Shiro 2.0.6 upgrade\n\n### What is this PR for?\nSince the Shiro 2.0.6 upgrade (ZEPPELIN-6528), logging in through `LdapRealm` fails with HTTP 403 even with the correct password, because `createAuthenticationInfo()` hashes the credentials with `SHA-1`, which Shiro 2\u0027s `SimpleHashProvider` no longer supports (only SHA-256/384/512).\n\nSwitching the algorithm alone is not enough. In Shiro 2, `DefaultHashService` defaults to 50,000 iterations with a random salt, while `HashedCredentialsMatcher` defaults to 1 iteration. With only the algorithm changed, the exception disappears but the hashes never match, so login still fails silently with 403.\n\nThis PR:\n- Switches `HASHING_ALGORITHM` from `SHA-1` to `SHA-256`.\n- Introduces `HASH_ITERATIONS` (Shiro\u0027s `SimpleHashProvider.Parameters.DEFAULT_ITERATIONS`) and uses it on both sides: the hash request in `createAuthenticationInfo()` and the `HashedCredentialsMatcher`.\n- Adds unit tests covering the `createAuthenticationInfo()` → credentials matcher path, which previously had no test coverage.\n\n\n### What type of PR is it?\nBug Fix\n\n### Todos\n* [x] Switch `LdapRealm` hashing algorithm from `SHA-1` to `SHA-256`\n* [x] Align hash iterations between `DefaultHashService` and `HashedCredentialsMatcher`\n* [x] Add unit tests for the `createAuthenticationInfo()` → credentials matcher path\n* [x] Verify login manually against a real LDAP server (389 Directory Server)\n\n### What is the Jira issue?\n[ZEPPELIN-6731](https://issues.apache.org/jira/browse/ZEPPELIN-6731)\n\n### How should this be tested?\nUnit tests:\n- `LdapRealmTest#testCreateAuthenticationInfoMatchesSubmittedCredentials`\n- `LdapRealmTest#testCreateAuthenticationInfoRejectsDifferentCredentials`\n\n| Code state | Result |\n|---|---|\n| Before fix (`SHA-1`) | Both tests error: `UnsupportedOperationException: Cannot create a hash with the given algorithm: SHA-1` |\n| Algorithm changed to `SHA-256` only | Match test fails: `expected: \u003ctrue\u003e but was: \u003cfalse\u003e` (iteration mismatch) |\n| This PR | All tests in `LdapRealmTest`, `RoleMappingLdapRealmTest`, `LdapRealmFilterInjectionTest`, `LdapRealmDnInjectionTest` pass |\n\nManual test, following the reproduction steps in the Jira issue (389 Directory Server in Docker, `LdapRealm` in `shiro.ini`):\n\n| Password | Before | After |\n|---|---|---|\n| `alice123` (correct) | HTTP 403 + SHA-1 exception in server log | HTTP 200 |\n| `wrong-pw` | HTTP 403 | HTTP 403 |\n\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5585 from JangAyeon/ZEPPELIN-6731.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "81e5de88d07270b950c056fe0f2628efcfa0feac",
      "tree": "809c05234a883e8f4ac672572259e682830aded6",
      "parents": [
        "f801b2e4c2f0fae5e5e47ed6e12a2eda9069fd14"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Wed Oct 21 21:48:32 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 21 21:48:32 2026 +0900"
      },
      "message": "[HOTFIX] Update vulnerable Vite and launch-editor dependencies in zeppelin-react\n\n### What is this PR for?\n\nUpdates development dependencies in zeppelin-react to address vulnerabilities in editor-launching code:\n\n- GHSA-587h-7wmj-h5pm (https://github.com/advisories/GHSA-587h-7wmj-h5pm): Windows file-existence check bypass — high severity.\n- GHSA-698v-4r3x-3vcv (https://github.com/advisories/GHSA-698v-4r3x-3vcv): missing Windows % escaping — moderate severity.\n- GHSA-r825-w8mm-5pxw (https://github.com/advisories/GHSA-r825-w8mm-5pxw): editor CLI argument misinterpretation — moderate severity.\n\nChanges:\n\n- Update Vite from `8.2.1` to `8.2.4`, which includes the editor-launching fixes.\n- Update the transitive launch-editor dependency used by webpack-dev-server from `2.14.1` to `2.14.2` in the lockfile.\n\n### What type of PR is it?\n\nBug Fix\n\n### How should this be tested?\n\nIn `zeppelin-web-angular/projects/zeppelin-react`:\n\n```sh\nnpm ci --ignore-scripts --no-audit\nnpm run apply:patches\nnpm run audit\nnpm test\n```\n\nAll commands passed locally. The React test suite passed with 28 test files and 262 tests.\n\nCloses #5583 from miinhho/npm-audit-hotfix.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "f801b2e4c2f0fae5e5e47ed6e12a2eda9069fd14",
      "tree": "c42e0c65a104a166971d76717f15bf0a1222664e",
      "parents": [
        "37ddc52e72d44b346661bf840b226537b0e4df64"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Tue Oct 20 22:50:00 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 20 22:50:00 2026 +0900"
      },
      "message": "[ZEPPELIN-6745] Add AI Assistant message and answer state UI\n\n### What is this PR for?\n\nAdd the AI Assistant message and answer state UI: user and Assistant messages are shown distinctly, and an answer displays its loading, streaming, tool-use, completed and error states. Everything is driven by fixture props. There is no server, transport or panel state. The components live in `projects/zeppelin-react/src/entities/assistant/ui`.\n\nThis PR adds new files under `entities/assistant/ui` and removes the temporary `Assistant/Setup` story. It builds on the shared contract from ZEPPELIN-6741 (#5561) and the Markdown answer from ZEPPELIN-6744 (#5570), both on `master`.\n\nCommits:\n1. **Message item and answer view types**\n   * `AssistantMessageItem` renders a question or an answer:\n     * A question is a right-aligned bubble, always shown as typed. It never goes through the content renderer.\n     * An answer is a full-width body under an \"AI / Assistant\" label. While it streams, it is marked `aria-busy` and shows a caret where the text ends.\n   * `AssistantAnswerView` is the display union (`loading` / `streaming` / `done` / `error`). It reuses `AssistantAnswerMessage` and `AssistantToolCallRef` from the ZEPPELIN-6741 contract.\n2. **Answer status, tool log and error displays**\n   * `AssistantAnswer` renders one view at a time. Each state fully replaces the last.\n   * The progress line (`role\u003d\"status\"`) reads \"Thinking…\", \"Writing answer…\" or \"Running \\\u003ctool\\\u003e…\".\n   * `AssistantToolLog` is open while a tool runs and collapses once the answer completes. A tool without a name is labelled \"Tool\".\n   * `AssistantAnswerError` is an antd `Alert` (`role\u003d\"alert\"`):\n     * `failed` (`run.failed`) and `stream` (`AssistantStreamError`) are errors with **Retry**.\n     * `connection` (`AssistantConnectionError`) is a warning with **Reload conversation**, because the answer may have finished on the server.\n     * With no `onRetry`, no button is shown.\n     * A partial answer that arrived before the error is kept.\n3. **Stories**\n   * `Assistant/Message`: User, CompletedReply, StreamingReply, LongContent, Conversation.\n   * `Assistant/Status`: Loading, Streaming, ToolRunning, Completed, CompletedWithTools, Failed, StreamError, ConnectionLost, ErrorWithoutRetry.\n   * `Assistant/Status/StateSwitcher` switches the fixture from the Controls panel, so you can check that the states stay consistent in both themes.\n4. **Review: remove the temporary theme check story**\n   * `Assistant/Setup › TemporaryThemeCheck` (`AssistantScope.stories.tsx`) was a placeholder until the Assistant UI stories landed. Nothing else referenced it.\n5. **Review: align the answer UI with segmented history** (by \u003cat\u003evoidmatcha)\n   * A completed answer is an `AssistantAnswerMessage` with ordered `segments`. Its text joins the rounds in order, and its tool log lists the tools from every round.\n   * Tools still marked running when an error arrives are shown as \"status unknown\", not as running or done.\n6. **Review: render answers as Markdown by default**\n   * `renderContent` now defaults to `MarkdownAnswer` from ZEPPELIN-6744. A parent can still pass its own, for example one that resolves paragraph references.\n   * `MarkdownAnswer` wraps the text in blocks, so the streaming caret is now drawn inside the last block (or the last item of a closing list). It stays on the line where the text ends instead of dropping below it.\n\nStyling uses `\u003cat\u003evanilla-extract/css` through the Assistant theme contract only, so light and dark need no per-component rules. The HTML/CSS screens in `voidmatcha/assistant-storybook-share` were used as a design reference. The code is written from scratch.\n\n**Out of scope** (per the issue / ZEPPELIN-6748): run event → view derivation, panel mounting in `AssistantWorkspace`, real tool calls, approval, persistence and WebSocket handling. Showing failed tool calls (raised in review) is tracked in ZEPPELIN-6754.\n\n### What type of PR is it?\nFeature\n\n### Todos\n* [x] Use the ZEPPELIN-6744 Markdown component as the default `renderContent` once it merges\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-6745\n\n### How should this be tested?\nIn `zeppelin-web-angular/projects/zeppelin-react`:\n* `npm ci`, `npm test` (254 passed), `npm run typecheck`, `npm run lint` and `npm run build:storybook` all pass.\n  * `typecheck` needs `npm ci` in `zeppelin-web-angular` first, because the SDK resolves `rxjs` from there.\n  * The new files also pass the frontend\u0027s `prettier --check`.\n* `npm run storybook`: both themes checked manually for every story above, including StateSwitcher.\n* The specs were mutation-checked: making the connection error say \"Retry\", keeping the progress line on error, dropping the \"Tool\" fallback, rendering a question through `renderContent`, keeping the tool log open, or going back to a plain-text default each fails exactly the intended test.\n\n**`npm run test:storybook`:**\n* With `--workers\u003d1`, all 68 tests pass.\n* With the default config (3 workers), 1–5 tests time out between runs.\n  * The traces show asset requests to the `python3 -m http.server` web server failing (status -1) and a blank page.\n  * On the earlier temporary base (`4599ad2d9`), its own story alone reproduced this: with `--repeat-each\u003d8`, 1–2 of 16 time out.\n  * So it is a problem with the existing smoke-test server, not with these stories. I left it untouched here.\n\n### Screenshots (if appropriate)\nSee the `Assistant/Message` and `Assistant/Status` stories.\n\n### Questions:\n* Does the license files need to update? No. There are no new dependencies.\n* Is there breaking changes for older versions? No. Only new files are added, plus the removal of a temporary story.\n* Does this needs documentation? No.\n\n\n\nCloses #5567 from kimyenac/ZEPPELIN-6745.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "37ddc52e72d44b346661bf840b226537b0e4df64",
      "tree": "dd1995649350bb0079b241cf5ee1fed4fdb787b7",
      "parents": [
        "bf658867be1067a208d3b41cd07cb0a3feb4ef06"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Tue Oct 20 20:09:53 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Oct 20 20:09:53 2026 +0900"
      },
      "message": "[ZEPPELIN-6746] Add AI Assistant question composer component\n\n### What is this PR for?\n\nAdd the AI Assistant question composer: a controlled component that takes a value, change and submit callbacks, and read-only and sending states. Nothing is sent anywhere. The parent receives the question and decides what to do with it. The component lives in `projects/zeppelin-react/src/entities/assistant/ui`.\n\nCommits:\n1. **Question composer**\n   * `AssistantComposer` is a `\u003cform\u003e` with an antd `Input.TextArea` (auto-sizing, 2–8 rows) and a **Send** `Button`.\n   * The value is controlled. `onSubmit` receives the question with surrounding whitespace trimmed. Clearing the input afterwards is left to the parent, so it can keep the text if sending fails.\n   * Nothing is submitted, by the button, Enter or the form, when:\n     * the input is empty or whitespace only (the server rejects a blank prompt with 400),\n     * `readOnly` is set (for example a conversation owned by another user). The textarea is disabled and a note explains why (`readOnlyReason`, with a default).\n     * `sending` is set (the server accepts one run per conversation). The textarea becomes read-only, so the question stays visible, and the button shows a spinner.\n   * Enter sends and Shift+Enter adds a new line. An Enter that confirms an IME composition (Korean, Japanese, …) does not send. Otherwise the last syllable of a Korean question would send it. Commit 3 extends this to Safari.\n2. **Stories**\n   * `Assistant/Composer`: Empty, Draft, WhitespaceOnly, Sending, ReadOnly.\n   * `Assistant/Composer/Playground` keeps its own value: type, send with the button or Enter, see `onSubmit` in the Actions panel and the input cleared.\n3. **Review: do not send on the Enter that confirms an IME composition in Safari** (by \u003cat\u003evoidmatcha)\n   * Safari fires `compositionend` before that Enter, so it arrives with `isComposing: false` and `keyCode: 229`. The check now covers both.\n4. **Review: pin the controlled value of the composer in tests** (by \u003cat\u003evoidmatcha)\n   * The field keeps showing the parent\u0027s value when `onChange` is ignored, and shows and sends a value the parent sets later. Both tests fail if `value` becomes `defaultValue`.\n5. **Review: raise the composer placeholder contrast**\n   * antd\u0027s placeholder colour was about 1.8:1 (light) and 2.3:1 (dark). It now uses the theme\u0027s `textTertiary`, which the theme lifts to 4.5:1. Measured in Storybook: 6.10:1 / 6.39:1 on the panel, 5.84:1 on the read-only field.\n\nStyling uses `\u003cat\u003evanilla-extract/css` through the Assistant theme contract only. The field draws a single focus ring for the textarea inside it. The HTML/CSS screens in `voidmatcha/assistant-storybook-share` were used as a design reference. The code is written from scratch.\n\n**Out of scope** (per the issue): per-conversation draft persistence, actual sending, Stop and retry. These belong to panel assembly (ZEPPELIN-6748) or follow-up issues.\n\n### What type of PR is it?\nFeature\n\n### Todos\n* [ ] - Task\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-6746\n\n### How should this be tested?\nIn `zeppelin-web-angular/projects/zeppelin-react`:\n* `npm ci`, `npm test` (247 passed, 8 new), `npm run typecheck`, `npm run lint` and `npm run build:storybook` all pass.\n  * `typecheck` needs `npm ci` in `zeppelin-web-angular` first, because the SDK resolves `rxjs` from there.\n  * The new files also pass the frontend\u0027s `prettier --check`.\n* `npm run storybook`: every story above checked in both themes, including typing Korean and pressing Enter mid-composition in Playground (Chrome). Safari was not tried; commit 3 is covered by a `keyCode: 229` unit test.\n* The spec was mutation-checked: dropping the IME check, the Safari `keyCode` check, the trim, the sending guard, the read-only guard or the read-only textarea while sending, or using `defaultValue`, each fails the intended test.\n* `npm run test:storybook -- --workers\u003d1`: all 52 tests pass. It runs with one worker because the default 3 workers made the existing `python3 -m http.server` web server drop requests on the earlier base, independent of these stories (see #5567).\n\n### Screenshots (if appropriate)\nSee the `Assistant/Composer` stories.\n\n### Questions:\n* Does the license files need to update? No. There are no new dependencies.\n* Is there breaking changes for older versions? No. Only new files are added.\n* Does this needs documentation? No.\n\n\n\nCloses #5569 from kimyenac/ZEPPELIN-6746.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "bf658867be1067a208d3b41cd07cb0a3feb4ef06",
      "tree": "69847a5e2b0dc025d01e7b3776ead571b6a5442e",
      "parents": [
        "d01a1c3db804a036f319e2652b17196c7fdade8b"
      ],
      "author": {
        "name": "Lee SuJung",
        "email": "153787023+xhaktm00@users.noreply.github.com",
        "time": "Sun Oct 18 16:47:33 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 16:47:33 2026 +0900"
      },
      "message": "[ZEPPELIN-6747] Add AI Assistant conversation list and header components\n\n### What is this PR for?\r\n\r\nAdd `ConversationList` and `ConversationHeader`, the Assistant panel\u0027s conversation browsing UI, reviewable in Storybook without a server.\r\n\r\n**Components**\r\n* `ConversationList`\r\n  * Takes conversation data and the selection state as props\r\n  * Shows the list, search results, and an empty state\r\n  * Shows \"No conversations match your search.\" while a search is active and \"No conversations yet.\" otherwise, so the message stays correct when the panel passes an already-filtered list\r\n* `ConversationHeader`\r\n  * Shows the inner header for the selected conversation\r\n* Both report new conversation, selection, delete requests, and search term changes through callbacks\r\n* Deletion and its confirmation step are left to panel assembly (ZEPPELIN-6748)\r\n\r\n**Beyond the acceptance criteria**\r\n* The list groups conversations into \"Today\" (with a relative time) and \"Earlier\", within the issue\u0027s design latitude\r\n* Search shows a flat result list without sections\r\n* Read-only conversations (`canSendMessage \u003d\u003d\u003d false`) show a lock and no delete button, and the read-only state is announced to screen readers\r\n\r\n**Title handling**\r\n* `title` is optional in the contract, and the server preserves an explicit empty title on create\r\n* A missing or empty title is shown as \"Untitled conversation\" in the list, the header, the row button name, and both delete labels, through a shared `conversationTitle` helper\r\n* Search matches the displayed title, so an untitled conversation is found by \"untitled\"\r\n\r\n**Dependencies**\r\n* #5561 is merged and this branch is rebased onto master\r\n* Depends on #5565 (ZEPPELIN-6743) per Jira\r\n\r\n### What type of PR is it?\r\n\r\nFeature\r\n\r\n### Todos\r\n\r\n* [x] Add `ConversationList` with search, distinct empty states, \"Today\"/\"Earlier\" sections, and delete requests\r\n* [x] Add `ConversationHeader` for the selected conversation\r\n* [x] Hide the delete button for read-only conversations\r\n* [x] Expose the read-only state and relative time to screen readers\r\n* [x] Show \"Untitled conversation\" for a missing or empty title, and match it in search\r\n* [x] Key the empty-result message on whether a search is active\r\n* [x] Check the second conversation\u0027s ID in the select and delete tests and story\r\n* [x] Add stories for the empty list, search, and select and delete, plus a selected conversation, \"Today\"/\"Earlier\", and the header states\r\n* [x] Add unit tests for filtering, sections, callbacks, the fallback title, the read-only marker, and relative time formats\r\n* [x] Rebase onto master and fill the fields the master contract requires in fixtures\r\n\r\n### What is the Jira issue?\r\n\r\nZEPPELIN-6747\r\n\r\n### How should this be tested?\r\n\r\nRun from `zeppelin-web-angular/projects/zeppelin-react/`:\r\n\r\n```bash\r\nnpm ci\r\nnpm test\r\nnpm run typecheck\r\nnpm run lint\r\nnpm run build:storybook\r\nnpm run test:storybook\r\nnpm run storybook\r\n```\r\n\r\n`npm test` runs 22 files and 208 tests, 26 of them new. `npm run test:storybook` runs every story in both themes (40 tests) and needs Playwright Chromium. In Storybook, check `Assistant/ConversationList` (Empty, Search, Selected, SelectAndDelete, TodayAndEarlier) and `Assistant/ConversationHeader` (Current, NoSelection, ReadOnly) in both the light and dark themes.\r\n\r\n### Screenshots (if appropriate)\r\n\r\nN/A\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\n\nCloses #5575 from xhaktm00/ZEPPELIN-6747.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "d01a1c3db804a036f319e2652b17196c7fdade8b",
      "tree": "00c7e02909b2bb006c4374d94e016f83a6d4f884",
      "parents": [
        "76a7153885a652ddd1c945fbcd08f97bf4528cd8"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Oct 18 16:07:31 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 16:07:31 2026 +0900"
      },
      "message": "[ZEPPELIN-6742] Connect the AI Assistant frontend to conversation REST and WebSocket APIs\n\n### What is this PR for?\n\nConnect the Assistant frontend to the conversation REST and WebSocket APIs. The transport provides conversation creation and retrieval, message sending, and response delivery for the UI.\n\nServer PR #5547, #5558, and UI contracts #5561 have merged. This PR is now based on master.\n\n### What type of PR is it?\n\nFeature\n\n### Todos\n\n* [x] Merge #5547\n* [x] Merge #5558\n* [x] Merge #5561 before this PR\n* [x] Rebase onto master, retarget this PR to master, and rerun CI before merging\n* [x] Compare against the final API contract from server PR #5547\n* [x] Confirm CI on the current PR head\n\n### What is the Jira issue?\n\nZEPPELIN-6742\n\n### How should this be tested?\n\nRun from `zeppelin-web-angular/`:\n\n```bash\nnpm run build-project:sdk\nnpm run typecheck:react\nnpm --prefix projects/zeppelin-react test -- src/entities/assistant/model/assistantTransport.spec.ts\n```\n\nAlso verify the REST and WebSocket integration against the final API contract from server PR #5547.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5563 from voidmatcha/voidmatcha/assistant-v2-6-transport.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "76a7153885a652ddd1c945fbcd08f97bf4528cd8",
      "tree": "191cf0aed6a43fd28711e31f179ac234276c95ba",
      "parents": [
        "2f16789d4b4d0faa29fb861698c2e13cea89dd82"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Oct 18 16:07:00 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 16:07:00 2026 +0900"
      },
      "message": "[ZEPPELIN-6743] Mount an opt-in AI Assistant shell in the notebook sidebar\n\n### What is this PR for?\n\nAdd an opt-in AI Assistant button and empty panel shell to the notebook sidebar. With `?reactAssistant\u003dtrue`, the Angular notebook mounts the React shell, coordinates it with the file tree and table of contents, and shares the sidebar width for resizing. The panel closes when the active note changes and reports the failure and removes the button if the React remote fails to load.\n\nThis establishes the notebook mount point for later conversation UI work. Conversation components, server transport, and message handling are outside this PR.\n\n#5558 and #5561 have merged. This PR is now based on master.\n\n### What type of PR is it?\n\nFeature\n\n### Todos\n\n* [x] Merge #5558 and #5561 before this PR\n* [x] Rebase onto master and retarget this PR to master before merging\n* [x] Confirm CI results\n\n### What is the Jira issue?\n\nZEPPELIN-6743\n\n### How should this be tested?\n\nRun from `zeppelin-web-angular/`:\n\n```bash\nnpm run build-project:sdk\nnpm run typecheck:react\nnpm --prefix projects/zeppelin-react test -- src/pages/AssistantWorkspace.spec.tsx\nnpm run test:shell -- src/app/pages/workspace/notebook/assistant src/app/pages/workspace/notebook/sidebar/sidebar.component.spec.ts src/app/services/react-feature.service.spec.ts\nnpm run lint\nnpm run build:react\n```\n\nIn an authenticated notebook, open `?reactAssistant\u003dtrue` and check opening, closing, resizing, switching sidebar sections, and switching notes. Confirm that the button is absent without the flag and in view-only and revision views.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\n\n\nCloses #5565 from voidmatcha/voidmatcha/assistant-sidebar-shell.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "2f16789d4b4d0faa29fb861698c2e13cea89dd82",
      "tree": "13f6dbf776a4bd0939413dabd455771a7ed1a394",
      "parents": [
        "796c8c094f0324a12495a133deec255ea25be7ac"
      ],
      "author": {
        "name": "HwangRock",
        "email": "157935545+HwangRock@users.noreply.github.com",
        "time": "Sun Oct 18 15:34:13 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 18 15:34:13 2026 +0900"
      },
      "message": "[ZEPPELIN-5758] Raise BigQuery HTTP client timeout so large wait_time values work\n\n### What is this PR for?\n`zeppelin.bigquery.wait_time` is passed to BigQuery\u0027s `jobs.query` as the server-side `timeoutMs`, telling the server how long to wait for the query result before replying. The HTTP client (`NetHttpTransport`), however, kept its default read timeout (~20s). As a result, setting `wait_time` beyond that threshold threw `java.net.SocketTimeoutException: Read timed out` before the server responded, making the setting unusable above ~30s.\n\nThis wraps the Bigquery client credential in an `HttpRequestInitializer` that sets the connect/read timeouts to 200s. BigQuery\u0027s `getQueryResults` always returns within ~200s regardless of whether the job has completed, so a larger timeout provides no value. The credential\u0027s own `initialize()` is still invoked first, so OAuth token refresh behavior is preserved.\n\n### What type of PR is it?\nBug Fix\n\n### Todos\n* [x] - Wrap the client credential with connect/read timeouts\n* [x] - Add a unit test\n\n### What is the Jira issue?\nhttps://issues.apache.org/jira/browse/ZEPPELIN-5758\n\n### How should this be tested?\n* `./mvnw test -pl bigquery --am -Dtest\u003dBigQueryInterpreterTimeoutTest`\n* `BigQueryInterpreterTimeoutTest` verifies the initializer delegates to the wrapped credential and applies the 200s connect/read timeouts. It is a separate class because `BigQueryInterpreterTest` is excluded from the build (it needs live BigQuery credentials).\n\n### Questions:\n* Does the license files need to be updated? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\nCloses #5545 from HwangRock/ZEPPELIN-5758-bigquery-read-timeout.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "796c8c094f0324a12495a133deec255ea25be7ac",
      "tree": "7c0c4671da7cec692c7d8417a8d27150868e91f0",
      "parents": [
        "c10a4a8eb3826ec015745cec3f2eb3ca8e270bf3"
      ],
      "author": {
        "name": "SeungYoung Oh",
        "email": "seung-00@naver.com",
        "time": "Sat Oct 17 02:26:57 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 02:26:57 2026 +0900"
      },
      "message": "[ZEPPELIN-6340] Add ZeppelinEventBus and update NotebookServer to handle NoteRemoveEvent\n\n### What is this PR for?\r\n\r\nThis PR is the first step toward migrating Zeppelin’s listener-based event handling to an EventBus model, as outlined in the [proposal](https://cwiki.apache.org/confluence/x/vAsGFw). It sets up the EventBus infrastructure and migrates `NoteRemoveEvent` handling to it.\r\n\r\nKey changes:\r\n\r\n* Added the `ZeppelinEventBus` class\r\n* Added RxJava 3 as a dependency of the `zeppelin-zengine` module\r\n* Added the `zeppelin.eventbus.enabled` feature flag\r\n* Updated `NotebookServer` to handle `NoteRemoveEvent` through `ZeppelinEventBus` when the feature flag is enabled\r\n\r\nThis PR supersedes #5085. The original branch had fallen behind the current codebase, and the implementation has since changed, so I opened a new PR.\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [ ] Refactor other NoteEventListener methods and additional listeners to EventBus\r\n\r\n### What is the Jira issue?\r\n* Open an issue on Jira https://issues.apache.org/jira/browse/ZEPPELIN-6340\r\n\r\n### How should this be tested?\r\n- Run the existing test suite against the updated code  \r\n- Verify the note deletion flow through the UI\r\n\r\n### Screenshots (if appropriate)\r\n\r\n### Questions:\r\n* Does the license files need to update? N\r\n* Is there breaking changes for older versions? N\r\n* Does this needs documentation? N\n\nCloses #5441 from seung-00/ZEPPELIN-6340.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "c10a4a8eb3826ec015745cec3f2eb3ca8e270bf3",
      "tree": "c25cf3e4301485eaed276d50c0709e830932d041",
      "parents": [
        "f34835854a2a67ef0e8c86de8e151d810c4fa7c4"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sat Oct 17 02:25:34 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 02:25:34 2026 +0900"
      },
      "message": "[ZEPPELIN-6741] Define shared AI Assistant UI contracts and message history behavior\n\n### What is this PR for?\r\n\r\nDefine the shared types and message history behavior used by the Assistant UI and its host. This gives subsequent UI work a common contract to build against.\r\n\r\nDepends on #5558.\r\n\r\n### What type of PR is it?\r\n\r\nImprovement\r\n\r\n### Todos\r\n\r\n* [x] Merge #5558 before this PR\r\n* [x] Rebase onto master and retarget this PR to master before merging\r\n* [x] Confirm CI results\r\n\r\n### What is the Jira issue?\r\n\r\nZEPPELIN-6741\r\n\r\n### How should this be tested?\r\n\r\nRun from `zeppelin-web-angular/`:\r\n\r\n```bash\r\nnpm run build-project:sdk\r\nnpm run typecheck:react\r\nnpm --prefix projects/zeppelin-react test -- src/entities/assistant/model/messageHistory.spec.ts\r\n```\r\n\r\n### Screenshots (if appropriate)\r\n\r\nN/A\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5561 from voidmatcha/voidmatcha/assistant-v2-3-contracts.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "f34835854a2a67ef0e8c86de8e151d810c4fa7c4",
      "tree": "03a79d5c0a5893643772516a9c3718569e5bef94",
      "parents": [
        "0d344fb7b1318438c98b25fae317543792b962f7"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sat Oct 17 02:22:42 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 17 02:22:42 2026 +0900"
      },
      "message": "[ZEPPELIN-6738] Disable Ant Design motion in React surfaces\n\n### What is this PR for?\n\nFollow up on #5558 by simplifying how the React remote handles theme motion. The current implementation adds a document-wide class during a theme change and removes it after two animation frames. This PR removes that class, timer, and CSS rule, and uses Ant Design\u0027s `motion: false` token instead.\n\nThis disables Ant Design motion across React surfaces, in line with the Angular UI\u0027s existing transition reset. Custom Assistant panel transitions remain unchanged.\n\n### What type of PR is it?\n\nImprovement\n\n### Todos\n\n* [x] Compare theme switching in a live notebook with transitions disabled.\n\n### What is the Jira issue?\n\nZEPPELIN-6738\n\n### How should this be tested?\n\nFrom `zeppelin-web-angular/projects/zeppelin-react/`:\n\n```bash\nnpm test\nnpm run typecheck\nnpm run build\n```\n\nThe full React suite passed (125 tests), as did the typecheck, production build, and ESLint on the changed files. The live notebook as-is/to-be comparison showed no visible issues. It used a CSS preview before this PR build; the Ant Design motion token is covered by the React tests and production build.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5573 from voidmatcha/voidmatcha/assistant-theme-motion.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "0d344fb7b1318438c98b25fae317543792b962f7",
      "tree": "0ff7379681716f21f6a713bd8e9444335b833a2f",
      "parents": [
        "baeff2f5b8ceb0f3932bb66af7a61d760931ae66"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Fri Oct 16 23:29:03 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 23:29:03 2026 +0900"
      },
      "message": "[ZEPPELIN-6751] Prevent automatic image requests in AI Assistant answers\n\n### What is this PR for?\r\n\r\nAddresses the image-loading follow-up raised in [#5570](https://github.com/apache/zeppelin/pull/5570#issuecomment-6158231443).\r\n\r\nModel-generated Markdown can include image URLs containing notebook data. Loading these images automatically sends a request to the destination without user interaction.\r\n\r\nThis PR replaces automatic image loading with a **Load image** button. Before loading, the reader can review the image description, destination host, full URL, and a warning that the request may transmit information from the answer. Only HTTP(S) image URLs are supported.\r\n\r\nApproval is specific to each image in an answer. Unchanged images retain approval during streaming, including when a reference definition gains a title. Changing the destination or removing and restoring an image requires fresh approval.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6751\r\n\r\n### How should this be tested?\r\n\r\nFrom `zeppelin-web-angular/projects/zeppelin-react`, run:\r\n\r\n```bash\r\nnpm test -- src/entities/assistant/ui/MarkdownAnswer.spec.tsx\r\nnpm run typecheck\r\nnpm run build:storybook\r\nnpm run test:storybook -- markdown-answer-images.spec.mjs\r\n```\r\n\r\nFor manual verification, run `npm run storybook` and open **Assistant / MarkdownAnswer**:\r\n\r\n1. In **Image Loading**, inspect the browser’s Network panel. Confirm that no image request is sent before activation. Use Enter or Space to activate **Load image** and confirm that only the selected image loads.\r\n2. In **Streaming Images**, load the image and append the next chunk. Confirm that the image remains loaded while its destination is unchanged. When a later chunk changes the destination, confirm that the new URL is displayed and requires another activation before loading.\r\n3. Using the image story’s `content` control, remove an approved image and restore the same Markdown. Confirm that it requires approval again.\r\n\r\n### Questions\r\n\r\n- **License changes?** No.\r\n- **Breaking changes?** No.\r\n- **Documentation?** The React README explains image loading and the destination warning.\r\n\n\nCloses #5572 from miinhho/assistant-image-loading-policy.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "baeff2f5b8ceb0f3932bb66af7a61d760931ae66",
      "tree": "e917b3576a30a8e3686d5583fe1d7cc601ff1800",
      "parents": [
        "a041e9422cf623a423dde0fd00cd013438f494a2"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Fri Oct 16 23:20:01 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 23:20:01 2026 +0900"
      },
      "message": "[ZEPPELIN-6744] Add AI Assistant Markdown answer component\n\n### What is this PR for?\n\nAdd a React Markdown answer component for the AI Assistant.\n\nThe component renders GFM tables and language-labelled code blocks, supports unclosed code fences during streaming, and reports paragraph reference clicks through a callback. HTML is displayed as text and dangerous link URLs are blocked.\n\nIncludes Storybook examples and unit tests for rendering, input updates, paragraph references, and unsafe content.\n\n### What type of PR is it?\n\nFeature\n\n### What is the Jira issue?\n\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6744\n\n### How should this be tested?\n\nFrom `zeppelin-web-angular/projects/zeppelin-react`:\n\n```bash\nnpm ci\nnpm test -- --maxWorkers\u003d1\nnpm run typecheck\nnpm run lint\nnpm run build:storybook\nnpm run storybook\n```\n\nOpen **Assistant / MarkdownAnswer** and check both light and dark themes:\n\n- **GfmTable / SqlCode**: confirm tables and long code lines scroll within the answer, and code blocks show their language.\n- **PartialFence / Streaming**: confirm an unclosed fence remains readable as chunks arrive and the following paragraph appears after the fence closes.\n- **ParagraphReference**: click the reference and confirm its ID and name appear in the callback status.\n- **DangerousContent**: confirm HTML appears as text and dangerous URLs are not navigable.\n\n### Questions:\n\n* Does the license files need to update?\n  Yes. MIT license entries and texts for react-markdown and remark-gfm are included.\n\n* Is there breaking changes for older versions?\n  No existing public API is changed.\n\n* Does this needs documentation?\n  The React README includes a short component description and a pointer to its Storybook examples.\n\n\nCloses #5570 from miinhho/ZEPPELIN-6744-markdown-answer.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "a041e9422cf623a423dde0fd00cd013438f494a2",
      "tree": "c2c41abfbd529398062e007c9250cf15d5fde0d2",
      "parents": [
        "f1bb1b9a6e3b0ea4858f6a33f3089b2d455f7916"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Fri Oct 16 22:24:30 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 16 22:24:30 2026 +0900"
      },
      "message": "[ZEPPELIN-6735] Fix code editor model leaks and diff updates\n\n### What is this PR for?\r\n\r\nThe shared code editor leaves its Monaco text models behind when destroyed. This affects the regular paragraph editor.\r\n\r\nIn diff mode, the initial original and modified text are reversed. Value changes create new models, and changing only `nzOriginalText` does not update the original text.\r\n\r\nThis PR disposes of component-owned models, fixes the diff orientation, and updates the existing models when either input changes.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### Todos\r\n\r\n* [x] Fix model disposal and diff initialization and updates.\r\n* [x] Add regression tests.\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6735\r\n\r\n### How should this be tested?\r\n\r\nRun the regression tests from `zeppelin-web-angular`:\r\n\r\n```sh\r\nnpm run test:shell -- src/app/share/code-editor/code-editor.component.spec.ts\r\n```\r\n\r\nMake sure that the tests pass for these behaviors:\r\n\r\n* Diff mode displays the original text on the left and the modified text on the right.\r\n* Value changes update the existing models rather than create new ones.\r\n* Changing only `nzOriginalText` leaves the modified text unchanged.\r\n* Destroying the component disposes of its models but leaves caller-owned models intact.\r\n* Normal-mode writes update the attached model after a caller replaces it.\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No.\r\n* Is there breaking changes for older versions? No.\r\n* Does this needs documentation? No.\r\n\n\nCloses #5574 from miinhho/ZEPPELIN-6735-code-editor-model-lifecycle.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "f1bb1b9a6e3b0ea4858f6a33f3089b2d455f7916",
      "tree": "73745a7233cb6cbf79ceb8d2c7cfb51d1fa487b3",
      "parents": [
        "c4ac5d65621b895dee19cc7f99d68020604ef579"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Thu Oct 15 23:47:43 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 15 23:47:43 2026 +0900"
      },
      "message": "[ZEPPELIN-6740] Add local Storybook foundation for AI Assistant UI\n\n### What is this PR for?\n\nAdd a local Storybook foundation so contributors can inspect and test Assistant UI components without running a Zeppelin server. This PR includes a temporary theme-check story; later UI work can add component and interaction stories. Hosted previews can be shared separately when needed.\n\nApache Superset documents a similar workflow in its [Storybook guide](https://superset.apache.org/developer-docs/testing/storybook/) and provides a [public component reference](https://apache-superset.github.io/superset-ui/?path\u003d/story/*).\n\nDepends on #5558.\n\n### What type of PR is it?\n\nImprovement\n\n### Todos\n\n* [x] Merge #5558 before this PR\n* [x] Rebase onto master and retarget this PR to master before merging\n* [x] Verify the local Storybook build and browser tests\n\n### What is the Jira issue?\n\nZEPPELIN-6740\n\n### How should this be tested?\n\nRun from `zeppelin-web-angular/projects/zeppelin-react/`:\n\n```bash\nnpm ci\nnpm run storybook\nnpm run build:storybook\nnpx playwright install chromium\nnpm run test:storybook\nnpm test -- src/shared/ui/assistant-theme\n```\n\nThe browser tests serve the built output locally. Set `STORYBOOK_PORT` if port 6007 is occupied.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? Yes. The bundled vanilla-extract packages are listed; Storybook is credited in the frontend README.\n* Is there breaking changes for older versions? No\n* Does this needs documentation? Yes. Local Storybook commands are documented.\n\n\n\n\nCloses #5562 from voidmatcha/voidmatcha/assistant-v2-4-storybook.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "c4ac5d65621b895dee19cc7f99d68020604ef579",
      "tree": "1a5db3ab04d3192e40f97800f23d8eabee3c4e59",
      "parents": [
        "a865c949ff0841dc09bae28026a550af05699638"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Thu Oct 15 22:55:29 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 15 22:55:29 2026 +0900"
      },
      "message": "[ZEPPELIN-6738] Upgrade React to 19 and fix shared host integration\n\n### What is this PR for?\n\nUpgrade the React remote to React 19 and fix shared integration behavior between the Angular host and React surfaces.\n\nThese changes were identified during the notebook Assistant frontend work and are separated from that feature so they can be merged without its server changes.\n\n* Upgrade React, ReactDOM and their type definitions, with Ant Design compatibility updates.\n* Preserve host callback return values and stable wrapper identity so subscriptions can clean up correctly and avoid unnecessary restarts.\n* Extract the existing 401 redirect and 405 logout policy into `TicketService.handleAuthFailure`, preserving logout guards. This prepares a shared entry point for later remote integrations; connecting Assistant requests is outside this PR.\n* Commit React theme updates before the next paint and temporarily suppress document-wide CSS transitions during theme switching.\n\nThe callback, authentication and theme fixes do not inherently require React 19.\n\n### What type of PR is it?\n\nImprovement\n\n### Todos\n\n* [x] Complete automated verification on the PR branch.\n* [x] Check existing Ant Design surfaces and rapid theme switching in a browser.\n\n### What is the Jira issue?\n\nZEPPELIN-6738\n\n### How should this be tested?\n\n* Run the React unit tests, typecheck and lint.\n* Run the Angular shell tests and SDK contract typecheck.\n* Build the React remote and Angular application.\n\nProduction builds passed on the prerequisite branch. Chrome checks passed for repository form editing and cancellation, Select interaction, configuration table rendering and 18 rapid theme toggles, with no page errors.\n\nRepository and configuration responses used browser-local fixtures because the QA repository list was empty. No server settings were saved.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5558 from voidmatcha/voidmatcha/assistant-prerequisites.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "a865c949ff0841dc09bae28026a550af05699638",
      "tree": "bb90907df38cd70d3834dfc81a6f5705d8a94c6d",
      "parents": [
        "e8d710f3689e763fe53a1efcd0f07f93c4b15eea"
      ],
      "author": {
        "name": "Lee SuJung",
        "email": "153787023+xhaktm00@users.noreply.github.com",
        "time": "Thu Oct 15 20:50:17 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 15 20:50:17 2026 +0900"
      },
      "message": "[ZEPPELIN-6454] Stabilize and re-enable flaky PyFlink streaming SQL tests\n\n### What is this PR for?\n\nRe-enables `IPyFlinkInterpreterTest.testCancelStreamSql`. The two other disabled\ncases are a different situation and are left alone.\n\nWhy this one can be re-enabled:\n\n- `PyFlinkInterpreterTest.testCancelStreamSql` calls the same static\n  `IPyFlinkInterpreterTest.testCancelStreamSql` helper and is not disabled, so it\n  runs on every build. The cancel logic is already covered in CI; only the\n  IPython variant was left off.\n- The disabling commit `62a892792` (2021-03-03) also raised the Flink log levels\n  from WARN to INFO. No issue or PR is linked to it.\n- Eight days later `ZEPPELIN-5284` landed: on Flink 1.12 the interpreter updated\n  a copied `Configuration`, so savepoints and checkpoints did not work. Same area\n  as the hotfix, and fixed since.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Remove `\u003cat\u003eDisabled` from the IPython variant\n* [x] Confirm it passes locally\n* [x] Confirm on CI, where the runner is slower than a dev machine\n\n### What is the Jira issue?\n* [ZEPPELIN-6454](https://issues.apache.org/jira/browse/ZEPPELIN-6454)\n\n### How should this be tested?\n\n```\n./mvnw clean install -pl flink/flink-scala-2.12 --am -Pflink-1.20 -DskipTests\n./mvnw test -pl flink/flink-scala-2.12 -Pflink-1.20 -Dtest\u003dIPyFlinkInterpreterTest#testCancelStreamSql\n```\n\nTwo prerequisites:\n\n- `clean` is needed on the install step. Without it the Scala sources are skipped\n  and the test fails to compile with `FlinkScalaInterpreter cannot be resolved to\n  a type`.\n- A PyFlink environment has to be on `PATH`, since the test hardcodes\n  `zeppelin.pyflink.python\u003dpython` (I used a venv with `apache-flink\u003d\u003d1.20.0`).\n\nRan four times, all passing:\n\n```\nTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 104.7 s\nTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 102.9 s\nTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 104.0 s\nTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 102.8 s\n```\n\nCI job: `flink-test-and-flink-integration-test` in `core.yml` (java 17 /\nflink-1.20).\n\nTwo limits:\n\n- The flakiness did not reproduce. Besides the four runs above, 12 earlier runs\n  also passed (8 unloaded, 1 under heavy load, 3 under moderate load). Load moved\n  the duration from 108s to 114s, so the helper\u0027s 20-second wait was never close\n  to insufficient here. A slower CI runner is the case I cannot reproduce\n  locally.\n- Historical CI logs are gone. The oldest retained workflow run in this repo is\n  from 2025-07-28, years after the test was disabled.\n\nIf it does fail on CI, that failure is the first concrete evidence about this\ntest, and it can go back to being disabled with that evidence attached.\n\n### Why the savepoint tests stay disabled\n\n- `testResumeStreamSqlFromSavePoint` (both variants) was committed in\n  `3cf32a093` (2020-04-02) with `// \u003cat\u003eTest` already commented out, so it has never\n  run in CI.\n- That is not stabilizing a flaky test but making a never-verified test work, and\n  it needs its own investigation.\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5571 from xhaktm00/ZEPPELIN-6454.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "e8d710f3689e763fe53a1efcd0f07f93c4b15eea",
      "tree": "568cee80c6d6d2dfaf49159aff5d1ee81b9d4dfa",
      "parents": [
        "de1d7a9e02a14436e1791838f74f12a2850490ef"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Wed Oct 14 22:39:41 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 14 22:39:41 2026 +0900"
      },
      "message": "[ZEPPELIN-6737] Connect a private read-only Angular notebook view to Shared Notebook Core\n\n### What is this PR for?\n\nConnect the Shared Notebook Core read state from ZEPPELIN-6736 to a private, read-only Angular notebook view that reads real notebook and revision data. The view is opt-in for development and testing with `?notebookCoreRead` on a notebook URL (`#/notebook/\u003cid\u003e?notebookCoreRead`, also under `/revision/\u003crevisionId\u003e`). Without the flag the editable notebook route is unchanged.\n\nCommits:\n\n1. **Server**: `GET_NOTE` and `NOTE_REVISION` replies, their `AUTH_INFO` and `ERROR_INFO` failures, and errors from the top-level `onMessage` handler for these two requests carry the request `msgId`. Broadcasts, other operations and requests without a `msgId` keep their previous payloads.\n2. **SDK and read transport**: `getNote` and `noteRevision` return the `msgId` they sent. `NotebookReadTransport` subscribes before it sends, accepts only the first reply carrying its `msgId`, then stops listening. It bounds each read with a timeout and keeps the Core\u0027s ACL handle for the permissions REST read, so an old success or failure cannot apply.\n3. **Host**: `NotebookCoreReadHost` owns one read store and one frozen `NotebookPort` for one private route lifetime. It reads only while the Shell\u0027s socket is connected, replaces loaded state with `failed` when the connection drops, reads again after the Shell reconnects without a reconnect loop of its own, and disposes once.\n4. **View and route**: a `canMatch` guard on the existing route boundary (ZEPPELIN-6675) selects `NotebookCoreReadComponent`. The component renders snapshots through a reused Observable (`async` pipe, OnPush) and does not mount the editable paragraph components.\n5. **Real-route E2E**.\n6. **Read captures and replay**.\n\n#### Read operations\n\n| Included | Path |\n| --- | --- |\n| Live note | `GET_NOTE` → `NOTE` with the request `msgId` |\n| Revision | `NOTE_REVISION` → `NOTE_REVISION` with the request `msgId`. A `NOTE` broadcast does not change a loaded revision |\n| Permissions | `GET /api/notebook/{noteId}/permissions`; `403` is `access-denied`, other failures `failed`, and permissions stay unknown on failure |\n| Forbidden | `AUTH_INFO` with the request `msgId` → `access-denied` |\n| Other failures | `ERROR_INFO` with the request `msgId`, an empty reply, or a timeout → `failed` |\n\nA missing note is reported as `failed`. The server only describes it in `ERROR_INFO` text, which this PR does not parse. The server also answers the permissions read of a missing note with `200`, so the view shows permissions only for a loaded note.\n\nExcluded: run, cancel, save, commit, patch, form and configuration changes, incremental paragraph and output updates, collaboration, Angular objects, ACL writes and reconnect recovery beyond reading again. The view sends no message other than its reads, including while it mounts and unmounts.\n\nSaved results rendered: `TABLE` (with persisted chart settings), `TEXT`, `HTML`, `IMG`, `SVG`, `NULL`. Shown as not rendered: `ANGULAR` (needs live Angular objects), `NETWORK` (no Angular renderer) and unknown types. The result component writes defaults into its config while it renders (`renderGraph` → `setDefaultConfig`), so it receives a per-render copy of the frozen chart settings that is never sent back.\n\n#### Fixture provenance\n\n`e2e/fixtures/notebook-read/read-anonymous.json` and `read-denied.json` were captured from this branch (server and UI built from the PR commits), because the replies depend on the server change above, which is not on Apache master yet. They are kept apart from the seven lifecycle captures and their inventory, and `metadata.source` names the branch commit. The core-contract README says to recapture them from master once this is merged. `AUTH_INFO` prints account names in its text, so the capture replaces them with `\u003cuser\u003e`. The ACL and error evidence here covers the reads of this view only; the rest of ZEPPELIN-6673 (ACL writes, REST 401/405, `SESSION_LOGOUT`) is left to that issue.\n\n### What type of PR is it?\nFeature\n\n### Todos\n* [ ] - Recapture `e2e/fixtures/notebook-read/` from Apache master after this is merged\n* [ ] - ZEPPELIN-6673 for the remaining permission, authentication and Shell error fixtures\n\n### What is the Jira issue?\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6737\n\n### How should this be tested?\n\nServer (`NotebookServerTest`, 36 tests; 6 new):\n\n```bash\n./mvnw test -pl zeppelin-server -Dtest\u003dNotebookServerTest\n```\n\nThe new tests cover the `msgId` on `NOTE`, `NOTE_REVISION`, `AUTH_INFO` and `ERROR_INFO` read replies, on the top-level exception path for both reads, and its absence on requests without a `msgId`, on an unrelated operation\u0027s failure and top-level error, and on `NOTE` broadcasts. Removing each server change made the corresponding test fail.\n\nFrontend, from `zeppelin-web-angular`:\n\n```bash\nnpm run test:shell                    # 292 passed\nnpm run typecheck:sdk-contracts\nnpm run check:core-contract-fixtures  # 150 passed\nnpm run build:notebook-core-port-proof \u0026\u0026 npm run test:notebook-route-boundary\nnpm run build:projects \u0026\u0026 ng build --configuration production\n```\n\nThe core-read unit tests cover the transport (listen-before-send, `msgId` matching, duplicate, late, post-timeout and post-cancel replies, A → B → A, permission success and failure for an earlier activation), the host (port identity, connection loss and reconnect, exactly-once teardown), the view model and the component (only reads are sent on mount, route changes and unmount). Breaking each of these behaviors made a test fail. The replay spec runs both captures through the production transport and Core, and fails if the captured replies lose their `msgId`.\n\nReal-route Playwright (`e2e/tests/notebook/core-read/notebook-core-read.spec.ts`), Chromium, against a server built from this branch:\n\n* anonymous: 7 passed, the denied-read test skipped (it needs two Shiro accounts)\n* authenticated (`conf/shiro.ini.template` with `admin` added to `user1`, as in CI): 8 passed\n\nA Playwright WebSocket route records every frame the page sends and holds, injects or drops server frames. Removing the `msgId` check made the pending-read broadcast test fail, and keeping loaded state on a dropped connection made the reconnect test fail.\n\nDefault notebook regression with the flag off (authenticated, `tests/notebook/{main,paragraph,persistence,revision}`): 25 passed, 6 failed for local environment reasons, not this change: 4 React footer tests (the React remote was not built for this local dist, `remoteEntry.js` 404) and 2 `%python` execution tests (no working local Python interpreter). Full CI covers both legs.\n\nNot run locally: Firefox and WebKit, and the full E2E suite.\n\nCaptures were recorded with:\n\n```bash\nZEPPELIN_READ_CAPTURE_COMMIT\u003d$(git rev-parse HEAD) PLAYWRIGHT_BASE_URL\u003d\u003cserver\u003e \\\n  npm run e2e:core-contract:live -- read-fixtures\n```\n\n### Screenshots (if appropriate)\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No. Clients that send no `msgId` get the same payloads, and the SDK methods only gain a return value.\n* Does this needs documentation? The read captures are documented in the core-contract README.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5568 from kimyenac/ZEPPELIN-6737.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "de1d7a9e02a14436e1791838f74f12a2850490ef",
      "tree": "c7cdfb31f290b4fb4cb932810402622dc1ae02a1",
      "parents": [
        "9db84719a9910e2801c235e1429d4750ff7dec89"
      ],
      "author": {
        "name": "SeungYoung Oh",
        "email": "seung-00@naver.com",
        "time": "Sun Oct 11 20:11:19 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 11 20:11:19 2026 +0900"
      },
      "message": "[ZEPPELIN-6733] Add AI assistant chat to notebooks (server-side)\n\n## What is this PR for?\r\nThis PR adds the server-side implementation of an AI assistant for notebooks.\r\n\r\n### Motivation\r\nAI can help with coding and data analysis, but using it with Zeppelin requires users to move code and results between the notebook and a separate chat. A built-in assistant can reduce this effort. It can also make notebook operations and other tasks easier through tools.\r\n\r\n### Decisions\r\n**Model adaptor**\r\n- The assistant currently supports OpenAI models.\r\n- It uses the official OpenAI Java SDK to keep up with API changes.\r\n\r\n**Data structure**\r\n```text\r\nNotebook 1 ── N Conversation\r\nConversation 1 ── N Message\r\nMessage (assistant) 1 ── N ToolCall\r\n```\r\n\r\n**File path**\r\n`$ZEPPELIN_HOME/assistant/\u003cnoteId\u003e/\u003cconversationId\u003e.json`\r\n\r\n**Permissions**\r\n- Anyone who can read a notebook can read its conversations.\r\n- Only the user who created a conversation can mutate it.\r\n\r\nSee the [proposal](https://cwiki.apache.org/confluence/x/5qbwGg) for more details.\r\n\r\n### Direction\r\n- The assistant is disabled by default and can be enabled through `zeppelin.notebook.assistant.enable`. Enabling it by default is planned once the feature is stable.\r\n- The initial tool, `list_paragraphs`, just returns paragraph metadata. More tools are needed to make the assistant more capable. Contributions are welcome.\r\n\r\n## What type of PR is it?\r\nFeature\r\n\r\n## What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6733\r\n\r\n## How should this be tested?\r\n- Run the assistant unit tests\r\n```bash\r\n./mvnw test -pl zeppelin-server \\\r\n  -Dtest\u003d\u0027org.apache.zeppelin.service.assistant.*Test\u0027\r\n```\r\n- Verify conversation management and message history through the REST APIs\r\n- Verify streaming responses and tool calls through WebSocket\r\n\r\n## Questions:\r\n* Does the license files need to update? Y\r\n* Is there breaking changes for older versions? N\r\n* Does this needs documentation? Y\r\n\n\nCloses #5547 from seung-00/feature/notebook-assistant.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "9db84719a9910e2801c235e1429d4750ff7dec89",
      "tree": "6822ae0e92fa587d440899c8a4b9870d19a1a802",
      "parents": [
        "76793932d50779bd2543db97467f8c3398649f75"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Sun Oct 11 17:13:47 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 11 17:13:47 2026 +0900"
      },
      "message": "[HOTFIX] Refresh zeppelin-react lockfile for npm audit (#5566)\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "76793932d50779bd2543db97467f8c3398649f75",
      "tree": "aa852c4e28f334da48127276e82b0e28fc3c5587",
      "parents": [
        "f9754f98e1c9791c5938e0650eef9a0fb46af2b6"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Oct 11 16:17:01 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 11 16:17:01 2026 +0900"
      },
      "message": "[MINOR] Backport braces depth guard for React tooling (#5528)"
    },
    {
      "commit": "f9754f98e1c9791c5938e0650eef9a0fb46af2b6",
      "tree": "cc0ba73580faeccf1e449c99633f2e52900e3717",
      "parents": [
        "3fc1d4dcc592d927c0d6826e9ccf1585f18a1b66"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Sun Oct 11 13:28:01 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 11 13:28:01 2026 +0900"
      },
      "message": "[ZEPPELIN-6736] Implement Shared Notebook Core read state and selectors\n\n### What is this PR for?\n\nImplement the read side of the Shared Notebook Core: plain TypeScript state, a store with cached immutable snapshots, and selectors. Everything is in `projects/zeppelin-notebook-core`, with no SDK, REST, WebSocket, RxJS or framework import. The existing boundary check enforces that: the Core may import only its own sources and `tslib`. Connecting a host transport and an Angular consumer is ZEPPELIN-6737.\n\nCommits:\n1. **Read inputs and read state** (`read-model.ts`):\n   * Core-owned input types for the NOTE note, NOTE_REVISION and the note permissions REST response. The Core cannot import SDK types, so these copy the shapes it reads.\n   * `test/notebook-core/read-input-compat.spec.ts` checks at compile time that the SDK `Note` / `NoteRevision` and the app `Permissions` types still pass into them unchanged.\n   * The read snapshot extends `NotebookCoreSnapshot`, so a read store can be handed to a remote as its `NotebookPort`.\n2. **Read store** (`read-store.ts`):\n   * `activate(target)` returns a request handle; the host passes each response through it.\n   * Snapshots are deeply frozen copies of the input. Unchanged branches keep their identity.\n   * Notifications are deterministic, and `dispose` cleans up.\n3. **Selectors** (`read-selectors.ts`): ordered paragraphs, a paragraph and its persisted chart settings, and note capabilities.\n4. **Review fixes:**\n   * Read-state keys are defined as own properties, so a special wire key such as an imported `__proto__` paragraph ID stays a property instead of setting the prototype.\n   * A `NOTE_REVISION` without a note reports `failed`.\n\n#### Read state\n* **Target:** `{ kind: \u0027note\u0027, noteId }` or `{ kind: \u0027revision\u0027, noteId, revisionId }`. A live note and a revision of it are distinct targets.\n* **Status:** `idle`, `loading`, `ready`, `not-found`, `access-denied`, `failed`, `disposed`.\n  * `not-found` and `access-denied` are reported only when the host can tell them apart.\n  * A failure ends the request, and a failure after `ready` is rejected.\n* **Note:** `id`, `name`, `path`, `paragraphIds` (order) and `paragraphsById`. Each paragraph holds `id`, `title`, `text`, `status`, `resultCode`, `resultMessages` and `chartConfigs` (persisted `graph` settings by result index, kept uninterpreted).\n* **Permissions:** `unknown`, `loading`, `ready`, `access-denied`, `failed`, plus the four lists.\n* **Capabilities** (`selectAclCapabilities`) follow `AuthorizationService`\u0027s list rules:\n  * an empty list admits everyone;\n  * owners can write, writers can run, runners can read;\n  * nothing is granted until the lists are `ready`.\n\n  The server\u0027s admin role and anonymous mode are not visible to the Core. So this can deny what the server allows, but never allows what the lists deny.\n\n#### Read operation inventory\n| Operation | Core input | Included |\n| --- | --- | --- |\n| `GET_NOTE` → `NOTE` (full note) | `request.acceptNote(note)` | yes |\n| `NOTE_REVISION` (full revision) | `request.acceptRevision(revision)`; a response without a note is `failed`, because `Notebook#getNoteByRevision` returns none both for a missing revision and when the default repository does not support revisions | yes |\n| `GET /api/notebook/{id}/permissions` | `request.readAcl()`, then `accept(lists)` or `fail(reason)` | yes |\n| `ERROR_INFO` / `AUTH_INFO` for a load | `request.fail(reason)`, only while loading | as an outcome the host attributes |\n| `PARAGRAPH`, `PATCH_PARAGRAPH`, `PARAGRAPH_ADDED` / `REMOVED` / `MOVED`, `NOTE_UPDATED`, progress, streaming output, collaboration, angular objects | none | **no** |\n\n**Reload policy.** The excluded events are not applied as live updates. Read state changes only through a full `NOTE` or `NOTE_REVISION`, or a new `activate()`. A host that needs current state re-activates the target or delivers a full `NOTE`. When a later full `NOTE` arrives for the same target, it replaces the loaded note, and unchanged paragraphs keep their identity.\n\n#### Field ownership\n* **Server (Core-owned read state):** note identity and name/path, paragraph order and content, saved results, persisted chart settings, revision identity, and the permission lists.\n* **Host (outside the Core):** authentication and the principal, navigation and route parameters, server authorization (the admin role and anonymous mode), the transport and request attribution.\n* **Not held:** editor drafts, run/cancel/save state and live execution output (later sub-tasks of ZEPPELIN-6687).\n\n#### Attribution: what the wire provides and what remains unresolved\nChecked against `NotebookServer` and `WebSocketServiceCallback` on `master`:\n* **`NOTE` has no `msgId`.** The same op is sent for `GET_NOTE`, `RELOAD_NOTE` and the note-change broadcast (`inlineBroadcastNote`). On the wire, a `NOTE` can be attributed only by `note.id`, never to a request.\n  * **Unresolved:** in A → B → A, a late `NOTE(A)` from the first visit is indistinguishable from the second visit\u0027s response.\n  * The Core rejects the first visit\u0027s handle. But a host that routes `NOTE` by note id alone would deliver that late `NOTE(A)` through the second visit\u0027s handle.\n  * As the issue notes, stamping the current generation when the message arrives does not establish its origin.\n* **`NOTE_REVISION` has no `msgId`** but carries `noteId` and `revisionId`. A repeated request for the same revision is likewise indistinguishable on the wire. Its content is the same immutable revision, so accepting either response gives the same state.\n* **Load failures:** `ERROR_INFO` (not found or other) and `AUTH_INFO` (forbidden) carry only an `info` string, with no note id or `msgId`. The op tells the kind apart, but not which request failed.\n* **Permissions:** a REST response is bound to its request, so its handle attribution is exact.\n\nIn the specs, the request handles are a **synthetic request context**, and the `request handles` describe block says so. They verify the Core\u0027s contract for responses the host has attributed. They are not evidence that the current wire can attribute them. That is ZEPPELIN-6737\u0027s acceptance criterion, as is any minimal read-transport change it needs.\n\n**Not in this PR:** route wiring, Angular or React rendering, editor drafts, save/run/cancel commands, structural mutations, incremental output, collaboration, reconnect recovery, ACL writes and React opt-in. This does not complete ZEPPELIN-6687.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Core-owned read inputs, with a compile-time SDK compatibility check\n* [x] Read store: request handles, frozen snapshots, stable identity, deterministic notifications, dispose\n* [x] Selectors for ordered paragraphs, results, chart settings and capabilities\n* [x] Read operation inventory, field ownership and unresolved attribution cases (above)\n\n### What is the Jira issue?\n[ZEPPELIN-6736](https://issues.apache.org/jira/browse/ZEPPELIN-6736)\n\n### How should this be tested?\n\n```bash\ncd zeppelin-web-angular\nnpm run test:notebook-core      # 162 passed (48 new store/selector specs, 1 compat spec)\nnpm run typecheck:notebook-core # passes (includes the compat spec and the \u003cat\u003ets-expect-error mutation checks)\nnpm run typecheck:react         # passes\nnpm run test:react              # passes\nnpx eslint projects/zeppelin-notebook-core/src test/notebook-core\n```\n\nNo Angular, React or browser is needed. Each of the first three commits passes `test:notebook-core`, the Core typecheck and eslint on its own (115 → 145 → 159 tests). With the review fixes, it is 162. On a merge with the current `master`, it is 166 (including the new specs there) and the typecheck passes.\n\nCovered:\n* **Load outcomes:** initial load, `not-found`, `access-denied`, `failed`, a revision without a note as `failed`, a failure ending the request, and no failure after `ready`.\n* **Targets:** live note ↔ revision transitions, A → B → A, the same revision requested again, mismatched note or revision ids, and deactivate.\n* **Snapshots:**\n  * the same reference while nothing changes, including for an identical full `NOTE`;\n  * paragraph and order identity on partial changes;\n  * no reference kept to host input;\n  * `__proto__` as a paragraph ID (looked up and updated by a later full `NOTE`) and inside chart settings;\n  * nested mutation throws a `TypeError` (and is rejected by the type checker), including the permission lists in every permissions state.\n* **Subscriptions:** notification order, subscribing and unsubscribing while notifying, the same listener subscribed twice, and dispose.\n* **Permissions:** reads, failures, a replaced read, a read from a replaced activation, and list identity across re-reads.\n\n**Each spec catches the defect it targets.** I broke the implementation on purpose and checked that the failures were assertions:\n* a handle that ignores its own currency;\n* no paragraph reuse;\n* no freezing;\n* no note id check;\n* an empty list treated as closed;\n* capabilities granted while permissions are unknown;\n* in-place subscription changes;\n* shallow-frozen permission lists.\n\nBreaking the compat types fails `typecheck:notebook-core` for all three payloads.\n\n### Screenshots (if appropriate)\n\nN/A.\n\n### Questions:\n* Does the license files need to update? No. New files carry the ASF header.\n* Is there breaking changes for older versions? No. The existing contract types are unchanged; the public API only gains exports.\n* Does this needs documentation? The read model is documented in the source and in this PR.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\n\nCloses #5559 from kimyenac/ZEPPELIN-6736.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "3fc1d4dcc592d927c0d6826e9ccf1585f18a1b66",
      "tree": "5cff99bfa568876687703fcd74cbd4415fd77924",
      "parents": [
        "883c9d65932609d071b4593941ec8cd62aa5fac0"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sat Oct 10 17:06:53 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 10 17:06:53 2026 +0900"
      },
      "message": "[MINOR] Format notebook lifecycle contract for Prettier 3.9.9\n\n### What is this PR for?\n\nPR #5540 passed its E2E checks with Prettier 3.8.3. Before #5540 merged, PR #5546 updated the Angular lockfile to Prettier 3.9.9, which formats this union type differently. #5540 was merged without rerunning its checks against the updated master, so the E2E jobs on #5559 now stop at the Prettier check before Playwright starts.\n\nThis PR applies only the Prettier 3.9.9 formatting to the affected type declaration. It does not change runtime behavior.\n\nThe existing Husky hook formats staged TypeScript files with locally installed dependencies at commit time, but it cannot detect a later base-branch dependency update. To prevent similar merge-order failures, maintainers could consider requiring checks against the latest master or using a merge queue. That policy change is outside this PR.\n\n### What type of PR is it?\n\nImprovement\n\n### Todos\n\n- [x] Format the affected file with Prettier 3.9.9\n- [x] Check the full Angular Prettier file set\n\n### What is the Jira issue?\n\nN/A\n\n### How should this be tested?\n\nThe following check passed locally from `zeppelin-web-angular`:\n\n```bash\nnpx --yes prettier\u003cat\u003e3.9.9 --check \u0027**/*.{ts,tsx,mts,js,mjs,json,css,html}\u0027\n```\n\nThe E2E CI jobs should then proceed past the formatting step.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\nCloses #5564 from voidmatcha/fix/zeppelin-notebook-lifecycle-prettier-399.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "883c9d65932609d071b4593941ec8cd62aa5fac0",
      "tree": "1304ea655788ac19e5eb88e9db7d6eaf81a621d2",
      "parents": [
        "5c414a717dfb49892737ad9695bbf9373cc2e08c"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Thu Oct 08 19:00:54 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 19:00:54 2026 +0900"
      },
      "message": "[ZEPPELIN-6676] Accept both Angular object removal payload shapes\n\n### What is this PR for?\r\n\r\nThe server emits two `ANGULAR_OBJECT_REMOVE` payload shapes. Interpreter removal supplies top-level `name`; client unbind supplies `angularObject.name`.\r\n\r\nRepresent both shapes and export a shared SDK helper using `data.name ?? data.angularObject?.name`. Update the existing Angular consumer to use this normalized identifier while preserving paragraph isolation and avoiding feedback messages.\r\n\r\nServer evidence:\r\n- `zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java:1518-1528,2276-2291`\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### Todos\r\n\r\n- [x] Represent and normalize both removal payloads.\r\n- [x] Test both shapes, name precedence and paragraph isolation.\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6676\r\n\r\nSlice 3 of 3: Angular object removal compatibility. Slice 1 merged in #5539 and slice 2 merged in #5544. \r\n\r\n### How should this be tested?\r\n\r\nRun from the repository root after installing frontend dependencies:\r\n\r\n```sh\r\ncd zeppelin-web-angular\r\nnpm run typecheck:sdk-contracts\r\nnpm run test:shell\r\nnpm run check:websocket-contract\r\n```\r\n\r\n### Questions:\r\n\r\n- Does the license files need to update? No.\r\n- Is there breaking changes for older versions? Consumers must normalize the identifier instead of assuming top-level `name` is always present. Both existing server shapes are accepted. No server wire-format change.\r\n- Does this needs documentation? The SDK helper and regression tests show both payload shapes and normalization.\r\n\n\nCloses #5557 from miinhho/ZEPPELIN-6676-upstream-angular-object-compat.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "5c414a717dfb49892737ad9695bbf9373cc2e08c",
      "tree": "c9754e46e087ec44931eeb6ddb8b10f7b85a9952",
      "parents": [
        "711f473c5865a36b6b93de55107d5cb13f7e8d82"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Thu Oct 08 18:50:54 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 18:50:54 2026 +0900"
      },
      "message": "[ZEPPELIN-6726] Add a React notebook adapter for the host-provided NotebookPort\n\n### What is this PR for?\n\nAdd the React notebook adapter that binds the host-provided `NotebookPort` (the `core` mount prop) to the React remote. It is the read-only part of the adapter. Commands follow once the contract defines them (see below).\n\n`projects/zeppelin-react/src/notebook/NotebookCoreProvider.tsx`:\n* `NotebookCoreProvider` puts the exact port object it receives into context. It does not create a Core, wrap the port or copy its state, so the host stays the only owner of notebook state.\n* `useNotebookCore()` returns that port. Outside the provider it throws instead of falling back to a local Core.\n* `useNotebookSnapshot()` is `useSyncExternalStore(core.subscribe, core.getSnapshot)`. React re-renders only when the port returns a different snapshot reference.\n* `useNotebookSelector(selector)` re-renders only when the selected value changes (`Object.is`).\n\n**Import boundary.** No new rule was needed. The existing notebook-core boundary check (`test/notebook-core/import-boundary.ts`, run by `test:notebook-core`) already discovers React modules that depend on the contract, and walks their dependencies for:\n* `\u003cat\u003ezeppelin/sdk`, `\u003cat\u003ezeppelin/services/`, `rxjs`, `axios`, WebSocket and HTTP modules;\n* the `fetch` / `WebSocket` / `XMLHttpRequest` globals;\n* runtime (non-type) core imports.\n\nSo the adapter is checked as soon as it imports the contract type. The existing SDK-backed result renderers do not depend on the contract, so they are not swept in. This PR adds one parameterized case: an SDK, rxjs WebSocket, runtime core or `fetch` dependency added to the adapter fails the check.\n\n**Not in this PR:**\n* **Semantic commands (\"one user intent dispatches one semantic command\"):** `NotebookPort` on `master` exposes only `getSnapshot` and `subscribe`. Defining commands belongs to the contract work under ZEPPELIN-6669 / ZEPPELIN-6687, so this PR does not invent them. The command dispatch and its count checks follow once the contract defines them. Happy to adjust the split in review.\n* **Exposing or mounting the adapter:** nothing imports it yet. Adding it to `main.ts` or the webpack `exposes`, and mounting it on the notebook URL, is ZEPPELIN-6727.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Bind the exact host-provided port and read snapshots through `useSyncExternalStore`\n* [x] Re-render only on a new snapshot reference or selected value\n* [x] Hold one subscription across mount, unmount, StrictMode and a port change\n* [x] Pin that a prohibited import in the adapter fails the boundary check\n* [ ] Semantic commands, once the `NotebookPort` contract defines them\n\n### What is the Jira issue?\n[ZEPPELIN-6726](https://issues.apache.org/jira/browse/ZEPPELIN-6726)\n\n### How should this be tested?\n\n```bash\ncd zeppelin-web-angular\nnpm run test:react\nnpm run typecheck:react\nnpm run test:notebook-core\nnpm run lint:react\nnpm run build:react\n```\n\nAll passed locally:\n* `test:react`: 16 files / 114 tests, including the 9 new adapter specs;\n* `test:notebook-core`: 118 tests, including the 4 new boundary cases;\n* `typecheck:react`, `typecheck:notebook-core`, `lint:react`, `build:react`, and prettier.\n\nThe adapter specs cover:\n* port identity;\n* the throw outside the provider;\n* rendering a published snapshot;\n* no re-render on the same snapshot reference;\n* unsubscribe on unmount and resubscribe on remount;\n* one subscription under StrictMode double mounting;\n* no resubscribe on a same-port re-render;\n* moving to a new port;\n* the selector re-rendering only on a changed value.\n\n**Each spec catches the defect it targets.** I broke the adapter on purpose and checked that the failure was an assertion, not a missing import:\n\n| Broken adapter | Failing specs |\n| --- | --- |\n| selector derived from the whole snapshot | the selector spec |\n| local port returned outside the provider | the throw spec |\n| subscription without cleanup | the unmount, StrictMode and port-change specs |\n| snapshot copied into React state | the same-reference and port-change specs |\n\n**The real boundary check fails on a prohibited import.** Adding `import \u0027\u003cat\u003ezeppelin/sdk\u0027;` to the adapter makes `checks all production React consumers of the notebook contract` fail with `NotebookCoreProvider.tsx: import \u003cat\u003ezeppelin/sdk`. Reverted.\n\n### Screenshots (if appropriate)\n\nN/A.\n\n### Questions:\n* Does the license files need to update? No. New files carry the ASF header.\n* Is there breaking changes for older versions? No. Nothing existing changes.\n* Does this needs documentation? No. Nothing is exposed yet.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5556 from kimyenac/ZEPPELIN-6726.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "711f473c5865a36b6b93de55107d5cb13f7e8d82",
      "tree": "4fa19767940a655cab02439c3fe742e3e9507ab0",
      "parents": [
        "156cdd1e1b29eb58aae5020d31d2042c6ea3c491"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Thu Oct 08 18:50:19 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 08 18:50:19 2026 +0900"
      },
      "message": "[ZEPPELIN-6672] Capture and replay notebook lifecycle transport fixtures\n\n### What is this PR for?\n\nAdd recorded notebook traffic and a replay runner to test paragraph edits, revisions, collaboration, and reconnect behavior without a running Zeppelin server.\n\nThe tests preserve REST and WebSocket message differences, distinguish lost saves from lost replies, and verify that two viewers reach the recorded server state after collaboration faults and a refetch. The Core runtime used by these tests is included in the repository.\n\n### What type of PR is it?\n\nImprovement\n\n### Todos\n\n* [x] Add lifecycle captures and replay tests.\n* [x] Cover message loss, duplication, delay, and reordering.\n* [x] Document how to run tests and update captures.\n\n### What is the Jira issue?\n\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6672\n\n### How should this be tested?\n\nFrom `zeppelin-web-angular/`, run:\n\n```bash\nnpm run check:core-contract-fixtures\nnpm run e2e:core-contract\n```\n\nPassed: 148 unit tests, TypeScript checks, and 13 Chromium tests. ESLint passed for changed files.\n\nFor recording new fixtures, see [the fixture README](https://github.com/miinhho/zeppelin/blob/ZEPPELIN-6672/zeppelin-web-angular/e2e/core-contract/README.md).\n\n### Questions:\n\n* Does the license files need to update? No.\n* Is there breaking changes for older versions? No.\n* Does this needs documentation? Yes. Test and capture instructions are included.\n\nCloses #5540 from miinhho/ZEPPELIN-6672.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "156cdd1e1b29eb58aae5020d31d2042c6ea3c491",
      "tree": "2de8c039cb21cc8d5190a7cdb7eb10bc9aa3cf27",
      "parents": [
        "4cb077b301135621eac8ab23eb132b4b38eacd12"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Wed Oct 07 21:32:00 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 21:32:00 2026 +0900"
      },
      "message": "[ZEPPELIN-6713] Stabilize editor blur E2E assertion\n\n### What is this PR for?\r\n\r\nNB-PARITY-003 can fail intermittently when Monaco\u0027s suggestion widget is open because the first Escape dismisses the widget instead of removing editor focus.\r\n\r\nThis PR makes the assertion deterministic by dismissing the suggestion widget first, waiting for it to close, and then pressing Escape again to blur the editor.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### What is the Jira issue?\r\n\r\nZEPPELIN-6713\r\n\r\n### How should this be tested?\r\n\r\n```bash\r\nCI\u003dtrue PLAYWRIGHT_BASE_URL\u003dhttp://127.0.0.1:8081 npm exec -- playwright test \\\r\n  e2e/tests/notebook/paragraph/paragraph-functionality.spec.ts \\\r\n  --grep \u003cat\u003eNB-PARITY-003 \\\r\n  --project\u003dchromium \\\r\n  --project\u003dfirefox \\\r\n  --project\u003dwebkit \\\r\n  --repeat-each\u003d100 \\\r\n  --retries\u003d0 \\\r\n  --workers\u003d3 \\\r\n  --no-deps\r\n```\r\n\r\nThe test passed 100 times on each browser without retries:\r\n\r\n* Chromium: 100/100\r\n* Firefox: 100/100\r\n* WebKit: 100/100\r\n* Total: 300/300\r\n\r\n### Questions\r\n\r\n* Does the license file need updating? No\r\n* Is there breaking changes for older versions? No\r\n* Does this need documentation? No\r\n\n\nCloses #5549 from voidmatcha/ZEPPELIN-6713-deterministic-blur.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "4cb077b301135621eac8ab23eb132b4b38eacd12",
      "tree": "c80230b6526798ef1ea20f2715b610811b512445",
      "parents": [
        "f68ea3d1e73d346d071ffe2ac36347c9cd4e85c8"
      ],
      "author": {
        "name": "YooJung Huh",
        "email": "gjenfwo@gmail.com",
        "time": "Wed Oct 07 21:31:10 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 21:31:10 2026 +0900"
      },
      "message": "[ZEPPELIN-6656] Patch New UI dependencies and refresh lockfile\n\n### What is this PR for?\r\nPartial remediation of the npm audit findings in the New UI (`zeppelin-web-angular`). It updates dependencies that have compatible patched releases and pins patched transitive versions, keeping Angular 21 and G2 3.\r\n\r\n- Bump Angular packages to `^21.2.25`, and bump `vitest` / `\u003cat\u003evitest/coverage-v8` to 4.1.11, `concurrently` to 9.2.4 and `ws` to 8.22.0\r\n- Switch `xlsx` from the unmaintained npm `0.14.3` to the official SheetJS `0.20.3` distribution (`cdn.sheetjs.com`)\r\n- Upgrade `highlight.js` from 9.x to 10.7.3. Add an `HTMLElement` type parameter for `highlightBlock`\r\n- Add `overrides` for patched transitive releases: `fast-uri`, `js-yaml`, `nanoid`, `undici` (6/7), `minimatch\u003cat\u003e3`, `brace-expansion` (1/5), `fmin`, `d3-color`\r\n- Refresh `package-lock.json`\r\n- Add regression tests:\r\n  - `result.component.spec.ts`: HTML results keep their markup, and code blocks are still highlighted with the new highlight.js\r\n  - `test/g2-dependency-compatibility.spec.ts`: a G2 3 interval chart still renders with the overridden `d3-color`\r\n\r\nClassic UI (`zeppelin-web`) dependencies are unchanged.\r\n\r\n**This PR does not bring `npm audit` to zero.** After this change:\r\n- New UI: 11 high and 2 moderate findings\r\n- React remote (existing CI audit job): 5 high findings\r\n\r\nThe remaining findings are blocked by:\r\n- `braces \u003c\u003d3.0.3` (GHSA-vfj7-8cjw-p6xm) has no patched release yet. It is pulled in through `micromatch` → `http-proxy-middleware` / `webpack-dev-server`, and through `ts-loader` in React.\r\n- `angular` 1.8.x (AngularJS) has no compatible patched npm release.\r\n- MathJax 2: moving to a patched major requires reworking the `MathJax.Hub` configuration and bundled assets.\r\n- Other findings come through `webpack-dev-server` and `lint-staged`.\r\n\r\nThese need upstream fixes or an agreed migration scope, so I\u0027d suggest handling them in follow-up issues.\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] - Update compatible dependencies and pin patched transitive releases\r\n* [x] - Add regression tests for highlight.js and G2 rendering\r\n* [ ] - Resolve remaining audit findings (braces, AngularJS, MathJax 2), possibly in follow-up issues\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6656\r\n\r\n### How should this be tested?\r\n* CI passes.\r\n* Run locally in `zeppelin-web-angular`:\r\n  - `npm ci`\r\n  - Production build (notebook-core, SDK, visualization, React remote and Angular app) passes.\r\n  - Shell tests: 29 files, 179 tests pass.\r\n  - React tests: 14 files, 98 tests pass.\r\n  - In Chromium, G2 charts and the React remote render correctly.\r\n* Manually: run a paragraph that returns `%html` containing `\u003cpre\u003e\u003ccode\u003e`, and check that the code is highlighted. Export a table result to XLSX, and check that the file downloads and opens.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No. SheetJS `xlsx` is still Apache-2.0.\r\n* Is there breaking changes for older versions? No user-facing changes are intended. Angular and G2 major versions are unchanged.\r\n* Does this needs documentation? No.\r\n\n\nCloses #5546 from gjenfwo/ZEPPELIN-6656.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "f68ea3d1e73d346d071ffe2ac36347c9cd4e85c8",
      "tree": "6abccb46064964b64f7cccf2e5fc8abaf0131d0b",
      "parents": [
        "e9d0b01b957605957e90dcf85fbc6192c29d6518"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Wed Oct 07 12:20:35 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 12:20:35 2026 +0900"
      },
      "message": "[ZEPPELIN-6676] Correct notebook runtime info, GUI and Angular object value shapes\n\n### What is this PR for?\r\n\r\nSeveral SDK declarations do not match the servers notebook payloads. Model runtime information as arbitrary property maps, form parameters as JSON scalar/array/object values, note forms as typed Input maps, and paragraph settings as GUI data separate from editor settings.\r\n\r\nSupport legacy form labels and preserve structured values through existing controls. Checkbox indexes remain inside the control; emitted parameters contain the original values. Preserve supplied falsy values and match Select values after JSON hydration.\r\n\r\nAlso correct scoped Note parameter, binding and metadata maps, and allow non-string Angular object values through public update/bind helpers.\r\n\r\nServer evidence:\r\n- `zeppelin-server/src/main/java/org/apache/zeppelin/notebook/Paragraph.java:79-83,98,668-683`; `ParagraphRuntimeInfo.java:31-56`\r\n- `zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/GUI.java:46-64,103-145`; `Input.java:48-64`\r\n- `zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/ui/OptionInput.java:33-39`; `Select.java:23-29`; `CheckBox.java:26-32`\r\n- `zeppelin-server/src/main/java/org/apache/zeppelin/notebook/Note.java:79-93,986-1022`; `zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java:44-54`\r\n- `zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java:1388-1437`; `ConnectionManager.java:65-69`; `zeppelin-server/src/main/java/org/apache/zeppelin/scheduler/QuartzSchedulerService.java:103-124`\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### Todos\r\n\r\n- [x] Correct structural/scalar declarations and affected consumers.\r\n- [x] Add compiler contracts and form-control regression tests.\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6676\r\n\r\nSlice 2 of 3: structural and scalar shape corrections. Slice 1 merged in #5539. Angular object removal compatibility will follow as a separate PR after this slice merges.\r\n\r\n### How should this be tested?\r\n\r\nRun from the repository root after installing frontend dependencies:\r\n\r\n```sh\r\ncd zeppelin-web-angular\r\nnpm run typecheck:sdk-contracts\r\nnpm run test:shell\r\nnpm run check:websocket-contract\r\nnpx ngc -p src/tsconfig.json --noEmit\r\n```\r\n\r\n### Questions:\r\n\r\n- Does the license files need to update? No.\r\n- Is there breaking changes for older versions? TypeScript callers must adapt incorrect GUI/editor assumptions and narrow unknown values before use. No server wire-format change.\r\n- Does this needs documentation? Examples of corrected shapes are included in the compiler contracts.\r\n\n\nCloses #5544 from miinhho/ZEPPELIN-6676-upstream-value-shapes.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "e9d0b01b957605957e90dcf85fbc6192c29d6518",
      "tree": "cfa6e241ff1d709b90c1b305cd1f860135dda359",
      "parents": [
        "6c87bece0ae0bc1cec68a66b59f5d1ffdbad4262"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Wed Oct 07 12:20:21 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 12:20:21 2026 +0900"
      },
      "message": "[ZEPPELIN-6566] Run frontend unit checks in CI\n\n### What is this PR for?\n\nGive the frontend unit checks named results in pull-request CI and run the React remote tests and typecheck through Maven.\n\n* **Scripts:**\n  * `projects/zeppelin-react` gains `typecheck` (`tsc --noEmit`).\n  * The frontend root gains `test:react` and `typecheck:react`. Both delegate with `npm --prefix projects/zeppelin-react`, so the React project\u0027s working directory is unchanged.\n* **Maven:** the `test` phase gains two executions, `npm test react` and `npm typecheck react`. A failure names the execution in the Maven log, for example `Failed to execute goal ... npm (npm typecheck react)`.\n* **Workflow:** `frontend.yml` gains three steps on the anonymous leg of `run-playwright-e2e-tests`: `Run Angular shell unit tests`, `Run React unit tests` and `Typecheck React`.\n  * They call the same root scripts, so the local, Maven and workflow entry points run one implementation.\n  * The auth leg still runs the Maven-owned checks inside `mvnw verify -Pweb-e2e`, without a duplicate named result.\n* **TS2802 fix:** `exportFile.spec.ts` spread a `Uint8Array`, which fails `tsc --noEmit` under the React project\u0027s ES5 target. It now uses `Array.from`. This was the only typecheck error on `master` (`943a3fb8d`).\n* **`fail-fast: false` on the e2e matrix:**\n  * When I first ran the deliberate typecheck failure on my fork, the auth leg\u0027s Maven `npm typecheck react` execution failed first. Matrix fail-fast then cancelled the anonymous leg during `Install application`, so `Typecheck React` never ran.\n  * The failure only showed up under the e2e job name, which is what this issue is meant to prevent.\n  * With `fail-fast: false`, both legs report ([run](https://github.com/kimyenac/zeppelin/actions/runs/37421560253)). `core.yml` already uses `fail-fast: false` for its matrices.\n* **Docs:** `AGENTS.md` and `projects/zeppelin-react/AGENTS.md` describe the new commands and CI steps. The parts that are still true are kept:\n  * the checks without a named step still run inside `verify -Pweb-e2e` on both legs and surface under the e2e job name;\n  * React lint still runs only there;\n  * the npm-audit remediation workflow also runs `npm test`.\n\nCommits, continued from the `ZEPPELIN-6566-shell-react-ci` branch in `voidmatcha/zeppelin` with the author\u0027s agreement:\n1. `7c709e5ac`, the original commit unchanged: scripts, Maven executions, named steps, the TS2802 fix and the first docs update.\n2. `038784611`: `fail-fast: false` on the e2e matrix.\n3. `9adb65413`: the docs corrections above.\n\nThe verification below covers the combined result.\n\nCost: on the anonymous leg the shell tests, React tests and React typecheck now run twice, once as named steps and again in the Maven `test` phase inside `verify`. Locally that is about 16 seconds in total: shell 8.2s, React 6.7s, typecheck 1.5s.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Add `typecheck` to the React project, and `test:react` / `typecheck:react` to the frontend root\n* [x] Add Maven `npm test react` and `npm typecheck react` executions\n* [x] Add named shell test, React test and React typecheck steps on the anonymous leg\n* [x] Fix the existing TS2802 typecheck failure\n* [x] Keep the anonymous leg from being cancelled before its named steps report\n* [x] Demonstrate the deliberate failures and revert them\n\n### What is the Jira issue?\n[ZEPPELIN-6566](https://issues.apache.org/jira/browse/ZEPPELIN-6566)\n\n### How should this be tested?\n\n```bash\ncd zeppelin-web-angular\nnpm run test:react\nnpm run typecheck:react\ncd ..\n./mvnw test -pl zeppelin-web-angular\n```\n\n**Same pass count from every entry point.** The React suite runs 15 files / 105 tests from each of:\n* `npm test` in `projects/zeppelin-react`\n* `npm run test:react` at the frontend root\n* the Maven `npm test react` execution\n\nThe shell suite runs 211 tests. `./mvnw test -pl zeppelin-web-angular` reports BUILD SUCCESS.\n\n**Deliberate failures (all reverted).** Each one was written to pass lint, so it fails in the targeted check and not earlier. The fork runs used throwaway branches, now deleted; the run pages remain.\n\n| Deliberate failure | Local | Fork CI (anonymous leg) |\n| --- | --- | --- |\n| failing shell spec | `npm run test:shell` fails (1 failed / 211 passed) | `Run Angular shell unit tests` fails ([run](https://github.com/kimyenac/zeppelin/actions/runs/37415025910)) |\n| failing React spec | `npm run test:react` fails; Maven fails at `(npm test react)` | `Run React unit tests` fails ([run](https://github.com/kimyenac/zeppelin/actions/runs/37415031039)) |\n| TypeScript error in React `src` | `npm run typecheck:react` fails; Maven fails at `(npm typecheck react)` | `Typecheck React` fails, and the auth leg fails at Maven `(npm typecheck react)` ([run](https://github.com/kimyenac/zeppelin/actions/runs/37421560253)) |\n\nFor the TypeScript error, the React webpack build uses `ts-loader` with `transpileOnly: true`. So the error does not fail `Install application` first, and it surfaces at the named step.\n\n### Screenshots (if appropriate)\n\nN/A.\n\n### Questions:\n* Does the license files need to update? No.\n* Is there breaking changes for older versions? No. Existing scripts and executions are unchanged.\n* Does this needs documentation? The two `AGENTS.md` files are updated.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5548 from kimyenac/ZEPPELIN-6566.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "6c87bece0ae0bc1cec68a66b59f5d1ffdbad4262",
      "tree": "8c50203995dd006d61dadcc6073f99a96ea87ec8",
      "parents": [
        "943a3fb8dfaa6d05cf4b92c013a01f75ad8a940d"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Wed Oct 07 12:20:04 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Oct 07 12:20:04 2026 +0900"
      },
      "message": "[ZEPPELIN-6675] Prove the notebook route can consume the Shared Notebook Core port\n\n### What is this PR for?\n\nAdd a browser proof that the current Angular notebook route can hand one host-owned `NotebookCorePort` to a separately built React consumer. This builds on the ZEPPELIN-6674 port identity proof and moves it onto the real notebook route.\n\n* The proof harness bootstraps the production `WorkspaceModule` and `NotebookModule` lazy routes and asserts that the activated component is the production `NotebookComponent`.\n* It reads the activated `/notebook/:noteId` and `/notebook/:noteId/revision/:revisionId` parameters into one host-owned test Core. The React consumer reads the snapshot and receives route-driven subscription updates (note → other note → revision), always through the same port object.\n* A browser-only `MessageService` double records the production component\u0027s `getNote`, `noteRevision` and `listRevisionHistory` requests, and the test asserts their exact order.\n\nThis is a seam-only proof. It does not switch the production renderer, move notebook state out of Angular, or implement re-subscription, recovery or mutation reducers (ZEPPELIN-6687).\n\nThe implementation is based on the `ZEPPELIN-6675-notebook-route-boundary` branch in the voidmatcha fork (`823183338`), which was written before ZEPPELIN-6674 merged. Porting it onto current `master`:\n\n* **CI wiring:** the route proof runs in the `integration-test` phase behind `web.e2e.core.port.proof.disabled`, the same as the merged port identity proof, so it runs on the anonymous leg of `run-playwright-e2e-tests`. The branch bound it to the `test` phase with `${skipTests}`, which `frontend.yml`\u0027s `-DskipTests` build skips.\n* **Shared static server:** it now returns 404 for unknown paths, matching the merged ZEPPELIN-6674 review change, instead of serving `index.html`.\n* **Message double:** it gains `receiveEnvelope`, added to `MessageService` by ZEPPELIN-6683. Without it, the workspace route did not render.\n* **Theme double:** it gains `getCurrentTheme` and `theme$`. Without them, `ThemeToggleComponent` throws in `ngOnInit`. The original test did not catch this, because Angular\u0027s `ErrorHandler` reports it through `console.error(\u0027ERROR\u0027, ...)` and never as a `pageerror`. The test now fails on those errors too. Removing the theme fix makes it fail with `this.themeService.getCurrentTheme is not a function`.\n* **Lifecycle boundary is now asserted, not only documented:**\n  * the port\u0027s own keys are exactly `getSnapshot` and `subscribe`, and the port is frozen;\n  * route activation and port consumption make no `bootstrap`, `connect` or `close` call.\n* **README:** the section moves to the end of `e2e/core-contract/README.md` instead of splitting the replay subsections. It describes the actual CI wiring and notes that ZEPPELIN-6683\u0027s stale-reply rejection lives inside `NotebookComponent` and is not moved into the Core.\n* **Kept as is:** the route path constants (`notebook-route-boundary.ts`). Production code changes are limited to extracting the existing route paths into those constants, which both the routing modules and the proof use.\n* **Dropped from the branch:** the `./NotebookRouteBoundaryProbe` webpack alias (it re-exposed the same module), and unused route-proof `proofs` state.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Run the route proof on the production notebook routes with one host-owned port\n* [x] Assert route-driven snapshot and subscription updates through the same port\n* [x] Assert the port shape and that the connection lifecycle is not reached\n* [x] Run it through the normal browser CI path\n* [x] Record host-side responsibilities and what remains outside this proof\n\n### What is the Jira issue?\n[ZEPPELIN-6675](https://issues.apache.org/jira/browse/ZEPPELIN-6675)\n\n### How should this be tested?\n\n```bash\ncd zeppelin-web-angular\nnpm run build:projects\nnpm run build:notebook-core-port-proof\nnpm run test:notebook-core-port-identity\nnpm run test:notebook-route-boundary\n```\n\nWhat I ran locally (after rebasing onto `6a5ed4459`):\n* Both browser proofs passed. Also passing:\n  * `test:notebook-core`, `typecheck:notebook-core`\n  * `check:core-contract-fixtures`, `test:shell`\n  * prettier and eslint on the changed files\n* `./mvnw verify -pl zeppelin-web-angular -Pweb-e2e` (before the rebase): the proof build, the port identity proof and the route proof passed in `integration-test`.\n* The main Playwright suite finished with 749 passed and 20 failed. Rerunning only the failing specs with one worker left 6 failures:\n  * `paragraph-functionality.spec.ts:174` and `:335`, on all three browsers;\n  * both execute `%python`, and every failure context shows `Fail to launch python process` from my local Python setup;\n  * the other 14 failures passed when run serially.\n* **Not run locally:** the classic UI e2e. The maven run stopped after the main suite because I ran it without `CI\u003dtrue`, so the HTML reporter waited for input. This PR does not touch `zeppelin-web`.\n* I checked that each build setting kept from the branch is still required by building without it:\n  * `mathjax` types: without them, the `MathJax` directive fails to compile;\n  * the custom webpack builder: without it, Monaco CSS fails to parse;\n  * the style include paths: without them, the components\u0027 `.less` imports fail to resolve.\n\n### Screenshots (if appropriate)\n\nN/A.\n\n### Questions:\n* Does the license files need to update? No. New files carry the ASF header.\n* Is there breaking changes for older versions? No. Route shapes and behaviour are unchanged.\n* Does this needs documentation? `e2e/core-contract/README.md` is updated.\n\nUnrelated, found while testing: production `main.js` builds the Monaco `codicon.ttf` URL from the build machine\u0027s absolute `file:///` path, so the browser refuses to load that font. It also happens on `master`.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5527 from kimyenac/ZEPPELIN-6675.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "943a3fb8dfaa6d05cf4b92c013a01f75ad8a940d",
      "tree": "45179b68a3e747a9f6dcc4211a58fff63bb55435",
      "parents": [
        "2919b442bd86cdcaeadb557e162194d4696d0165"
      ],
      "author": {
        "name": "HwangRock",
        "email": "157935545+HwangRock@users.noreply.github.com",
        "time": "Mon Oct 05 22:55:49 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:55:49 2026 +0900"
      },
      "message": "[ZEPPELIN-6171] Resolve nested LDAP groups on FreeIPA via memberOf\n\n### What is this PR for?\n\n`LdapRealm` resolves a user\u0027s groups in one of two ways today: the Active Directory `LDAP_MATCHING_RULE_IN_CHAIN` operator, or a group search over the `member` attribute. Neither works for nested groups on FreeIPA / 389 Directory Server — the AD matching rule isn\u0027t supported there, and the plain `member` search only sees direct members. So if a user is in `dev` and `dev` is a member of `eng`, the user\u0027s `eng` membership (and any role mapped to it) silently disappears.\n\nThis adds a third path. When `ldapRealm.groupSearchEnableMemberOf \u003d true`, the realm reads the user entry\u0027s own `memberOf` attribute instead of walking the group tree. FreeIPA/389 DS already flattens direct **and** nested membership onto `memberOf`, so a single lookup of the user entry gives you the full set, nested groups included.\n\nWhile adding it I split `rolesFor()` into three small per-strategy methods (matching-rule / group-membership / memberOf) so each path is readable on its own. The two existing paths are moved as-is, no behavior change.\n\nNew settings:\n\n```\n# resolve nested groups via the user\u0027s memberOf attribute (e.g. FreeIPA / 389 DS)\nldapRealm.groupSearchEnableMemberOf \u003d true\nldapRealm.memberOfAttribute \u003d memberOf\n```\n\nA few decisions worth calling out:\n\n- **Precedence when both are on.** If `groupSearchEnableMatchingRuleInChain` and `groupSearchEnableMemberOf` are both set, the matching-rule path wins and we log a one-time warning, rather than refusing to start. This keeps existing AD setups behaving exactly as before; the cost is that a contradictory config isn\u0027t hard-rejected, just warned.\n- **Group name comes from the leaf RDN only.** A `memberOf` value is a full group DN, and we take the group name from its leaf RDN without scanning ancestors. On FreeIPA a container on the path (`cn\u003dgroups,cn\u003daccounts,...`) has the same `cn\u003d` type as the group itself, so scanning would pick the wrong one. A malformed DN is skipped (and logged) instead of failing the login.\n- **No behavior change for the existing paths.** The matching-rule branch still doesn\u0027t populate the session group-name set the way the default branch does — that\u0027s pre-existing and I left it alone on purpose rather than \"fixing\" it in a refactor.\n\nOne prerequisite (documented in `shiro_authentication.md`): `memberOf` is only returned to an authenticated bind, which Zeppelin already does via `systemUsername`/`systemPassword`. Deployments that split groups and members across separate backends may also need server-side memberOf scope configuration.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] memberOf-based group resolution path\n* [x] split `rolesFor()` into per-strategy methods\n* [x] unit tests\n* [x] docs\n\n### What is the Jira issue?\n[ZEPPELIN-6171](https://issues.apache.org/jira/browse/ZEPPELIN-6171)\n\n### How should this be tested?\n\n`LdapRealmTest` (11 tests, mock-based) covers the memberOf path: nested resolution, matching-rule precedence, leaf-RDN fallback, and the empty / missing `memberOf` cases. The existing tests pass unchanged, which is what pins down that the two old paths still behave the same.\n\nI also ran it end-to-end against a real 389 Directory Server (FreeIPA\u0027s LDAP engine) with a nested setup — `alice` ∈ `dev`, and `dev` ∈ `eng`:\n\n```\n# alice\u0027s memberOf at the directory level (server-flattened, ground truth)\n$ ldapsearch ... -b \u0027uid\u003dalice,ou\u003dpeople,dc\u003dexample,dc\u003dcom\u0027 -s base memberOf\ndn: uid\u003dalice,ou\u003dpeople,dc\u003dexample,dc\u003dcom\nmemberOf: cn\u003ddev,ou\u003dgroups,dc\u003dexample,dc\u003dcom\nmemberOf: cn\u003deng,ou\u003dgroups,dc\u003dexample,dc\u003dcom\n\n# LdapRealm.rolesFor(alice) against that server, only the new flag differs:\ncase A  groupSearchEnableMemberOf\u003dfalse  -\u003e  [dev]        # nested cn\u003deng missing\ncase B  groupSearchEnableMemberOf\u003dtrue   -\u003e  [dev, eng]   # nested cn\u003deng resolved\n```\n\nSo the nested group is recovered only with the new flag on.\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? Yes — `docs/setup/security/shiro_authentication.md` is updated.\n\n\nCloses #5505 from HwangRock/ZEPPELIN-6171-freeipa-memberof-nested-groups.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "2919b442bd86cdcaeadb557e162194d4696d0165",
      "tree": "d9fb4a2e1e7c5cc9a3d6146e5f323f06b50c93be",
      "parents": [
        "2ef78bcc2a59944cd829debd2ad2e66f07aff08a"
      ],
      "author": {
        "name": "Naeun Park",
        "email": "57740138+world970511@users.noreply.github.com",
        "time": "Mon Oct 05 22:42:12 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:42:12 2026 +0900"
      },
      "message": "[ZEPPELIN-6629] Fix anchor links hidden under navbar\n\n### What is this PR for?\r\n\r\nAnchor links in the documentation can be hidden behind the fixed 60px navbar.\r\n\r\nThe existing `maybeScrollToHash()` JavaScript workaround uses a hardcoded 57px offset and does not handle explicit named anchors such as `\u003ca name\u003d\"S3\"\u003e`.\r\n\r\nThis PR replaces the JavaScript workaround with `scroll-padding-top: 60px`, allowing native fragment navigation to account for the fixed navbar. It also removes `maybeScrollToHash()` and its related event handlers.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6629\r\n\r\n### How should this be tested?\r\n\r\nRun the documentation site locally and verify the following fragments on the Notebook Storage page:\r\n\r\n* `#overview`\r\n* `#notebook-storage-in-s3`\r\n* `#S3`\r\n\r\nVerify that each target is visible below the fixed navbar.\r\n\r\nAlso verify the behavior with a mobile-width viewport.\r\n\r\n### Screenshots\r\n\r\nBefore/after screenshots for `#S3`, if appropriate.\r\n\r\n### Questions\r\n\r\n* Does the licenses files need update? No.\r\n* Is there breaking changes for older versions? No.\r\n* Does this needs documentation? No.\r\n\n\nCloses #5407 from world970511/ZEPPELIN-6629.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "2ef78bcc2a59944cd829debd2ad2e66f07aff08a",
      "tree": "d69a6968aaa0881abbbbec3ef94f36b7e2b20600",
      "parents": [
        "def2de1cc24e9cfb80f3d22dd2232e8f73885cc0"
      ],
      "author": {
        "name": "HwangRock",
        "email": "157935545+HwangRock@users.noreply.github.com",
        "time": "Mon Oct 05 22:31:02 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:31:02 2026 +0900"
      },
      "message": "[ZEPPELIN-6594] Serialize NoteManager.addNote and removeFolder with the other tree mutations\n\n### What is this PR for?\n\n`NoteManager` serializes its tree mutations — `saveNote`, `removeNote`, `moveNote`, `moveFolder` — on a single `synchronized (this)` monitor so they never interleave on the folder tree, the noteId→path mapping, and the notebook repo. `addNote` and `removeFolder` were left out of this serialization.\n\n**As-Is:** Because `addNote` and `removeFolder` do not take the monitor, they can run concurrently with a `moveNote` that holds it, corrupting shared state:\n\n- A note being moved to another folder while its original folder is removed becomes unreachable — the note is effectively lost.\n- Adding a note at a path while another note is concurrently moved to that same path lets both pass the \"path is available\" check and commit, leaving two different notes at one path.\n- Removing the same folder concurrently throws a `NullPointerException`.\n\n**To-Be:** `addNote` and `removeFolder` take the same `synchronized (this)` monitor as the other mutations, so the whole class shares one serialization point and these interleavings can no longer happen. Reads are unaffected — `processNote` resolves against the volatile `noteTree` and never takes the monitor.\n\n### What type of PR is it?\n\nBug Fix\n\n### What is the Jira issue?\n\n[ZEPPELIN-6594](https://issues.apache.org/jira/browse/ZEPPELIN-6594)\n\n### How should this be tested?\n\nAdded a deterministic gate-based test (`NoteManagerMutationSerializationTest`) that pins the monitor inside a parked `moveNote` and asserts the other mutation blocks on it, plus two concurrency stress tests in `NoteManagerTest`.\n\nRunning the same tests before and after the fix:\n\n```\n# Before the fix (same tests run against master\u0027s pre-fix behavior)\nTests run: 11, Failures: 4, Errors: 0, Skipped: 0\n\n  testAddNoteWaitsForInFlightMoveNote\n    The mutation completed while moveNote held the NoteManager monitor; it is not serialized with moveNote\n  testRemoveFolderWaitsForInFlightMoveNote\n    The mutation completed while moveNote held the NoteManager monitor; it is not serialized with moveNote\n  testConcurrentAddNoteAndMoveNoteOnSamePath\n    exactly one operation may claim /dst_1/note \u003d\u003d\u003e expected: \u003c1\u003e but was: \u003c2\u003e\n  testConcurrentRemoveFolderAndMoveNote\n    java.lang.NullPointerException: Cannot invoke\n    \"NoteManager$Folder.getNoteInfoRecursively()\" because \"folder\" is null\n\n# After the fix (this branch)\nTests run: 11, Failures: 0, Errors: 0, Skipped: 0\n```\n\n```\n./mvnw test -pl zeppelin-server --am -Dtest\u003dNoteManagerTest,NoteManagerMoveResaveRaceTest,NoteManagerMutationSerializationTest\n```\n\n### Questions:\n\n- Does the license files need to be updated? No\n- Is there breaking changes for older versions? No\n- Does this need documentation? No\n\n\nCloses #5530 from HwangRock/ZEPPELIN-6594-serialize-notemanager-mutations.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "def2de1cc24e9cfb80f3d22dd2232e8f73885cc0",
      "tree": "3447786ae12bb7e8b98a8ec516dd789003ddd355",
      "parents": [
        "db540a1eb585dd21bcfb0ce6c7c1840d0a670f39"
      ],
      "author": {
        "name": "chaeyoung kim",
        "email": "152389483+chelsseeey@users.noreply.github.com",
        "time": "Mon Oct 05 22:30:20 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:30:20 2026 +0900"
      },
      "message": "[ZEPPELIN-6446] Type message listener callbacks\n\n### What is this PR for?\r\n\r\nThe message listener decorator previously required `\u003cat\u003ets-ignore` when invoking decorated callbacks because its conditional callback type did not align with the received payload.\r\n\r\nThis PR introduces a typed `MessageHandler\u003cT\u003e`, explicitly connects each message operation `K` to `MessageReceiveDataTypeMap[K]`, and invokes the callback without TypeScript suppression or broad `any` types. The existing test now uses the actual `\u003cat\u003eMessageListener` decorator syntax to verify the typed integration.\r\n\r\n### What type of PR is it?\r\n\r\nRefactoring\r\n\r\n### Todos\r\n\r\n* [x] Remove the `\u003cat\u003ets-ignore` suppression\r\n* [x] Preserve the relationship between message operations and payload types\r\n* [x] Verify all existing message listeners compile\r\n* [x] Add coverage using the actual decorator syntax\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6446\r\n\r\n### How should this be tested?\r\n\r\n```bash\r\ncd zeppelin-web-angular\r\nnpm run test:shell\r\nnpm run lint\r\nnpm run build:angular\r\n```\r\n\r\nResults:\r\n\r\n* 167 shell unit tests passed\r\n* Frontend lint passed with no errors\r\n* Production Angular build passed\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No.\r\n* Is there breaking changes for older versions? No.\r\n* Does this needs documentation? No.\r\n\n\nCloses #5533 from chelsseeey/ZEPPELIN-6446-type-message-listener-callback.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "db540a1eb585dd21bcfb0ce6c7c1840d0a670f39",
      "tree": "e9f12e71b4fa5daf5e8488202922c887bc8e82ad",
      "parents": [
        "bebb849299a71a0a046ca0557a917b36de98ff23"
      ],
      "author": {
        "name": "김다은 (Daeun Kim)",
        "email": "150661115+dani1552@users.noreply.github.com",
        "time": "Mon Oct 05 22:29:47 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:29:47 2026 +0900"
      },
      "message": "[ZEPPELIN-6500] Replace ansi-to-react with anser in the React text re…\n\n### What is this PR for?\r\n`projects/zeppelin-react` rendered ANSI-colored interpreter output through `ansi-to-react`, which comes from the archived nteract project and declares `linkify-it\u003cat\u003e^3.0.3` (GHSA-22p9-wv53-3rq4). The fix only exists in linkify-it 5.x, so PR #5278 worked around it with an npm `overrides` entry that crosses `ansi-to-react`\u0027s declared range. Nothing would ever prompt us to remove that override.\r\n\r\n`linkify-it` only backs `ansi-to-react`\u0027s optional `linkify` prop, which `TextRenderer.tsx` never enabled, and the actual ANSI parsing is done by `anser`. This renders `anser.ansiToJson()` output directly, which removes `ansi-to-react`, `linkify-it`, `escape-carriage`, `uc.micro` and the `linkify-it` override from the tree.\r\n\r\n- The rendered DOM (`\u003cpre\u003e\u003ccode\u003e\u003cspan style\u003e`) and the color/style mapping are kept.\r\n- Carriage returns are now handled only by the caller\u0027s `checkAndReplaceCarriageReturn()`, removing the duplicate `escapeCarriageReturn()` pass.\r\n- All active decorations are applied (e.g. bold + underline + strikethrough), where `ansi-to-react` applied only the last one.\r\n- `ansi-to-react`\u0027s Jupyter-Classic `\\b` handling is dropped, matching the Angular `renderText()` (ansi_up), which does not do it either.\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] - Render ANSI output with `anser` directly in `TextRenderer.tsx`\r\n* [x] - Remove `ansi-to-react` and the `linkify-it` override\r\n* [x] - Add `TextRenderer.spec.tsx`\r\n\r\n### What is the Jira issue?\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6500\r\n\r\n### How should this be tested?\r\n* `cd zeppelin-web-angular/projects/zeppelin-react \u0026\u0026 npm ci \u0026\u0026 npm test` passes, including the new `TextRenderer.spec.tsx`.\r\n* `npm ls linkify-it` is empty.\r\n* `npm audit --audit-level\u003dhigh` no longer reports `linkify-it`. The remaining high findings (`braces` via `webpack-dev-server`/`ts-loader`) are dev-only and pre-existing on master.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No.\r\n* Is there breaking changes for older versions? No.\r\n* Does this needs documentation? No.\n\nCloses #5536 from dani1552/ZEPPELIN-6500.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "bebb849299a71a0a046ca0557a917b36de98ff23",
      "tree": "ceb40ab7f6f33b5a59853b3cd4ddad083a0d88cc",
      "parents": [
        "d63fda37973052b7a684cba8450e289a942b2dbc"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Mon Oct 05 22:25:25 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:25:25 2026 +0900"
      },
      "message": "[ZEPPELIN-6676] Match notebook status, result codes and dataset types to server values\n\n### What is this PR for?\r\n\r\nThe SDK declares paragraph status and result codes as open strings and omits SVG and NULL dataset types. Match these declarations to the server?s seven job states, four result codes and eight dataset types.\r\n\r\nUpdate the affected consumers in the same PR. Use the servers terminal-state classification, render SVG as an encoded image, and clear previous output for NULL. Prevent pending output work from restoring content cleared by SVG or NULL. Keep explicit handling for every dataset type without changing existing unsupported-type behavior.\r\n\r\nServer evidence:\r\n- `zeppelin-interpreter/src/main/java/org/apache/zeppelin/scheduler/Job.java:56-80`\r\n- `zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterResult.java:40-61`\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### Todos\r\n\r\n- [x] Correct finite types and adapt affected consumers.\r\n- [x] Add type, rendering and output-transition regression tests.\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6676\r\n\r\nSlice 1 of 3: finite value corrections. Structural/scalar corrections and Angular object removal compatibility will follow as separate PRs after this slice merges.\r\n\r\n### How should this be tested?\r\n\r\nRun from the repository root after installing frontend dependencies:\r\n\r\n```sh\r\ncd zeppelin-web-angular\r\nnpm run typecheck:sdk-contracts\r\nnpm run test:shell\r\nnpm run check:websocket-contract\r\nnpx ngc -p src/tsconfig.json --noEmit\r\n\r\ncd projects/zeppelin-react\r\nnpm test\r\n```\r\n\r\n### Questions:\r\n\r\n- Does the license files need to update? No.\r\n- Is there breaking changes for older versions? TypeScript callers using arbitrary status/result strings must narrow them to the exported types. No server wire-format change.\r\n- Does this needs documentation? The type migration note is included above.\r\n\n\nCloses #5539 from miinhho/ZEPPELIN-6676-upstream-finite-values.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "d63fda37973052b7a684cba8450e289a942b2dbc",
      "tree": "79b78a5f61f6894ed7d724bdcd0218109cdd34e0",
      "parents": [
        "a6b101ebf1bf630a92677babd5fb8b232d7aeb4b"
      ],
      "author": {
        "name": "Naeun Park",
        "email": "57740138+world970511@users.noreply.github.com",
        "time": "Mon Oct 05 22:19:02 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:19:02 2026 +0900"
      },
      "message": "[ZEPPELIN-6636] Use lint-staged\u0027s local binary resolution instead of explicit node_modules paths\n\n### What is this PR for?\r\n`lint-staged` in `zeppelin-web-angular/package.json` mixes two conventions: `cross-env` and `eslint` are invoked by bare name, while `prettier` uses an explicit `./node_modules/.bin/prettier` path.\r\n\r\nlint-staged runs tasks through execa with `preferLocal` enabled, so locally installed binaries resolve by bare name. The explicit path is unnecessary and fragile, since it depends on the working directory (e.g. if nested packages add their own lint-staged configuration).\r\n\r\nThis PR drops the `./node_modules/.bin/` prefix from both `prettier --write` entries.\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] - Remove `./node_modules/.bin/` prefix from the lint-staged prettier tasks\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6636\r\n\r\n### How should this be tested?\r\n* Stage a `.ts` file with bad formatting and run `npx lint-staged` in `zeppelin-web-angular/`: `eslint --fix` runs first, then `prettier --write` reformats the file.\r\n* Stage a `.json`/`.js`/`.css`/`.html` file and run `npx lint-staged`: `prettier --write` runs on it.\r\n* Committing triggers the same flow through the Husky pre-commit hook.\r\n* No `./node_modules/.bin/` prefix remains in the `lint-staged` configuration.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\n\nCloses #5543 from world970511/ZEPPELIN-6636.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "a6b101ebf1bf630a92677babd5fb8b232d7aeb4b",
      "tree": "8b64fae12d30475b906905bca6764c02de7bf187",
      "parents": [
        "193276827499707ac6628ae0d8d1a4f7a19b34a8"
      ],
      "author": {
        "name": "YooJung Huh",
        "email": "gjenfwo@gmail.com",
        "time": "Mon Oct 05 22:17:34 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:17:34 2026 +0900"
      },
      "message": "[ZEPPELIN-6725] Remove obsolete Py4J download properties from build g…\n\n### What is this PR for?\r\nThis PR fixes the build documentation for Py4J so it matches the actual Maven configuration in the repository. It removes obsolete properties and URL examples that are not used by the current build, and keeps the documented `python.py4j.version` entry aligned with the real Maven dependency version used in `pom.xml`. No build behavior, dependency version, or runtime artifact changes are included.\r\n\r\n\r\n### What type of PR is it?\r\nDocumentation\r\n\r\n### Todos\r\n* [x] Update the build guide to remove unused Py4J download configuration entries\r\n\r\n* [x] Clarify that python.py4j.version is the Maven dependency version\r\n\r\n* [x] Align the documented default with `pom.xml`\r\n\r\n* [x] Keep bundled Py4J source ZIP behavior clearly separated from the Maven dependency\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6725\r\n* PR title includes: [ZEPPELIN-6725]\r\n\r\n### How should this be tested?\r\n* Confirm that no repository references remain for `pypi.repo.url` or `python.py4j.repo.folder`\r\n* Compare the documented `python.py4j.version` default with `pom.xml`\r\n* Review the “Optional configurations” section to confirm it no longer describes non-existent Py4J download properties\r\n\r\n### Screenshots (if appropriate)\r\n\r\n### Questions:\r\nDoes the license files need to update? No\r\nIs there breaking changes for older versions? No\r\nDoes this needs documentation? Yes, this PR updates the build documentation\r\n\n\nCloses #5542 from gjenfwo/ZEPPELIN-6725.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "193276827499707ac6628ae0d8d1a4f7a19b34a8",
      "tree": "b2906127b1c19f181190954cbc5558e51b3ca44d",
      "parents": [
        "a46011e93e41d899a180644ee01fd226d3fc71bf"
      ],
      "author": {
        "name": "chaeyoung kim",
        "email": "152389483+chelsseeey@users.noreply.github.com",
        "time": "Mon Oct 05 22:09:40 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:09:40 2026 +0900"
      },
      "message": "[ZEPPELIN-6445] Type AngularJS drag-and-drop callback bridge\n\n### What is this PR for?\r\n\r\nThis PR adds explicit types to the AngularJS drag-and-drop callback bridge and removes the existing `\u003cat\u003ets-ignore` directives.\r\n\r\nIt preserves callback arguments and scope binding while safely ignoring callbacks that are not defined.\r\n\r\n### What type of PR is it?\r\n\r\nImprovement\r\n\r\n### Todos\r\n\r\n* [x] Remove `\u003cat\u003ets-ignore` directives\r\n* [x] Preserve existing callback behavior\r\n* [x] Add regression tests for callback invocation and missing callbacks\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6445\r\n\r\n### How should this be tested?\r\n\r\nAutomated tests cover callback argument forwarding, scope binding, and missing callback handling.\r\n\r\n* `npm run test:shell`\r\n* `npm run lint`\r\n* `npm run build:angular`\r\n* `./mvnw -pl zeppelin-web-angular org.apache.rat:apache-rat-plugin:check -Prat`\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No.\r\n* Is there breaking changes for older versions? No.\r\n* Does this needs documentation? No. This is an internal type-safety improvement with no user-facing changes.\n\nCloses #5534 from chelsseeey/ZEPPELIN-6445-type-angular-drag-drop-callbacks.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "a46011e93e41d899a180644ee01fd226d3fc71bf",
      "tree": "b37f4025635f19fd71b3484b12d3a5199689256b",
      "parents": [
        "182e8fbcab5cbca2d8d3629cd561a9302427a3a5"
      ],
      "author": {
        "name": "chaeyoung kim",
        "email": "152389483+chelsseeey@users.noreply.github.com",
        "time": "Mon Oct 05 22:09:04 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 22:09:04 2026 +0900"
      },
      "message": "[ZEPPELIN-6653] Keep AGENTS.md chains within Codex budget\n\n### What is this PR for?\r\n\r\nCodex CLI reads the root and scoped `AGENTS.md` files as one cumulative instruction chain. Some Zeppelin chains exceeded the default 32 KiB limit, causing the most specific guidance to be truncated.\r\n\r\nThis PR moves detailed architecture and E2E guidance into linked reference files under `.agents/`, while keeping essential instructions in the automatically loaded files. The largest remaining chain is 29,026 bytes.\r\n\r\n### What type of PR is it?\r\n\r\nDocumentation\r\n\r\n### Todos\r\n\r\n* [x] Keep every existing `AGENTS.md` chain under 32 KiB\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6653\r\n\r\n### How should this be tested?\r\n\r\nThis is a documentation-only change.\r\n\r\nThe combined instruction-chain sizes were verified as follows:\r\n\r\n* Root: 8,820 bytes\r\n* `docs`: 15,950 bytes\r\n* `zeppelin-web-angular`: 22,764 bytes\r\n* `zeppelin-web-angular/projects/zeppelin-react`: 26,578 bytes\r\n* `zeppelin-web-angular/e2e`: 29,026 bytes\r\n\r\nThe following checks pass:\r\n\r\n```bash\r\n./mvnw clean org.apache.rat:apache-rat-plugin:check -Prat\r\ngit diff --check\r\n```\r\n### Screenshots (if appropriate)\r\n\r\nNot applicable\r\n\r\n### Questions:\r\n- Does the license files need to update? No\r\n- Is there breaking changes for older versions? No\r\n- Does this needs documentation? No, this PR is the documentation update\n\nCloses #5531 from chelsseeey/ZEPPELIN-6653-trim-agents-chain.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "182e8fbcab5cbca2d8d3629cd561a9302427a3a5",
      "tree": "084802b7c816d2a31d9ddb7e5912dfdc48f46ed0",
      "parents": [
        "1a7f475d33884b675c81e793380e1fef180338c1"
      ],
      "author": {
        "name": "HwangRock",
        "email": "157935545+HwangRock@users.noreply.github.com",
        "time": "Mon Oct 05 14:05:02 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 14:05:02 2026 +0900"
      },
      "message": "[ZEPPELIN-5901] Sanitize interpreter pod user label to satisfy Kubernetes label rules\n\n### What this fixes\n\nWhen a user\u0027s name has special characters (like a space), the interpreter pod fails to launch because the value breaks the Kubernetes label rules.\n\nThis shows up with external auth like Shiro + OIDC/JWT, where the principal is a display name / username / email — so it can easily contain spaces or other special chars.\n\nJIRA: https://issues.apache.org/jira/browse/ZEPPELIN-5901\n\n### Why it happened\n\nThe pod name already gets normalized through `K8sUtils.generateK8sName`, but the `user` label didn\u0027t go through anything — the principal was put into the label almost as-is (only `.trim()`). So Kubernetes rejected the pod.\n\nThe root cause was basically an asymmetry: the pod name was sanitized, the user label wasn\u0027t.\n\n### How I fixed it\n\nI added a label-specific sanitizer `K8sUtils.generateK8sLabelValue`, following the same removal rule as the existing pod-name normalization, but capping the length at 63 (the K8s label limit). The user label now goes through it before being set, and if nothing usable is left (e.g. a blank principal) the label is just omitted instead of writing an empty/`\"null\"` value.\n\n### Reproduction\n\nI reproduced it on a local kind cluster by mimicking the interpreter pod\u0027s label block.\n\n**As-is** — user label `\"Firstname Lastname\"` (contains a space):\n```\nThe Pod \"jdbc-repro-5901\" is invalid: metadata.labels: Invalid value: \"Firstname Lastname\": a valid label must be an empty string or consist of alphanumeric characters, \u0027-\u0027, \u0027_\u0027 or \u0027.\u0027, and must start and end with an alphanumeric character (regex used for validation is \u0027(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])?\u0027)\n```\n\n**To-be** — same pod with the normalized value `\"firstnamelastname\"`:\n```\npod/jdbc-repro-5901-fixed created\n```\n\n### Tests\n\n- Unit tests for the sanitizer (space / special chars / over-63-char cut / blank input).\n- Rendered-spec tests that check the `user` label is normalized, and that the label line is omitted when the principal is blank.\n- All `k8s-standard` module tests pass (32 tests, 0 failures).\n\n\nCloses #5529 from HwangRock/ZEPPELIN-5901-sanitize-user-label.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "1a7f475d33884b675c81e793380e1fef180338c1",
      "tree": "46be595f0f336e22a467334fd973be25e51179db",
      "parents": [
        "1e750fd145a434c3084aee9e81a1fd354117a03e"
      ],
      "author": {
        "name": "huiseong29",
        "email": "tobestar29@naver.com",
        "time": "Mon Oct 05 14:04:23 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 14:04:23 2026 +0900"
      },
      "message": "[ZEPPELIN-6649] Add unit tests for the remaining shared utilities (shell + remote)\n\n### What is this PR for?\r\nAdds unit tests for the three utilities left over in ZEPPELIN-6649, following the conventions in `zeppelin-web-angular/AGENTS.md`.\r\n\r\n- `isRecord` (`src/app/utility/type-utility.ts`): the `null` and array boundaries, primitives, functions, and an object without a prototype.\r\n- `parseTableData` (`projects/zeppelin-react/src/utils/tableUtils.ts`): header/rows split on tabs, header-only input, trailing newline, and an empty cell between tabs.\r\n- `exportFile` (`projects/zeppelin-react/src/utils/exportFile.ts`): extends the existing spec with multi-row CSV assembly, the xlsx branch (file name, MIME type, and header plus rows read back from `Sheet1`), and the empty-data guard for xlsx and for data without `rows`.\r\n\r\nSpec files only; no production code is changed. The files the issue lists as out of scope (`element.ts`, `css-unit-conversion.ts`, `line-map.ts`) are not touched.\r\n\r\nNot pinned on purpose, since the baseline says not to record behaviour that is already questionable: `parseTableData` trims the whole input, so a leading empty header cell loses its tab (`\"\\tb\\n1\\t2\"` gives `[\"b\"]`); CRLF input leaves a trailing `\\r` on each cell at the end of a line; an empty string yields one empty column name. I can open a follow-up issue for these if useful.\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] - Add unit tests for `isRecord`, `parseTableData` and `exportFile`\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6649\r\n\r\n### How should this be tested?\r\n* `cd zeppelin-web-angular \u0026\u0026 npm run test:shell -- type-utility.spec.ts` (10 tests)\r\n* `cd zeppelin-web-angular/projects/zeppelin-react \u0026\u0026 npm test \u0026\u0026 npm run lint` (18 tests in `src/utils`)\r\n* The React suite does not run in pull-request CI yet (see ZEPPELIN-6566), so it was run locally.\r\n\r\n### Screenshots (if appropriate)\r\n\r\n### Questions:\r\n* Does the license files need to update? No.\r\n* Is there breaking changes for older versions? No.\r\n* Does this needs documentation? No.\n\nCloses #5524 from huiseong29/ZEPPELIN-6649.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "1e750fd145a434c3084aee9e81a1fd354117a03e",
      "tree": "f3523b53dfccaf7e20ca473efcce5aa565276059",
      "parents": [
        "df3edd6ec727921b5abc718ce5d50382dcd22567"
      ],
      "author": {
        "name": "Yerin Lee",
        "email": "91695537+yxinot@users.noreply.github.com",
        "time": "Mon Oct 05 14:03:12 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 14:03:12 2026 +0900"
      },
      "message": "[ZEPPELIN-2506] Improve error message when no interpreter is bound to a note\n\n### What is this PR for?\r\n\r\n  When a paragraph is executed without any interpreter bound to the note, the error message displays \"Interpreter null not found\", which is confusing and unhelpful. This PR improves the error message to clearly state \"No interpreter is bound to this note. Please check the interpreter settings.\" when intpText is null or blank.\r\n                                                                                                                                                                           \r\n### What type of PR is it?                                                                                                                                                   \r\n   \r\n  Bug Fix                                                                                                                                                                  \r\n                  \r\n  ### Todos                                                                                                                                                                            \r\n- [x] Improve error message in Paragraph.setInterpreterNotFound() for null/blank intpText                                                                              \r\n- [x] Add unit tests for both null and present intpText cases\r\n\r\n                                                                                                                                                                           \r\n### What is the Jira issue?                                                                                                                                                  \r\n                                                                                                                                                                           \r\n  - https://issues.apache.org/jira/browse/ZEPPELIN-2506                                                                                                                    \r\n  - [ZEPPELIN-2506] \"Interpreter null not found\" when a note is not bound to any interpreters\r\n                                                                                                                                                                           \r\n  ### How should this be tested?                                                                                                                                               \r\n                                                                                                                                                                           \r\n  - Two unit tests added in ParagraphTest:                                                                                                                                 \r\n    - testInterpreterNotFoundMessageWhenIntpTextIsNull — verifies the improved message when no interpreter is specified\r\n    - testInterpreterNotFoundMessageWhenIntpTextIsPresent — verifies the existing message is preserved when an invalid interpreter name is given                           \r\n  - Manual: create a note with no interpreter binding, run a paragraph without %interpreter prefix, and confirm the new error message appears.                             \r\n                                                                                                                                                                           \r\n  ### Screenshots (if appropriate)                                                                                                                                             \r\n                                                                                                                                                                           \r\n  N/A                                                                                                                                                                      \r\n                  \r\n  ### Questions:                                                                                                                                                               \r\n                  \r\n  - Does the license files need to update? No                                                                                                                              \r\n  - Is there breaking changes for older versions? No\r\n  - Does this needs documentation? No\n\nCloses #5521 from yxinot/ZEPPELIN-2506-fix-interpreter-null-not-found.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "df3edd6ec727921b5abc718ce5d50382dcd22567",
      "tree": "7d4ecae9d425ad23a5bcd43cdd765284f43310d9",
      "parents": [
        "74b51b28d6f3c1c170f44822beadba299df9a959"
      ],
      "author": {
        "name": "김동환",
        "email": "66408194+dev-donghwan@users.noreply.github.com",
        "time": "Mon Oct 05 14:01:30 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 05 14:01:30 2026 +0900"
      },
      "message": "[ZEPPELIN-5989] Resolve a local notebook dir as a file path instead of parsing it as a URI\n\n### What is this PR for?\n\n`VFSNotebookRepo.setNotebookDirectory()` parses the notebook dir with `new URI()` unless it is a Windows absolute path like `C:\\...`. A local path is not a URI and can contain characters that a URI does not allow:\n\n* On Windows the default dir is built as `./` + `\\` + `notebook`, so the server fails to start with `URISyntaxException: Illegal character in path at index 2: ./\\notebook`.\n* On any OS, a dir with a space, like `/home/me/My Notebooks`, fails the same way.\n\nThe issue suggests joining the dir with `Paths.get`, but on Windows that gives `.\\notebook`, which `new URI()` rejects too.\n\nThis PR:\n\n* Resolves a notebook dir without a scheme as a file path, `new File(getAbsoluteDir(path)).toURI()`, and parses only a dir with a scheme as a URI. The branch that handled a URI without a scheme is removed, since that case no longer reaches it.\n* Keeps `rootNotebookFolder` as a decoded path for a local dir. It was the root\u0027s URI with `file:///` replaced, so it kept `%20` for a space. `list()` strips it from note file names that are decoded since ZEPPELIN-6202, which would shift note paths by two characters per space, and `GitNotebookRepo` opens the repository at `rootNotebookFolder/.git`, which would be a different directory. `list()` now resolves the root by its URI instead of by this path. A dir with another scheme keeps its current value.\n\nFor a local dir without such characters, both values are the same as before.\n\nI could not run it on Windows. On other systems the same code path is reached with a space, and Commons VFS treats a backslash in the file URI as a separator. It would help if someone on Windows could start the server from this branch without a configuration file, which is how the issue reproduces it.\n\n### What type of PR is it?\nBug Fix\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-5989\n\n### How should this be tested?\n\n* `VFSNotebookRepoTest.testNotebookDirWithCharactersThatAUriDoesNotAllow` uses a dir with a space and one with a backslash, saves and lists a note, and checks its path.\n* `GitNotebookRepoTest.notebookDirWithSpace` checks that `.git` is created in the dir with a space and that a checkpoint is recorded.\n\nWithout the first change both tests fail with the `URISyntaxException` above; without the second the path and `.git` checks fail.\n\nRun locally: `VFSNotebookRepoTest` (8), `GitNotebookRepoTest` (12), `NotebookRepoSyncTest` (10), `NotebookServiceTest` (13), `NotebookServiceRaceConditionTest` (1), `NoteManagerMoveResaveRaceTest` (1), `NotebookTest` (42). `testSchedule`, `testScheduleDisabledWithName` and `testSchedulePoolUsage` fail locally with and without this change: they wait five seconds for the cron run, and the interpreter process here takes about six seconds to sync its libraries and register.\n\n\nCloses #5518 from dev-donghwan/ZEPPELIN-5989.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "74b51b28d6f3c1c170f44822beadba299df9a959",
      "tree": "674d793059212fe34bde38cc5355b419718ce5af",
      "parents": [
        "5b8f3ee75b1c981b944a1aa11c699120cc3abc0e"
      ],
      "author": {
        "name": "Yerin Lee",
        "email": "91695537+yxinot@users.noreply.github.com",
        "time": "Sun Oct 04 00:25:31 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 04 00:25:31 2026 +0900"
      },
      "message": "[ZEPPELIN-5658] Fix infinite recursion in AzureNotebookRepo.list()\n\n### What is this PR for?\r\n  Fix infinite recursion (`StackOverflowError`) in `AzureNotebookRepo.list()` when notebooks are stored in subdirectories. The private `list(CloudFileDirectory folder)` method was iterating over `rootDir` instead of the `folder` parameter, causing the recursive call to never descend and loop infinitely.                                  \r\n   \r\n  ### What type of PR is it?                                                                                                                                               \r\n  Bug Fix                                                   \r\n                                                                                                                                                                           \r\n  ### Todos                                                 \r\n  * [x] - Fix `rootDir` → `folder` in `AzureNotebookRepo.list()`                                                                                                           \r\n                                                                                                                                                                           \r\n  ### What is the Jira issue?                                                                                                                                              \r\n  * https://issues.apache.org/jira/browse/ZEPPELIN-5658                                                                                                                    \r\n                                                                                                                                                                           \r\n  ### How should this be tested?                                                                                                                                           \r\n  * No existing unit tests (Azure infrastructure dependency)                                                                                                               \r\n  * The fix is a single-variable change correcting a clear copy-paste error where the method parameter was completely ignored                                              \r\n  * Manual test: deploy Zeppelin with Azure Storage backend, create notebooks in subdirectories, and verify they persist across restarts without `StackOverflowError`      \r\n                                                                                                                                                                           \r\n  ### Screenshots (if appropriate)                                                                                                                                         \r\n  N/A                                                                                                                                                                      \r\n                                                                                                                                                                           \r\n  ### Questions:                                            \r\n  * Does the license files need to update? No                                                                                                                              \r\n  * Is there breaking changes for older versions? No                                                                                                                       \r\n  * Does this needs documentation? No\n\nCloses #5522 from yxinot/ZEPPELIN-5658-fix-azure-notebook-repo-infinite-recursion.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "5b8f3ee75b1c981b944a1aa11c699120cc3abc0e",
      "tree": "be9c1d976b596cd117956233f0ad6d672976d9d0",
      "parents": [
        "6a5ed44594e88b22140e9159e6b96589fccf4e06"
      ],
      "author": {
        "name": "Sohee Moon",
        "email": "121299334+soheetech@users.noreply.github.com",
        "time": "Sun Oct 04 00:12:16 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Oct 04 00:12:16 2026 +0900"
      },
      "message": "[ZEPPELIN-6487] Update the deprecated pypi.python.org URL in the build docs\n\n### What is this PR for?\r\nThis PR updates the deprecated `pypi.python.org` host to the active distribution file host `files.pythonhosted.org` in `docs/setup/basics/how_to_build.md`.\r\nIt also synchronizes the documented `python.py4j.version` (0.10.7) and `python.py4j.repo.folder` path with the project\u0027s actual build configuration in `python/pom.xml`, ensuring that the composed Py4J package download URL resolves correctly.\r\n\r\n### What type of PR is it?\r\nDocumentation\r\n\r\n### Todos\r\n* [x] - Replace deprecated pypi.python.org host with files.pythonhosted.org\r\n* [x] - Sync python.py4j.version and repo folder path with project build settings\r\n* [x] - Verify composed download URL produces HTTP 200\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6487\r\n\r\n### How should this be tested?\r\n1. Check `docs/setup/basics/how_to_build.md` in the \"Py4J package\" section.\r\n2. Confirm the composed URL `${pypi.repo.url}${python.py4j.repo.folder}py4j-${python.py4j.version}.zip` constructs: `https://files.pythonhosted.org/packages/dd/03/d83f659f045d819fc7550dd472b3831fe8c8fa7204c6428270a46a4a5ab9/py4j-0.10.7.zip`\r\n3. Verify the URL returns HTTP 200 via `curl -I`:\r\n   ```bash\r\n   curl -I [https://files.pythonhosted.org/packages/dd/03/d83f659f045d819fc7550dd472b3831fe8c8fa7204c6428270a46a4a5ab9/py4j-0.10.7.zip](https://files.pythonhosted.org/packages/dd/03/d83f659f045d819fc7550dd472b3831fe8c8fa7204c6428270a46a4a5ab9/py4j-0.10.7.zip)\r\n   ```\r\n4. Run `git diff --check` to ensure no whitespace errors.\r\n\r\n### Screenshots (if appropriate)\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No (this PR updates documentation itself)\r\n\n\nCloses #5525 from soheetech/ZEPPELIN-6487.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "6a5ed44594e88b22140e9159e6b96589fccf4e06",
      "tree": "2021ee875fd1702f7d85835d04acc0305ae0ecbd",
      "parents": [
        "1dc3d4f0d63aa10e2da61e24cfca33c9ab09bb6b"
      ],
      "author": {
        "name": "ChanHo Lee",
        "email": "chanholee@apache.org",
        "time": "Sat Oct 03 11:05:08 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Oct 03 11:05:08 2026 +0900"
      },
      "message": "[ZEPPELIN-6724] Add a convention for frontend type tests\n\n### What is this PR for?\nType tests in the frontend currently come in two layouts: assertions inside an SDK spec (ZEPPELIN-6664) and a separate `type-tests/` directory (ZEPPELIN-6663). This PR settles on the first and documents it in `zeppelin-web-angular/AGENTS.md`, so the next type test has one place to go.\n\n**The convention**\n- Type assertions (`expectTypeOf`, `assertType`, `\u003cat\u003ets-expect-error`) go in ordinary `.spec.ts` files, beside the interface they pin.\n- They count only where `tsc` checks the spec: today, the zeppelin-sdk and notebook-core specs. Lint now accepts a type-only test there and still rejects one elsewhere.\n- To show a value is accepted, pass it to `assertType\u003cT\u003e(...)`. Prefer an exact matcher to `\u003cat\u003ets-expect-error`, which any error on the next line satisfies.\n\n**Why ordinary specs**\n- Type assertions are erased before Vitest runs a spec, so only `tsc` checks them. The two spec programs above already have a `tsc` pass in Maven (`typecheck:sdk-contracts`, `typecheck:notebook-core`), so a type test there needs no extra tsconfig, script or runner.\n- The usual alternative is separate `*.test-d.ts` files checked by `vitest --typecheck`. It reports failures per test, but it is still experimental and reports a file outside its tsconfig as passed ([vitest#7988](https://github.com/vitest-dev/vitest/issues/7988)), so a type test could go unchecked without anyone noticing. Per-test output is not worth that risk or a second checker.\n\n**Commits** (each passes typecheck, lint and tests on its own)\n1. `eslint.config.js`: accept type assertions in the two typechecked spec programs.\n2. Move the `CompletionItem` type test into `completion-item.spec.ts`, using exact matchers instead of `\u003cat\u003ets-expect-error`.\n3. Drop the now-empty `type-tests/` include from the SDK spec tsconfig.\n4. List `typecheck:sdk-contracts` in AGENTS.md. Maven already ran it.\n5. Document the convention.\n6. Replace runtime `expect`s on typed literals in the SDK specs with `assertType`. `tsc` already checked those literals; `assertType` keeps that check, excess properties included, without a variable that needs a use.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Accept type-only tests in typechecked spec programs\n* [x] Move the `CompletionItem` type test into an SDK spec\n* [x] Document the convention in `zeppelin-web-angular/AGENTS.md`\n\n### What is the Jira issue?\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6724\n\n### How should this be tested?\n```bash\ncd zeppelin-web-angular\nnpm run typecheck:sdk-contracts\nnpm run typecheck:notebook-core\nnpm run test:shell\nnpx eslint projects/zeppelin-sdk projects/zeppelin-notebook-core test/notebook-core\n```\n- To see the lint boundary, put a test containing only `expectTypeOf` under `src/`: `vitest/expect-expect` reports it. The same test under `projects/zeppelin-sdk/src` passes.\n- To see the type test fail, make `CompletionItem.name` optional: `typecheck:sdk-contracts` reports `completion-item.spec.ts`.\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? Yes, `zeppelin-web-angular/AGENTS.md` is updated in this PR\n\n\nCloses #5520 from tbonelee/ZEPPELIN-6724.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "1dc3d4f0d63aa10e2da61e24cfca33c9ab09bb6b",
      "tree": "a9b676cd259cc98e71f97f8732ac7629b4555f21",
      "parents": [
        "18aaa28817132deea28617e32ddcaeb7db4c67d6"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Fri Oct 02 23:48:28 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 02 23:48:28 2026 +0900"
      },
      "message": "[ZEPPELIN-6663] Mark CompletionItem.meta optional to match completion payloads\n\n### What is this PR for?\r\n`CompletionItem.meta` is declared as required in the SDK, but real completion payloads from the Spark and Flink interpreters omit the `meta` key. This PR makes only `meta` optional, keeps `name` and `value` required, and adds a compile-time regression fixture that runs as part of the existing SDK contract typecheck (`typecheck:sdk-contracts`).\r\n\r\nPart of ZEPPELIN-6627.\r\n\r\n**Why `meta` is absent on the wire**\r\n- The following interpreters construct `new InterpreterCompletion(name, value, null)`:\r\n  - `SparkScala212Interpreter.scala:117`\r\n  - `SparkScala213Interpreter.scala:142`\r\n  - `FlinkScala212Interpreter.scala:39`\r\n- `NotebookServer.java:142-146` builds Gson without `serializeNulls()`, so null fields are dropped.\r\n- `serializeMessage()` uses that Gson (`NotebookServer.java:633-635`). The completion reply is sent through it at `NotebookServer.java:1372-1374`, so these payloads contain no `meta` key at all (not `meta: null`).\r\n- The Jupyter path supplies an empty string (`JupyterKernelInterpreter.java:367`), so this PR does not claim every payload omits `meta`. It only makes the shared type accept the proven Spark/Flink shape.\r\n\r\n**Why `name` and `value` stay required**\r\n- All current production construction sites supply both fields.\r\n- The New UI reads `name` without a fallback (`completion.service.ts:82-83`).\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] Make `CompletionItem.meta` optional (`meta?: string`)\r\n* [x] Add `projects/zeppelin-sdk/type-tests/completion-item-meta.ts`\r\n* [x] Include `type-tests/**/*.ts` in `projects/zeppelin-sdk/tsconfig.spec.json`\r\n\r\n### What is the Jira issue?\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6663\r\n\r\n### How should this be tested?\r\n```bash\r\ncd zeppelin-web-angular\r\nnpm run typecheck:sdk-contracts\r\nnpm run build-project:sdk\r\nnpm run check:websocket-contract\r\n```\r\n- The fixture assigns a literal with `name` and `value` but no `meta` to `CompletionItem` without a type assertion.\r\n- `\u003cat\u003ets-expect-error` cases reject literals missing `name` or `value`, so neither field can become optional by accident.\r\n- The issue suggests a new `tsconfig.type-tests.json` and a new script. Instead, this PR adds `type-tests/**/*.ts` to the existing `projects/zeppelin-sdk/tsconfig.spec.json`.\r\n  - The existing `typecheck:sdk-contracts` script already type-checks that config.\r\n  - `zeppelin-web-angular/pom.xml` already runs `npm run typecheck:sdk-contracts` in the Maven `test` phase (`npm typecheck sdk contracts` execution).\r\n  - So the regression runs in the existing Maven/frontend build path without changing `package.json`, and without running the same typecheck twice through `build-project:sdk`.\r\n- `check:websocket-contract` does not inspect field optionality. It is only a guard against unrelated operation-map regressions.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\n\nCloses #5519 from JangAyeon/ZEPPELIN-6663.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "18aaa28817132deea28617e32ddcaeb7db4c67d6",
      "tree": "844894d4c07f9ce3f882c4d173eebc3e2f6371b8",
      "parents": [
        "d3e932f0b1e61aea2a2cec3b52666947294fca8b"
      ],
      "author": {
        "name": "김동환",
        "email": "66408194+dev-donghwan@users.noreply.github.com",
        "time": "Fri Oct 02 23:40:29 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 02 23:40:29 2026 +0900"
      },
      "message": "[ZEPPELIN-6632] Pass the ipynb extension without a leading dot when exporting a note\n\n### What is this PR for?\n\nExporting a note to ipynb from the classic UI downloads a file with two dots before the extension, e.g. `test sh..ipynb`.\n\n`saveAsService.saveAs()` joins the file name and the extension with a dot itself, and every other call site passes the extension without one (`\u0027zpln\u0027`, `\u0027csv\u0027`, `\u0027tsv\u0027`), as does the New UI\u0027s `SaveAsService`. The ipynb call site passes `\u0027.ipynb\u0027`.\n\nZEPPELIN-4823 meant to produce `{note_name}.ipynb` and replaced `\u0027zepl.ipynb\u0027` with `\u0027.ipynb\u0027`, but `saveAs()` already added the dot at that time, so the result became `{note_name}..ipynb`.\n\nThis passes `\u0027ipynb\u0027`, so the call site follows the same convention as the others.\n\n### What type of PR is it?\nBug Fix\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-6632\n\n### How should this be tested?\n\n`websocket-event.factory.test.js` now replaces `saveAsService` with a spy and checks that a `CONVERTED_NOTE_NBFORMAT` message saves with `\u0027ipynb\u0027`. The test fails with the previous `\u0027.ipynb\u0027` argument.\n\nI also checked the resulting download name with the real `saveAsService` by capturing the anchor\u0027s `download` attribute: `test sh..ipynb` before the change, `test sh.ipynb` after.\n\n* zeppelin-web karma suite: 194 tests pass\n\n\nCloses #5515 from dev-donghwan/ZEPPELIN-6632.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "d3e932f0b1e61aea2a2cec3b52666947294fca8b",
      "tree": "9a223a553f38f04908bad103c3b8e012dcb4e89b",
      "parents": [
        "95b25f25fb8e19425867e04b080763adfb7ed147"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Thu Oct 01 23:09:28 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 23:09:28 2026 +0900"
      },
      "message": "[ZEPPELIN-6591] Discard unsaved note permission edits on Cancel\n\n### What is this PR for?\r\nIn the New UI note permissions panel, each select was bound with `[(ngModel)]` directly to the `permissions` object owned by `NotebookComponent`. Editing a list mutated the parent\u0027s object, and Cancel only hid the panel. Reopening the panel reused the same mutated object, so it showed the unsaved edits while `GET /api/notebook/{noteId}/permissions` still returned the saved values. A later Save could also submit those stale edits.\r\n\r\nThis PR makes the panel edit a detached draft:\r\n\r\n* `NotebookPermissionsComponent` builds `draftPermissions` from the input when it initializes and when a new `permissions` input arrives. All four lists are copied, so in-place array edits do not reach the parent either.\r\n* The template binds every select to the draft. Cancel discards it and sends no request.\r\n* Save sends a copy of the draft through the existing endpoint, then emits `permissionsSaved`. `NotebookComponent` handles it by calling `getPermissions(note)`, so the saved state (and `isOwner`) is refreshed from the backend.\r\n* The empty-Owners modal now fills and resets the draft. `permissionsBack` is removed because the draft replaces it.\r\n\r\nAs the issue notes, reassigning the child\u0027s `\u003cat\u003eInput()` would not repair an object already mutated in the parent. With this change the parent object is never mutated, and the panel is destroyed on close, so reopening always starts from the parent\u0027s saved state.\r\n\r\n\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n* [x] Edit a detached draft instead of the parent-owned permissions object\r\n* [x] Refresh the saved permissions from the backend after Save\r\n* [x] Add unit tests for cancel, reopen, reset and save\r\n\r\n### What is the Jira issue?\r\n[ZEPPELIN-6591](https://issues.apache.org/jira/browse/ZEPPELIN-6591)\r\n\r\n### How should this be tested?\r\n* add unit tests for changed behavior\r\n```bash\r\n  cd zeppelin-web-angular\r\n  npm run test:shell -- permissions.component.spec.ts\r\n```\r\n\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5510 from JangAyeon/ZEPPELIN-6591.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "95b25f25fb8e19425867e04b080763adfb7ed147",
      "tree": "d2443ade3288f4efeadc4105cce4e5872a54c063",
      "parents": [
        "45f305a765915fe22e616a74c37fd7d6dbdb4d31"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Thu Oct 01 00:58:47 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 00:58:47 2026 +0900"
      },
      "message": "[ZEPPELIN-6523] Sanitize href in ExternalLinkDirective\n\n### What is this PR for?\r\n`ExternalLinkDirective` (selector `a[href]`) declares `\u003cat\u003eInput() href`. Because the directive claims the `href` input, `[href]` bindings on anchors are delivered to the directive rather than to the DOM property, so Angular\u0027s built-in URL sanitization (`ɵɵsanitizeUrl`) never runs. The directive then assigned the raw value via `nativeElement.href \u003d this.href`, which keeps `javascript:` URLs executable on click.\r\n\r\nOne reachable path is the interpreter setting page, where a `url`-type property value is rendered as `\u003ca [href]\u003d\"...\"\u003e` (`interpreter/item/item.component.html`). Interpreter properties are usually admin-controlled, so the practical risk is limited, but this is still a sanitization bypass and a defense-in-depth fix for any current or future dynamic `[href]` binding.\r\n\r\nThis PR sanitizes the value with `DomSanitizer.sanitize(SecurityContext.URL, ...)` before assigning it, so unsafe URLs become `unsafe:...` just like a normal Angular `[href]` binding. The existing `rel\u003d\"noopener noreferrer\"` / `target\u003d\"_blank\"` handling for external links is unchanged.\r\n\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n* [x] Sanitize href in `ExternalLinkDirective`\r\n* [x] Add unit tests\r\n\r\n### What is the Jira issue?\r\n\r\n[ZEPPELIN-6523](https://issues.apache.org/jira/browse/ZEPPELIN-6523)\r\n\r\n### How should this be tested?\r\n* Unit tests: `cd zeppelin-web-angular \u0026\u0026 npx vitest run --config vitest.shell.config.mts src/app/share/external-links/`\r\n\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5508 from JangAyeon/ZEPPELIN-6523.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "45f305a765915fe22e616a74c37fd7d6dbdb4d31",
      "tree": "5c3e34aa4f08ed49cafc4ac2a03a2fc109eee4ab",
      "parents": [
        "a42417484bf5a3ee41c1fac37a3bb406f765b181"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Thu Oct 01 00:58:01 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 00:58:01 2026 +0900"
      },
      "message": "[ZEPPELIN-6584] Fix reversed line diff direction in New UI revision comparator\n\n### What is this PR for?\r\nThe New UI revision comparator labels a comparison as `first --\u003e second` (e.g. `older --\u003e newer`), but `compareRevisions()` built the line-level diff from the second revision back to the first. As a result, added lines were rendered as red deletions and removed lines as green insertions for paragraphs present in both revisions.\r\n\r\nThis PR computes the line diff in the same `first --\u003e second` direction shown in the UI, matching the legacy AngularJS comparator (`diffLines(firstText, secondText)`). The whole-paragraph `added`/`deleted` classification, which was already correct, is unchanged.\r\n\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n* [x] - Fix line diff direction\r\n* [x] - Add focused comparator unit tests\r\n\r\n### What is the Jira issue?\r\n[ZEPPELIN-6584](https://issues.apache.org/jira/browse/ZEPPELIN-6584)\r\n\r\n### How should this be tested?\r\n* Unit tests:\r\n```\r\n  cd zeppelin-web-angular\r\n  npm run test:shell -- revisions-comparator.component.spec.ts\r\n  npm run lint\r\n```\r\n\r\n### Screenshots (if appropriate)\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5507 from JangAyeon/ZEPPELIN-6584.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "a42417484bf5a3ee41c1fac37a3bb406f765b181",
      "tree": "d315203451bafbf488b14366662a3f937fa85295",
      "parents": [
        "28894a1fc68bc188be72437f81d8d014240c5c52"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Thu Oct 01 00:10:50 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Oct 01 00:10:50 2026 +0900"
      },
      "message": "[ZEPPELIN-6439] Fix typos and non-ASCII lookalike characters in interpreter documentation\n\n### What is this PR for?\r\nInterpreter settings and documentation are shown directly to users in Zeppelin\u0027s UI and docs, but some of this text contains typos and non-ASCII lookalike characters.\r\n\r\nThe most notable case is the JDBC `default.completer.schemaFilters` description, which starts with `Сomma` using a Cyrillic `С` (U+0421) instead of the Latin `C`. It looks identical on screen, but it can break text search, copy-paste, and encoding-sensitive tooling. This PR replaces it with the Latin `C` in both the interpreter setting (`interpreter-setting.json`) and the corresponding docs (`jdbc.md`), so the two stay consistent.\r\n\r\nThis PR also fixes the following typos:\r\n- `seperated` → `separated` in the notebook authorization docs\r\n- `inteprreters` → `interpreters` in the `zeppelin.interpreter.include` / `zeppelin.interpreter.exclude` descriptions of `conf/zeppelin-site.xml.template`\r\n- `phatomJs` → `PhantomJS` in the Vagrant dev environment Ansible task\r\n\r\nWording changes are kept minimal. Only description text is changed; no property keys, default values, or runtime behavior are affected. Following the issue guidance, generated files (e.g. `zeppelin-server/src/main/resources/zeppelin-site.xml`) and vendored/minified assets are not modified.\r\n\r\n\r\n### What type of PR is it?\r\nDocumentation\r\n\r\n### Todos\r\n* [x] Replace the Cyrillic `С` (U+0421) in `Сomma separated` with the Latin `C` in the JDBC interpreter setting and docs\r\n* [x] Fix `seperated` → `separated` in the notebook authorization docs\r\n* [x] Fix `inteprreters` → `interpreters` (2 occurrences) in `conf/zeppelin-site.xml.template`\r\n* [x] Fix `phatomJs` → `PhantomJS` in the Vagrant dev environment Ansible task\r\n\r\n### What is the Jira issue?\r\n[ZEPPELIN-6439](https://issues.apache.org/jira/browse/ZEPPELIN-6439)\r\n\r\n### How should this be tested?\r\nSearch the whole repository and confirm there are no matches:\r\n```bash\r\nrg -n \"Сomma|seperated|Thats|phatomJs|inteprreters\" .\r\n```\r\n\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5506 from JangAyeon/ZEPPELIN-6439.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "28894a1fc68bc188be72437f81d8d014240c5c52",
      "tree": "ba6eea088ab533e4d9dfba2869d602e7545cf59d",
      "parents": [
        "c63b73bfcc434b1d9ace6e1330fa2d1572346a57"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Wed Sep 30 21:04:12 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 30 21:04:12 2026 +0900"
      },
      "message": "[ZEPPELIN-6722] Record the pinned Angular notebook route baseline\n\n### What is this PR for?\n\nRecord the pinned Angular notebook route baseline with the benchmark contract from ZEPPELIN-6668, before the React route host (ZEPPELIN-6675) lands and the current Angular path can no longer be measured under the same conditions.\n\n* Measured at `7f7b995c3` (the ZEPPELIN-6668 merge, current `master`), with a clean working tree (`workingTreeDirty: false`).\n* One run in one environment: 10 cold and 10 warm samples, no outlier removed, nothing merged from other runs.\n* No script, fixture or config change. The measurement tool stays exactly as ZEPPELIN-6668 fixed it, so the recorded commit identifies the tool that produced these numbers.\n\n| Metric (ms) | Cold median | Cold p95 | Warm median | Warm p95 |\n| --- | --- | --- | --- | --- |\n| `notebookReadyMs` | 1102.9 | 1181.9 | 806.2 | 871.6 |\n| `fcpMs` | 28 | 44 | 36 | 40 |\n\nRaw samples: cold 1092.4–1181.9 ms, warm 768.9–871.6 ms. The JSON files are authoritative; the table rounds to 0.1 ms.\n\nEntry bundles (raw / gzip bytes): `main` 6,691,449 / 1,786,481, `scripts` 825,757 / 238,428, `styles` 136,950 / 23,253, `polyfills` 56,102 / 20,644; React `remoteEntry.js` 4,109 / 1,785.\n\nEnvironment: macOS (Darwin 23.6.0), Apple M3 Pro, 36 GiB, Playwright Chromium 140.0.7339.186, Node v22.21.1 (the `.nvmrc` version), AC power. Zeppelin was built from the same commit (`zeppelin-server` with its dependencies, and `shell`), with anonymous access and an empty isolated notebook directory. Measurement started after the post-build Spotlight indexing settled (1-minute load average 3.8).\n\nFiles:\n* `e2e/performance/baselines/70eef3f8-….raw.json` / `.summary.json`: added with `git add -f`, as the README describes, because generated outputs stay git-ignored.\n* `e2e/performance/README.md`: the sentence saying there is no pinned baseline now points to the recorded one, and a `Recorded Angular baseline` section lists the commit, environment and summary. It also notes that note import needs at least one interpreter. With none installed, import fails with HTTP 500 (`InterpreterSettingManager.getDefaultInterpreterSetting` throws `IndexOutOfBoundsException`). The fixture\u0027s paragraphs use `%sh`, so building `shell` is enough. No existing sentence was removed; the two changed lines keep their original content.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Record 10 cold and 10 warm samples at a pinned `master` commit\n* [x] Commit raw and summary JSON with the environment record\n* [x] Point the README at the recorded baseline\n\n### What is the Jira issue?\n[ZEPPELIN-6722](https://issues.apache.org/jira/browse/ZEPPELIN-6722)\n\n### How should this be tested?\n\n```bash\ncd zeppelin-web-angular\nnpm run test:shell -- test/notebook-baseline.spec.ts\n# against an isolated Zeppelin serving the `npm run build` output, with the shell interpreter installed\nPLAYWRIGHT_BASE_URL\u003dhttp://localhost:8080/ PERF_NOTEBOOK_DISPOSABLE\u003d1 npm run perf:notebook-baseline\n```\n\nWhat I ran locally:\n* Contract unit tests: 12/12 passed.\n* Dry run (1 cold + 1 warm) passed before the real run; its output was not committed.\n* The real run passed and the imported note was deleted afterwards (the notebook store was empty again).\n* I recomputed the median and nearest-rank p95 from the raw samples. They match the summary, and the raw and summary metadata are identical.\n* Bundle SHA-256, raw bytes and `zlib` gzip bytes match the built `dist` files.\n* Fixture hash mismatch: changing one byte in the fixture made the command fail with `Benchmark fixture SHA-256 mismatch`. The fixture was restored before committing.\n* Ready-condition mismatch was **not** exercised against a live server. It relies on the existing ZEPPELIN-6668 spec and unit tests.\n* No Playwright E2E suite run, since this PR changes no application or test code.\n\nNumbers from a different machine are not expected to match. Compare a later run with this baseline only when it was recorded in the same environment.\n\n### Screenshots (if appropriate)\n\nN/A.\n\n### Questions:\n* Does the license files need to update? No. The baseline JSON is covered by the existing RAT `**/*.json` exclusion.\n* Is there breaking changes for older versions? No.\n* Does this needs documentation? The benchmark README is updated in this PR.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5512 from kimyenac/ZEPPELIN-6722.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "c63b73bfcc434b1d9ace6e1330fa2d1572346a57",
      "tree": "642cf70470ea2b16266f978e6fb9ed0d59dfbd6e",
      "parents": [
        "7f7b995c35978c4a3ef3df31ec8faf206ce179f9"
      ],
      "author": {
        "name": "github-actions[bot]",
        "email": "41898282+github-actions[bot]@users.noreply.github.com",
        "time": "Wed Sep 30 20:28:39 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 30 20:28:39 2026 +0900"
      },
      "message": "[HOTFIX] Refresh zeppelin-react lockfile for npm audit (#5514)\n\nCo-authored-by: github-actions[bot] \u003c41898282+github-actions[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "7f7b995c35978c4a3ef3df31ec8faf206ce179f9",
      "tree": "7b078edd9618b5a62511b2b9becd51fb1d8ef657",
      "parents": [
        "4e49e3c7f262ddb5e82081160d49355d6e93f88b"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Sep 27 17:34:57 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 27 17:34:57 2026 +0900"
      },
      "message": "[ZEPPELIN-6668] Add notebook route benchmark contract\n\n### What is this PR for?\nAdd a reproducible benchmark contract for the notebook route, without committing baseline numbers (a follow-up records them).\n\n* Fixture: 100 paragraphs (80 TEXT, 10 TABLE, 10 collapsed), pinned by SHA-256\n* Ready condition: action bar visible, 100 paragraph containers, first Monaco editor attached\n* Runs: 10 cold (new context) and 10 warm (after one unrecorded prime), with raw samples, median, and p95\n* Bundles: raw and gzip sizes of the Angular entry chunks and React `remoteEntry.js`\n\nRuntime metrics cover the Angular route only. The benchmark is excluded from the normal E2E run.\n\nMost of the diff (3,319 of 3,957 added lines) is the fixture JSON. It is data, pinned by SHA-256 and checked for composition by `validateFixture`, so it does not need a line-by-line review. The code to review is about 590 lines under `e2e/performance/`, `e2e/models/notebook-performance-page.ts`, `test/notebook-baseline.spec.ts` and `playwright.performance.config.js`.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Add a hash-pinned benchmark fixture\n* [x] Add the Playwright performance runner\n* [x] Validate the benchmark contract with unit tests\n\n### What is the Jira issue?\nZEPPELIN-6668\n\n### How should this be tested?\n```bash\ncd zeppelin-web-angular\nnpm run test:shell -- test/notebook-baseline.spec.ts\n# against an isolated Zeppelin serving the `npm run build` output\nPLAYWRIGHT_BASE_URL\u003dhttp://localhost:8080 PERF_NOTEBOOK_DISPOSABLE\u003d1 PERF_NOTEBOOK_DRY_RUN\u003d1 npm run perf:notebook-baseline\n```\n\nA local dry run passes (1 cold + 1 warm, every summary field recorded). Use `localhost`: the server rejects a `127.0.0.1` WebSocket origin unless `zeppelin.server.allowed.origins` is set.\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? Yes - `e2e/performance/README.md`\n\n\n\n\n\nCloses #5484 from voidmatcha/ZEPPELIN-6668-notebook-benchmark.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "4e49e3c7f262ddb5e82081160d49355d6e93f88b",
      "tree": "1fd7bb40b43df954f4d960a0fa864ac7e6a7af97",
      "parents": [
        "ece5393fc3500386f2c78e382272a3be50a5cb1d"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Sun Sep 27 17:27:21 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 27 17:27:21 2026 +0900"
      },
      "message": "[ZEPPELIN-6588] Use theme colors in the pivot and scatter settings panels\n\n### What is this PR for?\n\nIn dark mode the Pivot and Scatter visualization settings panels were unreadable. Both components hard-coded light backgrounds on their cards (`#fff`) and card headers (`#fafafa`), but the card titles take the theme\u0027s heading color. So in dark mode the titles were near-white text on a white background. The field labels (`.drag-tag`, defined in `global.less`) also stayed light.\n\nThis PR replaces those values with the existing theme variables. It adds no new colors, and the light theme resolves to the same values as before.\n\n| Element | Before | After |\n|---|---|---|\n| Card background | `#fff` | `\u003cat\u003ecomponent-background` |\n| Card header background | `#fafafa` | `\u003cat\u003ebackground-color-light` |\n| Field label text / background / border | `rgba(0,0,0,.65)` / `#fafafa` / `#d9d9d9` | `\u003cat\u003etext-color` / `\u003cat\u003ebackground-color-light` / `\u003cat\u003eborder-color-base` |\n\nThe cards already sit inside `.themeMixin(...)`, so their fix is a one-line swap in each file. The field label styles are only used by these two panels, but they stay in `global.less`. The CDK drag preview is appended to `\u003cbody\u003e`, outside the component host, so a component-scoped rule would not reach the label being dragged. Dark values are applied under `html.dark .drag-tag { \u003cat\u003eimport \u0027theme-dark\u0027; ... }`, the same pattern `antd-dark.less` uses.\n\nComputed styles measured in the browser, before and after (`/#/notebook/...` with a `%sh` table paragraph, Pivot through the Bar Chart and Scatter through the Scatter Chart):\n\n| Dark theme | Before | After |\n|---|---|---|\n| Card | `rgb(255, 255, 255)` | `rgb(31, 31, 31)` |\n| Card header | `rgb(250, 250, 250)` | `rgb(38, 38, 38)` |\n| Card title | `rgba(255, 255, 255, 0.95)` (on white) | `rgba(255, 255, 255, 0.95)` |\n| Field label bg / text | `rgb(250, 250, 250)` / `rgba(0, 0, 0, 0.65)` | `rgb(38, 38, 38)` / `rgba(255, 255, 255, 0.85)` |\n| Drag preview (child of `\u003cbody\u003e`) | same as field label, light | `rgb(38, 38, 38)` / `rgba(255, 255, 255, 0.85)` |\n\nThe \"before\" row matches the values in the Jira report. In the light theme, every value above is identical before and after, including the drag preview. The compiled `.drag-tag` rule is character-for-character the same as before.\n\n### What type of PR is it?\n\nBug Fix\n\n### Todos\n\n* [x] Use theme variables for the Pivot and Scatter settings card and header backgrounds\n* [x] Theme the field labels, including the drag preview\n* [x] Add Playwright coverage for both panels in both themes\n\n### What is the Jira issue?\n\n[ZEPPELIN-6588](https://issues.apache.org/jira/browse/ZEPPELIN-6588)\n\n### How should this be tested?\n\nDone:\n\n* New spec `e2e/tests/theme/visualization-settings-theme.spec.ts`: Pivot and Scatter, each in light and dark (4 tests). Each test checks every card, card header and card title, plus a field label, against the theme\u0027s resolved colors. The table paragraph fixture moved to `notebook-visualization-page.ts`, so this spec and `visualization-rendering.spec.ts` share it.\n* Ran the new spec against the unfixed styles. The two dark tests fail on the card background (expected `rgb(31, 31, 31)`, received `rgb(255, 255, 255)`), and the two light tests pass. With only the `global.less` change reverted, the dark tests get past the cards and fail on the field label (expected `rgb(38, 38, 38)`, received `rgb(250, 250, 250)`). So both assertions catch the defect.\n* With the fix, the new spec plus `visualization-rendering.spec.ts` pass on chromium, firefox and webkit: 19 passed, no retries.\n* `npm run test:shell`: 131 passed. `npm run lint`: exit 0, with the same warning count as master.\n* Manual check on a local server in both themes: card titles and field labels are readable, dragging a field between Keys/Groups/Values still works, and the light theme looks unchanged.\n\nNotes:\n\n* Not tagged with `\u003cat\u003eNB-PARITY-060` (theme). That scenario\u0027s action is changing the theme while a notebook is mounted, but this spec sets the theme in localStorage and reloads. Tagging it would also mean updating the registry coverage that ZEPPELIN-6640 tracks.\n* Drag-and-drop was checked by hand but has no new automated coverage. Behavior coverage for these panels is ZEPPELIN-6514.\n* Unrelated existing behavior found while testing, present on master too: reload a note whose saved mode is Scatter, switch to Bar and back to Scatter, and the Scatter settings panel stays hidden while `Setting` shows it as open. Each test here uses a fresh note, so it does not hit this.\n\n### Screenshots (if appropriate)\n\nN/A. The computed-style tables above record the before/after values.\n\n### Questions:\n\n* Does the license files need to update? No. The new spec has the ASF header.\n* Is there breaking changes for older versions? No. Light theme output is unchanged.\n* Does this needs documentation? No.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5504 from kimyenac/ZEPPELIN-6588.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "ece5393fc3500386f2c78e382272a3be50a5cb1d",
      "tree": "0859c154b8c4acf23876b417c48b320b27d901f3",
      "parents": [
        "ed0d731775b915c6fac5eb0b564c6c12694c5596"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Sun Sep 27 16:53:04 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 27 16:53:04 2026 +0900"
      },
      "message": "[ZEPPELIN-6581] Match interpreter search queries literally instead of as regex\n\n### What is this PR for?\n\nThe New UI interpreter page filters settings by name as the user types, but `filterInterpreters()` compiled the raw query with `new RegExp(value, \u0027i\u0027)`. So the search box took regular-expression syntax:\n\n* An incomplete metacharacter such as `(`, `[`, `*` or a trailing `\\` threw an uncaught `SyntaxError: Invalid regular expression`. The list was not updated, so it kept showing the results of the previous query.\n* A valid metacharacter changed what matched. `.` matched every interpreter, and `sp.rk` matched `spark`.\n\nThis PR filters with a case-insensitive literal substring match (`name.toLowerCase().includes(query.toLowerCase())`). That keeps the case-insensitive behavior ZEPPELIN-6147 added, which was the only reason the `RegExp` was introduced. ZEPPELIN-6535 (#5320) fixed the same coercion in the Table visualization column filter. This is a separate code path.\n\nChecked in the browser before and after the change (`/#/interpreter`, 22 settings, anonymous mode):\n\n| Query | Before | After |\n|---|---|---|\n| `(` | `SyntaxError: ... /(/i: Unterminated group`, list unchanged | 0 items, no error |\n| `[`, `*`, `\\` | `SyntaxError`, list left on the previous query\u0027s results | 0 items, no error |\n| `.` | all 22 | 0 items |\n| `sp.rk` | 2 | 0 items |\n| `spark` / `SPARK` | 2 | 2 |\n| cleared | 22 | 22 |\n\nA note on scope. `InterpreterSettingManager` rejects new setting names outside `^[-_a-zA-Z0-9]+$`, and every bundled interpreter group fits that set. So in practice a metacharacter query now matches nothing, where before it threw or matched too much. The test fixtures stay inside that character set, so they do not rely on names the server would reject.\n\n### What type of PR is it?\n\nBug Fix\n\n### Todos\n\n* [x] Match interpreter search queries literally instead of compiling them as a `RegExp`\n* [x] Add unit tests for `InterpreterComponent.filterInterpreters`\n\n### What is the Jira issue?\n\n[ZEPPELIN-6581](https://issues.apache.org/jira/browse/ZEPPELIN-6581)\n\n### How should this be tested?\n\nDone:\n\n* `cd zeppelin-web-angular \u0026\u0026 npm run test:shell -- src/app/pages/workspace/interpreter/`: 8 passed. The new spec covers every acceptance criterion: `(`, `[`, `*`, `.` and `\\` without throwing, literal matching, case-insensitive matching, and restoring the full list when the query is cleared.\n* Ran the same spec against the unfixed component. The 6 tests for this bug fail for the reason the issue describes: 4 with `SyntaxError: Invalid regular expression`, and 2 because `.` and `sp.rk` still match as patterns. The 2 tests for existing behavior (case-insensitive matching, clearing) pass both before and after.\n* `npm run test:shell`: 21 files, 139 tests passed.\n* `npm run lint`: exit 0. `interpreter.component.ts` has one `member-ordering` warning about the constructor\u0027s position, and master has the same warning.\n* Manual reproduction from the issue: ran a local Zeppelin server with `ng serve` and drove `/#/interpreter` with Playwright, before and after. Results are in the table above. Typing `sp(ar[k*` one key at a time also produces no console errors. The other console errors and warnings on page load (`codicon.ttf` load failure, `NG8107`, `NG0912`) appear identically on master.\n\nNot done:\n\n* No Playwright e2e spec was added. The behavior is a pure filter function, so per `zeppelin-web-angular/AGENTS.md` it belongs in a unit test. The template and debounce wiring are unchanged.\n\n### Screenshots (if appropriate)\n\nN/A. The before/after table above records the browser run.\n\n### Questions:\n\n* Does the license files need to update? No. The new spec file has the ASF header.\n* Is there breaking changes for older versions? Only for anyone who relied on regular-expression syntax in the interpreter search box, which was never documented. ZEPPELIN-6147 introduced the `RegExp` only to make the search case-insensitive.\n* Does this needs documentation? No.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5503 from kimyenac/ZEPPELIN-6581.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "ed0d731775b915c6fac5eb0b564c6c12694c5596",
      "tree": "eaaf15e59520f2e5feee104477068decf98b31f9",
      "parents": [
        "de33e026519cfa5b67a9cf45f79637cecb190a68"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Sun Sep 27 16:47:39 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 27 16:47:39 2026 +0900"
      },
      "message": "[ZEPPELIN-6694] Reap dead websocket connections via pong tracking\n\n### What is this PR for?\r\nSince [ZEPPELIN-6092](https://issues.apache.org/jira/browse/ZEPPELIN-6092), heartbeat pings keep resetting Jetty\u0027s idle timer, so the idle timeout no longer detects dead clients. A dead session stays open until TCP retransmission gives up.\r\n\r\nThis PR tracks pongs to detect dead sessions explicitly:\r\n\r\n* Register a per-session PongMessage handler. A pong resets the session\u0027s ping count.\r\n* In sendHeartbeat, close a session after N consecutive missed pongs (GOING_AWAY, 1001). It is removed from bookkeeping first, since a dead peer may never trigger onClose.\r\n* Skip sessions that are handling a message. Jetty reads pongs only after onMessage returns, so a long-running op would otherwise look like missed pongs.\r\n* Add zeppelin.websocket.heartbeat.max.missed.pongs (default 3, \u003c\u003d 0 disables). With the default 60s interval, a dead client is reaped in ~3-4 minutes.\r\n\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] Track pongs and close sessions that miss N in a row\r\n* [x] Skip sessions that are handling a message\r\n* [x] Add config, docs and zeppelin-site.xml.template\r\n* [x] Update docs and `zeppelin-site.xml.template`\r\n* [x] Add unit tests\r\n\r\n### What is the Jira issue?\r\n[ZEPPELIN-6694](https://issues.apache.org/jira/browse/ZEPPELIN-6694)\r\n\r\n### How should this be tested?\r\n* Unit tests added:\r\n   * NotebookSocketTest: ping counting, reset on pong, failed ping still counted, close swallows exceptions\r\n   * NotebookServerHeartbeatTest:\r\n       * a session with too many missed pongs is closed and removed from ConnectionManager, while a healthy session keeps receiving pings\r\n       * nothing is closed when reaping is disabled\r\n       * a session that is handling a message is not reaped\r\n       * onMessage marks the session as handling a message until it returns\r\n       * onOpen(Session, EndpointConfig) registers a pong handler that resets the ping count\r\n  * ZeppelinConfigurationTest: default and override values for the new config\r\n   * Run: `./mvnw -pl zeppelin-server test -Dtest\u003d\u0027NotebookSocketTest,NotebookServerHeartbeatTest,ZeppelinConfigurationTest\u0027`\r\n\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions?  No. Reaping is on by default, but only affects sessions that stop answering pings, and can be disabled by setting the new property to 0.\r\n* Does this needs documentation? Yes, included in `docs/setup/operation/configuration.md`\r\n\n\nCloses #5500 from JangAyeon/ZEPPELIN-6694.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "de33e026519cfa5b67a9cf45f79637cecb190a68",
      "tree": "b580fcee4ffdb0cec716ac2b5a261472c35f2a4c",
      "parents": [
        "23483c69df74e6c5892a5b21ef3213e1c2121973"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Sep 27 15:53:03 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 27 15:53:03 2026 +0900"
      },
      "message": "[ZEPPELIN-6674] Prove Shared Notebook Core port identity\n\n### What is this PR for?\nProve that separately built Angular host and React remote code receive the exact same host-owned NotebookCorePort object. The build also rejects a React remote that bundles its own Shared Notebook Core runtime.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Add the Angular host and React remote proof\n* [x] Reject duplicate Core runtime bundles\n* [x] Add the proof to the frontend build\n\n### What is the Jira issue?\nZEPPELIN-6674\n\n### How should this be tested?\n```bash\ncd zeppelin-web-angular\nnpm run typecheck:notebook-core\nnpm run build:notebook-core-port-proof\nnpm run test:notebook-core-port-identity\n```\n\n### Screenshots (if appropriate)\nNot applicable.\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5481 from voidmatcha/ZEPPELIN-6674-shared-core-port-identity.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "23483c69df74e6c5892a5b21ef3213e1c2121973",
      "tree": "91ae3462c54f93129f0522c375322ebeb02543b5",
      "parents": [
        "0d6e7b7a10d18d5ce7de053edeb093e040a2698a"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Sep 27 14:49:08 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 27 14:49:08 2026 +0900"
      },
      "message": "[MINOR] Remove orphaned login modal backdrops before driving the navbar in Selenium tests\n\n### What is this PR for?\nAfter ZEPPELIN-6711, `AuthenticationIT.testSimpleAuthentication` still fails intermittently in `test-selenium-with-spark-module-for-spark-3-5`. `#loginModal` is already hidden, but when `logoutUser` clicks the navbar user menu, `\u003cdiv class\u003d\"modal-backdrop fade\"\u003e` intercepts the click.\n\nBootstrap 3.4.1 removes a backdrop through `this.$backdrop`. When the login modal is shown and hidden again while an earlier transition is still running, that reference is replaced and the earlier backdrop is never removed. It stays over the page at opacity 0 and intercepts every click, so the existing retry in `logoutUser` fails for the same reason.\n\n`dismissLoginModal()` now removes `.modal-backdrop` elements that no displayed modal owns once the login modal is closed. An intercepted navbar click also logs the modal and backdrop state. The app-side behaviour that leaves the backdrop behind is not addressed here.\n\n### What type of PR is it?\nBug Fix\n\n### Todos\n* [x] Remove backdrops that no displayed modal owns\n* [x] Log the modal state when the navbar click is intercepted\n\n### What is the Jira issue?\n\n### How should this be tested?\n```bash\n./mvnw clean install -DskipTests -am -pl zeppelin-integration -Pweb-classic -Pintegration -Pspark-scala-2.12 -Pspark-3.5 -Pweb-dist\n./mvnw verify -pl zeppelin-integration -Dit.test\u003dAuthenticationIT -Dtest\u003dnone -Dsurefire.failIfNoSpecifiedTests\u003dfalse -Pweb-classic -Pintegration -Pspark-scala-2.12 -Pspark-3.5 -Pweb-dist -Pusing-source-tree\n```\n\nI ran only `AuthenticationIT` on a fork, with the same build as the CI job:\n\n| Variant | Runs | Pass | Fail |\n|---|---|---|---|\n| master + diagnostics only | 30 | 17 | 13 |\n| this PR | 100 | 100 | 0 |\n\nAll 13 failures logged the same state: `loginModal\u003dmodal fade ng-scope display\u003dnone, backdrops\u003d[modal-backdrop fade]`. With this PR, 44 of the 100 runs logged and removed such a backdrop, and all passed.\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5502 from voidmatcha/fix/login-modal-orphan-backdrop.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "0d6e7b7a10d18d5ce7de053edeb093e040a2698a",
      "tree": "d960d7c86350c7f63ed898207c2448baf702fe41",
      "parents": [
        "a19d488d3d39342169a45142e6baf71d51457c24"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Sat Sep 26 15:59:48 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 26 15:59:48 2026 +0900"
      },
      "message": "[ZEPPELIN-6460] Deprecate the Vagrant developer environment\n\n### What is this PR for?\n\nThe Vagrant developer environment under `scripts/vagrant/zeppelin-dev` points contributors at a clone URL, build profiles and toolchain versions that are all obsolete. ZEPPELIN-6460 asks to decide whether the setup is still supported, and to update it if so or mark it deprecated if not.\n\nIt is not supported. The toolchain it provisions has not been updated since 2018, and provisioning cannot succeed today:\n\n* The `ubuntu/xenial64` box is Ubuntu 16.04, past end of life.\n* `ansible-roles.yml` installs `python-minimal` and `python-simplejson`, and `python-addons` installs `python-pip`, `python-matplotlib`, `python-scipy`, `python-numpy`, `python-pandas` — Python 2 packages that no longer exist on supported Ubuntu releases. Current `ansible-core` also requires Python 3 on the managed node.\n* The `maven` role resolves Maven 3.3.9 through `closer.cgi`. That request still succeeds, but the mirror it returns answers 404 — 3.3.9 has been moved off the distribution mirrors and is only on `archive.apache.org`. I verified this: `dlcdn.apache.org` and `downloads.apache.org` both 404, `archive.apache.org` 200.\n* The `common` role installs `libfontconfig` for PhantomJS, which the project no longer uses.\n* It installs OpenJDK 8, Maven 3.3.9 and Node.js 4.2.6 against a baseline of JDK 11, Maven 3.6.3 and Node.js 22.21.1.\n\nRewriting the provisioning was the alternative, but it cannot be verified from this machine (see *How should this be tested?*), so this PR marks the setup deprecated and fixes the pointers instead.\n\nChanges:\n\n* Deprecation notice in `README.md`, `show-instructions.sh` and the `Vagrantfile`, with the reasons above. This matters beyond the source tree: `zeppelin-distribution/src/assemble/distribution.xml` includes `../scripts` with no excludes, so release users receive these files too.\n* `git://git.apache.org/zeppelin.git` → `https://github.com/apache/zeppelin.git`.\n* `mvn clean package -Pspark-1.6 -Phadoop-2.4 -DskipTests` → `./mvnw clean package -DskipTests`, with a link to the current build profiles.\n* The stale version list is kept but reframed as what the roles install, next to a new table of the project baseline — each row naming the pom property that defines it (`java.version`, `maven.version`, `node.version`/`npm.version`). It also notes that only the JDK needs installing by hand, since `./mvnw` fetches Maven and `frontend-maven-plugin` fetches the pinned Node.js and npm per web module.\n* `docs/setup/deployment/virtual_machine.md` is rewritten to match. It had drifted further than the README, still documenting Ubuntu 14.04, Node.js 0.12.7 and OpenJDK 7. `docs/index.md` and the navigation label it deprecated.\n\nTwo deliberate removals, both easy to reverse if you would rather keep them:\n\n* The Python 2 PySpark examples (`print \"numpy \" + ...`, `StringIO`). They are syntax errors under Python 3 and depend on the `python-addons` role that no longer works.\n* The `ansible --version` should report `1.9.2 or higher` check and the Python 2.7 Windows prerequisite.\n\nEverything else that was merely old is kept and rewritten rather than dropped, including the `vagrant up`/`vagrant ssh` steps, the prerequisites, the z-manager installer (that repository is still up — I checked), the VM inventory, the synced-folder note and the private-network tweak.\n\n### Two follow-up commits for the same defect elsewhere\n\nLooking for other instances of the obsolete clone pointer turned up two more places, each in its own `[MINOR]` commit so you can drop either one without touching the rest:\n\n* `docs/setup/deployment/yarn_install.md` advertised `git://git.apache.org/zeppelin.git` as link text while the href already pointed at GitHub.\n* The `git access` sections of `how_to_contribute_code.md` and `how_to_contribute_website.md` tell contributors to clone over `git://gitbox.apache.org`, which is no longer served — `git clone git://gitbox.apache.org/repos/asf/zeppelin.git` fails with a connection refused. The surrounding prose in both pages already names the https URL as the official location, so the commands now match it. This one also fixes a second defect on the same line: `branch-0.11.0` does not exist on gitbox, so the branch example would have failed even over https. The release line is `branch-0.11`.\n\nThat last one is arguably the most user-visible part of this PR, since it is the first command a new contributor runs. Happy to split the two `[MINOR]` commits into a separate PR if you would rather keep this one to the Vagrant scope.\n\nThis PR does not decide when the Vagrant directory should be removed; that seems like a question for the mailing list rather than a PR.\n\n### What type of PR is it?\n\nDocumentation\n\n### Todos\n\nNone.\n\n### What is the Jira issue?\n\n* https://issues.apache.org/jira/browse/ZEPPELIN-6460\n\n### How should this be tested?\n\nDocumentation only, no code paths change.\n\nDone:\n\n* Ran `scripts/vagrant/zeppelin-dev/show-instructions.sh` and checked the printed commands, as the issue asks. Confirmed every path it now names exists in the tree (`./mvnw`, `bin/zeppelin-daemon.sh`, `docs/setup/basics/how_to_build.md`) and that `git ls-remote https://github.com/apache/zeppelin.git` resolves.\n* Reproduced the `docs` workflow locally — `bundle exec jekyll build --safe` plus html-proofer 5.2.2 with the same flags. Build clean, 318 internal links over 93 files, no failures.\n* Verified each claim rather than assuming it: the Maven mirror 404s above; `git ls-remote git://gitbox.apache.org/...` gives `errno\u003dConnection refused` while the https URL resolves; `git ls-remote --heads` shows `branch-0.11` and no `branch-0.11.0`; PhantomJS survives only as a comment in `zeppelin-web/karma.conf.js` while the actual karma browser is `FirefoxHeadless`; the baseline versions were read from the poms.\n* Confirmed `-Pspark-1.6`, `-Phadoop-2.4`, `git://git.apache.org` and `git://gitbox.apache.org` no longer appear anywhere in the repository.\n\nNot done:\n\n* I did not bring the VM up. VirtualBox is not practical on this machine (Apple Silicon), and the box, the Ansible roles and the Maven download are each independently broken, so `vagrant up` cannot succeed regardless of the host. That external blocker is the reason this PR deprecates rather than updates, and it is now documented in the files themselves.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No. All touched files keep their existing ASF headers; no files were added or removed.\n* Is there breaking changes for older versions? No. Nothing that builds or runs Zeppelin changes.\n* Does this needs documentation? This is the documentation change.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5496 from kimyenac/ZEPPELIN-6460.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "a19d488d3d39342169a45142e6baf71d51457c24",
      "tree": "558af69b5c940615c084dd1bea8de726bc7889e0",
      "parents": [
        "6f60984f4e74344de200bf36715cc533b56c4f7f"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sat Sep 26 14:55:48 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 26 14:55:48 2026 +0900"
      },
      "message": "[ZEPPELIN-6661] Cover notebook editor save timing\n\n### What is this PR for?\nWhen a paragraph save response arrives late, `ParagraphBase` treats it as a remote update and replaces the editor text, losing edits typed in the meantime.\n\nThis PR tracks pending saves by `msgId`. A response to one of the user\u0027s own saves no longer replaces the editor text when a newer edit or save followed it; otherwise the response is the server copy and is applied as before. Other paragraph fields in that response always apply.\n\nRelated behavior changes in `ParagraphBase`:\n* A remote edit that differs from the local unsaved text now replaces it and resets the saved baseline, so the discarded local text is not re-committed later.\n* An empty local edit (all text deleted) is now treated as a local edit and protected like any other.\n* A broadcast that does not match a pending local save and repeats the saved text no longer rewinds the editor while the user is typing.\n\nThis PR adds the E2E scenarios for ZEPPELIN-6661 (idle autosave, edit during an in-flight save). The in-flight scenario fails without this fix, so the fix is included here.\n\n`ParagraphBase` reads the save acknowledgement `msgId` from the message envelope (`\u003cat\u003eMessageEnvelopeListener(OP.PARAGRAPH)`). The SDK `commitParagraph()`, `insertParagraph()` and `copyParagraph()` now return the sent `msgId`, and `MessageService` records the insert/copy `msgId` used for editor focus from that return value instead of subscribing to `sent()`.\n\n### What type of PR is it?\nBug Fix\n\n### Todos\n* [x] Match save responses to pending saves by `msgId`\n* [x] Add unit tests and browser scenarios for save timing\n* [x] Register the scenarios in the notebook parity inventory\n\n### What is the Jira issue?\nZEPPELIN-6661\n\n### How should this be tested?\n```bash\ncd zeppelin-web-angular\nnpx vitest run --config vitest.shell.config.mts src/app/core/paragraph-base/paragraph-base.spec.ts projects/zeppelin-sdk/src/message.spec.ts src/app/services/message.service.spec.ts\nnpm run check:notebook-parity-scenarios\nCI\u003dtrue PLAYWRIGHT_HTML_OPEN\u003dnever npm run e2e -- --reporter\u003dlist tests/notebook/persistence/notebook-save-timing.spec.ts\n```\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\n\n\nCloses #5483 from voidmatcha/ZEPPELIN-6661-editor-save-timing.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "6f60984f4e74344de200bf36715cc533b56c4f7f",
      "tree": "20fc0045777cb4015ea85ab249f5ef6baed9212a",
      "parents": [
        "33f1fff8aeff3926af30a0d8faa834e833dd9e32"
      ],
      "author": {
        "name": "김동환",
        "email": "66408194+dev-donghwan@users.noreply.github.com",
        "time": "Sat Sep 26 00:53:17 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 26 00:53:17 2026 +0900"
      },
      "message": "[ZEPPELIN-6394] Make the interpreter setting write safe under concurrent saves\n\n### What is this PR for?\n\nWhen several interpreters finish downloading their dependencies at the same time, each of them saves the interpreter settings from its own thread, so `conf/interpreter.json` is written concurrently. The reporter\u0027s log shows those writes failing:\n\n```\nERROR ({Thread-16}) InterpreterSetting.java[run]:1003 - Fail to save interpreter.json\njava.nio.file.NoSuchFileException: /data/soft/zeppelin-0.11.2/conf/interpreter.json\n    at java.nio.file.Files.move(Files.java:1395)\n    at org.apache.zeppelin.util.FileUtils.atomicWriteToFile(FileUtils.java:60)\n    at org.apache.zeppelin.storage.LocalConfigStorage.save(LocalConfigStorage.java:54)\n    at org.apache.zeppelin.interpreter.InterpreterSettingManager.saveToFile(InterpreterSettingManager.java:350)\n    at org.apache.zeppelin.interpreter.InterpreterSetting$1.run(InterpreterSetting.java:1001)\n```\n\nThere are two problems behind it.\n\n**1. The write itself is not atomic.** `FileUtils.atomicWriteToFile` writes a temp file and then moves it over the destination with `REPLACE_EXISTING` alone. That replace is not a single operation, so when two writers move their own temp file onto the same destination, one of them can fail with `NoSuchFileException` and leave its temp file behind in the config directory. The failure is swallowed as an `ERROR` log, so the settings silently do not reach disk.\n\nMeasured on the current code with 16 threads writing the same file 300 times each:\n\n| move options | failed writes (of 4800) | leftover temp files |\n| --- | --- | --- |\n| `REPLACE_EXISTING` | 9 – 24, reproduced on every run | same count |\n| `REPLACE_EXISTING, ATOMIC_MOVE` | 0 | 0 |\n\nThis PR requests `ATOMIC_MOVE` as well. The temp file is created in the destination directory (`Files.createTempFile(destinationDirectory, ...)`), so the move never crosses file systems and the atomic move is always supported. The option was present as a trailing comment from the first version of this method in ZEPPELIN-4907 and was never enabled; there is no recorded reason for leaving it off.\n\n**2. The snapshot and the write are two steps.** `InterpreterSettingManager.saveToFile` copies the settings and then writes them, without holding anything in between, so an older snapshot can be written after a newer one. When that happens, a setting that was added in between is dropped from the file while it survives in memory, and the loss only shows up after the next restart. This is the serialization the Jira asks for; it is done with a private lock rather than `synchronized` on the method so that the monitor stays internal.\n\nNote for the Jira description: on the default `LocalConfigStorage` the concurrent writes do not corrupt the file, because every write goes to its own temp file. What they do is fail, and lose an update.\n\n**Relation to #5144.** The `saveToFile()` serialization in this PR overlaps #5144, which was opened by the reporter and already carries an LGTM that a later rebase dismissed. That PR does not cover the move itself, which is what produces the `NoSuchFileException` in the report. If it is preferred to land #5144 for the serialization, I am happy to drop the `InterpreterSettingManager` change from here and leave only the `FileUtils` fix.\n\n### What type of PR is it?\nBug Fix\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-6394\n\n### How should this be tested?\nTwo new tests, both verified to fail without the corresponding change:\n\n* `FileUtilsTest.testConcurrentWritesToTheSameFileSucceed` — 16 threads write the same file 300 times each and no write may fail or leave a temp file behind. Fails on master on every run with the `NoSuchFileException` above.\n* `InterpreterSettingManagerSaveRaceTest.testSaveDuringAnotherSaveIsNotOverwritten` — a setting is added while another save is in flight, and the last write has to carry it. Fails on master with `the last write dropped added_during_save`.\n\nExisting suites run: `InterpreterSettingManagerTest`, `InterpreterSettingTest`, `InterpreterFactoryTest`, `InterpreterInfoSavingTest`, `LocalConfigStorageTest`, `CredentialsTest`, `LocalRecoveryStorageTest`.\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\nCloses #5426 from dev-donghwan/ZEPPELIN-6394.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "33f1fff8aeff3926af30a0d8faa834e833dd9e32",
      "tree": "0b23504be874dd98572a1c84eb892de259e75440",
      "parents": [
        "8c46e755a6ec5bf7eaa2922114492efd1db98a31"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Sat Sep 26 00:50:30 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 26 00:50:30 2026 +0900"
      },
      "message": "[ZEPPELIN-6717] Install locked Python dependencies in Linux CI\n\n### What is this PR for?\r\n\r\nLinux CI jobs repeatedly resolve the same Python 3.9 Conda dependencies during environment setup. This PR makes those jobs install from explicit Linux x86-64 Conda specifications instead, and pins the PyFlink packages installed with pip.\r\n\r\nIt also separates Maven, npm, Conda, and pip package caches by dependency type. The Livy job now caches the Spark distribution at the path used by its download script. Lock update and validation instructions are documented in `testing/locks/README.md`.\r\n\r\nThis targets dependency setup time.\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6717\r\n\r\n### How should this be tested?\r\n\r\n- Run the affected Linux CI jobs and confirm they install from the committed Conda specifications without dependency resolution.\r\n- Confirm both PyFlink jobs install their pinned requirements and pass.\r\n- Run CI again to check package-cache reuse and the Livy Spark distribution cache hit.\r\n- Compare environment-setup durations separately from test durations.\r\n\r\n### Questions\r\n\r\n- License files: No.\r\n- Breaking changes for older versions: No product-runtime change. The explicit Conda specifications are Linux x86-64-specific.\r\n- Documentation: Lock maintenance instructions are included.\n\nCloses #5492 from miinhho/ci/dependency-resolve.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "8c46e755a6ec5bf7eaa2922114492efd1db98a31",
      "tree": "94e99fa189b5658762249f817fc38ae95f7d3c67",
      "parents": [
        "e4346ceb2e2af553998c59b23130451f9c05098c"
      ],
      "author": {
        "name": "Chaiwon Hwang",
        "email": "90598552+uommou@users.noreply.github.com",
        "time": "Sat Sep 26 00:49:58 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 26 00:49:58 2026 +0900"
      },
      "message": "[ZEPPELIN-6485] Add unit tests for PropertiesUtil\n\n### What is this PR for?\r\n\r\nThis PR adds unit tests for `PropertiesUtil` in the `zeppelin-interpreter` module.\r\n\r\nThe tests cover the behavior of `getString`, `getLong`, and `getInt`, including missing properties, empty and whitespace-only values, successful numeric parsing, parsing failures, and numeric boundary values.\r\n\r\nNo production code is changed.\r\n\r\n### What type of PR is it?\r\n\r\nImprovement\r\n\r\n### Todos\r\n\r\n- [x] Add tests for missing properties\r\n- [x] Add tests for empty and whitespace-only values\r\n- [x] Add tests for valid positive and negative numeric values\r\n- [x] Add tests for numeric boundary values\r\n- [x] Add tests for invalid and out-of-range numeric values\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6485\r\n\r\n### How should this be tested?\r\n\r\nRun the new unit tests:\r\n\r\n```bash\r\n./mvnw test -pl zeppelin-interpreter -Dtest\u003dPropertiesUtilTest\r\n```\r\n\r\nExpected result:\r\n\r\n```text\r\nTests run: 6, Failures: 0, Errors: 0, Skipped: 0\r\nBUILD SUCCESS\r\n```\r\n\r\n### Screenshots (if appropriate)\r\n\r\nThis PR does not change the user interface.\r\n\r\n### Questions:\r\n\r\n- Does the license files need to update? No. \r\n- Is there breaking changes for older versions? No. \r\n- Does this needs documentation? No. \r\n\n\nCloses #5493 from uommou/fix/ZEPPELIN-6485.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "e4346ceb2e2af553998c59b23130451f9c05098c",
      "tree": "750600bb220d2558563bbddb0731c093d0baba1d",
      "parents": [
        "89b014e44d662a74ed65dc6c8c037a348632a00e"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Sat Sep 26 00:49:41 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 26 00:49:41 2026 +0900"
      },
      "message": "[ZEPPELIN-6711] Wait for the login modal to close before driving the navbar\n\n### What is this PR for?\n\n`AuthenticationIT.testSimpleAuthentication` is the only test left that drives the login modal, and it fails intermittently in `test-selenium-with-spark-module-for-spark-3-5`. The click on the navbar user menu is intercepted by `#loginModal`, which is still displayed:\n\n```\norg.openqa.selenium.ElementClickInterceptedException: element click intercepted:\n  Element \u003cli style\u003d\"margin-left: 10px\"\u003e...\u003c/li\u003e is not clickable at point (1858, 21).\n  Other element would receive the click:\n  \u003cdiv id\u003d\"loginModal\" class\u003d\"modal fade ng-scope in\" role\u003d\"dialog\" style\u003d\"display: block;\"\u003e\n\tat org.apache.zeppelin.AbstractZeppelinIT.logoutUser(AbstractZeppelinIT.java:173)\n\tat org.apache.zeppelin.integration.AuthenticationIT.testSimpleAuthentication(AuthenticationIT.java:101)\n```\n\n`authenticationUser` did not wait for the modal at all. Once the navbar dropdown appeared it removed the backdrop, forced `modal(\u0027hide\u0027)` and slept 500 ms. The classic UI closes the modal itself — `login.controller.js` calls `modal(\u0027toggle\u0027)` when the login request succeeds — so that cleanup raced the application instead of waiting for it, and it left no trace when the modal was in fact still up.\n\nThis PR:\n\n* Waits for `#loginModal` to become invisible in `authenticationUser`, and keeps the forced cleanup, unchanged, as the fallback for when that wait times out. The fallback, and a modal still displayed after it, are now logged, so a future failure says which case it hit instead of only surfacing as an intercepted click.\n* Waits for the modal in `logoutUser` immediately before opening the user menu, and retries that one click if it is still intercepted.\n* Fixes the error message in `testSimpleAuthentication`, which named `testCreateNewButton`.\n\nTest-only. No production code changes.\n\n### Why `logoutUser` needs its own wait\n\nWaiting once in `authenticationUser` is not sufficient, because the modal can be legitimately re-opened *after* it was closed:\n\n* `NotebookServer.onMessage` answers a WebSocket message whose ticket does not match the one on file by sending `OP.SESSION_LOGOUT` (`NotebookServer.java:362`).\n* `login.controller.js:64` reacts to `session_logout` by calling `modal(\u0027show\u0027)` inside a `$timeout(..., 1000)`, guarded by `$rootScope.userName !\u003d\u003d \u0027\u0027` — true exactly after a successful login.\n\nThe failing run\u0027s log is consistent with this. The WebSocket opened before the login stays open across it and no new ticket is requested:\n\n```\n04:49:28,276  Open connection to /0:0:0:0:0:0:0:1:43492\n04:49:29,197  Login request completed: principal\u003dadmin, success\u003dtrue\n04:49:31,352  ERROR AbstractZeppelinIT - Exception in AuthenticationIT ...\n04:49:31,479  Closed connection to /0:0:0:0:0:0:0:1:43492 (1001)\n```\n\nThe next test in the same run is the contrast: after `finance1` logs in through `authenticationUserViaRest`, the log shows `WebSocket ticket request completed: principal\u003dfinance1` followed by a new connection. Only the modal login path keeps a connection established under the previous ticket.\n\nTo be clear about the limit of that evidence: `NotebookServer` logs the mismatch at DEBUG and the job runs at INFO, so the log does not show whether a `SESSION_LOGOUT` was actually emitted. The mechanism is established from the code and the timing fits, but the emission itself is unverified. I have left the same note on the Jira issue.\n\n### Questions a reviewer may have\n\n**Why two new timeout constants instead of `MAX_BROWSER_TIMEOUT_SEC`?**\n`MAX_BROWSER_TIMEOUT_SEC` is 30 s. `logoutUser` has around 40 callers, so a 30 s wait on a path that is only reached when something is already wrong makes a bad run much slower. `MODAL_CLOSE_TIMEOUT_SEC` is 10 s, generous for a modal the application closes on an HTTP response, and `MODAL_CLEANUP_TIMEOUT_SEC` is 2 s, enough for a 300 ms Bootstrap fade — there is no reason to wait 10 s more just to log a warning. Happy to fold them into the existing constant if you would rather have fewer knobs.\n\n**Does this slow down the other tests?**\nNo. `logoutUser` has around 40 callers and all but one log in through `authenticationUserViaRest`, which refreshes the page and never touches the modal. `invisibilityOfElementLocated` returns immediately when the element is hidden or absent, which is the normal case. The wait only costs time when the modal is genuinely up — where the old code failed outright.\n\n**Why is the retry only around the first click?**\nAn intercepted click never reached the user menu, so the dropdown is still closed and opening it again is safe. Retrying the whole open-menu-then-logout sequence would not be: if the *second* click were intercepted, the dropdown would already be open, and clicking the user menu again would close it and leave the logout link unclickable. The sleeps and the logout click are therefore left exactly as they were, and only the first click is wrapped.\n\n**Why keep the forced `modal(\u0027hide\u0027)` at all?**\nIt is the existing behaviour and it is the only lever left if the application does not close the modal. It is now a fallback rather than the first move, and it is byte-identical to what is on master — the only behavioural change in that path is that we wait first.\n\n**Should the WebSocket reconnect be fixed instead?**\nArguably the classic UI should re-request the WebSocket ticket after a modal login, the way the REST path effectively does. That is a production change and the issue puts it out of scope, so I have not touched it; it seems worth a separate issue if you agree.\n\n### What type of PR is it?\n\nBug Fix\n\n### Todos\n\nNone.\n\n### What is the Jira issue?\n\n* https://issues.apache.org/jira/browse/ZEPPELIN-6711\n\n### How should this be tested?\n\nDone:\n\n* `./mvnw install -DskipTests -am -pl zeppelin-integration -Pweb-classic -Pintegration` — `BUILD SUCCESS`, and `testCompile` recompiled the module\u0027s sources.\n* Checked that the changed lines add no Checkstyle violations. The module is not wired into `checkstyle-fail-build` and carries pre-existing violations, so I compared the reported lines against the lines this PR touches rather than the module total: zero on changed lines.\n* Read the failing job\u0027s log and the code paths quoted above rather than assuming the cause.\n\nNot done:\n\n* **I have not run the Selenium suite.** This machine has no Chrome, Firefox or Edge — only Safari, which would need `safaridriver --enable` plus a manual Develop-menu step, and the suite runs headed. The flake is also specific to the CI browser, so a Safari run would not be evidence. CI is the real check here.\n* The issue\u0027s verification step is to re-run `test-selenium-with-spark-module-for-spark-3-5` several times and confirm `testSimpleAuthentication` no longer fails this way. Being a flake, one green run does not prove much; it is worth watching the job over the next few runs. For reference, between 2026-09-13 and 2026-09-17 the issue reports 13 runs failing this way, and I hit it again on 2026-09-22.\n\n### Screenshots (if appropriate)\n\nN/A\n\n### Questions:\n\n* Does the license files need to update? No. No files added or removed; both touched files keep their ASF headers.\n* Is there breaking changes for older versions? No. Test-only.\n* Does this needs documentation? No.\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\n\nCloses #5497 from kimyenac/ZEPPELIN-6711.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "89b014e44d662a74ed65dc6c8c037a348632a00e",
      "tree": "d72737631619094756d24f69262693fa951726a2",
      "parents": [
        "24968cdf471dca93c8d6125e58fcd597eb1ead46"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Fri Sep 25 19:04:20 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 25 19:04:20 2026 +0900"
      },
      "message": "[ZEPPELIN-6664] Add notebook core SDK wire fields\n\n### What is this PR for?\nDeclare five notebook WebSocket fields that the server already sends but the SDK types omitted, so Shared Notebook Core can build on typed values instead of casts. This PR adds those declarations only; it does not model every payload variant or every nullable nested value.\n\n* `ParagraphItem.progress: number`: `zeppelin-server/src/main/java/org/apache/zeppelin/notebook/Paragraph.java:78` (primitive `int`, always serialized). Declared fields enumerated across `Paragraph.java:73-99`, `zeppelin-interpreter/src/main/java/org/apache/zeppelin/scheduler/Job.java:84-93` and `JobWithProgressPoller.java:23`.\n* `Note.note.version?: string`: `zeppelin-server/src/main/java/org/apache/zeppelin/notebook/Note.java:77`, range `Note.java:73-98`. Optional because a personalized `GET_NOTE` returns `getUserNote()` (`Note.java:948-967`, reached from `NotebookService.java:147-151`), which is built without a version.\n* `EditorSettingReceived.editor.completionKey?: string`: emitted by `NotebookServer.java:2240-2248` through `NotebookService.java:1244-1246` and `InterpreterSettingManager.java:616-685`, which returns the interpreter\u0027s editor map (for example `livy/src/main/resources/interpreter-setting.json:137`). Optional because many editor blocks and the default map (`InterpreterSettingManager.java:111-113`) omit it.\n* `AngularObjectRemove.angularObject?` and `.interpreterGroupId?`: sent only by `NotebookServer.java:1495-1498`; the other emit site (`NotebookServer.java:2218-2231`) omits both. Nested fields come from `zeppelin-interpreter/src/main/java/org/apache/zeppelin/display/AngularObject.java:42-49`. Correcting loosely typed payload shapes is tracked by ZEPPELIN-6676.\n\n`ImportNote` keeps using `ImportParagraphItem`, where `progress` and `version` stay optional, because an imported note file is user input and may not carry them. TypeScript callers that construct a received `ParagraphItem` now have to set `progress`; the paragraph test fixture in this PR does so.\n\n### What type of PR is it?\nImprovement\n\n### Todos\n* [x] Declare the five fields\n* [x] Add a type-level contract spec, typechecked in the Maven `test` phase\n\n### What is the Jira issue?\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6664\n\n### How should this be tested?\nThe first command typechecks the contract spec and the second executes it. The third checks WebSocket operation names and message-map consistency, not payload fields.\n\n```bash\ncd zeppelin-web-angular\nnpm run typecheck:sdk-contracts\nnpx vitest run --config vitest.shell.config.mts projects/zeppelin-sdk/src/interfaces/notebook-wire-fields.spec.ts\nnpm run check:websocket-contract\n```\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\n\n\nCloses #5480 from voidmatcha/ZEPPELIN-6664-sdk-notebook-fields.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "24968cdf471dca93c8d6125e58fcd597eb1ead46",
      "tree": "846e3a1f0eb1c066d9fe37ac3616b4e474daac19",
      "parents": [
        "3219ccc8eddd84396a1c2ae249b9c19439cc17a5"
      ],
      "author": {
        "name": "JangAyeon",
        "email": "67853616+JangAyeon@users.noreply.github.com",
        "time": "Fri Sep 25 18:34:48 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 25 18:34:48 2026 +0900"
      },
      "message": "[ZEPPELIN-6693] Drive NotebookServer heartbeat scheduler shutdown from ZeppelinServer lifecycle\n\n### What is this PR for?\r\nZEPPELIN-6092 added a websocket heartbeat scheduler to `NotebookServer`, torn down by a dedicated JVM shutdown hook that the class registered for itself. That hook only covers the JVM-exit path:\r\n\r\n- When the server is closed inside a running JVM (e.g. `MiniZeppelinServer.shutDown()` calling `zepServer.close()`), the hook never runs, so repeated start/stop cycles can leave a scheduler and a hook behind per instance.\r\n- On SIGTERM, `ZeppelinServer`\u0027s own shutdown hook and this one run in parallel for the same event.\r\n\r\nThis PR stops the scheduler from `ZeppelinServer#shutdown`, which already covers both paths (the JVM shutdown hook and `close()`), and removes the dedicated hook together with its `removeShutdownHook` / `IllegalStateException` handling and self-reference guard. The scheduler is stopped after Jetty, so no new connection can restart it.\r\n\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n* [x] - Stop the heartbeat scheduler from `ZeppelinServer#shutdown`\r\n* [x] - Remove the dedicated shutdown hook from `NotebookServer`\r\n* [x] - Add a test that covers the `ZeppelinServer#shutdown` path\r\n* [x] - Add tests for repeated start/stop cycles\r\n\r\n### What is the Jira issue?\r\n[ZEPPELIN-6693](https://issues.apache.org/jira/browse/ZEPPELIN-6693)\r\n\r\n### How should this be tested?\r\n* `NotebookServerHeartbeatTest#zeppelinServerShutdownStopsHeartbeatScheduler`: starts a `MiniZeppelinServer`, starts the heartbeat scheduler, calls `shutDown()`, and checks the scheduler is shut down. Fails if the `stopHeartbeatScheduler()` call in `ZeppelinServer#shutdown` is removed.\r\n* `NotebookServerHeartbeatTest#stopHeartbeatSchedulerAllowsRepeatedStartStopCycles`: starts and stops the scheduler three times and checks that each scheduler is shut down and a new one can start.\r\n* `NotebookServerHeartbeatTest#stopHeartbeatSchedulerIsSafeWhenNeverStarted`: stopping without a prior start, twice, does not throw.\r\n* Existing `NotebookServerHeartbeatTest` cases still pass.\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5499 from JangAyeon/ZEPPELIN-6693.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "3219ccc8eddd84396a1c2ae249b9c19439cc17a5",
      "tree": "091ef2ffc2e073e05d0fab6c35f1101483f5fdad",
      "parents": [
        "8916d7aee1982d32b8f8538518f3ac9dbd3a5b7a"
      ],
      "author": {
        "name": "gyowoo1113",
        "email": "58352333+gyowoo1113@users.noreply.github.com",
        "time": "Thu Sep 24 23:04:54 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 23:04:54 2026 +0900"
      },
      "message": "[ZEPPELIN-6683] Prevent stale notebook WebSocket replies from mutating the active note\n\n### What is this PR for?\r\nThis PR prevents stale notebook WebSocket replies from mutating the currently active note.\r\n\r\n`GET_INTERPRETER_BINDINGS`, `SAVE_INTERPRETER_BINDINGS`, `LIST_REVISION_HISTORY`, checkpoint creation, and `SET_NOTE_REVISION` previously returned replies without preserving the originating request identity. The SDK `receive()` path also exposed only `message.data`, so notebook listeners could not determine which note a late reply belonged to.\r\n\r\nThis PR preserves the originating `msgId` on the relevant server reply paths, exposes the full WebSocket envelope through the SDK, and records the note context for pending requests on the client. Notebook handlers now reject replies with missing or unknown request identities, as well as replies whose request note no longer matches the active route.\r\n\r\nThe existing operation names are unchanged, and the change is limited to interpreter-binding and revision-related reply paths.\r\n\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n- [x] Preserve `msgId` on `INTERPRETER_BINDINGS` responses\r\n- [x] Preserve `msgId` on `LIST_REVISION_HISTORY` responses, including checkpoint replies\r\n- [x] Preserve `msgId` on `SET_NOTE_REVISION` responses\r\n- [x] Expose WebSocket reply envelopes through the SDK\r\n- [x] Track pending request note context and reject stale, missing, or unknown replies\r\n- [x] Add server tests for all affected response paths\r\n- [x] Add frontend tests for stale reply handling and valid same-note handling\r\n\r\n### What is the Jira issue?\r\n[[ZEPPELIN-6683]](https://issues.apache.org/jira/browse/ZEPPELIN-6683)\r\n\r\n### How should this be tested?\r\nFrontend focused tests (from `zeppelin-web-angular`):\r\n\r\n```bash\r\nnpm run test:shell -- \\\r\n  projects/zeppelin-sdk/src/message.spec.ts \\\r\n  src/app/core/message-listener/message-listener.spec.ts \\\r\n  src/app/pages/workspace/notebook/notebook.component.spec.ts\r\n```\r\nWebSocket contract check:\r\n\r\n```bash\r\nnpm run check:websocket-contract\r\n```\r\n\r\nServer focused test:\r\n```bash\r\n./mvnw -pl zeppelin-server -Dtest\u003dNotebookServerTest test\r\n```\r\nAll checks above pass successfully.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5487 from gyowoo1113/ZEPPELIN-6683-stale-notebook-replies.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "8916d7aee1982d32b8f8538518f3ac9dbd3a5b7a",
      "tree": "0db363121e998fbacea7efbd8c7ee32f87e497fc",
      "parents": [
        "bd1ecc6dc442c8b05124ae7afc1233006e21441d"
      ],
      "author": {
        "name": "dae won",
        "email": "99483390+big-cir@users.noreply.github.com",
        "time": "Thu Sep 24 22:34:07 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 24 22:34:07 2026 +0900"
      },
      "message": "[ZEPPELIN-6704] Scope personalized streaming output to its execution user\n\n### What is this PR for?\nIn a personalized note, paragraph results are stored per user, but the incremental output produced while a paragraph runs is not. The interpreter knows who started the execution, yet the output events it sends back carry no owner, so `NotebookServer` cannot tell who the output belongs to. Personalized incremental output is therefore dropped, and a user sees nothing until the paragraph finishes.\n\nThe owner is lost in two places. `OutputAppendEvent` and `OutputUpdateEvent` have no user field, and `createInterpreterOutput` captures only the note and paragraph ids from the interpreter context, even though the authentication info is available there too. Recovering it on the server is not an option either. The shared paragraph\u0027s `user` field is updated only when the note owner runs it, so it can hold a stale user from an earlier run rather than the owner of the current output.\n\nThis PR carries the execution owner end to end, in three commits:\n\n1. Add an optional `user` field to the interpreter output events and thread it from the interpreter to the server. The interpreter captures the owner when the output is created, before any chunks are produced, so every event from that execution carries the same owner. `AppendOutputRunner` now keys its buffer by owner as well, because two users running the same paragraph would otherwise have their chunks merged into the same buffer, leaving one chunk with no single owner. Behaviour is unchanged in this commit.\n2. Deliver personalized append and update events to the execution owner through `multicastToUser`, write updates to that user\u0027s own paragraph copy rather than the shared one, and make clear events discard only the owner\u0027s output. An interpreter that predates the field reports no owner, and that output is still dropped rather than broadcast.\n3. Add two-user e2e coverage.\n\nShared mode is untouched. A shared paragraph has only one execution producing output for a given index at a time, so adding the owner to the buffer key does not change its batching behavior. `AppendOutputRunnerTest.appendsFromOneExecutionAreStillBatchedIntoOneChunk` verifies this.\n\nTwo notes on scope. The paragraph output callbacks on `RemoteInterpreterProcessListener` are renamed to `onParagraphOutputAppend`, `onParagraphOutputUpdated` and `onParagraphOutputClear`: once the owner is added, they have the same erasure as the app output overloads that `NotebookServer` also implements, so the class would not compile. The Helium app output events carry no owner either, but I could not find any personalized code path that uses them, so they are left out of this PR.\n\n### What type of PR is it?\nBug Fix\n\n### Todos\n* [x] - Carry the execution owner from the interpreter to `NotebookServer`\n* [x] - Key the append buffer by owner so concurrent runs are not merged\n* [x] - Route personalized append, update and clear to the execution owner\n* [x] - Add server tests and a two-user e2e test\n\n### What is the Jira issue?\n* [ZEPPELIN-6704](https://issues.apache.org/jira/browse/ZEPPELIN-6704)\n\n### How should this be tested?\nServer side:\n\n```\n./mvnw package -pl zeppelin-server --am \\\n  -Dtest\u003d\"NotebookServerStreamingScopeTest,AppendOutputRunnerTest,RemoteInterpreterEventServerTest\" \\\n  -DfailIfNoTests\u003dfalse -Dsurefire.failIfNoSpecifiedTests\u003dfalse\n```\n\n27 tests pass. `NotebookServerStreamingScopeTest` covers the routing, including a test that reproduces the original failure mode: the shared paragraph is given a stale owner and a different user runs the paragraph, and the output must still reach the user who started that execution.\n\nThe e2e test signs in as two shiro accounts in separate browser contexts, opens one personalized note, and records the `PARAGRAPH_APPEND_OUTPUT` and `PARAGRAPH_UPDATE_OUTPUT` frames each socket receives. The test asserts on WebSocket frames rather than rendered UI because the bug is in server-side connection routing. It runs on the authenticated leg:\n\n```\ncd zeppelin-web-angular \u0026\u0026 npx playwright test e2e/tests/notebook/personalized --project\u003dchromium\n```\n\nReverting the routing change makes the new tests fail:\n\n```\nNotebookServerStreamingScopeTest.personalizedOutputReachesOnlyItsExecutionOwner\n  Wanted but not invoked: connectionManager.multicastToUser(\"owner\", ...)\nNotebookServerStreamingScopeTest.personalizedUpdateWritesToTheOwnersCopyNotTheSharedParagraph\n  the owner\u0027s copy did not receive its own output \u003d\u003d\u003e expected: \u003c1\u003e but was: \u003c0\u003e\nNotebookServerStreamingScopeTest.personalizedClearOnlyDiscardsTheOwnersOutput\n  the owner\u0027s output survived its own clear \u003d\u003d\u003e expected: \u003cnull\u003e but was: \u003c%text owned\u003e\npersonalized-streaming-scope.spec.ts\n  no marker in 0 streaming frames\n  Expected substring: \"RUNNER-ONLY\" / Received string: \"\"\n```\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No. The thrift field is optional, so an older interpreter process simply reports no owner and its personalized output is dropped instead of broadcast.\n* Does this needs documentation? No\n\n\nCloses #5479 from big-cir/ZEPPELIN-6704.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "bd1ecc6dc442c8b05124ae7afc1233006e21441d",
      "tree": "1996ce60023e8ff17c441b7c016ddac32f1ba93c",
      "parents": [
        "9b271d5f2c6a3686c0dc16096b641d69be17b61d"
      ],
      "author": {
        "name": "ChanHo Lee",
        "email": "chanholee@apache.org",
        "time": "Mon Sep 21 23:28:43 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 21 23:28:43 2026 +0900"
      },
      "message": "[ZEPPELIN-6718] Carry every persisted field into a personalized user note\n\n### What is this PR for?\n\nReading a personalized note does not return the note itself. `NotebookService.getNote` hands back a per-user copy built by `Note.getUserNote(user)`, and that copy is assembled by moving fields across one at a time, covering 5 of the 11 persisted fields.\n\n`path`, `defaultInterpreterGroup`, `version`, `info`, `noteParams` and `noteForms` are left null. Gson omits null fields, so those keys disappear from every response for a personalized note, over REST and WebSocket alike.\n\n`path` is the one that breaks the UI. It is not stored in the note file: the path comes from where the file sits and is reattached by `NoteManager` after load, so a copy that loses it has nowhere to recover it from. The front end reads it to detect the trash folder, `note.path.split(\u0027/\u0027)` throws on undefined, and the exception aborts change detection so the notebook action bar is never rendered. That includes the button that turns personalized mode back off, which means **a note switched to personalized mode cannot be switched back from the UI**.\n\nThe server defect has been there since `getUserNote` was introduced in ZEPPELIN-1594. The classic UI guarded against the missing value:\n\n```js\n// zeppelin-web/src/app/notebook/notebook.controller.js:267\nreturn note \u0026\u0026 note.path ? note.path.split(\u0027/\u0027)[1] \u003d\u003d\u003d TRASH_FOLDER_ID : false;\n```\n\nThe Angular UI carries the same check without that guard, which is what finally exposed the server side.\n\nThis PR copies the six missing fields. Because the copy is still written field by field, it also adds a regression test that walks every persisted field of `Note` by reflection and compares the copy against the original, so a field added to `Note` later and not copied here fails by name.\n\nThe front end is left alone on purpose. `path` is a value the server must always send; typing it as optional or guarding at the call site would let the same class of server defect pass unnoticed again, which is exactly why this one went unnoticed for so long.\n\n### What type of PR is it?\nBug Fix\n\n### Todos\n* [x] Copy the six fields `getUserNote` was dropping\n* [x] Add a reflection regression test that catches a future missing field\n\n### What is the Jira issue?\n* [ZEPPELIN-6718](https://issues.apache.org/jira/browse/ZEPPELIN-6718)\n\n### How should this be tested?\n\n```\n./mvnw test -pl zeppelin-server --am -Dtest\u003dNoteTest\n```\n\n10 tests pass. Reverting the change to `Note.java` while keeping the tests makes the two new ones fail and name the cause:\n\n```\n[ERROR] Tests run: 10, Failures: 2, Errors: 0, Skipped: 0\n[ERROR]   NoteTest.userNoteKeepsEveryPersistedField:254 getUserNote dropped Note.defaultInterpreterGroup \u003d\u003d\u003e expected: \u003cspark\u003e but was: \u003cnull\u003e\n[ERROR]   NoteTest.userNoteKeepsThePath:233 expected: \u003c/folder/my note\u003e but was: \u003cnull\u003e\n```\n\nChecked by hand as well. Create a note, switch it to personal mode, and open it. Before the change, `GET /api/notebook/{noteId}` comes back without `path` and the console repeats the `split` error while the action bar never renders. After it, `path` is back, no errors are logged, the action bar renders, and `Switch to collaboration mode` completes the switch (`personalizedMode: false`).\n\n### Screenshots (if appropriate)\nN/A\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No\n* Does this needs documentation? No\n\nCloses #5494 from tbonelee/ZEPPELIN-6718.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "9b271d5f2c6a3686c0dc16096b641d69be17b61d",
      "tree": "7a61a197836a95e96139039c7f5537f0cf3b5711",
      "parents": [
        "bcb428dde5346b0803587292d06839a003bd03f0"
      ],
      "author": {
        "name": "Gyeongtae Park",
        "email": "gyeongtae@apache.org",
        "time": "Mon Sep 21 16:11:35 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 21 16:11:35 2026 +0900"
      },
      "message": "[ZEPPELIN-6716] Update links in NOTICE\n\n### What is this PR for?\r\nThis PR updates the root NOTICE file.\r\n\r\nIt removes the unavailable NFLabs website URL while preserving the\r\nattribution to NFLabs, Inc., and changes the pty4j Eclipse Public\r\nLicense URL from HTTP to HTTPS.\r\n\r\n### What type of PR is it?\r\nDocumentation\r\n\r\n### Todos\r\n* [x] - Update the NFLabs attribution in NOTICE\r\n* [x] - Update the pty4j license URL to HTTPS\r\n\r\n### What is the Jira issue?\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6716\r\n\r\n### How should this be tested?\r\nNo automated tests are required because this is a documentation-only change.\r\n\r\nThe final diff should be reviewed to confirm that only NOTICE was modified.\r\n\r\n### Screenshots (if appropriate)\r\nNot applicable.\r\n\r\n### Questions:\r\n* Does the license files need to update?\r\n  No additional license files need to be updated. This PR only updates NOTICE.\r\n\r\n* Is there breaking changes for older versions?\r\n  No.\r\n\r\n* Does this needs documentation?\r\n  No additional documentation is needed.\n\nCloses #5491 from ParkGyeongTae/ZEPPELIN-6716.\n\nSigned-off-by: ParkGyeongTae \u003cgyeongtae@apache.org\u003e"
    },
    {
      "commit": "bcb428dde5346b0803587292d06839a003bd03f0",
      "tree": "f594adac79d40a9fd45a00195c77f97d7d58dc68",
      "parents": [
        "2ee180ffab215aa18fd167815b65bc23fcc64d1f"
      ],
      "author": {
        "name": "Gyeongtae Park",
        "email": "gyeongtae@apache.org",
        "time": "Sun Sep 20 20:14:25 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 20 20:14:25 2026 +0900"
      },
      "message": "[ZEPPELIN-6712] Fix CLI version options and restore CommandLineUtils\n\n### What is this PR for?\r\n\r\nFix `bin/zeppelin.sh --version` and `bin/zeppelin.sh -v`, which currently fail with `Unsupported argument.` because the option parser rejects them before reaching the version-handling code.\r\n\r\nRestore `CommandLineUtils` and its unit tests, as `getZeppelinVersion()` in `bin/common.sh` still references the removed class. Update the script to recognize both version options, invoke the version command after loading `common.sh`, and include the options in the usage message.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6712\r\n\r\n### How should this be tested?\r\n\r\nThe restored `CommandLineUtilsTest` covers `--version`, `-v`, and invocation without arguments.\r\n\r\nRun:\r\n\r\n```bash\r\n./mvnw package -pl zeppelin-server --am \\\r\n  -Dtest\u003dCommandLineUtilsTest \\\r\n  -Dsurefire.failIfNoSpecifiedTests\u003dfalse\r\n```\r\n\r\nAll 3 tests passed with no failures, errors, or skipped tests. The build succeeded.\r\n\r\nManual validation:\r\n\r\n```bash\r\nbin/zeppelin.sh --version\r\nbin/zeppelin.sh -v\r\nbin/zeppelin.sh --config conf --version\r\n```\r\n\r\nAll three commands printed `0.13.0-SNAPSHOT` and exited successfully without starting the server in the local development checkout. Bash syntax validation also passed.\r\n\r\n### Questions:\r\n\r\n* Do the license files need updating? No.\r\n* Are there breaking changes for older versions? No.\r\n* Does this need documentation? The script\u0027s usage message has been updated.\n\nCloses #5488 from ParkGyeongTae/ZEPPELIN-6712.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "2ee180ffab215aa18fd167815b65bc23fcc64d1f",
      "tree": "6c633c39d6d6b19490c4160fa3de91c547d0b961",
      "parents": [
        "7076ea41c57d1fe3b172fc53ffde1d5229c57ef0"
      ],
      "author": {
        "name": "huiseong29",
        "email": "tobestar29@naver.com",
        "time": "Sun Sep 20 11:11:47 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 20 11:11:47 2026 +0900"
      },
      "message": "[ZEPPELIN-6465] Extract magic numbers in EmbeddingSearch.saveIndex() into named constants\n\n### What is this PR for?\r\n`EmbeddingSearch` declares its tuning values as named `private static final int` constants near the top of the class (`EMBEDDING_DIM`, `MAX_TEXT_LENGTH`, `MAX_INDEX_ENTRIES`), but the two truncation limits in `saveIndex()` were left as bare literals. Each value appeared twice — once in the length check and once in the `substring(0, ...)` call — so changing only one occurrence would silently let the check bound and the truncation bound drift apart.\r\n\r\nThis extracts `2000` and `1000` into `MAX_PERSISTED_TEXT_LENGTH` and `MAX_PERSISTED_OUTPUT_LENGTH`, following the constant style already used in the class, and replaces all four usages.\r\n\r\nThe names deliberately distinguish these persistence limits from the existing `MAX_TEXT_LENGTH` (1500), which bounds in-memory processing before embedding and is a different value for a different purpose. Javadoc on the new text constant makes that distinction explicit.\r\n\r\nValues are unchanged, so behavior and the persisted binary format are identical and `INDEX_VERSION` does not need to move. `loadIndex()` has no corresponding truncation logic and is untouched.\r\n\r\n### What type of PR is it?\r\nRefactoring\r\n\r\n### Todos\r\n- [x]  Extract the two truncation limits into named constants\r\n- [x]  Replace all four literal usages in saveIndex()\r\n\r\n### What is the Jira issue?\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6465\r\n\r\n### How should this be tested?\r\nThe EmbeddingSearch tests are gated behind `ZEPPELIN_EMBEDDING_TEST` and require the embedding model to be installed first:\r\n\r\n    bash bin/install-search-model.sh\r\n    ZEPPELIN_EMBEDDING_TEST\u003dtrue ./mvnw test -pl zeppelin-server -Dtest\u003d\u0027*EmbeddingSearch*\u0027\r\n\r\nAll 12 tests pass. `grep -n \"2000\\|1000\" EmbeddingSearch.java` shows the values only at the two constant declarations, with no bare literals left in `saveIndex()`.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\n\nCloses #5489 from huiseong29/ZEPPELIN-6465.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "7076ea41c57d1fe3b172fc53ffde1d5229c57ef0",
      "tree": "10a7783a388995f81ea0e2adc21c49f066c85078",
      "parents": [
        "710edf257c43826ffabc47cefc2617e828e3363e"
      ],
      "author": {
        "name": "HwangRock",
        "email": "157935545+HwangRock@users.noreply.github.com",
        "time": "Sun Sep 20 11:11:22 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 20 11:11:22 2026 +0900"
      },
      "message": "[ZEPPELIN-6710] Keep Enter as a newline for no-op Monaco suggestions\n\n### What is this PR for?\r\n\r\nIn the New UI paragraph editor (Monaco), pressing Enter can be silently swallowed while the auto-suggest popup is open, dropping a line break so the next characters land on the current line instead of a new one.\r\n\r\nThe trigger is a *no-op* suggestion. When word-based suggestions offer a candidate identical to the word the user just finished typing, accepting it changes nothing. With Monaco\u0027s `acceptSuggestionOnEnter` left at its default (`\u0027on\u0027`), Enter accepts that no-op candidate instead of inserting a newline: the keystroke is consumed, the line break never lands, and rapid multi-line typing loses lines.\r\n\r\nThe fix sets `acceptSuggestionOnEnter: \u0027smart\u0027` on the paragraph editor. The auto-suggest popup still appears; only the Enter behavior changes, and only for a focused candidate whose acceptance would not change the text.\r\n\r\n#### Why `\u0027smart\u0027` over the alternatives\r\n\r\n- **`wordBasedSuggestions: \u0027off\u0027`** — removes the document-word completion feature entirely. That is heavier than the bug warrants, and it is not even the right lever: Monaco\u0027s built-in word-based provider already filters out an exact match of the current token (`editorSimpleWorker.js`, `if (word \u003d\u003d\u003d leadingWord) continue`), so turning it off does not target the actual no-op source.\r\n- **Filtering exact-match candidates in the interpreter completion provider** (`completion.service.ts`) — the most surgical *removal* of the candidate, but it changes interpreter completion behavior, which ZEPPELIN-6710 explicitly lists as out of scope (\"Changing interpreter completion behavior or the Ctrl+Space-then-Enter accept flow\"). It also lives outside `updateEditorOptions()`, which the issue scopes the change to.\r\n- **`acceptSuggestionOnEnter: \u0027smart\u0027`** — a one-line change inside `updateEditorOptions()`, keeps the completion feature intact, and defends the newline regardless of which provider produced the candidate. It matches the issue\u0027s scope (\"Stop Enter from silently discarding a newline when the focused suggestion would make no textual change\") exactly.\r\n\r\n#### Trade-offs, and why they are not problems here\r\n\r\n- **It defends Enter rather than removing the candidate.** The no-op candidate still appears in the popup, and Tab/click still accept it. But accepting a no-op is inert (it changes nothing), so there is no harm left to prevent — only the *silent newline loss* mattered, and that is what `\u0027smart\u0027` fixes.\r\n- **`acceptSuggestionOnEnter` is editor-wide** (within the paragraph code editor). Behavior only changes for the exact combination \"no-op candidate + auto-triggered popup + Enter\"; every other completion path — partial-word accept, Ctrl+Space, Tab — is unchanged. There is no scenario where turning a no-op accept into a newline is a regression.\r\n- **`\u0027smart\u0027` does not cover `additionalTextEdits` (auto-import) or snippet candidates** — Monaco treats those as text-changing and still accepts them on Enter. This does not apply to Zeppelin: interpreter completions are mapped as plain-string `insertText` with no `insertTextRules` or `additionalTextEdits` (`completion.service.ts`), so those candidate shapes are never produced.\r\n\r\n#### How `\u0027smart\u0027` works internally\r\n\r\nMonaco recomputes a context key `suggestionMakesTextEdit` whenever the focused suggestion changes. Under `\u0027smart\u0027`, it gates on: the popup was auto-triggered (`state \u003d\u003d\u003d Auto`, i.e. not a manual Ctrl+Space), no `additionalTextEdits`, not a snippet, and the replace range length equals the insert-text length. When that gate passes, it compares the editor text against the candidate\u0027s `insertText`; if they are identical the key is set to `false`.\r\n\r\nEnter is bound to `acceptSelectedSuggestion`, which requires `Visible \u0026\u0026 textInputFocus \u0026\u0026 acceptSuggestionOnEnter \u0026\u0026 suggestionMakesTextEdit`. With the key `false`, that binding no longer matches, so Enter falls through to the editor\u0027s default action — a newline. Ctrl+Space (a manual trigger) never enters the `state \u003d\u003d\u003d Auto` gate, so interpreter completion\u0027s accept-on-Enter is unaffected; inline ghost-text is a separate `registerInlineCompletionsProvider` subsystem and is likewise untouched.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### What is the Jira issue?\r\n\r\nhttps://issues.apache.org/jira/browse/ZEPPELIN-6710\r\n\r\n### How should this be tested?\r\n\r\nA new Playwright regression, `zeppelin-web-angular/e2e/tests/notebook/monaco-enter-newline.spec.ts`, drives the auto-suggest path (typing to let quickSuggestions open the popup, not a manual trigger, since `\u0027smart\u0027` only applies to auto-triggered popups). It asserts:\r\n\r\n- a no-op exact-match candidate + Enter keeps the newline (`foobar\\nbaz`, not `foobarbaz`);\r\n- a genuine partial-prefix candidate still accepts on Enter (`\u0027smart\u0027` only skips no-ops).\r\n\r\nVerified: the test passes with the fix, and fails deterministically (`foobar` and `baz` merge onto one line) when the `\u0027smart\u0027` line is removed — so the regression actually pins the bug. `tsc`, `prettier`, and `eslint` are clean.\r\n\r\n### Screenshots (if appropriate)\r\n\r\nhttps://github.com/user-attachments/assets/e06c66fb-8cea-4837-bcd3-e84689109695\r\n\r\n### Questions:\r\n\r\n- Does the documentation need to be updated? No.\r\n\n\nCloses #5490 from HwangRock/ZEPPELIN-6710-monaco-enter-newline.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "710edf257c43826ffabc47cefc2617e828e3363e",
      "tree": "4da6b1a0e70f280e8ca459dcfd66b1e85ce8f1ab",
      "parents": [
        "b13ddf4a4968b2a5514ec976e52b4eabacb5944f"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Wed Sep 16 22:24:21 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 16 22:24:21 2026 +0900"
      },
      "message": "[ZEPPELIN-6517] Add E2E tests for notebook paragraph components\n\n### What is this PR for?\r\nThis PR improves the behavior-focused E2E coverage for the notebook paragraph sub-components.\r\n\r\nIt replaces shallow visibility checks and interpreter-error fallbacks with scenarios that verify user-observable paragraph behavior:\r\n- Add paragraphs above and below the current paragraph\r\n- Edit Monaco content and verify focused, dirty, and rendered line states\r\n- Inspect the paragraph settings available for single and multiple paragraphs\r\n- Clone, insert, move, and remove paragraphs\r\n- Toggle the editor, output, line numbers, and run state\r\n- Edit paragraph titles and verify Enter, Escape, and blur behavior\r\n- Verify running, finished, outdated, and cancelled paragraph states\r\n- Verify progress and footer timing information\r\n- Verify that paragraph insertion is disabled while execution is in progress\r\n\r\nThe paragraph page object is also updated to:\r\n\r\n- Scope component locators to the primary paragraph\r\n- Provide helpers for add-paragraph and settings-menu interactions\r\n- Replace individual settings-menu locators with a typed `settingsMenuItem()` accessor\r\n- Support interactions with settings menus belonging to different paragraphs\r\n- Use stable, component-specific locators instead of broad fallback selectors\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6517\r\n\r\n### How should this be tested?\r\nFrom `zeppelin-web-angular/`, run:\r\n\r\n```bash\r\nnpm run e2e:fast -- tests/notebook/paragraph/paragraph-functionality.spec.ts\r\n```\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5476 from miinhho/test/notebook-paragraph-sub-component.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "b13ddf4a4968b2a5514ec976e52b4eabacb5944f",
      "tree": "700c6a28754e5b0191aab0038bb1d4b585062916",
      "parents": [
        "e816bf1b76b50282cc32b284cdb8755f932f657e"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Wed Sep 16 22:23:40 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 16 22:23:40 2026 +0900"
      },
      "message": "[ZEPPELIN-6631] Render the notebook repository list through a React remote behind a flag\n\n### What is this PR for?\n\nMoves the `/notebook-repos` repository list and its edit surface to the React remote behind `?reactNotebookRepos`, while Angular keeps the route, `NotebookRepoService`, the PUT, the refetch that follows it, the note-tree refresh the server broadcasts, and the fallback. Only the cards inside `.content` change hands; the default path stays Angular.\n\n**ZEPPELIN-6682**, first commit, is the safety net this rests on: a live-server E2E proving that a successful repository save reloads notebooks and refreshes the shell note tree. It carries no React implementation and stands on its own — its spec passes with none of the port applied, so the two split cleanly if you would rather take them separately. Both are here because ZEPPELIN-6631 cannot close until that scenario passes with the React flag enabled, and ZEPPELIN-6630/6363 took the same shape.\n\nThe host follows the shape ZEPPELIN-6630 established for the configuration table rather than inventing a second one: a `shouldUseReactList` getter folding the flag together with a mount failure, props memoized on the only input that changes, and `queryParamMap` subscribed rather than read once, because navigating between `/notebook-repos` and `/notebook-repos?reactNotebookRepos` reuses the component. An `onError` from the remote falls back to the Angular list for the rest of the session.\n\n`ReactMountDirective` now re-enters the Angular zone for **every** function-valued prop, not only `onError` as ZEPPELIN-6565 left it. The repository list is the first surface to hand the remote a real callback: its save calls back into the host, which issues the PUT and refetches. Outside the zone that work is untracked and the refresh lands late or not at all.\n\nThe remote owns no state beyond the open editor and its draft. A save hands the whole repo back with the edited values in place, not a partial patch, since the host issues the PUT and feeds the refetched list back down; the draft is rebuilt when that arrives, so a card cannot keep showing values the server already replaced. Blank settings are refused the way the Angular form\u0027s required validator refuses them, rather than sending a PUT the server would reject.\n\n`NotebookRepo` and its setting type are declared in the remote because the SDK does not carry them and the shell\u0027s `NotebookRepoSettingsItem` is an Angular interface the remote cannot import. On visual parity: `REPO_TOKENS` passes `fontWeightStrong` through the theme provider for the same reason the configuration table does (ng-zorro draws card titles and table headers at 500, antd at 600), the card gap is pinned to 24px to match `\u003cat\u003ecard-padding-base`, and the buttons carry the edit/save/close icons the Angular card draws through `nz-icon`.\n\n### What type of PR is it?\n\nImprovement\n\n### Todos\n\nNone\n\n### What is the Jira issue?\n\n* https://issues.apache.org/jira/browse/ZEPPELIN-6631\n* https://issues.apache.org/jira/browse/ZEPPELIN-6682\n\n### How should this be tested?\n\n* `npm run test:shell`: 51 tests across 11 files. `react-mount.directive.spec.ts` gains the zone case for a non-`onError` callback.\n* `projects/zeppelin-react` vitest: 76 tests across 12 files, including the 10 in `NotebookRepoList.spec.tsx`.\n* Production builds: `npm run build:react` (`NotebookRepoList` present in `remoteEntry.js`) and `npm run build:projects`.\n* Manually against a live server in both branches of the flag, anonymous mode:\n  * The save round trip issues `PUT /api/notebook-repositories` followed by the host\u0027s refetch, and the card returns to read mode showing the new value.\n  * A blank setting disables Save; Cancel restores the previous value and re-entering edit shows it.\n  * Reading the repository names and setting rows from each branch returns byte-identical output.\n  * The note-tree scenario ZEPPELIN-6682 covers, with the React flag on: a note created over REST is absent from a second client\u0027s home note tree, stays absent while nothing is saved, and appears after the repository save. Skipping the save leaves it absent, which is the control that makes the assertion mean something.\n  * Aborting `remoteEntry.js` falls back to the Angular list, with no mount host in the DOM.\n* Playwright was not run locally; the two new specs and the ZEPPELIN-6682 spec\u0027s two flag legs run for the first time in `run-playwright-e2e-tests`.\n* `DROPDOWN` settings are covered by unit tests only — the server used for the manual pass exposes one repository with a single `INPUT` setting.\n\n### Screenshots (if appropriate)\n\nThe two lists are hard to tell apart, which is the intent. Header weight, card gap and button icons match; the remaining difference is antd\u0027s own row height.\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No, the flag defaults to off and the Angular list is unchanged when it is\n* Does this needs documentation? The two places that enumerate the flagged React surfaces are updated in the last commit\n\n\nCloses #5472 from kimyenac/ZEPPELIN-6631.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "e816bf1b76b50282cc32b284cdb8755f932f657e",
      "tree": "458c5b0f0c7f19eede32fc4335831800f7d10db4",
      "parents": [
        "5a262cd76c9028fadca6aad285797acda1a8486d"
      ],
      "author": {
        "name": "SeungYoung Oh",
        "email": "seung-00@naver.com",
        "time": "Mon Sep 14 01:04:45 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 14 01:04:45 2026 +0900"
      },
      "message": "[ZEPPELIN-6708] Upgrade git-commit-id plugin to 10.0.1\n\n### What is this PR for?\r\nBuilding Zeppelin from a Git worktree fails because `git-commit-id-plugin 4.0.0` cannot resolve HEAD. This PR upgrades the plugin to `10.0.1` and updates its Maven coordinates to fix the build failure.\r\n\r\nReference: https://github.com/git-commit-id/git-commit-id-maven-plugin/issues/215\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### Todos\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN/ZEPPELIN-6708\r\n\r\n### How should this be tested?\r\nBuild Zeppelin from a Git worktree and verify that the build succeeds:\r\n- `git worktree add ../zeppelin-worktree -b reproduce-worktree-build`\r\n- `cd ../zeppelin-worktree`\r\n- `./mvnw package -pl markdown -am -DskipTests`\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? N\r\n* Is there breaking changes for older versions? N\r\n* Does this needs documentation? N\r\n\n\nCloses #5475 from seung-00/ZEPPELIN-6708.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "5a262cd76c9028fadca6aad285797acda1a8486d",
      "tree": "7a108cfc87e18c2a1ddc30a09862b4b86d87910f",
      "parents": [
        "0c35c61f407c0d6ca6d237b261e795f21c83c524"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Sep 13 19:36:55 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 19:36:55 2026 +0900"
      },
      "message": "[MINOR] Fix import-boundary consumer scan skipping non-consumer dependencies\n\n### What is this PR for?\r\nFix CI failure introduced by #5469 (already merged as 788d45aa37). Its `findReactNotebookConsumerViolations` scan restricted recursion to `consumers.has(target)`, but a consumer\u0027s own dependency (e.g. a helper file) is never itself added to `consumers`, so the scan stopped detecting forbidden transport imports reached through it. Reverts to the original unconditional recursion.\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n\r\n### What is the Jira issue?\r\n\r\n### How should this be tested?\r\n`npm run test:notebook-core`: the 3 previously-failing cases (`helper`/`javascript`/`require-outside`) now pass.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5478 from voidmatcha/hotfix/import-boundary-consumer-scan.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "0c35c61f407c0d6ca6d237b261e795f21c83c524",
      "tree": "7facea4526dbdd8682baeccf248eff958543d3f0",
      "parents": [
        "ec96819966b6db710a508490c74367f88efa8e26"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Sun Sep 13 19:31:35 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 19:31:35 2026 +0900"
      },
      "message": "[ZEPPELIN-6659] Render streaming interpreter output in Angular New UI\n\n### What is this PR for?\r\n\r\nThe Angular New UI declares `PARAGRAPH_APPEND_OUTPUT` and `PARAGRAPH_UPDATE_OUTPUT` in its WebSocket operation enum but does not consume either message. Interpreter output emitted while a paragraph is running\r\nis therefore discarded until the terminal `PARAGRAPH` snapshot arrives.\r\n\r\nThis PR adds the missing consumer based on the server\u0027s actual wire contract. It declares the receive payloads in the SDK, handles both operations in `ParagraphBase`, and introduces `ParagraphOutputState` to fold UPDATE, APPEND, and terminal snapshots into the current paragraph result. APPEND data is accumulated by result index, APPEND received before a typed UPDATE is held until its type is known, and the terminal `PARAGRAPH` snapshot becomes authoritative so late frames cannot duplicate or overwrite the final result.\r\n\r\nThe PR also fixes a server-side ordering ambiguity. APPEND events were buffered for up to 100 ms by `AppendOutputRunner`, while UPDATE events bypassed that queue and could overtake an earlier APPEND. A client\r\ncannot distinguish that delayed APPEND from one genuinely produced after the UPDATE. APPEND and UPDATE now share the same queue, with UPDATE acting as an ordering boundary: preceding APPEND chunks are flushed\r\nbefore the UPDATE, and subsequent APPEND chunks remain after it.\r\n\r\nA focused, versioned capture records the callback-order evidence and observed WebSocket sequences with paragraph streaming enabled and disabled. Reducer tests replay the capture and cover delayed-frame permutations. The client remains defensive against late frames for compatibility with older servers.\r\n\r\nThe change is limited to the standard paragraph result-rendering path. Application output rendering is unchanged.\r\n\r\n### What type of PR is it?\r\n\r\nBug Fix\r\n\r\n### Todos\r\n\r\n* [x] Declare the APPEND and UPDATE receive payloads and their type asymmetry\r\n* [x] Consume streaming paragraph output in the Angular New UI\r\n* [x] Preserve APPEND and UPDATE ordering on the server\r\n* [x] Cover coalesced, reordered, and late output events\r\n* [x] Record and replay enabled and disabled streaming captures\r\n* [x] Add browser coverage for output accumulation while RUNNING\r\n* [x] Add the post-fix streaming scenario to the notebook parity registry after apache/zeppelin#5456 lands\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6659\r\n\r\nThe reusable WebSocket fixture infrastructure tracked by ZEPPELIN-6665 and ZEPPELIN-6671 is not available yet, so this PR includes the focused capture and ordering replay required by ZEPPELIN-6659.\r\n\r\nThe notebook parity registry is being introduced by ZEPPELIN-6660 in apache/zeppelin#5456. After that PR lands, this change will register streaming output as a separate result scenario. The scenario will require the first chunk to be visible while the paragraph is RUNNING, later chunks to accumulate rather than replace earlier output, and the terminal result to contain every chunk exactly once.\r\n\r\n### How should this be tested?\r\n\r\n* Run the server ordering regression test:\r\n\r\n```bash\r\n./mvnw test -pl zeppelin-server -Dtest\u003dAppendOutputRunnerTest\r\n```\r\n\r\n* Run the frontend reducer and SDK contract tests:\r\n\r\n```bash\r\ncd zeppelin-web-angular\r\nnpm run test:shell -- src/app/core/paragraph-base/paragraph-output-state.spec.ts projects/zeppelin-sdk/src/interfaces/message-data-type-map.interface.spec.ts\r\n```\r\n\r\n* Validate the WebSocket operation contract:\r\n\r\n```bash\r\nnpm run check:websocket-contract\r\n```\r\n\r\nThe browser test runs a shell paragraph that prints three chunks separated by 3 and 5 seconds. It verifies that `first` is visible while the paragraph is RUNNING, `second` is appended while the paragraph\r\nremains RUNNING, and the FINISHED result contains `first`, `second`, and `third`.\r\n\r\nThe capture replay additionally verifies coalesced APPEND chunks, APPEND before a typed UPDATE, UPDATE overtaking a queued APPEND, APPEND after the terminal `PARAGRAPH`, and terminal fallback when `zeppelin.websocket.paragraph_status_progress.enable\u003dfalse`.\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No.\r\n* Is there breaking changes for older versions? No. \r\n* Does this needs documentation? No.\n\nCloses #5460 from miinhho/fix/streaming-interpreter-output.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "ec96819966b6db710a508490c74367f88efa8e26",
      "tree": "077adddd1d8fa23c122496c5375de1e7356873d4",
      "parents": [
        "8ed66e543eadd8484faeec8d7b3b244a1fae3df0"
      ],
      "author": {
        "name": "Minho Jang",
        "email": "166613620+miinhho@users.noreply.github.com",
        "time": "Sun Sep 13 19:29:28 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 19:29:28 2026 +0900"
      },
      "message": "[ZEPPELIN-6516] Add visualization rendering E2E coverage\n\n### What is this PR for?\r\nThs PR adds Playwright E2E coverage for Zeppelin\u0027s table and G2-based chart visualizations.\r\n\r\nThe test creates deterministic \u0027%table\u0027 output through a notebook paragraph and verifies:\r\n- Exact table headers and cell values\r\n- Bar chart rendering\r\n- Pie chart rendering\r\n- Line chart rendering\r\n- Area chart rendering\r\n- Scatter chart rendering\r\n- Table data preservation after switching between visualization modes\r\n\r\nSince G2 renders charts on canvas, checking only that a canvas element is visible is not sufficient. The test also inspects the canvas alpha channel and verifies that it contains rendered pixels.\r\n\r\nA dedicated `NotebookVisualizationPage` Page Object is added to isolate visualization selectors, table locators, chart canvas locators, and canvas-rendering inspection from the scenario code.\r\n\r\n### Todos\r\n* [x] Add E2E coverage for table rendering\r\n* [x] Add E2E coverage for bar chart rendering\r\n* [x] Add E2E coverage for pie chart rendering\r\n* [x] Add E2E coverage for line chart rendering\r\n* [x] Add E2E coverage for area chart rendering\r\n* [x] Add E2E coverage for scatter chart rendering\r\n\r\n### What type of PR is it?\r\nImprovement\r\n\r\n### What is the Jira issue?\r\n* https://issues.apache.org/jira/browse/ZEPPELIN-6516\r\n\r\n### How should this be tested?\r\n\r\nStart the Zeppelin backend, then run the focused Chromium E2E test:\r\n```bash\r\ncd zeppelin-web-angular\r\nnpm run e2e:fast -- tests/notebook/paragraph/visualization-rendering.spec.ts\r\n```\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5474 from miinhho/test/visual-charts-table-rendering.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "8ed66e543eadd8484faeec8d7b3b244a1fae3df0",
      "tree": "0568ebdd3ab1154982a8187ca2b0ba9406780e83",
      "parents": [
        "788d45aa372dcdeb35fa7903fbf2a2f267201e96"
      ],
      "author": {
        "name": "SeungYoung Oh",
        "email": "seung-00@naver.com",
        "time": "Sun Sep 13 17:50:03 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 17:50:03 2026 +0900"
      },
      "message": "[MINOR] Fix NotebookServiceTest compilation failure in CI\n\n### What is this PR for?\r\nFix CI compilation failures by adding the missing argument to `NotebookServiceTest`. \r\n#5427 changed the `query()` signature, while #5463 added a call using the old signature. CI did not test these changes together before merging.\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n\r\n### What is the Jira issue?\r\n\r\n### How should this be tested?\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? N\r\n* Is there breaking changes for older versions? N\r\n* Does this needs documentation? N\r\n\n\nCloses #5477 from seung-00/fix-CI-NotebookServiceTest.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "788d45aa372dcdeb35fa7903fbf2a2f267201e96",
      "tree": "994d6934982ff7cc454a70d130edaa92e1e8039d",
      "parents": [
        "2275a5d8c367c534980a2ff73cc834a1d9f46508"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Sep 13 17:17:27 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 17:17:27 2026 +0900"
      },
      "message": "[ZEPPELIN-6670] Add Shared Notebook Core mount contract\n\n### What is this PR for?\r\n\r\nAdd `\u003cat\u003ezeppelin/notebook-core` as a shared package for the Angular host and React remote.\r\n\r\nDefine common types for the read-only snapshot, `getSnapshot`, `subscribe`, and mount props. Add dependency-boundary checks and connect the package build, typecheck, and unit tests to the existing Maven/CI lifecycle.\r\n\r\nThis change does not implement the Core runtime. Separate-build object identity and notebook route integration will be verified in ZEPPELIN-6674 and ZEPPELIN-6675.\r\n\r\n### What type of PR is it?\r\n\r\nImprovement\r\n\r\n### What is the Jira issue?\r\n\r\nZEPPELIN-6670\r\n\r\n### How should this be tested?\r\n\r\nThe following checks passed locally in `zeppelin-web-angular`:\r\n\r\n* `npm run test:notebook-core`: 103 tests passed\r\n* `npm run typecheck:notebook-core`: passed\r\n* `npm run test:shell`: 49 tests passed\r\n* `npm run check:notebook-parity-scenarios`: 21 tests and the registry check passed\r\n* ESLint and Prettier checks for the changed code: passed\r\n\r\n### Screenshots (if appropriate)\r\n\r\nNo UI changes\r\n\r\n### Questions:\r\n\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? Updated README and AGENTS.md with the check commands and file locations.\r\n\n\nCloses #5469 from voidmatcha/ZEPPELIN-6670-shared-core-contract.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "2275a5d8c367c534980a2ff73cc834a1d9f46508",
      "tree": "86e72a1079a7827ebdd21ba451d602ec80132f61",
      "parents": [
        "e960f7c0d00d2c52dd22e1cf5c7520964d177142"
      ],
      "author": {
        "name": "SeungYoung Oh",
        "email": "seung-00@naver.com",
        "time": "Sun Sep 13 15:49:55 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 15:49:55 2026 +0900"
      },
      "message": "[ZEPPELIN-6705] Refactor shell terminal session management\n\n### What is this PR for?\r\nThis PR refactors `TerminalService` into `TerminalSession` to clarify its role.\r\n\r\nThe name `~Service` suggests a long-lived component providing shared functionality. However, each instance owns the state and resources of a single terminal connection and must be closed when that connection closes. `~Session` better reflects this ownership and lifecycle. This mismatch may have contributed to the missing cleanup in #5447.\r\n\r\nThis PR also includes minor code cleanup.\r\n\r\n### What type of PR is it?\r\nRefactoring\r\n\r\n### Todos\r\n\r\n\r\n### What is the Jira issue?\r\n- [ZEPPELIN-6705]\r\n\r\n### How should this be tested?\r\n- Run the shell module tests: `./mvnw test -pl shell.`\r\n\r\n### Screenshots (if appropriate)\r\n\r\n### Questions:\r\n* Does the license files need to update? N\r\n* Is there breaking changes for older versions? N\r\n* Does this needs documentation? N\r\n\n\nCloses #5473 from seung-00/ZEPPELIN-6705.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "e960f7c0d00d2c52dd22e1cf5c7520964d177142",
      "tree": "a851984a8f3b37a15f123c650a0743d7cfd62b1e",
      "parents": [
        "58f80fc6f3ffec7b1629f097f9e7450dfe7128e0"
      ],
      "author": {
        "name": "김동환",
        "email": "66408194+dev-donghwan@users.noreply.github.com",
        "time": "Sun Sep 13 15:43:34 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 15:43:34 2026 +0900"
      },
      "message": "[ZEPPELIN-6414] Apply the authorization filter before the search cutoff\n\n### What is this PR for?\n\n`/notebook/search` asked the search service for results and then dropped the ones the caller may not read. Both search services cut their results down to twenty before returning them, so that removal ran on an already shortened list:\n\n* A caller with access to few notes is served fewer results than it is allowed to see. If the twenty highest scoring hits all belong to notes it cannot read, the search comes back empty while its own matching notes sit just below the cut.\n* In `EmbeddingSearch` the entries the caller cannot read are also counted into the table boost of Phase 1, so notes that never reach the caller still move the ranking of the ones that do.\n\nThe read check now travels with the query, as a predicate over the note id, and every implementation applies it before it cuts anything.\n\n| | before | after |\n| --- | --- | --- |\n| `EmbeddingSearch` | scores every entry, cuts to `MAX_RESULTS`, REST filters | skips unreadable entries while scoring, so neither the table weights nor the cutoff see them |\n| `LuceneSearch` | `searcher.search(query, 20)`, REST filters | walks the hits in score order with `searchAfter` until a full page of readable hits is collected, or the hits run out |\n| `NotebookRestApi` | four permission calls per result, list mutated while iterating | passes the predicate, no post-filtering |\n\n`LuceneSearch` reads only the id field to decide on a hit and loads the whole document for the hits it keeps, so hits that are dropped cost one stored field read and no highlighting.\n\n`query(String)` is removed rather than kept next to the new method: leaving it would leave a way to search without saying who is asking, which is the defect this issue is about. `SearchService` is bound in `ZeppelinServer` to the three implementations in the repository and is not reachable as an extension point, so nothing outside the tree implements it.\n\nNote that this changes what the result limit means: it is now the top twenty results the caller may read, rather than what is left of the top twenty overall after filtering.\n\n### What type of PR is it?\nBug Fix\n\n### What is the Jira issue?\n* https://issues.apache.org/jira/browse/ZEPPELIN-6414\n\n### How should this be tested?\n\nNew tests in both search services, `keepsReadableResultsThatTheCutWouldHide`, put twenty-eight matching notes in the index and let the caller read three of them. Each test first checks its own fixture: it queries with an allow-all predicate and asserts that the readable notes really do fall outside the cut, so that the test cannot quietly stop testing anything if the limit or the scoring changes later. It then queries with the real predicate and expects all three readable notes back and nothing else.\n\n`LuceneSearchTest.returnsNothingWhenTheCallerMayReadNothing` covers the walk ending on its own when no hit is readable.\n\nRun locally:\n\n* `LuceneSearchTest` - 12 tests, including the two new ones\n* `EmbeddingSearchTest` - 12 tests, including the new one, run with `ZEPPELIN_EMBEDDING_TEST\u003dtrue` after `bin/install-search-model.sh`\n\nThe existing call sites in both test classes now pass `id -\u003e true` explicitly.\n\n### Questions:\n* Does the license files need to update? No\n* Is there breaking changes for older versions? `SearchService.query(String)` is replaced by `query(String, Predicate\u003cString\u003e)`. Only the three in-tree implementations and the REST resource use it.\n* Does this needs documentation? No\n\n### Possible follow-up\n\nIndexing the note id as its own field would let `LuceneSearch` hand the permission filter to Lucene instead of walking the hits, but it needs an index schema change and a rebuild, so it is left out of this issue.\n\n\nCloses #5427 from dev-donghwan/ZEPPELIN-6414.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "58f80fc6f3ffec7b1629f097f9e7450dfe7128e0",
      "tree": "93d8492e6965b3809894351630be4255e16ae643",
      "parents": [
        "38b3e9687c8e39bb64ec62ee44f5221aeca19a79"
      ],
      "author": {
        "name": "YONGJAE LEE (이용재)",
        "email": "dev.yongjaelee@gmail.com",
        "time": "Sun Sep 13 15:42:30 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Sep 13 15:42:30 2026 +0900"
      },
      "message": "[ZEPPELIN-6666] Add notebook transport fixtures\n\n### What is this PR for?\r\n\r\nAdds the versioned Notebook REST/WebSocket fixture format, isolated capture helper, and strict replay runner for ZEPPELIN-6666.\r\n\r\nThe recorder captures notebook REST traffic and `/ws` frames, normalizes volatile identifiers while preserving correlation, and redacts sensitive values. Replay rejects unexpected, reordered, or unconsumed traffic and requires REST deliveries to settle successfully. Requests outside the notebook boundary fall through to other route handlers.\r\n\r\nThe capture helper isolates configuration, notebooks, logs, search indexes, PID and recovery state. It verifies listener and process ownership, serializes start/stop operations, and stops only its owned process group. Unsupported whitespace paths are rejected before side effects.\r\n\r\nFixture-only browser tests use a dedicated configuration without backend cleanup or authentication state. Live capture is opt-in through `\u003cat\u003elive`, requires an explicit server URL, and supports isolated anonymous or authenticated setup. Ordinary E2E runs exclude live capture.\r\n\r\nThis PR also fixes E2E setup exposed by the full verification: Monaco select-all follows the browser keymap, cursor movement checks the exact buffer, inline completion checks actual ghost-text dismissal and focus, and cancellation uses exact seeded Python code before asserting RUNNING and ABORT.\r\n\r\nThis establishes the fixture foundation only. Execution/streaming, paragraph/revision/collaboration/reconnect, and permission/session fixtures remain in ZEPPELIN-6671, ZEPPELIN-6672, and ZEPPELIN-6673. Version 1 limitations are documented in `e2e/core-contract/README.md`.\r\n\r\n### What type of PR is it?\r\n\r\nImprovement\r\n\r\n### What is the Jira issue?\r\n\r\nZEPPELIN-6666\r\n\r\n### How should this be tested?\r\n\r\nLocal verification of the pushed source tree:\r\n\r\n- `./mvnw -B -ntp verify -pl zeppelin-web-angular -Pweb-e2e` — BUILD SUCCESS.\r\n- Full Angular/React lint and formatting checks passed.\r\n- Shell unit tests: 49 passed.\r\n- Fixture checks: 93 passed, 1 skipped.\r\n- Capture-server checks: 23 passed.\r\n- Playwright: 711 passed, 76 skipped; no failures or flaky tests reported.\r\n\r\nThe full run used an isolated anonymous server, JDK 11, Node 22, Python dependencies, and built Python/Markdown interpreters. Existing authentication/capability skips remain. This is local validation, not a claim about the new remote CI run. Live authenticated capture is separate and was not rerun in this final verification.\r\n\r\nFocused fixture and opt-in live commands are documented in `e2e/core-contract/README.md`.\r\n\r\n### Screenshots (if appropriate)\r\n\r\nN/A\r\n\r\n### Questions:\r\n\r\n- Does the license files need to update? No\r\n- Is there breaking changes for older versions? No\r\n- Does this needs documentation? Yes, `e2e/core-contract/README.md`\r\n\n\nCloses #5458 from voidmatcha/ZEPPELIN-6666-transport-fixtures.\n\nSigned-off-by: ChanHo Lee \u003cchanholee@apache.org\u003e"
    },
    {
      "commit": "38b3e9687c8e39bb64ec62ee44f5221aeca19a79",
      "tree": "b9c65c0dc1e804ca405faac6ee8e220f1aa9245f",
      "parents": [
        "5e36932e24cabac0224bba235659ca9f7e0aeeb4"
      ],
      "author": {
        "name": "gyowoo1113",
        "email": "58352333+gyowoo1113@users.noreply.github.com",
        "time": "Sat Sep 12 23:13:25 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 12 23:13:25 2026 +0900"
      },
      "message": "[ZEPPELIN-6692] centralize folder path handling\n\n### What is this PR for?\r\nFolder paths are currently handled differently depending on the operation. Some call sites add a leading `/`, while others pass the path unchanged. Some lower layers also assume a particular path form without checking it.\r\n\r\nThis can cause the same folder path to be interpreted differently depending on how it reaches the repository. For example, `VFSNotebookRepo` uses `substring(1)` assuming that the path starts with `/`, so a relative path can silently lose its first character.\r\n\r\nThis PR centralizes folder path normalization in `NotebookService`. Rename, move-to-trash, restore, and remove now use the same normalization so paths with or without a leading `/` are passed to lower layers in the same absolute form. The operation-specific leading-slash handling in `NotebookServer` is removed accordingly.\r\n\r\n`NotebookService` is used as the normalization point because all four affected folder operations pass through it before reaching `NoteManager`. This also keeps the shared normalization out of the individual `NotebookServer` handlers and lets the service apply the same rule to all four operations.\r\n\r\n`VFSNotebookRepo` also checks for the leading slash before using `substring(1)`, so an unexpected relative path is rejected instead of being silently truncated. The validation is currently applied to VFS, where the leading-slash assumption directly affects this path handling. It can be extended to other `NotebookRepo` implementations if needed as part of this PR.\r\n\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n- [x] Centralize folder path normalization in `NotebookService`\r\n- [x] Remove operation-specific folder path compensation from `NotebookServer`\r\n- [x] Apply the shared folder path convention to rename, trash, restore, and remove\r\n- [x] Reject non-absolute folder paths in `VFSNotebookRepo`\r\n- [x] Add regression tests for folder path normalization and VFS validation\r\n\r\n### What is the Jira issue?\r\n[[ZEPPELIN-6692]](https://issues.apache.org/jira/browse/ZEPPELIN-6692)\r\n\r\n### How should this be tested?\r\n`./mvnw test -pl zeppelin-server -Dtest\u003d\u0027NotebookServiceTest,NotebookServerTest,VFSNotebookRepoTest\u0027`\r\n`./mvnw test -pl zeppelin-server -Dtest\u003d\u0027NotebookRepoPathValidationTest\u0027`\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No\r\n* Does this needs documentation? No\r\n\n\nCloses #5459 from gyowoo1113/ZEPPELIN-6692-centralize-folder-path-handling.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "5e36932e24cabac0224bba235659ca9f7e0aeeb4",
      "tree": "c46f480213b8b3aa1e34418dd8144d504c8028b1",
      "parents": [
        "2f403f36b1b23183e2cff31b4024d9b85173bfb2"
      ],
      "author": {
        "name": "Lee SuJung",
        "email": "153787023+xhaktm00@users.noreply.github.com",
        "time": "Sat Sep 12 23:12:54 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Sep 12 23:12:54 2026 +0900"
      },
      "message": "[ZEPPELIN-6697] Prevent live NOTE_UPDATED from mutating revision snapshots\n\n### What is this PR for?\r\n`NotebookServer.updateNote()` broadcasts `NOTE_UPDATED` to every socket associated with the note, and a socket that navigates to a saved revision keeps that association. The Angular handler applied the payload unconditionally:\r\n\r\n```typescript\r\n\u003cat\u003eMessageListener(OP.NOTE_UPDATED)\r\nnoteUpdated(data) {\r\n  if (!this.note) {\r\n    return;\r\n  }\r\n  this.note.config \u003d data.config;   // overwrites the historical snapshot\r\n```\r\n\r\nSo changing the live note\u0027s look and feel from another browser rewrote the snapshot the revision view was showing.\r\n\r\nThe guard already exists elsewhere in the same component — `removeParagraph`, `addParagraph` and `moveParagraph` all check `revisionView`, and ZEPPELIN-2452 added the same check to the classic UI. It was only partly carried over during the migration, and `noteUpdated` was the one left out. This adds it there.\r\n\r\nPer the issue, this stays out of `noteId`, request correlation and socket generation: the reproduction only proves a revision-isolation defect, and nothing here required a wire change. The Shared Notebook Core revision adapter is not covered yet, since that slice has not landed.\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n* [x] Guard `noteUpdated` with `revisionView`\r\n* [x] Add a retained Playwright regression for the same-tab live-to-revision route\r\n\r\n### What is the Jira issue?\r\n* [ZEPPELIN-6697](https://issues.apache.org/jira/browse/ZEPPELIN-6697)\r\n\r\n### How should this be tested?\r\nNew spec `e2e/tests/notebook/revision/revision-isolation.spec.ts` opens a note, saves a revision, enters it on the same socket, then changes look and feel from an independent browser context. It asserts the live follower applies the update, and that the revision view still shows the value it was saved with.\r\n\r\n```\r\ncd zeppelin-web-angular \u0026\u0026 npx playwright test e2e/tests/notebook/revision/revision-isolation.spec.ts --project\u003dchromium --reporter\u003dlist\r\n```\r\n\r\nResult: `2 passed (22.5s)`. `--reporter\u003dlist` is worth passing locally, since the configured HTML reporter opens a report server afterwards and the command does not return on its own.\r\n\r\nReverting only the guard makes it fail, so it does catch the defect rather than passing by construction:\r\n\r\n```\r\nError: expect(locator).toContainText(expected) failed\r\nExpected string: \"default\"\r\nReceived string: \" simple \"\r\n```\r\n\r\nTwo details the spec depends on, both found the hard way:\r\n\r\n- **Look and feel, not rename.** Renaming goes through `renameNote`, which answers with `broadcastNote()` (`OP.NOTE`) and never emits `NOTE_UPDATED`. `setLookAndFeel()` is what calls `updateNote()`, which is why the issue names it in the reproduction.\r\n- **Waiting for the event.** Asserting the snapshot straight after the live change passes trivially, because the assertion resolves before the broadcast arrives. The spec first polls the revision page\u0027s console for `Receive: NOTE_UPDATED`, then asserts.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No — a live follower still applies the same update exactly once; only a revision view ignores it\r\n* Does this needs documentation? No\n\nCloses #5468 from xhaktm00/ZEPPELIN-6697.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "2f403f36b1b23183e2cff31b4024d9b85173bfb2",
      "tree": "1234bffd854087e3d5f9c4eeec3d79138cbdf246",
      "parents": [
        "d276aad3380cada5ee0e9bc8eb0ce0be18d07fcf"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Thu Sep 10 21:17:15 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 21:17:15 2026 +0900"
      },
      "message": "Bump vitest from 4.1.8 to 4.1.11 in /zeppelin-web-angular/projects/zeppelin-react\n\nBumps [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) from 4.1.8 to 4.1.11.\n\u003cdetails\u003e\n\u003csummary\u003eRelease notes\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca href\u003d\"https://github.com/vitest-dev/vitest/releases\"\u003evitest\u0027s releases\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003ev4.1.11\u003c/h2\u003e\n\u003ch3\u003e   🐞 Bug Fixes\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eRevive global concurrency limit for test lifecycle [backport to v4]  -  by \u003ca href\u003d\"https://github.com/sheremet-va\"\u003e\u003ccode\u003e\u003cat\u003e​sheremet-va\u003c/code\u003e\u003c/a\u003e and \u003ca href\u003d\"https://github.com/hi-ogawa\"\u003e\u003ccode\u003e\u003cat\u003e​hi-ogawa\u003c/code\u003e\u003c/a\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10992\"\u003evitest-dev/vitest#10992\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/5146df80b\"\u003e\u003c!-- raw HTML omitted --\u003e(5146d)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ebrowser\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003eEncode iframeId in tester iframe URL [backport to v4]  -  by \u003ca href\u003d\"https://github.com/sheremet-va\"\u003e\u003ccode\u003e\u003cat\u003e​sheremet-va\u003c/code\u003e\u003c/a\u003e, \u003cstrong\u003ePduhard\u003c/strong\u003e and \u003cstrong\u003eClaude Opus 4.8\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10955\"\u003evitest-dev/vitest#10955\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/10b2cd201\"\u003e\u003c!-- raw HTML omitted --\u003e(10b2c)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eTrigger playwright/chromium gc on lower disk availability [backport to v4]  -  by \u003ca href\u003d\"https://github.com/hi-ogawa\"\u003e\u003ccode\u003e\u003cat\u003e​hi-ogawa\u003c/code\u003e\u003c/a\u003e, \u003cstrong\u003eHiroshi Ogawa\u003c/strong\u003e and \u003cstrong\u003eOpenCode\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10951\"\u003evitest-dev/vitest#10951\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/9851dbc41\"\u003e\u003c!-- raw HTML omitted --\u003e(9851d)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003emocker\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003eRestrict redirect mocks to the fs allowlist [backport to v4]  -  by \u003ca href\u003d\"https://github.com/sheremet-va\"\u003e\u003ccode\u003e\u003cat\u003e​sheremet-va\u003c/code\u003e\u003c/a\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10974\"\u003evitest-dev/vitest#10974\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/fe5a11d3c\"\u003e\u003c!-- raw HTML omitted --\u003e(fe5a1)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5\u003e    \u003ca href\u003d\"https://github.com/vitest-dev/vitest/compare/v4.1.10...v4.1.11\"\u003eView changes on GitHub\u003c/a\u003e\u003c/h5\u003e\n\u003ch2\u003ev4.1.10\u003c/h2\u003e\n\u003ch3\u003e   🐞 Bug Fixes\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003ebrowser\u003c/strong\u003e: Check fs access in builtin commands [backport to v4]  -  by \u003ca href\u003d\"https://github.com/hi-ogawa\"\u003e\u003ccode\u003e\u003cat\u003e​hi-ogawa\u003c/code\u003e\u003c/a\u003e, \u003cstrong\u003eHiroshi Ogawa\u003c/strong\u003e and \u003cstrong\u003eOpenCode (claude-opus-4-8)\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10680\"\u003evitest-dev/vitest#10680\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/5c18dd267\"\u003e\u003c!-- raw HTML omitted --\u003e(5c18d)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003evm\u003c/strong\u003e: Fix external module resolve error with deps optimizer query for encoded URI [backport to v4]  -  by \u003ca href\u003d\"https://github.com/SveLil\"\u003e\u003ccode\u003e\u003cat\u003e​SveLil\u003c/code\u003e\u003c/a\u003e and \u003ca href\u003d\"https://github.com/hi-ogawa\"\u003e\u003ccode\u003e\u003cat\u003e​hi-ogawa\u003c/code\u003e\u003c/a\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10661\"\u003evitest-dev/vitest#10661\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/bae52b511\"\u003e\u003c!-- raw HTML omitted --\u003e(bae52)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5\u003e    \u003ca href\u003d\"https://github.com/vitest-dev/vitest/compare/v4.1.9...v4.1.10\"\u003eView changes on GitHub\u003c/a\u003e\u003c/h5\u003e\n\u003ch2\u003ev4.1.9\u003c/h2\u003e\n\u003ch3\u003e🐞 Bug Fixes\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eFix \u003ccode\u003eimportOriginal\u003c/code\u003e with optimizer and query import [backport to v4] - by \u003cstrong\u003eHiroshi Ogawa\u003c/strong\u003e, \u003cstrong\u003eDavid Harris\u003c/strong\u003e, \u003cstrong\u003eCodex\u003c/strong\u003eand \u003cstrong\u003eVladimir\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10546\"\u003evitest-dev/vitest#10546\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/a5180190c\"\u003e\u003c!-- raw HTML omitted --\u003e(a5180)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ebrowser\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003eWait for orchestrator readiness before resolving browser sessions [backport to v4] - by \u003cstrong\u003eVladimir\u003c/strong\u003e and \u003cstrong\u003eSéamus O\u0027Connor\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10555\"\u003evitest-dev/vitest#10555\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/7fb29651a\"\u003e\u003c!-- raw HTML omitted --\u003e(7fb29)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eWait for iframe tester readiness before preparing  [backport to v4] - by \u003cstrong\u003eVladimir\u003c/strong\u003e and \u003cstrong\u003eSéamus O\u0027Connor\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10497\"\u003evitest-dev/vitest#10497\u003c/a\u003e and \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10556\"\u003evitest-dev/vitest#10556\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/fbc626c40\"\u003e\u003c!-- raw HTML omitted --\u003e(fbc62)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003emocker\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003eHoist vi.mock() for vite-plus/test imports [backport to v4] - by \u003cstrong\u003eHiroshi Ogawa\u003c/strong\u003e, \u003cstrong\u003eLongYinan\u003c/strong\u003e, \u003cstrong\u003eClaude Opus 4.8\u003c/strong\u003e and \u003cstrong\u003eVladimir\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10548\"\u003evitest-dev/vitest#10548\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/2c9559c02\"\u003e\u003c!-- raw HTML omitted --\u003e(2c955)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003epool\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003ePrevent test run hang on worker crash  [backport to v4] - by \u003cstrong\u003eAri Perkkiö\u003c/strong\u003e and \u003cstrong\u003eJattioui Ismail\u003c/strong\u003e in \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10543\"\u003evitest-dev/vitest#10543\u003c/a\u003e and \u003ca href\u003d\"https://redirect.github.com/vitest-dev/vitest/issues/10564\"\u003evitest-dev/vitest#10564\u003c/a\u003e \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/934b0f587\"\u003e\u003c!-- raw HTML omitted --\u003e(934b0)\u003c!-- raw HTML omitted --\u003e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/compare/v4.1.8...v4.1.9\"\u003eView changes on GitHub\u003c/a\u003e\u003c/h5\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 href\u003d\"https://github.com/vitest-dev/vitest/commit/9bd8d464e6328c567c2dbcd8fdd977d57a9425c2\"\u003e\u003ccode\u003e9bd8d46\u003c/code\u003e\u003c/a\u003e chore: release v4.1.11 (\u003ca href\u003d\"https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10995\"\u003e#10995\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/9851dbc41c286a30abfb6b29cce65f3e5b7b40a1\"\u003e\u003ccode\u003e9851dbc\u003c/code\u003e\u003c/a\u003e fix(browser): trigger playwright/chromium gc on lower disk availability [back...\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/db616d227b6e0cb07a94f5d1bba262ee95db7e46\"\u003e\u003ccode\u003edb616d2\u003c/code\u003e\u003c/a\u003e chore: release v4.1.10 (\u003ca href\u003d\"https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10718\"\u003e#10718\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/bae52b5112a6fd8200101b88bf8af9685d077295\"\u003e\u003ccode\u003ebae52b5\u003c/code\u003e\u003c/a\u003e fix(vm): fix external module resolve error with deps optimizer query for enco...\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/a7a61e78c7d0718f00173cff6800a91a344457d4\"\u003e\u003ccode\u003ea7a61e7\u003c/code\u003e\u003c/a\u003e chore: release v4.1.9 (\u003ca href\u003d\"https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10598\"\u003e#10598\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/934b0f587cb61d8338d83f525295322692a2db40\"\u003e\u003ccode\u003e934b0f5\u003c/code\u003e\u003c/a\u003e fix(pool): prevent test run hang on worker crash (\u003ca href\u003d\"https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest/issues/10543\"\u003e#10543\u003c/a\u003e) [backport to v4] (#...\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/7fb29651afbae2a9b0cefe6c031a9308f168ac60\"\u003e\u003ccode\u003e7fb2965\u003c/code\u003e\u003c/a\u003e fix(browser): wait for orchestrator readiness before resolving browser sessio...\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/vitest-dev/vitest/commit/a5180190c1be7089e3705e3dd9e84fea118d09d3\"\u003e\u003ccode\u003ea518019\u003c/code\u003e\u003c/a\u003e fix: fix \u003ccode\u003eimportOriginal\u003c/code\u003e with optimizer and query import [backport to v4] (#...\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca href\u003d\"https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/vitest\"\u003ecompare view\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\nCloses #5470 from dependabot[bot]/dependabot/npm_and_yarn/zeppelin-web-angular/projects/zeppelin-react/vitest-4.1.11.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "d276aad3380cada5ee0e9bc8eb0ce0be18d07fcf",
      "tree": "1faef08f26f8d9bcf8d380113cc42d24f9d9b25d",
      "parents": [
        "006a3e157860a4ba18cd2210ac7bb7ff8a082e7f"
      ],
      "author": {
        "name": "Lee SuJung",
        "email": "153787023+xhaktm00@users.noreply.github.com",
        "time": "Thu Sep 10 20:27:37 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 20:27:37 2026 +0900"
      },
      "message": "[ZEPPELIN-6699] React remote CSV export omits the UTF-8 BOM that the Angular and classic paths write\n\n### What is this PR for?\r\nThe React remote builds its CSV export by hand and hands the string straight to a `Blob` with no UTF-8 BOM, so Excel reads it in the system code page and garbles non-ASCII data. The classic path prepends one through `saveAsService`, and the Angular path gets one from `XLSX.writeFile()`, so only this export was missing it. ZEPPELIN-672 added the BOM for exactly this reason.\r\n\r\n```diff\r\n- const blob \u003d new Blob([content], { type: \u0027text/plain;charset\u003dutf-8\u0027 });\r\n+ const BOM \u003d \u0027\\uFEFF\u0027;\r\n+ const blob \u003d new Blob([BOM, content], { type: \u0027text/plain;charset\u003dutf-8\u0027 });\r\n```\r\n\r\nThe xlsx branch is left alone, since that format carries its own encoding.\r\n\r\n### What type of PR is it?\r\nBug Fix\r\n\r\n### Todos\r\n* [x] Prepend the BOM in the React remote CSV export\r\n* [x] Add a regression test asserting the saved bytes\r\n\r\n### What is the Jira issue?\r\n* [ZEPPELIN-6699](https://issues.apache.org/jira/browse/ZEPPELIN-6699)\r\n\r\n### How should this be tested?\r\nNew spec `exportFile.spec.ts` mocks `file-saver` and inspects the bytes handed to `saveAs`, since `Blob.text()` decodes and drops a leading BOM.\r\n\r\n```\r\ncd zeppelin-web-angular/projects/zeppelin-react \u0026\u0026 npm test\r\n```\r\n\r\nResult: `Tests 1 failed | 67 passed (68)`. The one failure is `HTMLRenderer.spec.tsx \u003e highlights a code block`, which fails the same way on `origin/master` without this change. Running the new spec alone passes:\r\n\r\n```\r\nnpx vitest run src/utils/exportFile.spec.ts   → Tests 2 passed (2)\r\n```\r\n\r\nReverting only the production change makes it fail with `expected [ 110, 97, 109 ] to deeply equal [ 239, 187, 191 ]`, so it does catch the defect.\r\n\r\nManual: run a paragraph whose table result contains non-ASCII text, open the published paragraph with `?react\u003dtrue`, and choose \"Export all data as csv\". The file now starts with `EF BB BF` and opens in Excel with the text intact.\r\n\r\n### Screenshots (if appropriate)\r\nN/A\r\n\r\n### Questions:\r\n* Does the license files need to update? No\r\n* Is there breaking changes for older versions? No — the BOM only makes the React export match what the other two paths already write\r\n* Does this needs documentation? No\r\n\r\nNote: the issue scopes this to CSV and TSV, but the React remote has no TSV path, since `exportFile()` only takes `\u0027csv\u0027 | \u0027xlsx\u0027`. I\u0027ll file that parity gap separately; the BOM sits on the shared branch, so a TSV path added there inherits it.\n\nCloses #5466 from xhaktm00/ZEPPELIN-6699.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "006a3e157860a4ba18cd2210ac7bb7ff8a082e7f",
      "tree": "20ea22f93e663d934351cb9428f12e30b79aa560",
      "parents": [
        "07719fbf358b4bbe41da1d47e81f895870823c0d"
      ],
      "author": {
        "name": "김예나",
        "email": "101786858+kimyenac@users.noreply.github.com",
        "time": "Thu Sep 10 20:26:53 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 20:26:53 2026 +0900"
      },
      "message": "[ZEPPELIN-6643] Log out on session expiry instead of throwing in the interceptor\n\n### What is this PR for?\n\nThe New UI never logs out on session expiry. `AppHttpInterceptor` guards its 405 branch with `event.url.contains(\u0027logout\u0027)`, and JavaScript strings have no `contains` method, so the guard throws a `TypeError` inside `catchError` before `ticketService.logout()` is reached. Both statements after it are skipped: logout never runs, and the caller observes a `TypeError` instead of the 405 it needs to act on. The expired session stays in place until the user reloads the page by hand.\n\nThe guard\u0027s intent is right and is kept. It exists so that a 405 on the logout request itself does not call logout again, which would recurse. Only the method name changes:\n\n```diff\n-} else if (event.status \u003d\u003d\u003d 405 \u0026\u0026 !event.url.contains(\u0027logout\u0027)) {\n+} else if (event.status \u003d\u003d\u003d 405 \u0026\u0026 !event.url?.includes(\u0027logout\u0027)) {\n```\n\n`includes` is the method that exists. The optional chain covers `HttpErrorResponse.url` being `null`, which it is whenever the failure carries no resolved url, and which would otherwise throw at the same spot for a different reason. A 405 with no url cannot be identified as the logout call, so it falls through to logout — the same conclusion the branch already draws for every other request, and the safe one when the session is likely gone.\n\nThe 401 redirect branch is untouched.\n\nOut of scope, and left alone deliberately: the substring match means a 405 on a path that merely contains `logout` is also skipped, and the `catchError` parameter is untyped. Both belong to [ZEPPELIN-6469](https://issues.apache.org/jira/browse/ZEPPELIN-6469), which waits on this behaviour being correct first.\n\nThe spec constructs the interceptor directly with a `logout` stub rather than starting `TestBed`, per `zeppelin-web-angular/AGENTS.md`: no Angular wiring is under test here, only the branch. It pins three things the branch has to get right — a non-logout 405 calls logout exactly once, that 405 reaches the caller unchanged rather than replaced by a `TypeError`, and a 405 from the logout request itself does not call logout again — plus the null-url path.\n\n### What type of PR is it?\n\nBug Fix\n\n### Todos\n\nNone\n\n### What is the Jira issue?\n\n* https://issues.apache.org/jira/browse/ZEPPELIN-6643\n\n### How should this be tested?\n\n* `npm run test:shell` — 53 tests across 12 files, green. The four new ones are in `src/app/app-http.interceptor.spec.ts`.\n* The assertions were checked by breaking what they cover. Reverting the source line to `event.url.contains(\u0027logout\u0027)` fails three of the four, with `AssertionError: expected TypeError: event.url.contains is not a function to be HttpErrorResponse`. The fourth — the recursion guard — passes either way, because the `TypeError` also happens to prevent the logout call; it is there to confirm the guard survives the fix, not to reproduce the bug.\n* `npx prettier --check` on both files, clean. `npx eslint` on both reports only the two `prefer-arrow/prefer-arrow-functions` warnings that the named test helpers produce, the same two `src/app/services/save-as.service.spec.ts` already reports on master.\n* Not run locally: Playwright, and the production builds. Neither is reachable from this change — it is one expression in an interceptor plus a unit spec — but saying so rather than implying otherwise.\n\nManual reproduction, for a reviewer who wants to see the original failure: with an expired session, any REST call from the New UI answers 405 and the browser console shows `event.url.contains is not a function` from the interceptor, with no logout request following it. After this change the same 405 is followed by `POST /api/login/logout`.\n\n### Screenshots (if appropriate)\n\nNot applicable.\n\n### Questions:\n\n* Does the license files need to update? No\n* Is there breaking changes for older versions? No. The 405 branch did nothing but throw before this change, so nothing could have depended on it.\n* Does this needs documentation? No\n\n\nCloses #5464 from kimyenac/ZEPPELIN-6643.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    },
    {
      "commit": "07719fbf358b4bbe41da1d47e81f895870823c0d",
      "tree": "1c6613ee2755165ba49857d7f6ea3c6712e469e9",
      "parents": [
        "3c3c30331e93eb7f4bcaa01f6f26758726540c77"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Thu Sep 10 19:55:54 2026 +0900"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 19:55:54 2026 +0900"
      },
      "message": "Bump js-yaml from 4.3.1 to 4.3.2 in /zeppelin-web-angular/projects/zeppelin-react\n\nBumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.1 to 4.3.2.\n\u003cdetails\u003e\n\u003csummary\u003eChangelog\u003c/summary\u003e\n\u003cp\u003e\u003cem\u003eSourced from \u003ca href\u003d\"https://github.com/nodeca/js-yaml/blob/4.3.2/CHANGELOG.md\"\u003ejs-yaml\u0027s changelog\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003ch2\u003e4.3.2 - 2026-08-26\u003c/h2\u003e\n\u003ch3\u003eChanged\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e[backport] Hard-limit merge sequence size to 100.\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eSecurity\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e[backport] Count empty mappings in merge sequences toward \u003ccode\u003emaxTotalMergeKeys\u003c/code\u003e\nto limit CPU usage, \u003ca href\u003d\"https://redirect.github.com/nodeca/js-yaml/issues/797\"\u003e#797\u003c/a\u003e.\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 href\u003d\"https://github.com/nodeca/js-yaml/commit/79ca68d90f333fbe6d9e42827527e62636200191\"\u003e\u003ccode\u003e79ca68d\u003c/code\u003e\u003c/a\u003e 4.3.2 released\u003c/li\u003e\n\u003cli\u003e\u003ca href\u003d\"https://github.com/nodeca/js-yaml/commit/d90b6612a5a84385bdcb556c44578eac76dc0f6b\"\u003e\u003ccode\u003ed90b661\u003c/code\u003e\u003c/a\u003e Backport merge limits from v5.4.1\u003c/li\u003e\n\u003cli\u003eSee full diff in \u003ca href\u003d\"https://github.com/nodeca/js-yaml/compare/4.3.1...4.3.2\"\u003ecompare view\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/details\u003e\n\u003cbr /\u003e\n\n\n[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name\u003djs-yaml\u0026package-manager\u003dnpm_and_yarn\u0026previous-version\u003d4.3.1\u0026new-version\u003d4.3.2)](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 alter it yourself. You can also trigger a rebase manually by commenting `\u003cat\u003edependabot 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- `\u003cat\u003edependabot rebase` will rebase this PR\n- `\u003cat\u003edependabot recreate` will recreate this PR, overwriting any edits that have been made to it\n- `\u003cat\u003edependabot show \u003cdependency name\u003e ignore conditions` will show all of the ignore conditions of the specified dependency\n- `\u003cat\u003edependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)\n- `\u003cat\u003edependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)\n- `\u003cat\u003edependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)\nYou can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/apache/zeppelin/network/alerts).\n\n\u003c/details\u003e\n\nCloses #5471 from dependabot[bot]/dependabot/npm_and_yarn/zeppelin-web-angular/projects/zeppelin-react/js-yaml-4.3.2.\n\nSigned-off-by: YONGJAE LEE \u003cdev.yongjaelee@gmail.com\u003e"
    }
  ],
  "next": "3c3c30331e93eb7f4bcaa01f6f26758726540c77"
}
