From 95ba377cb766909ac74895ee28675e920470c173 Mon Sep 17 00:00:00 2001 From: garrytan Date: Sat, 31 Oct 2026 18:04:59 +0000 Subject: [PATCH] ci: oxlint correctness rules held to a shrink-only ratchet, run in the typecheck job (GSTA-203 PR 4) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- .github/workflows/free-tests.yml | 2 + .oxlintrc.json | 7 + bun.lock | 41 ++ package.json | 2 + scripts/lint-baseline.json | 640 ++++++++++++++++++++++++ scripts/lint-ratchet.ts | 192 +++++++ test/free-tests-workflow-wiring.test.ts | 2 +- test/lint-ratchet.test.ts | 148 ++++++ 8 files changed, 1033 insertions(+), 1 deletion(-) create mode 100644 .oxlintrc.json create mode 100644 scripts/lint-baseline.json create mode 100755 scripts/lint-ratchet.ts create mode 100644 test/lint-ratchet.test.ts diff --git a/.github/workflows/free-tests.yml b/.github/workflows/free-tests.yml index 443888a40..b71417878 100644 --- a/.github/workflows/free-tests.yml +++ b/.github/workflows/free-tests.yml @@ -259,6 +259,8 @@ jobs: run: bun run typecheck - name: Test-code type-debt ratchet run: bun run typecheck:test + - name: oxlint ratchet (correctness rules) + run: bun run lint - name: CSO source formatting run: bun run format:cso:check diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 000000000..d7dbb7dc2 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "categories": { + "correctness": "error" + }, + "ignorePatterns": ["design-html/vendor/**", "test/fixtures/**"] +} diff --git a/bun.lock b/bun.lock index 30f33b2fb..e7221c14c 100644 --- a/bun.lock +++ b/bun.lock @@ -22,6 +22,7 @@ "devDependencies": { "@anthropic-ai/claude-agent-sdk": "0.2.141", "@types/bun": "1.4.3", + "oxlint": "1.90.0", "prettier": "3.9.10", "typescript": "7.0.2", }, @@ -165,6 +166,44 @@ "@oozcitak/util": ["@oozcitak/util@8.3.4", "", {}, "sha512-6gH/bLQJSJEg7OEpkH4wGQdA8KXHRbzL1YkGyUO12YNAgV3jxKy4K9kvfXj4+9T0OLug5k58cnPCKSSIKzp7pg=="], + "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.90.0", "", { "os": "android", "cpu": "arm" }, "sha512-sgfalb1HuxYjiAa4wESZ626z1FGusqNcXYHyB5oIOEprS2sbPg0UYEfo83uF1GNG70DIfZxHkXuE6KFrlSdn8Q=="], + + "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.90.0", "", { "os": "android", "cpu": "arm64" }, "sha512-RcKhz1ETMq+fazE9TKS2+5NIRGwigm/nW8egqF0LI+A8Yw2iW5r0E/C3XAPRiwIm/vcPiutIRIa6IQCIKhZsTQ=="], + + "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.90.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PSrxMvP6mx+p1karZcUxLdy9lpaP+JWQPti4al9FgTaPhxE+pT/BjhGExloVVSWgZgIfOlLOjVyyq8BXlodhLQ=="], + + "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.90.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-OLbU9qsrV2Q8QxT2OEzOPdO8zCCpyI8qB+hDI8yr6RsYELtkf0FAZhJdfjM/RnLHKzt44HWwAPnk92vBtKofvw=="], + + "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.90.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fBA4pWyVDARmNucQqpyFuPC49xYf1r+sX7dxPL5fNPQrSMLum39Sn56tZ9JPleWC7FzLPwSQ7plYYfirYBHF8A=="], + + "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.90.0", "", { "os": "linux", "cpu": "arm" }, "sha512-zhxH78eP2nR6/pGdhBc7MIfjhhcgATeu8fkmkFJbuzfk6Cj0FzBxyEhL85yDqrCybjx+G2YDzZGsxIO9kvO4Iw=="], + + "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.90.0", "", { "os": "linux", "cpu": "arm" }, "sha512-MvYmpHyJqUJjEvkZbJHdwfdL45cGn8EVBkYmoXFiaYFW9suoD3dbJl5mBdpy0DVgdjlyddmldbRtk3cCgETadQ=="], + + "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.90.0", "", { "os": "linux", "cpu": "arm64", "libc": "glibc" }, "sha512-L13Sy+Kg0nZhwTsToniqjUFPA2TuM6962qCZ5Wp5KeB517Tw7ApdLTTtlb+bF86fcZZa2EtvCVvAJxk4Dya/MQ=="], + + "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.90.0", "", { "os": "linux", "cpu": "arm64", "libc": "musl" }, "sha512-wFDdZWGpzIPFdJFjSLWnKB0TGzFriTKUIrl04iMqMyM9BBIJTuerfCHYa0WpDSjr5x3lcW/CHLyacSt886WpGg=="], + + "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.90.0", "", { "os": "linux", "cpu": "ppc64", "libc": "glibc" }, "sha512-FRywfn+MoKn8xpBSzgNwNVliSKRI2QXkxi/iF7o6FEQs8Bh8z2RpVTaFAcO3pchXjvB2eGNFIoLLQABIQ+u7VA=="], + + "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.90.0", "", { "os": "linux", "cpu": "none", "libc": "glibc" }, "sha512-IS2PaUgpc/qeLADTyhUNmdx3x4ijs9pjJdPKBYHaT+mAE7k3FsjnHPTjhpsak1b++h6CIPhv6WX9Z+y7Pw0voQ=="], + + "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.90.0", "", { "os": "linux", "cpu": "none", "libc": "musl" }, "sha512-s7JFKRkGS8O7i2ZVODfuO++NC7sH6HDqpMn8lYxw91w0SXJOxnAVjQ8utvmDwLMMT0jaSkuOKuUYJDGDtu4sHQ=="], + + "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.90.0", "", { "os": "linux", "cpu": "s390x", "libc": "glibc" }, "sha512-b0GxrOQr5VONCkd7KLSqmP6b6nqZuTpuS8QPQHzltmqdXP5bY0Jl0CZ0QmlCTrS3ExaLYbioFYOARzNbYvcApQ=="], + + "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.90.0", "", { "os": "linux", "cpu": "x64", "libc": "glibc" }, "sha512-iaJeShJtgUp8rZbt9YUdTAGOpmX5KogCLba17Jp1tWdJ3F4M3D2g2TKUyI1FMTHxKH9NNHuQcuC2kZRg6IV7yQ=="], + + "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.90.0", "", { "os": "linux", "cpu": "x64", "libc": "musl" }, "sha512-/aZoXnL5WBLCXuzfHqvEFXcm4iwYmr/cYByHDTXzLFzJdE5DC7bm6phpWqHv6BeqpVgY9IpBAxGDv2WEkl5JCg=="], + + "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.90.0", "", { "os": "none", "cpu": "arm64" }, "sha512-SMhk7ozwoxYDKfYqGZCQEfULOKDneF9uhaoIf2neoDLWvNtjY9yVeL7YHmE5L9WdKvMpWNwwZxhenxBu6AgfOg=="], + + "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.90.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-KBvR3A9fO7fCi2vCP8ifWvlia7tGEQV9NaYh+IGwa/7Groy48Mt/UaYqMK9/zOtAWl20BUCf6RPqzJ32fRw33Q=="], + + "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.90.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-+x42rDHQGbTCuT3EzpWAzhP3NoVPE/cJsG4gnrakOSg0olV+GCdMpPU23Nvrl3zZMnXxFZdTtDv4D3SuaA5ZeQ=="], + + "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.90.0", "", { "os": "win32", "cpu": "x64" }, "sha512-30JiaFEBUB9peEOcvVM8ggo88SoN/IdSr9DW505JdBji/R6dM66gKEiG65hw6qcaF2f4mO0cEJ+RwRZprmun9g=="], + "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], "@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="], @@ -455,6 +494,8 @@ "onnxruntime-web": ["onnxruntime-web@1.31.0-dev.20260914-8d85527a0", "", { "dependencies": { "flatbuffers": "^25.1.24", "guid-typescript": "^1.0.9", "long": "^5.2.3", "onnxruntime-common": "1.31.0-dev.20260911-2a43ec07e", "platform": "^1.3.6", "protobufjs": "^7.2.4" } }, "sha512-Iy7rtadoBgxS/LLvDr3QW38DB1PNXRnr0GJMcL0TAt7c9qjgVQl83UlGCVyeAnK2InpmW8Uc3PL8XIuqtDeF6g=="], + "oxlint": ["oxlint@1.90.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.90.0", "@oxlint/binding-android-arm64": "1.90.0", "@oxlint/binding-darwin-arm64": "1.90.0", "@oxlint/binding-darwin-x64": "1.90.0", "@oxlint/binding-freebsd-x64": "1.90.0", "@oxlint/binding-linux-arm-gnueabihf": "1.90.0", "@oxlint/binding-linux-arm-musleabihf": "1.90.0", "@oxlint/binding-linux-arm64-gnu": "1.90.0", "@oxlint/binding-linux-arm64-musl": "1.90.0", "@oxlint/binding-linux-ppc64-gnu": "1.90.0", "@oxlint/binding-linux-riscv64-gnu": "1.90.0", "@oxlint/binding-linux-riscv64-musl": "1.90.0", "@oxlint/binding-linux-s390x-gnu": "1.90.0", "@oxlint/binding-linux-x64-gnu": "1.90.0", "@oxlint/binding-linux-x64-musl": "1.90.0", "@oxlint/binding-openharmony-arm64": "1.90.0", "@oxlint/binding-win32-arm64-msvc": "1.90.0", "@oxlint/binding-win32-ia32-msvc": "1.90.0", "@oxlint/binding-win32-x64-msvc": "1.90.0" }, "peerDependencies": { "oxlint-tsgolint": ">=7.0.2005", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-RkTN9EmgIUpLuhNoLhO3OliMGJlvb3Dk7XVjBZnfoMCHrVpuz5ESd97klfiyYeV7XfA2lNLnDCPMkUI+Qw5How=="], + "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], diff --git a/package.json b/package.json index 54a42668a..d39deca7e 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "format:cso:check": "prettier --check 'lib/cso/*.ts'", "typecheck": "tsc -p tsconfig.json", "typecheck:test": "bun run scripts/typecheck-test.ts", + "lint": "bun run scripts/lint-ratchet.ts", "test:cso:docker": "bun test --max-concurrency 1 test/cso-docker-integration.test.ts test/cso-node-lifecycle-integration.test.ts test/cso-stack-cold-integration.test.ts", "test:cso:macos": "bun test test/cso-macos-launcher.test.ts test/cso-registry-socket.test.ts", "test:cso:windows": "bun test test/cso-windows-launcher.test.ts", @@ -99,6 +100,7 @@ "devDependencies": { "@anthropic-ai/claude-agent-sdk": "0.2.141", "@types/bun": "1.4.3", + "oxlint": "1.90.0", "prettier": "3.9.10", "typescript": "7.0.2" }, diff --git a/scripts/lint-baseline.json b/scripts/lint-baseline.json new file mode 100644 index 000000000..2686ec23a --- /dev/null +++ b/scripts/lint-baseline.json @@ -0,0 +1,640 @@ +{ + "version": 1, + "oxlint": "1.90.0", + "findings": { + "bin/gstack-autoplan-snapshot.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "bin/gstack-brain-context-load.ts\teslint(no-unused-vars)\tIdentifier 'dirname' is imported but never used.": 1, + "bin/gstack-brain-context-load.ts\teslint(no-unused-vars)\tIdentifier 'readFileSync' is imported but never used.": 1, + "bin/gstack-brain-context-load.ts\teslint(no-unused-vars)\tParameter 'args' is declared but never used. Unused parameters should start with a '_'.": 1, + "bin/gstack-brain-context-load.ts\teslint(no-unused-vars)\tVariable 'GSTACK_HOME' is declared but never used. Unused variables should start with a '_'.": 1, + "bin/gstack-brain-context-load.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "bin/gstack-design-detect.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "bin/gstack-gbrain-sync.ts\teslint(no-unused-vars)\tIdentifier 'NEEDS_SHELL_ON_WINDOWS' is imported but never used.": 1, + "bin/gstack-memory-ingest.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "bin/gstack-memory-ingest.ts\teslint(no-unused-vars)\tIdentifier 'appendFileSync' is imported but never used.": 1, + "bin/gstack-memory-ingest.ts\teslint(no-unused-vars)\tIdentifier 'spawn' is imported but never used.": 1, + "bin/gstack-memory-ingest.ts\teslint(no-unused-vars)\tIdentifier 'withErrorContext' is imported but never used.": 1, + "bin/gstack-memory-ingest.ts\teslint(no-unused-vars)\tVariable 'DEFAULT_INCREMENTAL_BUDGET_MS' is declared but never used. Unused variables should start with a '_'.": 1, + "bin/gstack-memory-ingest.ts\teslint(no-unused-vars)\tVariable 'failed' is declared but never used. Unused variables should start with a '_'.": 1, + "bin/gstack-memory-ingest.ts\teslint(no-unused-vars)\tVariable 'written' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/activity.ts\teslint(no-unused-vars)\tVariable 'SENSITIVE_COMMANDS' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/browser-manager.ts\teslint(no-unused-vars)\tVariable 'fs' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/browser-manager.ts\teslint(no-unused-vars)\tVariable 'path' is declared but never used. Unused variables should start with a '_'.": 2, + "browse/src/browser-manager.ts\tunicorn(no-useless-spread)\t`Promise.all` accepts an iterable, so it's unnecessary to convert the iterable to an array.": 1, + "browse/src/browser-skills.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "browse/src/buffers.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "browse/src/cdp-inspector.ts\teslint(no-unused-vars)\tCatch parameter 'err' is caught but never used.": 1, + "browse/src/cdp-inspector.ts\teslint(no-unused-vars)\tVariable 'styleText' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/cli.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "browse/src/cookie-auth-verification.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 2, + "browse/src/cookie-import-browser.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "browse/src/cookie-import-browser.ts\teslint(no-unused-vars)\tCatch parameter 'err' is caught but never used.": 1, + "browse/src/cookie-import-browser.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "browse/src/cookie-import-native-job.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "browse/src/cookie-import-native-worker.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "browse/src/domain-skills.ts\teslint(no-unused-vars)\tInterface 'SkillKey' is declared but never used.": 1, + "browse/src/meta-commands.ts\teslint(no-unused-vars)\tIdentifier 'META_COMMANDS' is imported but never used.": 1, + "browse/src/meta-commands.ts\teslint(no-unused-vars)\tIdentifier 'PAGE_CONTENT_COMMANDS' is imported but never used.": 1, + "browse/src/meta-commands.ts\teslint(no-unused-vars)\tIdentifier 'READ_COMMANDS' is imported but never used.": 1, + "browse/src/read-commands.ts\teslint(no-unused-vars)\tIdentifier 'TEMP_DIR' is imported but never used.": 1, + "browse/src/routes/inspector.ts\teslint(no-unused-vars)\tVariable 'activeTabUrl' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/server.ts\teslint(no-unused-vars)\tIdentifier 'isProcessAlive' is imported but never used.": 1, + "browse/src/server.ts\teslint(no-unused-vars)\tIdentifier 'net' is imported but never used.": 1, + "browse/src/server.ts\teslint(no-unused-vars)\tIdentifier 'safeKill' is imported but never used.": 1, + "browse/src/server.ts\teslint(no-unused-vars)\tVariable 'server' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/snapshot.ts\teslint(no-unused-vars)\tType 'Frame' is imported but never used.": 1, + "browse/src/snapshot.ts\teslint(no-unused-vars)\tType 'Page' is imported but never used.": 1, + "browse/src/terminal-agent-control.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "browse/src/token-registry.ts\teslint(no-unused-vars)\tIdentifier 'META_COMMANDS' is imported but never used.": 1, + "browse/src/token-registry.ts\teslint(no-unused-vars)\tIdentifier 'READ_COMMANDS' is imported but never used.": 1, + "browse/src/token-registry.ts\teslint(no-unused-vars)\tIdentifier 'WRITE_COMMANDS' is imported but never used.": 1, + "browse/src/token-registry.ts\teslint(no-unused-vars)\tVariable 'commandCount' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/src/write-commands.ts\teslint(no-unused-vars)\tCatch parameter 'e' is caught but never used.": 1, + "browse/src/write-commands.ts\teslint(no-unused-vars)\tIdentifier 'getModificationHistory' is imported but never used.": 1, + "browse/src/write-commands.ts\teslint(no-unused-vars)\tIdentifier 'resetModifications' is imported but never used.": 1, + "browse/test/batch.test.ts\teslint(no-unused-vars)\tFunction 'batch' is declared but never used.": 1, + "browse/test/batch.test.ts\teslint(no-unused-vars)\tIdentifier 'handleMetaCommand' is imported but never used.": 1, + "browse/test/batch.test.ts\teslint(no-unused-vars)\tVariable 'handleReadCommand' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/batch.test.ts\teslint(no-unused-vars)\tVariable 'handleWriteCommand' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/batch.test.ts\teslint(no-unused-vars)\tVariable 'snap1' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/batch.test.ts\teslint(no-unused-vars)\tVariable 'startServer' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/browser-skill-commands.test.ts\teslint(no-unused-vars)\tIdentifier 'validateToken' is imported but never used.": 1, + "browse/test/browser-skill-commands.test.ts\teslint(no-unused-vars)\tVariable 'dir' is declared but never used. Unused variables should start with a '_'.": 6, + "browse/test/bun-polyfill.test.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "browse/test/bun-polyfill.test.ts\teslint(no-unused-vars)\tIdentifier 'afterAll' is imported but never used.": 1, + "browse/test/cdp-inspector-history-cap.test.ts\ttypescript(prefer-as-const)\tExpected a `const` assertion instead of a literal type annotation.": 1, + "browse/test/commands.test.ts\teslint(no-unused-vars)\tIdentifier 'addDialogEntry' is imported but never used.": 1, + "browse/test/commands.test.ts\teslint(no-unused-vars)\tIdentifier 'dialogBuffer' is imported but never used.": 1, + "browse/test/commands.test.ts\teslint(no-unused-vars)\tVariable 'snap' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/content-security.test.ts\teslint(no-unused-vars)\tParameter 'cmd' is declared but never used. Unused parameters should start with a '_'.": 1, + "browse/test/content-security.test.ts\teslint(no-unused-vars)\tParameter 'url' is declared but never used. Unused parameters should start with a '_'.": 1, + "browse/test/content-security.test.ts\teslint(no-unused-vars)\tVariable 'm1' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/cookie-import-native-job.test.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "browse/test/cookie-import-native-job.test.ts\teslint(no-unused-vars)\tParameter 'file' is declared but never used. Unused parameters should start with a '_'.": 3, + "browse/test/cookie-picker-ui.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 1, + "browse/test/data-platform.test.ts\teslint(no-unused-vars)\tIdentifier 'validateOutputPath' is imported but never used.": 1, + "browse/test/data-platform.test.ts\teslint(no-unused-vars)\tIdentifier 'validateReadPath' is imported but never used.": 1, + "browse/test/dx-polish.test.ts\teslint(no-unused-vars)\tVariable 'syntheticSet' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/file-drop.test.ts\teslint(no-unused-vars)\tIdentifier 'handleMetaCommand' is imported but never used.": 1, + "browse/test/file-drop.test.ts\teslint(no-unused-vars)\tVariable 'bm' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/handoff.test.ts\teslint(no-unused-vars)\tType 'BrowserState' is imported but never used.": 1, + "browse/test/security-adversarial.test.ts\teslint(no-unused-vars)\tType 'LayerSignal' is imported but never used.": 1, + "browse/test/security-sidecar-client.test.ts\teslint(no-unused-vars)\tIdentifier 'writeFileSync' is imported but never used.": 1, + "browse/test/security.test.ts\teslint(no-unused-vars)\tType 'LayerSignal' is imported but never used.": 1, + "browse/test/security.test.ts\teslint(no-unused-vars)\tVariable 'prompt' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/server-pty-lease-routes.test.ts\teslint(no-unused-vars)\tFunction 'sliceBetween' is declared but never used.": 1, + "browse/test/sidebar-ux.test.ts\teslint(no-unused-vars)\tVariable 'bmSrc' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/sidebar-ux.test.ts\teslint(no-unused-vars)\tVariable 'html' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/socks-bridge.test.ts\teslint(no-unused-vars)\tIdentifier 'afterAll' is imported but never used.": 1, + "browse/test/socks-bridge.test.ts\teslint(no-unused-vars)\tIdentifier 'beforeAll' is imported but never used.": 1, + "browse/test/stealth-webdriver.test.ts\teslint(no-eval)\teval can be harmful.": 1, + "browse/test/tab-each.test.ts\teslint(no-unused-vars)\tVariable 'calls' is assigned a value but never used. Unused variables should start with a '_'.": 1, + "browse/test/tab-session-frame-detach.test.ts\teslint(no-unused-vars)\tVariable 'result' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/terminal-agent-integration.test.ts\teslint(no-unused-vars)\tParameter 'e' is declared but never used. Unused parameters should start with a '_'.": 1, + "browse/test/terminal-agent-integration.test.ts\teslint(no-unused-vars)\tVariable 'closed' is assigned a value but never used. Unused variables should start with a '_'.": 1, + "browse/test/terminal-agent-lifecycle.test.ts\teslint(no-unused-vars)\tVariable 'pid' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/terminal-agent-ring-buffer-runtime.test.ts\teslint(no-unused-vars)\tIdentifier 'beforeEach' is imported but never used.": 1, + "browse/test/terminal-pty-lifecycle.test.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "browse/test/test-server.ts\teslint(no-unused-vars)\tVariable 'server' is declared but never used. Unused variables should start with a '_'.": 1, + "browse/test/token-registry.test.ts\teslint(no-unused-vars)\tVariable 'exemptFromScope' is declared but never used. Unused variables should start with a '_'.": 1, + "design/prototype.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "design/src/brief.ts\teslint(no-unused-vars)\tVariable 'raw' is declared but never used. Unused variables should start with a '_'.": 1, + "design/src/daemon-client.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "design/src/gallery.ts\teslint(no-unused-vars)\tParameter 'i' is declared but never used. Unused parameters should start with a '_'.": 1, + "design/src/serve.ts\teslint(no-unused-vars)\tIdentifier 'os' is imported but never used.": 1, + "design/test/daemon-discovery.test.ts\teslint(no-unused-vars)\tIdentifier 'DAEMON_SCRIPT' is imported but never used.": 1, + "design/test/daemon-discovery.test.ts\teslint(no-unused-vars)\tIdentifier 'os' is imported but never used.": 1, + "design/test/daemon-tests-fixtures.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "design/test/daemon.test.ts\teslint(no-unused-vars)\tVariable 'newHtml' is declared but never used. Unused variables should start with a '_'.": 1, + "design/test/models.test.ts\teslint(no-unused-vars)\tParameter 'url' is declared but never used. Unused parameters should start with a '_'.": 1, + "extension/background.js\teslint(no-unused-vars)\tVariable 'inspectorMode' is assigned a value but never used. Unused variables should start with a '_'.": 1, + "extension/content.js\teslint(no-unused-vars)\tFunction 'renderRefBadges' is declared but never used.": 1, + "extension/content.js\teslint(no-unused-vars)\tVariable 'basicPickerOverlay' is declared but never used. Unused variables should start with a '_'.": 1, + "extension/content.js\teslint(no-unused-vars)\tVariable 'mode' is declared but never used. Unused variables should start with a '_'.": 1, + "extension/inspector.js\teslint(no-unused-vars)\tVariable 'idx' is declared but never used. Unused variables should start with a '_'.": 1, + "extension/sidepanel-terminal.js\teslint(no-unused-expressions)\tExpected expression to be used": 6, + "extension/sidepanel-terminal.js\teslint(no-unused-vars)\tCatch parameter 'err' is caught but never used.": 1, + "extension/sidepanel-terminal.js\teslint(no-unused-vars)\tFunction 'getHealth' is declared but never used.": 1, + "extension/sidepanel-terminal.js\teslint(no-unused-vars)\tFunction 'teardown' is declared but never used.": 1, + "extension/sidepanel.js\teslint(no-unused-expressions)\tExpected expression to be used": 1, + "extension/sidepanel.js\teslint(no-unused-vars)\tFunction 'inspectorShowEmpty' is declared but never used.": 1, + "extension/sidepanel.js\teslint(no-unused-vars)\tParameter 'isUA' is declared but never used. Unused parameters should start with a '_'.": 1, + "hosts/claude/hooks/auq-error-fallback-hook.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "hosts/claude/hooks/question-log-hook.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "hosts/claude/hooks/question-log-hook.ts\teslint(no-unused-vars)\tInterface 'ExtractedQuestion' is declared but never used.": 1, + "ios-qa/daemon/src/devicectl.ts\teslint(no-unused-vars)\tIdentifier 'writeFileSync' is imported but never used.": 1, + "ios-qa/daemon/test/allowlist.test.ts\teslint(no-unused-vars)\tIdentifier 'writeFileSync' is imported but never used.": 1, + "ios-qa/daemon/test/audit.test.ts\teslint(no-unused-vars)\tIdentifier 'statSync' is imported but never used.": 1, + "ios-qa/daemon/test/audit.test.ts\teslint(no-unused-vars)\tIdentifier 'writeFileSync' is imported but never used.": 1, + "ios-qa/daemon/test/cli-mint.test.ts\teslint(no-unused-vars)\tIdentifier 'chmodSync' is imported but never used.": 1, + "ios-qa/daemon/test/cli-mint.test.ts\teslint(no-unused-vars)\tIdentifier 'rmSync' is imported but never used.": 1, + "ios-qa/daemon/test/daemon-integration.test.ts\teslint(no-unused-vars)\tType 'IncomingMessage' is imported but never used.": 1, + "ios-qa/daemon/test/session-cache.test.ts\tunicorn(no-invalid-fetch-options)\t\"body\" is not allowed when method is \"GET\"": 1, + "ios-qa/daemon/test/tunnel-bootstrap.test.ts\teslint(no-unsafe-optional-chaining)\tUnsafe usage of optional chaining": 1, + "ios-qa/daemon/test/tunnel-bootstrap.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 27, + "lib/agent-model.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/approval-record.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 1, + "lib/aside-render.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/autoplan-gate.ts\teslint(no-unused-vars)\tVariable 'CONTENT_SCOPE' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/autoplan-gate.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 2, + "lib/autoplan-run.ts\teslint(no-unused-vars)\tType 'Scope' is imported but never used.": 1, + "lib/autoplan-run.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "lib/autoplan-scope.ts\teslint(no-useless-escape)\tUnnecessary escape character '-'": 2, + "lib/autoplan-scope.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 2, + "lib/captain-brief.ts\teslint(no-unused-vars)\tVariable 'clip' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/captain-brief.ts\teslint(no-unused-vars)\tVariable 'recOption' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/checks.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/code-intelligence/sourcebot-adapter.ts\teslint(no-unused-vars)\tIdentifier 'assertCapability' is imported but never used.": 1, + "lib/cso/cache.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/cso/cli.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/cso/cli.ts\teslint(no-unused-vars)\tIdentifier 'renderReport' is imported but never used.": 1, + "lib/cso/contracts.ts\teslint(no-control-regex)\tUnexpected control characters": 4, + "lib/cso/preparation-container.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/cso/preparation-container.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/cso/preparation-container.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/cso/preparation-docker.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/cso/preparation-docker.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/cso/preparation-docker.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 2, + "lib/cso/preparation-docker.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/cso/preparation-docker.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "lib/cso/preparation-docker.ts\tunicorn(no-useless-spread)\t`Promise.allSettled` accepts an iterable, so it's unnecessary to convert the iterable to an array.": 1, + "lib/cso/preparation-executor.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/cso/preparation.ts\teslint(no-unused-vars)\tVariable 'key' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/cso/preparation.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/cso/preparation.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "lib/cso/scanner-catalog.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/cso/scanner-executor.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/cso/scanners.ts\teslint(no-control-regex)\tUnexpected control characters": 6, + "lib/cso/snapshot.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/cso/state.ts\teslint(no-unused-vars)\tIdentifier 'canonical' is imported but never used.": 1, + "lib/cso/state.ts\teslint(no-useless-catch)\tUnnecessary try/catch wrapper": 2, + "lib/cso/verification.ts\teslint(no-unused-vars)\tParameter '_' is declared but never used.": 1, + "lib/cso/verification.ts\teslint(no-unused-vars)\tVariable 'artifactId' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/cso/verification.ts\teslint(no-unused-vars)\tVariable 'id' is declared but never used. Unused variables should start with a '_'.": 2, + "lib/cso/verification.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "lib/cso/witness.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/cso/witness.ts\teslint(no-unused-vars)\tParameter '_' is declared but never used.": 1, + "lib/design-lint/html.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "lib/design-lint/render-probe.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/design-lint/report.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/design-lint/rules/motion.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 4, + "lib/design-lint/rules/structure.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/design-lint/rules/type.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "lib/design-lint/rules/type.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 3, + "lib/design-lint/static.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/design-lint/tailwind.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 2, + "lib/design-md.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/design-md.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/diagram-render/src/entry.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "lib/dom-dump.js\teslint(no-unused-expressions)\tExpected expression to be used": 1, + "lib/dom-dump.js\teslint(no-unused-vars)\tCatch parameter 'err' is caught but never used.": 1, + "lib/dx-error-capture.ts\teslint(no-control-regex)\tUnexpected control characters": 2, + "lib/eval-models.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/evidence-bundle.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "lib/flaky-run.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/gate-diff/git.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 2, + "lib/gbrain-local-status.ts\teslint(no-unused-vars)\tVariable 'gbrainBin' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/gbrain-sources.ts\teslint(no-unused-vars)\tIdentifier 'execGbrainJson' is imported but never used.": 1, + "lib/gstack-decision.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/gstack-memory-helpers.ts\teslint(no-unused-vars)\tCatch parameter 'err' is caught but never used.": 1, + "lib/gstack-memory-helpers.ts\teslint(no-unused-vars)\tVariable 'ERROR_LOG_PATH' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/gstack-memory-helpers.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/gstack-post.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/issue-links.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "lib/junit.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/model-policy-freshness.ts\teslint(no-unused-vars)\tVariable 'parsed' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/model-policy.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/pr-shots.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/pr-shots.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/pr-shots.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "lib/pr-shots.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "lib/pr-wait.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/pregate/checks/lanes.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/pregate/checks/lanes.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "lib/pregate/environment.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/pregate/rust.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "lib/pregate/supervise.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/pregate/supervise.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/pricing.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/prose-lint.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "lib/qa-deadline.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/qa-deadline.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "lib/qa-evidence.ts\teslint(no-unused-vars)\tParameter 'name' is declared but never used. Unused parameters should start with a '_'.": 1, + "lib/qa-evidence.ts\teslint(no-unused-vars)\tVariable 'observed' is declared but never used. Unused variables should start with a '_'.": 1, + "lib/redact-audit-log.ts\teslint(no-unused-vars)\tIdentifier 'os' is imported but never used.": 1, + "lib/redact-engine.ts\teslint(no-misleading-character-class)\tUnexpected joined character sequence in character class.": 1, + "lib/redact-engine.ts\teslint(no-unused-vars)\tType 'RedactPattern' is imported but never used.": 1, + "lib/redact-engine.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "lib/redact-patterns.ts\teslint(no-useless-escape)\tUnnecessary escape character '-'": 15, + "lib/restamp.ts\teslint(no-unused-vars)\tIdentifier 'parseChangelog' is imported but never used.": 1, + "lib/review-collect.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/review-depth.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "lib/review-evidence.ts\teslint(no-control-regex)\tUnexpected control characters": 2, + "lib/review-scope.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/ship-queue-train-land.ts\teslint(no-unused-vars)\tIdentifier 'outOk' is imported but never used.": 1, + "lib/ship-queue.ts\teslint(no-unused-vars)\tType 'ResultCodeName' is imported but never used.": 1, + "lib/ship-receipt-depth.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/ship-receipt-docs.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/ship-receipt.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "lib/tree-receipt.ts\tunicorn(no-useless-length-check)\tFound a useless array length check": 1, + "lib/version-gate-train.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "lib/worktree.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "make-pdf/src/cli.ts\teslint(no-unused-vars)\tVariable 'name' is declared but never used. Unused variables should start with a '_'.": 1, + "make-pdf/src/docx-images.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "make-pdf/src/smartypants.ts\teslint(no-control-regex)\tUnexpected control character": 2, + "make-pdf/src/smartypants.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "make-pdf/src/smartypants.ts\teslint(no-useless-escape)\tUnnecessary escape character '('": 2, + "make-pdf/src/smartypants.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 2, + "make-pdf/src/smartypants.ts\teslint(no-useless-escape)\tUnnecessary escape character '{'": 2, + "make-pdf/test/cli-args.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "make-pdf/test/pdftotext.test.ts\teslint(no-unused-vars)\tIdentifier 'copyPasteGate' is imported but never used.": 1, + "scripts/analytics.ts\teslint(no-unused-vars)\tVariable 'maxCount' is declared but never used. Unused variables should start with a '_'.": 1, + "scripts/analytics.ts\teslint(no-unused-vars)\tVariable 'maxName' is declared but never used. Unused variables should start with a '_'.": 1, + "scripts/compare-pr-version.ts\teslint(no-unused-vars)\tCatch parameter 'e' is caught but never used.": 1, + "scripts/cso-scanner-matrix.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "scripts/garry-output-comparison.ts\teslint(no-unreachable)\tUnreachable code.": 1, + "scripts/gate-diff-calibrate.ts\teslint(no-unused-vars)\tIdentifier 'EMPTY_PROJECT_CONFIG' is imported but never used.": 1, + "scripts/gen-skill-docs.ts\teslint(no-unused-vars)\tParameter 'skillName' is declared but never used. Unused parameters should start with a '_'.": 1, + "scripts/gen-skill-docs.ts\teslint(no-unused-vars)\tVariable 'extractedDescription' is declared but never used. Unused variables should start with a '_'.": 1, + "scripts/gen-skill-docs.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "scripts/gen-skill-docs.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "scripts/host-config.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "scripts/lib/shard-engine.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "scripts/modules-cli.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "scripts/modules.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "scripts/pr-dependencies.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 5, + "scripts/recover-receipts.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "scripts/release-cut.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "scripts/resolvers/browse.ts\teslint(no-unused-vars)\tIdentifier 'toShellPath' is imported but never used.": 1, + "scripts/resolvers/defensive-review.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 12, + "scripts/resolvers/design.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 4, + "scripts/resolvers/index.ts\teslint(no-unused-vars)\tType 'TemplateContext' is imported but never used.": 1, + "scripts/resolvers/outside-voice-steps.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 8, + "scripts/resolvers/qa.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 8, + "scripts/resolvers/voice-triggers.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "scripts/review-dispatch-compare.ts\teslint(no-unused-vars)\tVariable 'a' is declared but never used. Unused variables should start with a '_'.": 2, + "scripts/skill-bin-drift.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 2, + "scripts/skill-bin-drift.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 2, + "scripts/test-free-shards.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "scripts/test-free-shards.ts\tunicorn(no-useless-spread)\t`Promise.allSettled` accepts an iterable, so it's unnecessary to convert the iterable to an array.": 1, + "scripts/test-free-shards.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "scripts/test-paid-shards.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/agent-model.test.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/agent-sdk-runner.test.ts\teslint(no-unused-vars)\tIdentifier 'fs' is imported but never used.": 1, + "test/agent-sdk-runner.test.ts\teslint(no-unused-vars)\tIdentifier 'os' is imported but never used.": 1, + "test/agent-sdk-runner.test.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "test/agent-sdk-runner.test.ts\teslint(require-yield)\tThis generator function does not have `yield`": 4, + "test/analytics.test.ts\teslint(no-unused-vars)\tIdentifier 'execSync' is imported but never used.": 1, + "test/analytics.test.ts\teslint(no-unused-vars)\tVariable 'SCRIPT' is declared but never used. Unused variables should start with a '_'.": 1, + "test/artifacts-init-migration.test.ts\teslint(no-unused-vars)\tIdentifier 'beforeEach' is imported but never used.": 1, + "test/auq-format-always-loaded.test.ts\teslint(no-unused-vars)\tVariable 'sectionsDir' is declared but never used. Unused variables should start with a '_'.": 1, + "test/auto-decide-fixture.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 1, + "test/autoplan-admission.test.ts\teslint(no-unused-vars)\tIdentifier 'HEAD' is imported but never used.": 1, + "test/autoplan-admission.test.ts\teslint(no-unused-vars)\tIdentifier 'ROOT' is imported but never used.": 1, + "test/autoplan-carry.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/autoplan-dual-voice-evidence.test.ts\teslint(no-unused-expressions)\tExpected expression to be used": 1, + "test/autoplan-dual-voice-fixture.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 4, + "test/autoplan-obligations.test.ts\teslint(no-unused-vars)\tVariable 'sourceBytes' is declared but never used. Unused variables should start with a '_'.": 1, + "test/autoplan-obligations.test.ts\teslint(no-unused-vars)\tVariable 'sourceSha256' is declared but never used. Unused variables should start with a '_'.": 1, + "test/autoplan-obligations.test.ts\teslint(no-unused-vars)\tVariable 'sourceSnapshotPath' is declared but never used. Unused variables should start with a '_'.": 1, + "test/autoplan-phase-observer.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 2, + "test/autoplan-phase-order.test.ts\teslint(no-unused-vars)\tFunction 'closeContent' is declared but never used.": 1, + "test/autoplan-review-discovery.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 6, + "test/benchmark-provider-adapters.test.ts\teslint(no-unused-vars)\tIdentifier 'GeminiAdapter' is imported but never used.": 1, + "test/binding-template-drift.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 2, + "test/brain-cache-roundtrip.test.ts\teslint(no-unused-vars)\tIdentifier 'readdirSync' is imported but never used.": 1, + "test/brain-cache-spec.test.ts\teslint(no-unused-vars)\tParameter '_' is declared but never used.": 1, + "test/brain-cache-spec.test.ts\teslint(no-unused-vars)\tVariable 'name' is declared but never used. Unused variables should start with a '_'.": 1, + "test/brain-cache-spec.test.ts\teslint(no-unused-vars)\tVariable 'skill' is declared but never used. Unused variables should start with a '_'.": 1, + "test/brain-preflight.test.ts\teslint(no-unused-vars)\tVariable 'userProfileLine' is declared but never used. Unused variables should start with a '_'.": 1, + "test/brain-sync.test.ts\teslint(no-unused-vars)\tVariable 'again' is declared but never used. Unused variables should start with a '_'.": 1, + "test/brain-sync.test.ts\teslint(no-unused-vars)\tVariable 'r' is declared but never used. Unused variables should start with a '_'.": 1, + "test/brain-sync.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/bun-entry-isolation.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/cache-concurrent-refresh.test.ts\teslint(no-unused-vars)\tIdentifier 'readFileSync' is imported but never used.": 1, + "test/cache-concurrent-refresh.test.ts\teslint(no-unused-vars)\tVariable 'callbackRan' is assigned a value but never used. Unused variables should start with a '_'.": 1, + "test/cache-concurrent-refresh.test.ts\teslint(no-unused-vars)\tVariable 'outer' is declared but never used. Unused variables should start with a '_'.": 1, + "test/captain-brief.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 2, + "test/ceo-mode-prerequisite.test.ts\teslint(no-unused-vars)\tVariable 'answeredAt' is declared but never used. Unused variables should start with a '_'.": 1, + "test/ceo-mode-prerequisite.test.ts\teslint(no-unused-vars)\tVariable 'answers' is declared but never used. Unused variables should start with a '_'.": 1, + "test/claude-overlay-setup-lifecycle.test.ts\teslint(no-unused-vars)\tIdentifier 'readFileSync' is imported but never used.": 1, + "test/codex-generation-model.test.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/context-bill.test.ts\teslint(no-unused-vars)\tIdentifier 'sha256Hex' is imported but never used.": 1, + "test/cookie-workflow-judge-input.test.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "test/coverage-audit-evidence.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 14, + "test/coverage-audit.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/cso-cli.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 4, + "test/cso-contracts.test.ts\teslint(no-unused-vars)\tIdentifier 'fingerprint' is imported but never used.": 1, + "test/cso-contracts.test.ts\teslint(no-unused-vars)\tIdentifier 'sanitizeHelperForJson' is imported but never used.": 1, + "test/cso-contracts.test.ts\teslint(no-useless-catch)\tUnnecessary try/catch wrapper": 1, + "test/cso-docker-integration.test.ts\teslint(no-unused-vars)\tIdentifier 'spawn' is imported but never used.": 1, + "test/cso-git-hardening.test.ts\teslint(no-unused-vars)\tVariable 'repo' is declared but never used. Unused variables should start with a '_'.": 1, + "test/cso-image-provisioning.test.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "test/cso-launcher-generation.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 2, + "test/cso-public-ghcr.test.ts\teslint(no-unsafe-optional-chaining)\tUnsafe usage of optional chaining": 1, + "test/cso-scanner-release.test.ts\teslint(no-unused-vars)\tIdentifier 'ScannerCatalog' is imported but never used.": 1, + "test/cso-scanner-release.test.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "test/cso-snapshot-state.test.ts\teslint(no-unused-vars)\tIdentifier 'CsoError' is imported but never used.": 1, + "test/cso-snapshot-state.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '.'": 1, + "test/cso-witness.test.ts\teslint(no-unused-vars)\tIdentifier 'CsoError' is imported but never used.": 1, + "test/design-completion-handoff-scored.test.ts\teslint(no-unused-vars)\tVariable 'handoff' is declared but never used. Unused variables should start with a '_'.": 1, + "test/design-completion-handoff-scored.test.ts\teslint(no-unused-vars)\tVariable 'qHandoff' is declared but never used. Unused variables should start with a '_'.": 1, + "test/design-consultation-command-contract.test.ts\tunicorn(no-thenable)\tDo not add `then` to an object.": 1, + "test/design-consultation-contract.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 2, + "test/design-lint.test.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "test/design-md.test.ts\teslint(no-unused-vars)\tIdentifier 'specSkeleton' is imported but never used.": 1, + "test/docsync-atomic-writes.test.ts\teslint(no-unused-vars)\tParameter 'cookie' is declared but never used. Unused parameters should start with a '_'.": 1, + "test/docsync-lifecycle-interface.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "test/egress-receipt-wiring.test.ts\teslint(no-unused-vars)\tFunction 'exists' is declared but never used.": 1, + "test/eng-batching-saved-ledger.test.ts\teslint(no-unused-vars)\tParameter '_' is declared but never used.": 1, + "test/eng-devex-s-count.test.ts\teslint(no-unused-vars)\tIdentifier 'retry' is imported but never used.": 1, + "test/eng-finding-retry-budget.test.ts\teslint(no-unused-vars)\tIdentifier 'DEFAULT_JOBS' is imported but never used.": 1, + "test/eng-finding-retry-budget.test.ts\teslint(no-unused-vars)\tIdentifier 'expandCaseShards' is imported but never used.": 1, + "test/eng-finding-retry-budget.test.ts\teslint(no-unused-vars)\tIdentifier 'expandTrialShards' is imported but never used.": 1, + "test/eng-finding-retry-budget.test.ts\teslint(no-unused-vars)\tIdentifier 'sliceSupervisedWallMs' is imported but never used.": 1, + "test/eng-scope-entry-ap.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 1, + "test/eng-semantic-terminal.test.ts\teslint(no-unused-vars)\tFunction 'response' is declared but never used.": 1, + "test/eval-input-cache.test.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "test/free-home-guard.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 2, + "test/gate-reuse.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 2, + "test/gbrain-detect-install.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/gbrain-local-status.test.ts\teslint(no-unused-vars)\tIdentifier 'CACHE_TTL_MS' is imported but never used.": 1, + "test/gbrain-local-status.test.ts\teslint(no-unused-vars)\tIdentifier 'beforeEach' is imported but never used.": 1, + "test/gbrain-local-status.test.ts\teslint(no-unused-vars)\tType 'LocalEngineStatus' is imported but never used.": 1, + "test/gbrain-repo-policy.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/gbrain-sources.test.ts\teslint(no-unused-vars)\tIdentifier 'existsSync' is imported but never used.": 1, + "test/gbrain-sync-voyage-code-3-integration.test.ts\teslint(no-unused-vars)\tIdentifier 'existsSync' is imported but never used.": 1, + "test/gen-skill-docs.test.ts\teslint(no-unused-vars)\tVariable 'cmd' is declared but never used. Unused variables should start with a '_'.": 2, + "test/gen-skill-docs.test.ts\teslint(no-unused-vars)\tVariable 'name' is declared but never used. Unused variables should start with a '_'.": 1, + "test/gen-skill-docs.test.ts\teslint(no-unused-vars)\tVariable 'processing' is declared but never used. Unused variables should start with a '_'.": 1, + "test/gen-skill-docs.test.ts\teslint(no-unused-vars)\tVariable 'review' is declared but never used. Unused variables should start with a '_'.": 1, + "test/gen-skill-docs.test.ts\teslint(no-unused-vars)\tVariable 'step5' is declared but never used. Unused variables should start with a '_'.": 1, + "test/gen-skill-docs.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 6, + "test/gstack-artifacts-init.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 20, + "test/gstack-artifacts-init.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/gstack-detach.test.ts\teslint(no-unused-vars)\tIdentifier 'spawn' is imported but never used.": 1, + "test/gstack-developer-profile.test.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/gstack-ff-update.test.ts\teslint(no-unused-vars)\tFunction 'gitStatus' is declared but never used.": 1, + "test/gstack-gbrain-source-wireup.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '$'": 3, + "test/gstack-gbrain-source-wireup.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/gstack-memory-ingest.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '$'": 37, + "test/gstack-ship-receipt-docs.test.ts\teslint(no-unused-vars)\tIdentifier 'os' is imported but never used.": 1, + "test/gstack-upgrade-fresh-shell.test.ts\teslint(no-unused-vars)\tParameter 'h' is declared but never used. Unused parameters should start with a '_'.": 1, + "test/gstack-upgrade-migration-v1_17_0_0.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/gstack-upgrade-migration-v1_37_0_0.test.ts\teslint(no-unused-vars)\tIdentifier 'execFileSync' is imported but never used.": 1, + "test/helpers/agent-sdk-runner.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "test/helpers/auq-native-capture.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "test/helpers/auq-sdk-capture.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "test/helpers/autoplan-dual-voice-evidence.ts\teslint(no-useless-escape)\tUnnecessary escape character '&'": 2, + "test/helpers/autoplan-dual-voice-evidence.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "test/helpers/autoplan-dual-voice-evidence.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/ceo-section-loading-fixture.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 5, + "test/helpers/claude-pty-runner.boundaries.unit.test.ts\teslint(no-unused-vars)\tIdentifier 'designStep0Boundary' is imported but never used.": 1, + "test/helpers/claude-pty-runner.boundaries.unit.test.ts\teslint(no-unused-vars)\tIdentifier 'devexStep0Boundary' is imported but never used.": 1, + "test/helpers/claude-pty-runner.boundaries.unit.test.ts\teslint(no-unused-vars)\tVariable 'focusQuestion' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/claude-pty-runner.boundaries.unit.test.ts\teslint(no-unused-vars)\tVariable 'nativeFocus' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/claude-pty-runner.boundaries.unit.test.ts\teslint(no-unused-vars)\tVariable 'questions' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/claude-pty-runner.classify.unit.test.ts\teslint(no-unused-vars)\tIdentifier 'isPlanReadyVisible' is imported but never used.": 1, + "test/helpers/claude-pty-runner.classify.unit.test.ts\teslint(no-unused-vars)\tIdentifier 'stripAnsi' is imported but never used.": 1, + "test/helpers/claude-pty-runner.runners.unit.test.ts\teslint(no-unused-vars)\tVariable 'fake' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/codex-host-runner.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/coverage-audit-evidence.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "test/helpers/docsync-contract.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "test/helpers/docsync-observer.ts\teslint(no-control-regex)\tUnexpected control characters": 2, + "test/helpers/docsync-observer.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "test/helpers/docsync-observer.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 2, + "test/helpers/dx-selected-navigation.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/e2e-helpers.ts\teslint(no-unused-vars)\tIdentifier 'afterAll' is imported but never used.": 1, + "test/helpers/e2e-helpers.ts\teslint(no-unused-vars)\tIdentifier 'judgePassed' is imported but never used.": 1, + "test/helpers/eng-cache-writer-decision.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 5, + "test/helpers/eng-seeded-coverage.ts\teslint(no-unused-vars)\tParameter 'at' is declared but never used. Unused parameters should start with a '_'.": 1, + "test/helpers/eng-seeded-coverage.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 3, + "test/helpers/eng-seeded-coverage.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 6, + "test/helpers/eval-store.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 2, + "test/helpers/exercised-prototype.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 2, + "test/helpers/generated-bash-lint.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/hermetic-env.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/hermetic-env.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "test/helpers/hermetic-skill-runtime.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/hermetic-skill-runtime.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "test/helpers/module-size.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "test/helpers/observability.test.ts\teslint(no-unused-vars)\tVariable 'expected' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/outside-voice-receipt.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "test/helpers/overlay-attempt.ts\teslint(no-unused-vars)\tParameter 'receiver' is declared but never used. Unused parameters should start with a '_'.": 1, + "test/helpers/overlay-case.ts\teslint(no-unused-vars)\tType 'SystemPromptOption' is imported but never used.": 1, + "test/helpers/plan-count-file-permission.ts\teslint(no-useless-escape)\tUnnecessary escape character '-'": 7, + "test/helpers/plan-count-file-permission.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 3, + "test/helpers/plan-floor-review.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/plan-review-board-feedback.ts\teslint(no-unused-vars)\tIdentifier 'fs' is imported but never used.": 1, + "test/helpers/plan-review-board-feedback.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 3, + "test/helpers/plan-scope-selection.ts\teslint(no-useless-escape)\tUnnecessary escape character '\\''": 1, + "test/helpers/plan-seed-submission.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/plan-skill-questions.ts\teslint(no-control-regex)\tUnexpected control characters": 5, + "test/helpers/plan-skill-questions.ts\teslint(no-unused-vars)\tVariable 'afkTimeoutMs' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/plan-skill-questions.ts\teslint(no-unused-vars)\tVariable 'annotations' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/plan-skill-questions.ts\teslint(no-unused-vars)\tVariable 'answers' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/plan-skill-questions.ts\teslint(no-unused-vars)\tVariable 'followUp' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/plan-skill-questions.ts\teslint(no-unused-vars)\tVariable 'response' is declared but never used. Unused variables should start with a '_'.": 1, + "test/helpers/pty/auq.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/pty/boundaries.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 9, + "test/helpers/pty/launch.ts\teslint(no-control-regex)\tUnexpected control character": 1, + "test/helpers/pty/plan-native.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 1, + "test/helpers/pty/plan-native.ts\tunicorn(no-useless-length-check)\tFound a useless array length check": 1, + "test/helpers/pty/runners/counting.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/pty/runners/floor.ts\teslint(no-control-regex)\tUnexpected control characters": 4, + "test/helpers/pty/runners/floor.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/pty/screen.ts\teslint(no-control-regex)\tUnexpected control character": 5, + "test/helpers/pty/screen.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/pty/screen.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "test/helpers/pty/session.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 2, + "test/helpers/qa-callers-fixture.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 14, + "test/helpers/qa-callers-fixture.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "test/helpers/qa-callers-fixture.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/helpers/qa-evidence-producer.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "test/helpers/qa-functional-eval.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "test/helpers/read-only-commands.ts\teslint(no-control-regex)\tUnexpected control characters": 1, + "test/helpers/secret-sink-harness.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/helpers/session-runner.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 2, + "test/helpers/shared-libs-review-start-evidence.ts\teslint(no-useless-escape)\tUnnecessary escape character '['": 1, + "test/helpers/ship-skip-actor.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 1, + "test/helpers/skill-parser.ts\teslint(no-useless-escape)\tUnnecessary escape character '$'": 1, + "test/hermetic-skill-runtime.test.ts\teslint(no-unused-vars)\tIdentifier 'getHermeticDirs' is imported but never used.": 1, + "test/hook-scripts.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 2, + "test/host-conformance.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "test/ios-qa.test.ts\teslint(no-unused-vars)\tType 'RunningDaemon' is imported but never used.": 1, + "test/learnings.test.ts\teslint(no-unused-vars)\tVariable 'learningsFile' is declared but never used. Unused variables should start with a '_'.": 1, + "test/memory-pipeline.test.ts\teslint(no-unused-vars)\tIdentifier 'statSync' is imported but never used.": 1, + "test/memory-pipeline.test.ts\teslint(no-unused-vars)\tVariable 'stateAfterFirst' is declared but never used. Unused variables should start with a '_'.": 1, + "test/no-stale-gstack-brain-refs.test.ts\teslint(no-unused-vars)\tIdentifier 'fs' is imported but never used.": 1, + "test/outside-voice-evidence.test.ts\teslint(no-unused-vars)\tVariable 'isSidechain' is declared but never used. Unused variables should start with a '_'.": 1, + "test/outside-voice-preflight.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 14, + "test/outside-voice-preflight.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 2, + "test/overlay-lifecycle.test.ts\teslint(require-yield)\tThis generator function does not have `yield`": 2, + "test/paid-rerun.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "test/paid-retry-supervision.test.ts\teslint(no-unused-vars)\tIdentifier 'DEFAULT_JOBS' is imported but never used.": 1, + "test/paid-retry-supervision.test.ts\teslint(no-unused-vars)\tIdentifier 'paidShardWallUpperBoundMs' is imported but never used.": 1, + "test/paid-retry-supervision.test.ts\teslint(no-unused-vars)\tIdentifier 'sliceSupervisedWallMs' is imported but never used.": 1, + "test/paid-run-manifest.test.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "test/plan-count-clipped-elision.test.ts\teslint(no-unused-vars)\tVariable 'body' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-completion.test.ts\teslint(no-unused-vars)\tIdentifier 'isNumberedOptionListVisible' is imported but never used.": 1, + "test/plan-count-completion.test.ts\teslint(no-unused-vars)\tIdentifier 'isPermissionDialogVisible' is imported but never used.": 1, + "test/plan-count-completion.test.ts\teslint(no-unused-vars)\tIdentifier 'isProseAUQVisible' is imported but never used.": 1, + "test/plan-count-completion.test.ts\teslint(no-unused-vars)\tVariable 'actual' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-completion.test.ts\teslint(no-unused-vars)\tVariable 'handoff' is declared but never used. Unused variables should start with a '_'.": 2, + "test/plan-count-completion.test.ts\teslint(no-unused-vars)\tVariable 'retryHandoff' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-cross-cwd-ancestry.test.ts\teslint(no-unused-vars)\tParameter 'index' is declared but never used. Unused parameters should start with a '_'.": 1, + "test/plan-count-cross-cwd-ancestry.test.ts\teslint(no-unused-vars)\tParameter 'order' is declared but never used. Unused parameters should start with a '_'.": 1, + "test/plan-count-preview-footer.test.ts\teslint(no-unused-vars)\tVariable 'answeredAt' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-preview-footer.test.ts\teslint(no-unused-vars)\tVariable 'answers' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-preview-footer.test.ts\teslint(no-unused-vars)\tVariable 'unansweredQuestionIndices' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-truncated-question.test.ts\teslint(no-unused-vars)\tVariable 'answeredAt' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-truncated-question.test.ts\teslint(no-unused-vars)\tVariable 'answers' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-count-truncated-question.test.ts\teslint(no-unused-vars)\tVariable 'unansweredQuestionIndices' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-edit-cropped-permission.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '-'": 1, + "test/plan-review-cases.test.ts\teslint(no-unused-vars)\tVariable 'prepare' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-review-cases.test.ts\teslint(no-unused-vars)\tVariable 'report' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-scope-selection.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 4, + "test/plan-skill-questions.test.ts\teslint(no-unused-vars)\tParameter 'preview' is declared but never used. Unused parameters should start with a '_'.": 4, + "test/plan-skill-questions.test.ts\teslint(no-unused-vars)\tVariable 'description' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-skill-questions.test.ts\teslint(no-unused-vars)\tVariable 'multiSelect' is declared but never used. Unused variables should start with a '_'.": 4, + "test/plan-skill-questions.test.ts\teslint(no-unused-vars)\tVariable 'preview' is declared but never used. Unused variables should start with a '_'.": 1, + "test/plan-tune.test.ts\teslint(no-unused-vars)\tIdentifier 'SIGNAL_MAP' is imported but never used.": 1, + "test/post-rename-doc-regen.test.ts\teslint(no-unused-vars)\tVariable 'FORBIDDEN_PATTERNS' is declared but never used. Unused variables should start with a '_'.": 1, + "test/pr-title-sync-workflow-safety.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/qa-browser-deadline-evidence.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/qa-exploratory-callers.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "test/qa-lazy-sections.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 5, + "test/redact-doc-resolver.test.ts\teslint(no-unused-vars)\tIdentifier 'PATTERNS' is imported but never used.": 1, + "test/redact-dotenv-filename-false-positive.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '-'": 1, + "test/release-cut.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 4, + "test/release-cut.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 10, + "test/relink.test.ts\teslint(no-dupe-keys)\tDuplicate key 'GSTACK_HOME'": 1, + "test/relink.test.ts\teslint(no-dupe-keys)\tDuplicate key 'GSTACK_USER_RENDER_DIR'": 1, + "test/relink.test.ts\teslint(no-unused-vars)\tVariable 'result' is declared but never used. Unused variables should start with a '_'.": 1, + "test/resolver-ask-user-format.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 2, + "test/resolvers-gbrain-put-rewrite.test.ts\teslint(no-unused-vars)\tIdentifier 'readdirSync' is imported but never used.": 1, + "test/resolvers-gbrain-put-rewrite.test.ts\teslint(no-unused-vars)\tIdentifier 'statSync' is imported but never used.": 1, + "test/review-checklists.test.ts\teslint(no-unused-vars)\tVariable 'PHASE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/review-checklists.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/review-quality-provenance.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/review-scope.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 4, + "test/review-targeted.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/review-workflow-clarity.test.ts\teslint(no-unused-vars)\tIdentifier 'generatePlanCompletionGateShip' is imported but never used.": 1, + "test/review-workflow-clarity.test.ts\teslint(no-unused-vars)\tVariable 'audit' is declared but never used. Unused variables should start with a '_'.": 1, + "test/review-workflow-clarity.test.ts\teslint(no-unused-vars)\tVariable 'persist' is declared but never used. Unused variables should start with a '_'.": 1, + "test/review-workflow-clarity.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\\''": 1, + "test/review-workflow-clarity.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 6, + "test/review-workflow-clarity.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 1, + "test/setup-claude-skill-assets.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '/'": 1, + "test/setup-codesign.test.ts\teslint(no-unused-vars)\tIdentifier 'os' is imported but never used.": 1, + "test/setup-codex-scope-migrations.test.ts\teslint(no-unused-vars)\tIdentifier 'owned' is imported but never used.": 1, + "test/setup-playwright-best-effort.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/shared-libs-fixture.test.ts\teslint(no-unused-vars)\tVariable 'interactive' is declared but never used. Unused variables should start with a '_'.": 1, + "test/shared-libs-index-flags-readonly.test.ts\teslint(no-unused-vars)\tIdentifier 'path' is imported but never used.": 1, + "test/ship-apple-gate.test.ts\teslint(no-unused-vars)\tVariable 'apple' is declared but never used. Unused variables should start with a '_'.": 1, + "test/ship-control-flow.test.ts\teslint(no-unused-vars)\tVariable 'merge' is declared but never used. Unused variables should start with a '_'.": 1, + "test/ship-document-release-dispatch.test.ts\teslint(no-unused-vars)\tVariable 'claude' is declared but never used. Unused variables should start with a '_'.": 1, + "test/ship-document-release-dispatch.test.ts\teslint(no-unused-vars)\tVariable 'ship' is declared but never used. Unused variables should start with a '_'.": 1, + "test/ship-document-release-dispatch.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 1, + "test/ship-driver.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 1, + "test/ship-measure-bar.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/ship-measure.test.ts\teslint(no-unused-vars)\tType 'MeasureConfig' is imported but never used.": 1, + "test/ship-publication-gates.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 1, + "test/ship-publication-gates.test.ts\ttypescript(no-non-null-asserted-optional-chain)\tOptional chain expressions can return undefined by design: using a non-null assertion is unsafe and wrong.": 1, + "test/ship-queue-train.test.ts\teslint(no-unused-vars)\tVariable 'pregate' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-ceo-section-ordering.test.ts\teslint(no-unused-vars)\tVariable 'STOP' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-ceo-section-ordering.test.ts\teslint(no-unused-vars)\tVariable 'comparison' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-ceo-section-ordering.test.ts\teslint(no-unused-vars)\tVariable 'history' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-ceo-section-ordering.test.ts\teslint(no-unused-vars)\tVariable 'temporal' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-ceo-section-ordering.test.ts\teslint(no-useless-escape)\tUnnecessary escape character 's'": 1, + "test/skill-cross-model-recommendation-emit.test.ts\teslint(no-unused-vars)\tFunction 'sliceBetween' is declared but never used.": 1, + "test/skill-e2e-aside.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-aside.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-aside.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "test/skill-e2e-autoplan-dual-voice.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-bws.test.ts\teslint(no-unused-vars)\tIdentifier 'copyDirSync' is imported but never used.": 1, + "test/skill-e2e-bws.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-bws.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-bws.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-context-skills.test.ts\teslint(no-unused-vars)\tIdentifier 'beforeAll' is imported but never used.": 1, + "test/skill-e2e-context-skills.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-context-skills.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-context-skills.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-deploy.test.ts\teslint(no-unused-vars)\tIdentifier 'browseBin' is imported but never used.": 1, + "test/skill-e2e-deploy.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-deploy.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-deploy.test.ts\teslint(no-unused-vars)\tIdentifier 'setupBrowseShims' is imported but never used.": 1, + "test/skill-e2e-deploy.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-design.test.ts\teslint(no-unused-vars)\tIdentifier 'copyDirSync' is imported but never used.": 1, + "test/skill-e2e-design.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-design.test.ts\teslint(no-unused-vars)\tParameter '_' is declared but never used.": 1, + "test/skill-e2e-design.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/skill-e2e-gbrain-roundtrip-local.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-gbrain-roundtrip-local.test.ts\teslint(no-unused-vars)\tIdentifier 'runId' is imported but never used.": 1, + "test/skill-e2e-gbrain-roundtrip-local.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-gbrain-roundtrip-local.test.ts\teslint(no-unused-vars)\tVariable 'evalCollector' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-learnings.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-learnings.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-learnings.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-model-panel.test.ts\tunicorn(no-new-array)\tDo not use `new Array(singleArgument)`.": 1, + "test/skill-e2e-office-hours-auto-mode.test.ts\teslint(no-unused-vars)\tIdentifier 'expect' is imported but never used.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tVariable 'CON_BULLET_RE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tVariable 'D_NUMBER_RE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tVariable 'NET_LINE_RE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tVariable 'PROS_CONS_HEADER_RE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tVariable 'PRO_BULLET_RE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-plan-format.test.ts\teslint(no-unused-vars)\tVariable 'STAKES_RE' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-plan-prosons.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-plan-prosons.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-plan-prosons.test.ts\teslint(no-unused-vars)\tParameter 'signal' is declared but never used. Unused parameters should start with a '_'.": 4, + "test/skill-e2e-plan.test.ts\teslint(no-unused-vars)\tIdentifier 'CAPTURE_MS' is imported but never used.": 1, + "test/skill-e2e-plan.test.ts\teslint(no-unused-vars)\tIdentifier 'JUDGE_MS' is imported but never used.": 1, + "test/skill-e2e-plan.test.ts\teslint(no-unused-vars)\tIdentifier 'browseBin' is imported but never used.": 1, + "test/skill-e2e-plan.test.ts\teslint(no-unused-vars)\tIdentifier 'copyDirSync' is imported but never used.": 1, + "test/skill-e2e-plan.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-qa-bugs.test.ts\teslint(no-unused-vars)\tIdentifier 'describeE2E' is imported but never used.": 1, + "test/skill-e2e-qa-bugs.test.ts\teslint(no-unused-vars)\tIdentifier 'describeIfSelected' is imported but never used.": 1, + "test/skill-e2e-qa-bugs.test.ts\teslint(no-unused-vars)\tIdentifier 'spawnSync' is imported but never used.": 1, + "test/skill-e2e-qa-bugs.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-qa-workflow.test.ts\teslint(no-unsafe-finally)\tUnsafe `finally` block.": 5, + "test/skill-e2e-qa-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-qa-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-review-army.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-review-army.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-review-attribution.test.ts\teslint(no-unused-vars)\tVariable 'allOutput' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'browseBin' is imported but never used.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'copyDirSync' is imported but never used.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'selectedTests' is imported but never used.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'setupBrowseShims' is imported but never used.": 1, + "test/skill-e2e-review.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-session-intelligence.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-session-intelligence.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-session-intelligence.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-skillify.test.ts\teslint(no-unused-vars)\tIdentifier 'beforeAll' is imported but never used.": 1, + "test/skill-e2e-skillify.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-skillify.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'browseBin' is imported but never used.": 1, + "test/skill-e2e-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-e2e-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'evalsEnabled' is imported but never used.": 1, + "test/skill-e2e-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'setupBrowseShims' is imported but never used.": 1, + "test/skill-e2e-workflow.test.ts\teslint(no-unused-vars)\tIdentifier 'test' is imported but never used.": 1, + "test/skill-e2e-workflow.test.ts\teslint(no-unused-vars)\tVariable 'mentionsUpgrade' is declared but never used. Unused variables should start with a '_'.": 1, + "test/skill-e2e-write-skill.test.ts\teslint(no-unused-vars)\tIdentifier 'describe' is imported but never used.": 1, + "test/skill-routing-e2e.test.ts\teslint(no-unused-vars)\tType 'EvalTestEntry' is imported but never used.": 1, + "test/sync-gbrain-source-probe.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '`'": 2, + "test/test-free-shards.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/touchfiles.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "test/train-backstop.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#endsWith over a regex with a dollar sign.": 1, + "test/typecheck-test-ratchet.test.ts\teslint(no-useless-escape)\tUnnecessary escape character '\"'": 2, + "test/ubicloud-runner.test.ts\tunicorn(no-useless-fallback-in-spread)\tEmpty fallbacks in spreads are unnecessary": 1, + "test/user-slug-fallback.test.ts\teslint(no-unused-vars)\tIdentifier 'mkdirSync' is imported but never used.": 1, + "test/voice-directive.test.ts\teslint(no-unused-vars)\tIdentifier 'readFileSync' is imported but never used.": 1, + "test/workflow-concurrency.test.ts\tunicorn(prefer-string-starts-ends-with)\tPrefer String#startsWith over a regex with a caret.": 1, + "test/workflow-judge-cache.test.ts\tunicorn(no-useless-spread)\tUsing a spread operator here creates a new array unnecessarily.": 1, + "test/worktree.test.ts\teslint(no-unused-vars)\tType 'HarvestResult' is imported but never used.": 1 + } +} diff --git a/scripts/lint-ratchet.ts b/scripts/lint-ratchet.ts new file mode 100755 index 000000000..c6dd0b551 --- /dev/null +++ b/scripts/lint-ratchet.ts @@ -0,0 +1,192 @@ +#!/usr/bin/env -S bun --no-env-file --config=/dev/null +/** + * oxlint ratchet: `bun run lint [--write-baseline [--oxlint-upgrade]]`. + * + * oxlint runs its correctness rules (.oxlintrc.json) over the repository. + * Existing findings are held to a committed baseline, keyed the way + * scripts/typecheck-test.ts keys test-code diagnostics: file + rule + message, + * line-insensitive, mapped to how many times it occurs. Every failure prints a + * stable code: + * LINT_RATCHET_NEW a new finding, or one more of a known finding + * LINT_RATCHET_FIXED a finding was fixed; --write-baseline locks it in + * LINT_BASELINE_INVALID the baseline is unreadable, malformed or written + * by another oxlint version; never rewritten on its own + * OXLINT_MISSING oxlint is not installed at package.json's pin + * OXLINT_CRASH oxlint exited without a report + * --write-baseline only shrinks the allowance. The baseline header records + * the oxlint version, which must equal package.json's exact pin; an oxlint + * bump rewrites the baseline with --write-baseline --oxlint-upgrade in the + * same change, so the growth shows up in review. + */ +import { spawnSync } from 'node:child_process'; +import * as fs from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import { bunIsolationArgs } from '../lib/bun-isolation'; +import { compareDiagnostics, type DiagnosticCounts } from './typecheck-test'; + +export const BASELINE_FILE = 'scripts/lint-baseline.json'; +export const CONFIG_FILE = '.oxlintrc.json'; +const ROOT = path.resolve(import.meta.dir, '..'); + +export interface LintBaseline { oxlint: string; findings: DiagnosticCounts } +export interface Findings { counts: DiagnosticCounts; lines: Record } +export interface OxlintRun { status: number | null; signal?: string | null; error?: Error; stdout: string; stderr: string } +export interface LintResult { exitCode: number; out: string[]; err: string[] } + +class LintFailure extends Error {} + +const sorted = (counts: DiagnosticCounts): DiagnosticCounts => + Object.fromEntries(Object.entries(counts).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))); + +/** Parse `oxlint --format json` into identity -> count, plus the lines each identity sits on (for messages only). */ +export function parseFindings(report: string): Findings { + const diagnostics = (JSON.parse(report) as { diagnostics?: unknown }).diagnostics; + if (!Array.isArray(diagnostics)) throw new Error('report has no diagnostics array'); + const counts: DiagnosticCounts = {}, lines: Record = {}; + for (const d of diagnostics as Array<{ filename: string; code?: string; message: string; labels?: Array<{ span?: { line?: number } }> }>) { + const identity = `${d.filename.replaceAll('\\', '/')}\t${d.code ?? 'syntax-error'}\t${d.message.trim()}`; + counts[identity] = (counts[identity] ?? 0) + 1; + (lines[identity] ??= []).push(d.labels?.[0]?.span?.line ?? 0); + } + return { counts: sorted(counts), lines }; +} + +export function readBaseline(file: string): LintBaseline { + const invalid = (why: string) => new LintFailure(`LINT_BASELINE_INVALID: ${BASELINE_FILE} ${why}. ` + + `It is never rewritten automatically: restore it with \`git checkout origin/main -- ${BASELINE_FILE}\`, then rerun bun run lint.`); + let parsed: { version?: unknown; oxlint?: unknown; findings?: unknown }; + try { + parsed = JSON.parse(fs.readFileSync(file, 'utf8')); + } catch (error) { + throw invalid(`is missing or unreadable (${(error as Error).message})`); + } + const { version, oxlint, findings } = parsed ?? {}; + if (version !== 1 || typeof oxlint !== 'string' || !findings || typeof findings !== 'object' || Array.isArray(findings) || + !Object.values(findings).every(n => Number.isSafeInteger(n) && (n as number) > 0)) { + throw invalid('is malformed (expected { "version": 1, "oxlint": "", "findings": { "": } })'); + } + return { oxlint, findings: findings as DiagnosticCounts }; +} + +function pinnedVersion(root: string): string { + const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')) as { devDependencies?: Record }; + const pin = pkg.devDependencies?.oxlint; + if (!pin || !/^\d+\.\d+\.\d+$/.test(pin)) { + throw new LintFailure(`LINT_BASELINE_INVALID: package.json must pin oxlint to an exact version in devDependencies (found ${pin ?? 'none'}), so ${BASELINE_FILE} can name the version it was written by.`); + } + return pin; +} + +function installedVersion(root: string, pin: string): string { + let installed: string | undefined; + try { + installed = (JSON.parse(fs.readFileSync(path.join(root, 'node_modules', 'oxlint', 'package.json'), 'utf8')) as { version?: string }).version; + } catch { + throw new LintFailure('OXLINT_MISSING: oxlint is not installed (node_modules/oxlint). Run: bun install'); + } + if (installed !== pin) throw new LintFailure(`OXLINT_MISSING: installed oxlint ${installed} does not match package.json's pin ${pin}. Run: bun install`); + return installed; +} + +/** The report goes to a file: under Bun, oxlint's CLI exits before a piped stdout drains (a 406 KB report arrived as 219 KB). */ +export function runOxlint(root: string): OxlintRun { + const bin = path.join(root, 'node_modules', 'oxlint', 'bin', 'oxlint'); + const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-oxlint-')); + const report = path.join(dir, 'report.json'); + const fd = fs.openSync(report, 'w'); + try { + const run = spawnSync(process.execPath, [...bunIsolationArgs(), bin, '-c', CONFIG_FILE, '--format', 'json'], { + cwd: root, encoding: 'utf8', timeout: 120_000, maxBuffer: 64 * 1024 * 1024, stdio: ['ignore', fd, 'pipe'], + }); + return { status: run.status, signal: run.signal, error: run.error, stdout: fs.readFileSync(report, 'utf8'), stderr: run.stderr ?? '' }; + } finally { + fs.closeSync(fd); + fs.rmSync(dir, { recursive: true, force: true }); + } +} + +function writeBaseline(file: string, oxlint: string, findings: DiagnosticCounts): void { + fs.writeFileSync(file, JSON.stringify({ version: 1, oxlint, findings: sorted(findings) }, null, 2) + '\n'); +} + +function describe(identity: string, lines: number[] = []): string { + const [file, rule, message] = identity.split('\t'); + return `${file}${lines.length ? `:${lines.join(',')}` : ''} ${rule}: ${message}`; +} + +export function runLint(options: { write?: boolean; upgrade?: boolean; root?: string; oxlint?: (root: string) => OxlintRun } = {}): LintResult { + const root = options.root ?? ROOT, out: string[] = [], err: string[] = []; + const done = (exitCode: number): LintResult => ({ exitCode, out, err }); + if (options.upgrade && !options.write) { + err.push('lint ratchet: --oxlint-upgrade only goes with --write-baseline.'); + return done(2); + } + const baselinePath = path.join(root, BASELINE_FILE); + let pin: string, installed: string, baseline: LintBaseline; + try { + pin = pinnedVersion(root); + baseline = readBaseline(baselinePath); + installed = installedVersion(root, pin); + } catch (error) { + if (!(error instanceof LintFailure)) throw error; + err.push(error.message); + return done(2); + } + if (options.upgrade && baseline.oxlint === pin) { + err.push(`lint ratchet: --oxlint-upgrade rewrites a baseline written by another oxlint version, and ${BASELINE_FILE} already matches the pin ${pin}. Use --write-baseline, which only shrinks.`); + return done(2); + } + if (!options.upgrade && baseline.oxlint !== pin) { + err.push(`LINT_BASELINE_INVALID: ${BASELINE_FILE} was written by oxlint ${baseline.oxlint}, and package.json pins ${pin}. ` + + 'Rewrite it for the new pin in the same change: bun run lint --write-baseline --oxlint-upgrade'); + return done(2); + } + const run = (options.oxlint ?? runOxlint)(root); + let current: Findings | undefined; + try { + if (!run.error && !run.signal && (run.status === 0 || run.status === 1)) current = parseFindings(run.stdout); + } catch { + current = undefined; + } + if (!current) { + const why = run.error?.message ?? (run.signal ? `signal ${run.signal}` : `exit ${run.status}`); + err.push(`OXLINT_CRASH: oxlint ${installed} (config ${CONFIG_FILE}) ended without a report (${why}).`); + const tail = `${run.stderr}${run.stdout}`.trim().split(/\r?\n/).slice(-20).join('\n'); + if (tail) err.push(tail); + return done(2); + } + const total = Object.values(current.counts).reduce((sum, n) => sum + n, 0); + if (options.upgrade) { + writeBaseline(baselinePath, pin, current.counts); + out.push(`lint ratchet: rewrote ${BASELINE_FILE} for oxlint ${pin} (was ${baseline.oxlint}; ${total} findings, ${Object.keys(current.counts).length} identities). Review the growth in the diff.`); + return done(0); + } + const { added, fixed } = compareDiagnostics(baseline.findings, current.counts); + if (added.length) { + err.push(`LINT_RATCHET_NEW: ${added.length} new or more frequent oxlint finding(s). Fix them; do not add them to the baseline.`); + for (const d of added) err.push(` + ${describe(d.identity, current.lines[d.identity])} (${d.baseline} → ${d.current})`); + err.push(`Reproduce with: bunx oxlint -c ${CONFIG_FILE} ${[...new Set(added.map(d => d.identity.split('\t')[0]))].join(' ')}`); + if (options.write) err.push('--write-baseline only shrinks the baseline; it never adds a finding.'); + return done(1); + } + if (options.write) { + writeBaseline(baselinePath, pin, current.counts); + out.push(`lint ratchet: wrote ${BASELINE_FILE} (${total} findings, ${Object.keys(current.counts).length} identities, ${fixed.length} lowered or removed).`); + return done(0); + } + if (fixed.length) { + err.push(`LINT_RATCHET_FIXED: ${fixed.length} finding(s) fixed. Lock the smaller allowance in with: bun run lint --write-baseline (it only shrinks)`); + for (const d of fixed) err.push(` - ${describe(d.identity)} (${d.baseline} → ${d.current})`); + return done(1); + } + out.push(`lint ratchet: ${total} known findings, none new (oxlint ${pin}).`); + return done(0); +} + +if (import.meta.main) { + const result = runLint({ write: process.argv.includes('--write-baseline'), upgrade: process.argv.includes('--oxlint-upgrade') }); + for (const line of result.out) console.log(line); + for (const line of result.err) console.error(line); + process.exit(result.exitCode); +} diff --git a/test/free-tests-workflow-wiring.test.ts b/test/free-tests-workflow-wiring.test.ts index 613936f0d..511256bb8 100644 --- a/test/free-tests-workflow-wiring.test.ts +++ b/test/free-tests-workflow-wiring.test.ts @@ -61,7 +61,7 @@ describe('free-tests workflow wiring', () => { expect(gate.env.TYPECHECK_RESULT).toBe('${{ needs.typecheck.result }}'); expect(gate.run).toContain('test "$TYPECHECK_RESULT" = success'); const typecheck = workflow.jobs.typecheck.steps.map((step: any) => step.run).filter(Boolean); - expect(typecheck).toEqual(expect.arrayContaining(['bun run typecheck', 'bun run typecheck:test', 'bun run format:cso:check'])); + expect(typecheck).toEqual(expect.arrayContaining(['bun run typecheck', 'bun run typecheck:test', 'bun run lint', 'bun run format:cso:check'])); expect(source).not.toContain('--quick'); }); diff --git a/test/lint-ratchet.test.ts b/test/lint-ratchet.test.ts new file mode 100644 index 000000000..01ce746e7 --- /dev/null +++ b/test/lint-ratchet.test.ts @@ -0,0 +1,148 @@ +import { afterEach, describe, expect, test } from 'bun:test'; +import * as fs from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import { BASELINE_FILE, parseFindings, readBaseline, runLint, type OxlintRun } from '../scripts/lint-ratchet'; + +const PIN = '1.2.3'; +const roots: string[] = []; + +type Finding = { file: string; rule?: string; message: string; line: number }; +const report = (findings: Finding[]) => JSON.stringify({ + diagnostics: findings.map(f => ({ filename: f.file, code: f.rule, message: f.message, severity: 'error', labels: [{ span: { line: f.line, column: 1 } }] })), +}); +const oxlint = (findings: Finding[], status = findings.length ? 1 : 0) => (): OxlintRun => ({ status, signal: null, stdout: report(findings), stderr: '' }); + +const unused = { file: 'src/a.ts', rule: 'eslint(no-unused-vars)', message: "Identifier 'fs' is imported but never used.", line: 3 }; +const escape = { file: 'src/b.ts', rule: 'eslint(no-useless-escape)', message: 'Unnecessary escape character \'.\'', line: 9 }; + +function fixture(options: { pin?: string; installed?: string | null; baseline?: unknown } = {}): string { + const root = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-lint-ratchet-')); + roots.push(root); + fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify({ devDependencies: { oxlint: options.pin ?? PIN } })); + if (options.installed !== null) { + fs.mkdirSync(path.join(root, 'node_modules', 'oxlint'), { recursive: true }); + fs.writeFileSync(path.join(root, 'node_modules', 'oxlint', 'package.json'), JSON.stringify({ version: options.installed ?? PIN })); + } + fs.mkdirSync(path.join(root, 'scripts'), { recursive: true }); + if (options.baseline !== undefined) { + const text = typeof options.baseline === 'string' ? options.baseline : JSON.stringify(options.baseline); + fs.writeFileSync(path.join(root, BASELINE_FILE), text); + } + return root; +} +const baselineOf = (findings: Finding[], oxlintVersion = PIN) => ({ version: 1, oxlint: oxlintVersion, findings: parseFindings(report(findings)).counts }); +const baselineBytes = (root: string) => fs.readFileSync(path.join(root, BASELINE_FILE), 'utf8'); + +afterEach(() => { + for (const root of roots.splice(0)) fs.rmSync(root, { recursive: true, force: true }); +}); + +describe('oxlint ratchet', () => { + test('identity is file + rule + message: repeats count, lines do not matter, a missing rule is a syntax error', () => { + const counts = parseFindings(report([unused, { ...unused, line: 40 }, { file: 'src\\c.ts', message: 'Identifier `os` has already been declared', line: 22 }])).counts; + expect(counts).toEqual({ + "src/a.ts\teslint(no-unused-vars)\tIdentifier 'fs' is imported but never used.": 2, + 'src/c.ts\tsyntax-error\tIdentifier `os` has already been declared': 1, + }); + expect(parseFindings(report([{ ...unused, line: 300 }])).counts).toEqual(parseFindings(report([unused])).counts); + }); + + test('a clean tree passes, and a known finding that moved lines still passes', () => { + const root = fixture({ baseline: baselineOf([unused, escape]) }); + const result = runLint({ root, oxlint: oxlint([{ ...unused, line: 120 }, escape]) }); + expect(result).toEqual({ exitCode: 0, out: [`lint ratchet: 2 known findings, none new (oxlint ${PIN}).`], err: [] }); + }); + + test('LINT_RATCHET_NEW names file:line, rule, the fix text and a reproduce command', () => { + const root = fixture({ baseline: baselineOf([unused]) }); + const result = runLint({ root, oxlint: oxlint([unused, { ...unused, line: 7 }, escape]) }); + expect(result.exitCode).toBe(1); + expect(result.err).toEqual([ + 'LINT_RATCHET_NEW: 2 new or more frequent oxlint finding(s). Fix them; do not add them to the baseline.', + " + src/a.ts:3,7 eslint(no-unused-vars): Identifier 'fs' is imported but never used. (1 → 2)", + " + src/b.ts:9 eslint(no-useless-escape): Unnecessary escape character '.' (0 → 1)", + 'Reproduce with: bunx oxlint -c .oxlintrc.json src/a.ts src/b.ts', + ]); + }); + + test('LINT_RATCHET_FIXED asks for --write-baseline, which shrinks the baseline', () => { + const root = fixture({ baseline: baselineOf([unused, escape]) }); + const fixed = runLint({ root, oxlint: oxlint([escape]) }); + expect(fixed.exitCode).toBe(1); + expect(fixed.err[0]).toBe('LINT_RATCHET_FIXED: 1 finding(s) fixed. Lock the smaller allowance in with: bun run lint --write-baseline (it only shrinks)'); + expect(fixed.err[1]).toContain('src/a.ts eslint(no-unused-vars)'); + expect(runLint({ root, write: true, oxlint: oxlint([escape]) }).exitCode).toBe(0); + expect(readBaseline(path.join(root, BASELINE_FILE))).toEqual({ oxlint: PIN, findings: parseFindings(report([escape])).counts }); + expect(runLint({ root, oxlint: oxlint([escape]) }).exitCode).toBe(0); + }); + + test('--write-baseline never grows the baseline: a new finding refuses and leaves the file untouched', () => { + const root = fixture({ baseline: baselineOf([unused]) }); + const before = baselineBytes(root); + const result = runLint({ root, write: true, oxlint: oxlint([escape]) }); + expect(result.exitCode).toBe(1); + expect(result.err[0]).toStartWith('LINT_RATCHET_NEW:'); + expect(result.err.at(-1)).toBe('--write-baseline only shrinks the baseline; it never adds a finding.'); + expect(baselineBytes(root)).toBe(before); + }); + + test('LINT_BASELINE_INVALID for a missing, malformed or other-version baseline, never rewritten', () => { + const missing = fixture(); + const result = runLint({ root: missing, write: true, oxlint: oxlint([]) }); + expect(result.exitCode).toBe(2); + expect(result.err[0]).toStartWith('LINT_BASELINE_INVALID: scripts/lint-baseline.json is missing or unreadable'); + expect(result.err[0]).toContain('never rewritten automatically'); + expect(fs.existsSync(path.join(missing, BASELINE_FILE))).toBe(false); + for (const bad of ['{not json', { version: 2, oxlint: PIN, findings: {} }, { version: 1, findings: {} }, { version: 1, oxlint: PIN, findings: { x: 0 } }]) { + const root = fixture({ baseline: bad }); + const before = baselineBytes(root); + const invalid = runLint({ root, write: true, oxlint: oxlint([]) }); + expect(invalid.exitCode).toBe(2); + expect(invalid.err[0]).toStartWith('LINT_BASELINE_INVALID:'); + expect(baselineBytes(root)).toBe(before); + } + const stale = fixture({ baseline: baselineOf([unused], '1.0.0') }); + const old = runLint({ root: stale, oxlint: oxlint([unused]) }); + expect(old.exitCode).toBe(2); + expect(old.err).toEqual([`LINT_BASELINE_INVALID: scripts/lint-baseline.json was written by oxlint 1.0.0, and package.json pins ${PIN}. Rewrite it for the new pin in the same change: bun run lint --write-baseline --oxlint-upgrade`]); + const range = runLint({ root: fixture({ pin: '^1.2.3', baseline: baselineOf([]) }), oxlint: oxlint([]) }); + expect(range.err[0]).toStartWith('LINT_BASELINE_INVALID: package.json must pin oxlint to an exact version'); + }); + + test('--oxlint-upgrade rewrites only a baseline from another oxlint version', () => { + const root = fixture({ baseline: baselineOf([unused], '1.0.0') }); + const upgraded = runLint({ root, write: true, upgrade: true, oxlint: oxlint([unused, escape]) }); + expect(upgraded.exitCode).toBe(0); + expect(readBaseline(path.join(root, BASELINE_FILE))).toEqual({ oxlint: PIN, findings: parseFindings(report([unused, escape])).counts }); + const again = runLint({ root, write: true, upgrade: true, oxlint: oxlint([unused, escape]) }); + expect(again.exitCode).toBe(2); + expect(again.err[0]).toContain('Use --write-baseline, which only shrinks.'); + expect(runLint({ root, upgrade: true, oxlint: oxlint([]) }).err).toEqual(['lint ratchet: --oxlint-upgrade only goes with --write-baseline.']); + }); + + test('OXLINT_MISSING when oxlint is absent or not at the pin', () => { + const absent = runLint({ root: fixture({ installed: null, baseline: baselineOf([]) }), oxlint: oxlint([]) }); + expect(absent).toMatchObject({ exitCode: 2, err: ['OXLINT_MISSING: oxlint is not installed (node_modules/oxlint). Run: bun install'] }); + const drift = runLint({ root: fixture({ installed: '1.2.4', baseline: baselineOf([]) }), oxlint: oxlint([]) }); + expect(drift.err).toEqual([`OXLINT_MISSING: installed oxlint 1.2.4 does not match package.json's pin ${PIN}. Run: bun install`]); + }); + + test('OXLINT_CRASH prints the oxlint version, the config path and the output tail', () => { + const root = fixture({ baseline: baselineOf([]) }); + const crashed = runLint({ root, oxlint: () => ({ status: 2, signal: null, stdout: '', stderr: 'Failed to parse configuration file' }) }); + expect(crashed.exitCode).toBe(2); + expect(crashed.err).toEqual([`OXLINT_CRASH: oxlint ${PIN} (config .oxlintrc.json) ended without a report (exit 2).`, 'Failed to parse configuration file']); + const truncated = runLint({ root, oxlint: () => ({ status: 1, signal: null, stdout: report([unused]).slice(0, 40), stderr: '' }) }); + expect(truncated.err[0]).toStartWith('OXLINT_CRASH:'); + }); + + test('the committed baseline is readable and written by the oxlint package.json pins', () => { + const root = path.resolve(import.meta.dir, '..'); + const pin = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')).devDependencies.oxlint; + expect(pin).toMatch(/^\d+\.\d+\.\d+$/); + const baseline = readBaseline(path.join(root, BASELINE_FILE)); + expect(baseline.oxlint).toBe(pin); + expect(Object.keys(baseline.findings).length).toBeGreaterThan(0); + }); +});