Skip to content

fix(clp-package)!: Restore zstd-compressed job configs#2375

Open
junhaoliao wants to merge 7 commits into
y-scope:mainfrom
junhaoliao:feat/reverse-compression-zstd
Open

fix(clp-package)!: Restore zstd-compressed job configs#2375
junhaoliao wants to merge 7 commits into
y-scope:mainfrom
junhaoliao:feat/reverse-compression-zstd

Conversation

@junhaoliao

@junhaoliao junhaoliao commented Jul 9, 2026

Copy link
Copy Markdown
Member

Description

Reverts the compression-job config payload format change from Brotli back to zstd across the CLP package job-submission path.

Breaking change

Warning

Existing package SQL databases may contain compression_jobs.clp_config values written as Brotli-compressed MessagePack by older package builds. After this change, the WebUI decodes compression-job metadata as zstd-compressed MessagePack, so those historical compression-job rows must be migrated if operators need them to remain displayable in the Ingest page.

This updates the native package compressor, job-orchestration schedulers, Rust log-ingestor submission path, and WebUI server submission/metadata decoding to write/read zstd-compressed MessagePack again. Rust zstd support uses trifectatechfoundation/libzstd-rs-sys, with the unsafe FFI usage isolated in a small helper.

The WebUI server path now stores zstd job configs directly through CompressionJobDbManager.create(fastify), matching the pre-existing factory API. The API server was checked as well: it reads compression usage metadata but does not submit compression_jobs.clp_config; the relevant Rust submitter is the log-ingestor, which is updated here.

Migration

Pause compression-job submissions until the migration is complete.

Run these commands from a host that can reach the package SQL database, replacing the values below with its connection details:

export CLP_DB_HOST=127.0.0.1
export CLP_DB_PORT=3306
export CLP_DB_USER=clp-user
export CLP_DB_PASS='<password>'
export CLP_DB_NAME=clp-db

Save the following as migrate-compression-jobs.py:

#!/usr/bin/env -S uv run --script
#
# /// script
# requires-python = ">=3.10"
# dependencies = [
#   "brotli==1.2.0",
#   "pymysql==1.1.2",
#   "zstandard==0.25.0",
# ]
# ///

import argparse
import base64
import json
import os
from pathlib import Path

import brotli
import pymysql
import zstandard as zstd

parser = argparse.ArgumentParser()
parser.add_argument("operation", choices=("dump", "restore"))
parser.add_argument("--file", type=Path, default=Path("compression-jobs.json"))
args = parser.parse_args()

db = pymysql.connect(
    host=os.environ["CLP_DB_HOST"],
    port=int(os.environ["CLP_DB_PORT"]),
    user=os.environ["CLP_DB_USER"],
    password=os.environ["CLP_DB_PASS"],
    database=os.environ["CLP_DB_NAME"],
)

if "dump" == args.operation:
    with db.cursor() as cursor:
        cursor.execute("SELECT id, clp_config FROM compression_jobs")
        rows = [
            {
                "id": job_id,
                "msgpack": base64.b64encode(brotli.decompress(config)).decode("ascii"),
            }
            for job_id, config in cursor.fetchall()
        ]
    args.file.write_text(json.dumps(rows), encoding="utf-8")
    action = "Dumped"
else:
    rows = json.loads(args.file.read_text(encoding="utf-8"))
    compressor = zstd.ZstdCompressor(level=3)
    with db.cursor() as cursor:
        cursor.executemany(
            "UPDATE compression_jobs SET clp_config=%s WHERE id=%s",
            [
                (compressor.compress(base64.b64decode(row["msgpack"])), row["id"])
                for row in rows
            ],
        )
    db.commit()
    action = "Migrated"

db.close()
print(f"{action} {len(rows)} compression job(s).")

Then dump before upgrading and restore after starting the new package:

chmod +x migrate-compression-jobs.py
./migrate-compression-jobs.py dump
# Upgrade and start the new package.
./migrate-compression-jobs.py restore

This updates only clp_config, preserving job IDs and metadata without truncating compression_jobs, which is referenced by compression_tasks.

query_jobs.job_config is raw MessagePack rather than Brotli/zstd-compressed MessagePack, so search-job rows do not need this codec migration.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • task lint:fix-rust

    Checking clp-rust-utils v0.13.1-dev (/home/junhao/workspace/5-clp/components/clp-rust-utils)
    Checking log-ingestor v0.13.1-dev (/home/junhao/workspace/5-clp/components/log-ingestor)
    Checking api-server v0.13.1-dev (/home/junhao/workspace/5-clp/components/api-server)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.81s
    
  • task deps:lock:check-rust

    task: [deps:lock:cargo-workspace-fetch] . "/home/junhao/workspace/5-clp/build/toolchains/rust/env"
    cargo fetch --locked
    
  • task lint:check-rust

    cargo +nightly fmt --all -- --check
    cargo +nightly clippy --all-targets --all-features -- -D warnings
    Checking clp-rust-utils v0.13.1-dev (/home/junhao/workspace/5-clp/components/clp-rust-utils)
    Checking log-ingestor v0.13.1-dev (/home/junhao/workspace/5-clp/components/log-ingestor)
    Checking api-server v0.13.1-dev (/home/junhao/workspace/5-clp/components/api-server)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.12s
    
  • task lint:fix-js

    Tasks:    4 successful, 4 total
    Cached:    4 cached, 4 total
    
  • task

    #32 DONE 8.0s
    task: [package] echo '0.13.1-dev' > '/home/junhao/workspace/5-clp/build/clp-package/VERSION'
    
  • task tests:rust-all

    Summary [  13.071s] 33 tests run: 33 passed, 0 skipped
    
  • task tests:integration:clp-py-project-imports

    tests/test_clp_native_py_project_imports.py::test_clp_native_py_project_enum_classes PASSED
    ============================== 1 passed in 0.02s ===============================
    
  • pnpm --filter @webui/server test

    # { total: 12, pass: 12 }
    # time=774.123ms
    
  • pnpm --filter @webui/server build

    $ tsc
    
  • git diff --check c6e14789f..HEAD

    No output, exit 0.

  • Package integration, JSON flavour:

    CLP_BUILD_DIR=/home/junhao/workspace/clp/build \
    CLP_CORE_BINS_DIR=/home/junhao/workspace/clp/build/core \
    CLP_PACKAGE_DIR=/home/junhao/workspace/clp/build/clp-package \
    uv run pytest -m package tests/package_tests/clp_json --base-port 56000
    tests/package_tests/clp_json/test_clp_json.py::test_clp_json_startstop[clp-json] PASSED
    tests/package_tests/clp_json/test_clp_json.py::test_clp_json_compression_json_multifile[clp-json] PASSED
    tests/package_tests/clp_json/test_clp_json.py::test_clp_json_compression_text_multifile[clp-json] PASSED
    tests/package_tests/clp_json/test_clp_json.py::test_clp_json_search[clp-json] PASSED
    ============================== 4 passed in 35.60s ==============================
    
  • Package integration, text flavour:

    CLP_BUILD_DIR=/home/junhao/workspace/clp/build \
    CLP_CORE_BINS_DIR=/home/junhao/workspace/clp/build/core \
    CLP_PACKAGE_DIR=/home/junhao/workspace/clp/build/clp-package \
    uv run pytest -m package tests/package_tests/clp_text --base-port 56200
    tests/package_tests/clp_text/test_clp_text.py::test_clp_text_startstop[clp-text] PASSED
    tests/package_tests/clp_text/test_clp_text.py::test_clp_text_compression_text_multifile[clp-text] PASSED
    ============================== 2 passed in 34.69s ==============================
    
  • Package smoke start:

    Container clp-package-0e650871-51b6-4f3b-9a9c-8673f1e2a4b5-api-server-1 Healthy
    Container clp-package-0e650871-51b6-4f3b-9a9c-8673f1e2a4b5-results-cache-1 Healthy
    Container clp-package-0e650871-51b6-4f3b-9a9c-8673f1e2a4b5-database-1 Healthy
    2026-07-09T12:11:30.232 INFO [controller] Started CLP.
    
  • Package smoke compression:

    2026-07-09T12:11:38.295 INFO [compress] Compression job 4 submitted.
    2026-07-09T12:11:38.796 INFO [compress] Compressed 1.80KB into 1.28KB (1.41x). Speed: 4.29KB/s.
    2026-07-09T12:11:39.297 INFO [compress] Compression finished.
    2026-07-09T12:11:39.297 INFO [compress] Compressed 1.80KB into 1.28KB (1.41x). Speed: 3.30KB/s.
    
  • Package smoke stop:

    Network clp-package-0e650871-51b6-4f3b-9a9c-8673f1e2a4b5_default Removed
    2026-07-09T12:12:08.246 INFO [controller] Stopped CLP.
    
  • Legacy Brotli-to-zstd migration smoke:

    Built and started the old package from origin/main, then used playwright-cli against http://127.0.0.1:4000/ingest to submit one compression job and one search query through the WebUI server APIs:

    /api/compress -> 201 {"jobId":1}
    /api/search/query -> 201 {"searchJobId":1,"aggregationJobId":2}
    /api/compress-metadata -> 200, decoded dataset "migration_brotli"
    

    Dumped the old Brotli compression_jobs row with a one-off uv Python migration helper:

    Dumped 1 Brotli compression job row(s) to /tmp/clp-brotli-compression-jobs.json.
    

    Rebuilt and started the new zstd package, restored the dump as zstd, and verified the SQL payloads:

    Restored 1 compression job row(s) as zstd.
    Verified 1 zstd compression job row(s).
    

    Reopened the new WebUI with playwright-cli; /api/compress-metadata returned 200 with the restored migration_brotli job, the Ingest table displayed the restored succeeded row, and playwright-cli console reported:

    Total messages: 0 (Errors: 0, Warnings: 0)
    

Summary by CodeRabbit

  • Improvements

    • Compression metadata and job configurations now use Zstandard-compressed MessagePack data, improving consistency across services.
    • Compression job scheduling, ingestion, and metadata decoding now support the updated format.
    • Improved handling of invalid data and numeric conversion errors provides clearer job failures.
  • Bug Fixes

    • Fixed configuration serialization and deserialization across compression workflows.
    • Added validation to ensure compressed data is correctly recognized and decoded.
  • Tests

    • Added coverage for valid, missing, and invalid compression metadata and job configurations.

…ion-zstd

# Conflicts:
#	components/log-ingestor/src/ingestion_job_manager/clp_ingestion.rs
@junhaoliao
junhaoliao requested a review from a team as a code owner July 9, 2026 12:14
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR switches compression job configuration storage and retrieval from Brotli-compressed MessagePack to Zstandard-compressed MessagePack across Rust, Python, and web UI components. It also updates dependencies, error handling, overflow handling, and validation tests.

Changes

Brotli-to-Zstandard migration

Layer / File(s) Summary
Rust zstd_msgpack module and error handling
components/clp-rust-utils/Cargo.toml, components/clp-rust-utils/src/error.rs, components/clp-rust-utils/src/serde.rs, components/clp-rust-utils/src/serde/zstd_msgpack.rs, components/clp-rust-utils/src/serde/brotli_msgpack.rs, components/clp-rust-utils/tests/clp_config_test.rs
Adds ZstdMsgpack, adds Error::Zstd, removes BrotliMsgpack, updates re-exports and dependencies, and validates MessagePack and JSON representations.
Rust consumers of ZstdMsgpack
components/api-server/src/error.rs, components/log-ingestor/src/ingestion_job_manager/clp_ingestion.rs
Maps Zstandard errors to malformed-data client errors, switches ingestion job configuration serialization to Zstandard, and makes submitted-count conversion fallible.
Python zstd_msgpack utility and dependencies
components/clp-py-utils/clp_py_utils/zstd_msgpack.py, components/clp-py-utils/pyproject.toml
Adds per-thread Zstandard MessagePack serialization and deserialization helpers with their runtime dependencies.
Python job scheduling and packaging consumers
components/job-orchestration/..., components/clp-package-utils/..., components/job-orchestration/pyproject.toml, components/clp-package-utils/pyproject.toml
Replaces Brotli and direct MessagePack calls with Zstandard MessagePack helpers and removes Brotli dependencies.
Web UI compression job config lifecycle
components/webui/packages/server/src/plugins/app/CompressionJobDbManager/index.ts, components/webui/packages/server/src/routes/api/compress-metadata/utils.ts, components/webui/packages/server/src/test/*
Switches database insertion and metadata decoding to Zstandard and tests persisted payloads, decoding, invalid input, and metadata mapping.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LogIngestor
  participant ZstdMsgpack
  participant CompressionJobsTable
  participant CompressionScheduler
  participant WebUIServer

  LogIngestor->>ZstdMsgpack: serialize(io_config)
  ZstdMsgpack-->>LogIngestor: compressed job config bytes
  LogIngestor->>CompressionJobsTable: insert compressed clp_config
  CompressionScheduler->>CompressionJobsTable: load job_row.clp_config
  CompressionScheduler->>ZstdMsgpack: deserialize compressed config
  ZstdMsgpack-->>CompressionScheduler: ClpIoConfig
  WebUIServer->>CompressionJobsTable: load compression metadata
  WebUIServer->>WebUIServer: zstdDecompressSync and decode
Loading

Possibly related PRs

  • y-scope/clp#2369: Both PRs modify components/log-ingestor/src/ingestion_job_manager/clp_ingestion.rs in submit_for_compression; this PR changes serialization format while the related PR changes transaction isolation and update batching.

Suggested reviewers: linzhihao-723, hoophalab, jonathan-imanu

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: restoring zstd-compressed job configs across the package.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@components/clp-rust-utils/src/serde/zstd_msgpack.rs`:
- Around line 43-45: The zstd failure mapping in zstd_error currently only
formats the numeric result into Error::Zstd, which loses the real failure
reason. Update zstd_error to look up the human-readable zstd error name using
ZSTD_getErrorName and include that string in the Error::Zstd message, keeping
the existing Error::Zstd conversion path but replacing the generic "error code
{result}" text with the zstd-provided error name.

In
`@components/webui/packages/server/src/plugins/app/CompressionJobDbManager/index.ts`:
- Around line 1-26: The server package uses node:zlib zstd APIs in
CompressionJobDbManager, but no minimum Node version is declared for the
webui/server runtime. Add an engines.node floor of 22.15+ in either
components/webui/package.json or components/webui/packages/server/package.json
so the server cannot start on an unsupported Node version, and keep the change
aligned with the CompressionJobDbManager/index.ts usage of zstdCompressSync and
ZstdOptions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 736c0734-8064-4b12-91cf-fe1d4a3ed7db

📥 Commits

Reviewing files that changed from the base of the PR and between 6ed4fff and 1a15ef1.

⛔ Files ignored due to path filters (6)
  • Cargo.lock is excluded by !**/*.lock
  • components/clp-mcp-server/uv.lock is excluded by !**/*.lock
  • components/clp-package-utils/uv.lock is excluded by !**/*.lock
  • components/clp-py-utils/uv.lock is excluded by !**/*.lock
  • components/job-orchestration/uv.lock is excluded by !**/*.lock
  • integration-tests/uv.lock is excluded by !**/*.lock
📒 Files selected for processing (19)
  • components/api-server/src/error.rs
  • components/clp-package-utils/clp_package_utils/scripts/native/compress.py
  • components/clp-package-utils/pyproject.toml
  • components/clp-py-utils/clp_py_utils/zstd_msgpack.py
  • components/clp-py-utils/pyproject.toml
  • components/clp-rust-utils/Cargo.toml
  • components/clp-rust-utils/src/error.rs
  • components/clp-rust-utils/src/serde.rs
  • components/clp-rust-utils/src/serde/brotli_msgpack.rs
  • components/clp-rust-utils/src/serde/zstd_msgpack.rs
  • components/clp-rust-utils/tests/clp_config_test.rs
  • components/job-orchestration/job_orchestration/scheduler/compress/compression_scheduler.py
  • components/job-orchestration/job_orchestration/scheduler/compress/partition.py
  • components/job-orchestration/pyproject.toml
  • components/log-ingestor/src/ingestion_job_manager/clp_ingestion.rs
  • components/webui/packages/server/src/plugins/app/CompressionJobDbManager/index.ts
  • components/webui/packages/server/src/routes/api/compress-metadata/utils.ts
  • components/webui/packages/server/src/test/compressMetadataUtils.test.ts
  • components/webui/packages/server/src/test/compressionJobDbManager.test.ts
💤 Files with no reviewable changes (3)
  • components/job-orchestration/pyproject.toml
  • components/clp-package-utils/pyproject.toml
  • components/clp-rust-utils/src/serde/brotli_msgpack.rs

Comment thread components/clp-rust-utils/src/serde/zstd_msgpack.rs
Comment on lines +1 to +26
import {
constants as zlibConstants,
zstdCompressSync,
type ZstdOptions,
} from "node:zlib";

import type {MySQLPromisePool} from "@fastify/mysql";
import {encode} from "@msgpack/msgpack";
import {ClpIoConfig} from "@webui/common/schemas/compression";
import {FastifyInstance} from "fastify";
import type {ClpIoConfig} from "@webui/common/schemas/compression";
import type {FastifyInstance} from "fastify";
import fp from "fastify-plugin";
import {ResultSetHeader} from "mysql2";
import type {ResultSetHeader} from "mysql2";

import {publicSettings} from "../../../settings.js";
import {COMPRESSION_JOBS_TABLE_COLUMN_NAMES} from "../../../typings/compression.js";


const ZSTD_COMPRESSION_LEVEL = 3;

const ZSTD_COMPRESSION_OPTIONS: ZstdOptions = {
params: {
[zlibConstants.ZSTD_c_compressionLevel]: ZSTD_COMPRESSION_LEVEL,
},
};


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for Node.js version requirements in the webui server package and repo root.
fd -t f -H '(package\.json|\.nvmrc|\.node-version|Dockerfile)' components/webui . --max-depth 3 2>/dev/null | head -20

# Show engines field and any Node version pinning
rg -n --glob 'package.json' '"engines"|"node"' components/webui/packages/server/ . --max-depth 1 2>/dev/null | head -20
rg -n 'node' .nvmrc .node-version 2>/dev/null

Repository: y-scope/clp

Length of output: 349


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package.json files =="
sed -n '1,220p' components/webui/package.json
echo
sed -n '1,220p' components/webui/packages/server/package.json
echo
sed -n '1,220p' components/webui/packages/client/package.json
echo
sed -n '1,220p' components/webui/packages/common/package.json
echo
echo "== version pin files =="
fd -H -t f '(^\.nvmrc$|^\.node-version$|^Dockerfile$|^package\.json$|^\.tool-versions$|^volta\.json$)' components/webui . 2>/dev/null | sort
echo
echo "== node version mentions =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' '\b(node\s*:?|\bnode\b|v22\.|v20\.|v18\.)' components/webui .github .gitlab-ci.yml azure-pipelines.yml 2>/dev/null | head -200

Repository: y-scope/clp

Length of output: 22625


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== top-level and webui Node version declarations =="
fd -H -t f '(^\.nvmrc$|^\.node-version$|^\.tool-versions$|^package\.json$|^Dockerfile$|^docker-compose.*\.ya?ml$|^.*\.yml$|^.*\.yaml$|^.*\.json$)' . \
  | rg '(^|/)(\.nvmrc|\.node-version|\.tool-versions|package\.json|Dockerfile|.*\.ya?ml|.*\.json)$' \
  | head -300

echo
echo "== engines/node fields in likely config files =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  '"engines"\s*:|"\bnode\b"\s*:|node\s+[0-9]+\.[0-9]+\.[0-9]+|FROM\s+node:|runtime-?version|NODE_VERSION|engines:' \
  .github components/webui components/core tools 2>/dev/null | head -300

echo
echo "== webui CI/workflow files =="
fd -H -t f '.github/workflows' . 2>/dev/null
rg -n --hidden --glob '.github/workflows/*' 'node|pnpm|setup-node|actions/setup-node|22\.|20\.' .github/workflows components/webui 2>/dev/null | head -300

echo
echo "== repo root package and version files =="
for f in package.json .nvmrc .node-version .tool-versions; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,220p' "$f"
  fi
done

Repository: y-scope/clp

Length of output: 28450


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow files =="
fd -H -t f .github/workflows . 2>/dev/null | sort

echo
echo "== node-related workflow lines =="
for f in $(fd -H -t f .github/workflows . 2>/dev/null); do
  echo "--- $f ---"
  rg -n 'setup-node|node-version|actions/setup-node|pnpm|22\.|20\.|18\.' "$f" || true
done

echo
echo "== root docs mentioning Node version =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  '\bNode\.?js\b|\bnode version\b|\bminimum Node\b|\bNode 22\b|\bNode 20\b' \
  README* docs components/webui components .github 2>/dev/null | head -300

Repository: y-scope/clp

Length of output: 170


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== github workflows and node pins =="
fd -H -t f '.github/workflows' . 2>/dev/null | sort | while read -r f; do
  echo "--- $f ---"
  sed -n '1,220p' "$f" | rg -n 'setup-node|node-version|node-version-file|pnpm|22\.|20\.|18\.' || true
done

echo
echo "== other repo-wide version pins =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  'setup-node|node-version-file|node-version:|volta|fnm|nvm|asdf|20\.19|22\.15|22\.19|22\.0' \
  . 2>/dev/null | head -300

Repository: y-scope/clp

Length of output: 186


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== search for explicit Node version pins in repo configs =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  'setup-node|node-version-file|node-version:|engines:|\"engines\"|\.nvmrc|\.node-version|\.tool-versions|NODE_VERSION|runtime-version|node22|Node 22|22\.15\.0|22\.19\.7' \
  .github components/webui taskfile.yaml taskfiles tools 2>/dev/null | head -300

echo
echo "== .github files list =="
fd -H -t f . .github 2>/dev/null | sort | head -200

echo
echo "== webui taskfiles and package manifests containing node/version refs =="
for f in components/webui/package.json components/webui/packages/server/package.json components/webui/packages/server/tsconfig.json components/webui/pnpm-workspace.yaml components/webui/turbo.json taskfile.yaml; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,220p' "$f"
    echo
  fi
done

Repository: y-scope/clp

Length of output: 209


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== explicit Node pins and setup-node usages =="
rg -n --hidden --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
  'actions/setup-node|setup-node|node-version|node-version-file|engines|\.nvmrc|\.node-version|\.tool-versions|NODE_VERSION|node22|22\.15\.0|22\.19\.7' \
  .github components/webui taskfile.yaml taskfiles tools 2>/dev/null | head -300

echo
echo "== files under .github =="
find .github -maxdepth 3 -type f | sort | head -200

Repository: y-scope/clp

Length of output: 22974


Add a Node 22.15+ engine floor for the server
node:zlib zstd APIs need Node 22.15+, but the webui manifests don’t declare a minimum engines.node version. Add one in components/webui/package.json or components/webui/packages/server/package.json so this service can’t be started on an unsupported runtime.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@components/webui/packages/server/src/plugins/app/CompressionJobDbManager/index.ts`
around lines 1 - 26, The server package uses node:zlib zstd APIs in
CompressionJobDbManager, but no minimum Node version is declared for the
webui/server runtime. Add an engines.node floor of 22.15+ in either
components/webui/package.json or components/webui/packages/server/package.json
so the server cannot start on an unsupported Node version, and keep the change
aligned with the CompressionJobDbManager/index.ts usage of zstdCompressSync and
ZstdOptions.

aws-sdk-s3 = "1.121.0"
aws-sdk-sqs = "1.92.0"
brotli = "8.0.2"
libzstd-rs-sys = "0.0.1-prerelease.2"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reason choosing this over zstd-rs

the maintainer org of this libzstd-rs-sys seems much more reputable than https://github.com/gyscos/zstd-rs

@junhaoliao junhaoliao changed the title fix(clp-package): Restore zstd-compressed job configs fix(clp-package): Restore zstd-compressed job configs. Jul 9, 2026
@junhaoliao junhaoliao changed the title fix(clp-package): Restore zstd-compressed job configs. fix(clp-package)!: Restore zstd-compressed job configs Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants