Source profileQuality 91/100

andymai/brepjs/.claude/skills/ci-triage/SKILL.md

ci-triage

This skill should be used when a brepjs GitHub Actions job is red or behaving oddly on github.com (a remote CI run, not a local pre-commit/pre-push hook) — "CI failed", "ci-pass is failing", "npm ci failed with EUSAGE/ETARGET in CI", "test shard timed out", "function-lookup.md diff failed in the build job", "check:patterns fails in CI on code I didn't touch", "npm publish workflow failed", "docs deploy didn't run", "playground smoke is red", "OSV scan is red", "release PR won't auto-merge", or n

Source repository stars
90
Declared platforms
0
Static risk flags
1
Last source update
2026-08-23
Source checked
2026-08-25

Decision brief

What it does: where it fits

Diagnose a red or stuck brepjs GitHub Actions run. Triage in two moves: first classify which workflow and job failed and on what event (PR vs push-to-main vs manual dispatch vs deployment); then match the symptom to the table below.

Best for

    Not for

    • Tasks that require unconfirmed production actions or broad system permissions.
    • Environments where the pinned source and install steps cannot be inspected.

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/andymai/brepjs --skill ".claude/skills/ci-triage"
    Safe inspection promptEditorial

    Inspect the Agent Skill "ci-triage" from https://github.com/andymai/brepjs/blob/a307db9979ae5b70271d80b9365ff7850ea41ff2/.claude/skills/ci-triage/SKILL.md at commit a307db9979ae5b70271d80b9365ff7850ea41ff2. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      npm ci fails with EUSAGE in every job's setup step

      Lock file out of sync with package.json ("lock file does not satisfy"). Classic trigger: a Dependabot group bump silently drops the two top-level @emnapi/ peer-dep entries (package-lock.json nodemodules/@emnapi/core + nodemodules/@emnapi/runtime, lines 1180-1201) that satisfy @n…

      Lock file out of sync with package.json ("lock file does not satisfy"). Classic trigger: a Dependabot group bump silently drops the two top-level @emnapi/ peer-dep entries (package-lock.json nodemodules/@emnapi/core + n…
    2. 02

      Job map — what runs, when

      The single required PR check is ci-pass (ci.yml:431-459). It needs every gate job and fails if any result is failure or cancelled (a skipped result passes). Its needs-list: changes, typecheck, lint, quality, build, playground-build, packages-viewer, packages-verify, packages-she…

      The single required PR check is ci-pass (ci.yml:431-459). It needs every gate job and fails if any result is failure or cancelled (a skipped result passes). Its needs-list: changes, typecheck, lint, quality, build, play…The changes job (ci.yml:18-67) path-filters into three outputs — code, playground, voxel — that gate the rest. Branches named release-please-- skip the filter entirely (ci.yml:29-36): release PRs run no code jobs (they…Consequence: a PR failure can never come from coverage (push-only); a main-only failure can never come from size/benchmark (PR-only).
    3. 03

      Symptom → cause → fix

      Ordered roughly by frequency.

      release-please re-pin: the node-workspace plugin repins a leaf's brepjs dep to a pending (unmerged) root release version. This is why leaf release PRs are held until root merges+publishes (see auto-merge below).0.x caret exclusion: a ^0. range excludes the next 0.(x+1) minor, so an internal bump 404s any consumer still on the caret.Root brepjs: gh workflow run release-please.yml -f republish=true (input at release-please.yml:6-12; publish gate at :146-149).
    4. 04

      npm ci fails with ETARGET / 404 on an internal package (in a CI run)

      An internal workspace package is pinned to a version not yet on npm. Two causes:

      release-please re-pin: the node-workspace plugin repins a leaf's brepjs dep to a pending (unmerged) root release version. This is why leaf release PRs are held until root merges+publishes (see auto-merge below).0.x caret exclusion: a ^0. range excludes the next 0.(x+1) minor, so an internal bump 404s any consumer still on the caret.An internal workspace package is pinned to a version not yet on npm. Two causes:
    5. 05

      build job fails on git diff --exit-code docs/function-lookup.md

      A Fns.ts change added/renamed an exported function but docs/function-lookup.md wasn't regenerated (the gate at ci.yml:112-117 runs docs:generate-lookup → prettier --write → diff; pre-commit only reminds, so it's easy to miss locally). Fix: regenerate + prettier-align + commit th…

      A Fns.ts change added/renamed an exported function but docs/function-lookup.md wasn't regenerated (the gate at ci.yml:112-117 runs docs:generate-lookup → prettier --write → diff; pre-commit only reminds, so it's easy to…

    Permission review

    Static risk signals and limitations

    Reads files

    low · line 65

    The documentation asks the agent to read local files, directories, or repositories.

    `smoke` runs the **built** brepjs-cad CLI under plain node (catches bin/TS-load breaks that tsx/vitest hide in-repo). `smoke:standalone` packs the tarball into a clean project with **no brepjs present** (catches bundling / fallback-resolve

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score91/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars90SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    andymai/brepjs
    Skill path
    .claude/skills/ci-triage/SKILL.md
    Commit
    a307db9979ae5b70271d80b9365ff7850ea41ff2
    License
    Apache-2.0
    Collected
    2026-08-25
    Default branch
    main
    View the original SKILL.md

    CI failure triage

    Diagnose a red or stuck brepjs GitHub Actions run. Triage in two moves: first classify which workflow and job failed and on what event (PR vs push-to-main vs manual dispatch vs deployment); then match the symptom to the table below.

    Most failure modes are documented in inline comments in the workflow files themselves — cite line refs (e.g. .github/workflows/ci.yml:244-250) rather than re-deriving. This skill is the index and the recovery recipes.

    Job map — what runs, when

    The single required PR check is ci-pass (ci.yml:431-459). It needs every gate job and fails if any result is failure or cancelled (a skipped result passes). Its needs-list: changes, typecheck, lint, quality, build, playground-build, packages-viewer, packages-verify, packages-sheetmetal, packages-bim, voxel-wasm-rust, test, size, benchmark. Deliberately not in the list: coverage.

    The changes job (ci.yml:18-67) path-filters into three outputs — code, playground, voxel — that gate the rest. Branches named release-please--* skip the filter entirely (ci.yml:29-36): release PRs run no code jobs (they touch only CHANGELOG/version/manifest).

    JobCommand(s)Event / gate
    typechecknpm run typecheckPR+push, code
    lintnpm run lint + format:checkPR+push, code
    qualitycheck:boundaries + check:patterns + knipPR+push, code
    buildnpm run build + docs:api + function-lookup staleness gatePR+push, code
    playground-buildbuild root + brepjs-bim + brepjs-sheetmetal + apps/playground (mirrors Vercel)PR+push, playground
    packages-viewer / -sheetmetal / -bimtypecheck+lint+test+build per workspace (root build first for -sheetmetal/-bim; viewer builds no root)PR+push, code
    packages-verify (brepjs-cad)build root+viewer+cad, then eval, smoke, smoke:standalonePR+push, code
    voxel-wasm-rustcargo test + cargo clippy -D warningsPR+push, voxel only
    testtest:ci --shard=N/4, matrix [1,2,3,4]PR+push, code
    coveragetest:full (maxWorkers=2, timeout 180s)push-only, continue-on-error
    sizesize-limit-actionPR-only
    benchmarkcompare vs main, 25% regression thresholdPR-only

    Consequence: a PR failure can never come from coverage (push-only); a main-only failure can never come from size/benchmark (PR-only).

    Concurrency: ci-${{ github.ref }}, cancel-in-progress on non-main refs only (ci.yml:10-12).

    Symptom → cause → fix

    Ordered roughly by frequency.

    npm ci fails with EUSAGE in every job's setup step

    Lock file out of sync with package.json ("lock file does not satisfy"). Classic trigger: a Dependabot group bump silently drops the two top-level @emnapi/* peer-dep entries (package-lock.json node_modules/@emnapi/core + node_modules/@emnapi/runtime, ~lines 1180-1201) that satisfy @napi-rs/wasm-runtime's peerDependencies (~lines 2285-2286). Fix: surgically restore the dropped entries — never regenerate the lockfile from scratch. Run --package-lock-only from main to reproduce the correct shape. See the git-pr-workflow and companion-packages skills for lockfile-surgery discipline.

    npm ci fails with ETARGET / 404 on an internal package (in a CI run)

    An internal workspace package is pinned to a version not yet on npm. Two causes:

    1. release-please re-pin: the node-workspace plugin repins a leaf's brepjs dep to a pending (unmerged) root release version. This is why leaf release PRs are held until root merges+publishes (see auto-merge below).
    2. 0.x caret exclusion: a ^0.<older> range excludes the next 0.(x+1) minor, so an internal bump 404s any consumer still on the caret.

    Fix: use an open floor range, not a pin. Main already does this — packages/brepjs-cad/package.json:60 ("brepjs": ">=18.117.1") and packages/brepjs-voxel/package.json:24 ("brepjs-voxel-wasm": ">=0.2.0"). Full mechanics in the release-publishing skill.

    Note: for internal workspace devDeps the "*" wildcard is intentional (e.g. brepjs-cad's "brepjs-viewer": "*", package.json:81) — pinning it to a concrete version is what repeatedly broke npm ci when the pin outran what was published. A Dependabot alert on such a "*" spec is a false positive: raise the floor (>=x.y.z) if it must be cleared, don't pin it or bump the lockfile.

    build job fails on git diff --exit-code docs/function-lookup.md

    A *Fns.ts change added/renamed an exported function but docs/function-lookup.md wasn't regenerated (the gate at ci.yml:112-117 runs docs:generate-lookupprettier --write → diff; pre-commit only reminds, so it's easy to miss locally). Fix: regenerate + prettier-align + commit the file — full recipe in the adding-operations skill.

    quality job fails check:patterns on code the PR didn't touch

    An unbaselined pattern violation reached main and now fails the quality job on every open PR at once. Fix: land a tiny baseline-bump PR first, then rebase the others. Mechanism and baseline mechanics live in the quality-gates skill.

    test shard times out or stalls

    OCCT WASM linear memory grows monotonically across tests; a long run over-commits the 16 GB runner into swap and a fork stalls past the 90s per-test timeout (#1102, rationale at ci.yml:244-250). The 4-way shard exists precisely so each fork exits before accumulation hits that threshold. Do not "fix" by widening the timeout. Check whether one shard is genuinely slower (real leak / new heavy test) or just an infra blip — re-run the single shard. Coverage can't shard (vitest --merge-reports can't recombine v8 coverage here), which is why the coverage job runs single-runner with a raised timeout. Test-authoring details in the writing-tests skill.

    packages-verify fails on smoke or smoke:standalone

    smoke runs the built brepjs-cad CLI under plain node (catches bin/TS-load breaks that tsx/vitest hide in-repo). smoke:standalone packs the tarball into a clean project with no brepjs present (catches bundling / fallback-resolve breaks invisible in-repo). A green in-repo test with a red standalone smoke means a packaging or resolution regression, not a logic bug. See the companion-packages skill.

    playground-build fails but the library builds fine

    Type-resolution or bundler regression scoped to apps/playground (this job mirrors what Vercel runs). Historical example: a duplicate @types/three install broke tsc -b only inside the playground (#963, ci.yml:119-137). See the playground-examples skill.

    npm publish failed

    Publishes are OIDC-bound to the exact workflow filename — inlining npm publish elsewhere fails auth. Never re-run the failed push-event job; re-dispatch the same workflow. Recovery recipes:

    • Root brepjs: gh workflow run release-please.yml -f republish=true (input at release-please.yml:6-12; publish gate at :146-149).
    • A satellite (cad/bim/sheetmetal/viewer/opencascade): gh workflow run publish-<pkg>.yml -f dry_run=false --ref <release-tag>dry_run defaults to true, and dispatch against the immutable tag, not main.

    Full recipe set and the OIDC-binding rationale: the release-publishing skill.

    prepack fails: "Too many files" or ".d.ts.map"

    scripts/validate-pack.sh (root prepack hook, package.json:216) caps the packed tarball at MAX_FILES=500 and rejects any .d.ts.map sidecars (count must be 0). It fires during pack/publish, not PR CI. Fix "too many files" by trimming the published set; fix .d.ts.map by keeping declarationMap off in vite.config.ts.

    "Deploy API Docs" didn't run after a main merge

    docs.yml triggers on workflow_run of CI completing on main with conclusion == 'success'. A red CI on main blocks the docs deploy. This is exactly why coverage is continue-on-error (ci.yml:260-266): an informational threshold dip must not flip CI's conclusion to failure and starve the docs gate. Emergency redeploy: gh workflow run docs.yml (workflow_dispatch bypasses the CI gate, main-only).

    "Playground Smoke" is red

    playground-smoke.yml runs on deployment_status from Vercel, loads the deployed playground headless, and requires the WASM kernel to reach Ready within 60s. A red here is a CSP / COEP / COOP / asset-path class regression that blocks engine init — not a build-class failure (the static build already passed).

    "OSV Scan" is red

    osv-scan.yml scans package-lock.json for known-vulnerable versions. It splits by event: scan-pr ("OSV Scan (report-only)") on pull requests never fails the merge (findings surface in the Security tab only), while scan-main ("OSV Scan (blocking)") on push-to-main and the weekly cron fails closed. So a red OSV check on a PR is informational; a red one on main is a real gate. Fix a genuine finding by bumping the vulnerable transitive dep (lockfile surgery, see git-pr-workflow).

    Dependabot flags a security alert on a workspace "*" dependency

    False positive. An internal devDep pinned to "*" (e.g. brepjs-cad's "brepjs-viewer": "*") is intentional — pinning it to a concrete version is what repeatedly broke npm ci. Fix: raise the spec floor to >=x.y.z if the alert must be cleared — do not pin the spec or bump the lockfile. Mechanism in the companion-packages skill.

    A release PR won't auto-merge

    Expected during a release train: while the root brepjs release PR (branch release-please--branches--main--components--brepjs) is open, every leaf PR (cad/bim/sheetmetal) is held; leaves auto-merge only after root merges+publishes. brepjs-opencascade is held permanently (manual, expensive WASM build). Mechanism at release-please.yml:57-133; deep dive in the release-publishing skill.

    Looks like a failure but isn't

    • coverage red on main: informational only (continue-on-error, push-only, out of ci-pass). Not a gate.
    • benchmark "main install failed" warning: continue-on-error on the main-baseline install so a broken main can't deadlock the PR that fixes it (ci.yml:323-330). The PR's own benchmark still runs; only the comparison is skipped.
    • benchmark shows ±9-15% noise: shared runners vary run-to-run; the threshold is 25% for that reason (ci.yml:366).
    • held release PRs: opencascade always held; leaves held while root is open. See above.
    • skipped jobs: a skipped needs result passes ci-pass — only failure/cancelled fail it.

    Blind spots — things CI never runs

    • alwaysExclude tests never execute in any CI project (vitest.config.ts): tests/brepkit-adapter.test.ts, tests/brepkit-validation.test.ts, tests/kernel-agreement.test.ts, tests/io-stress.test.ts, plus benchmarks/, the cad/viewer packages (own jobs), apps/, and worktree dirs. They rot silently — run them locally when touching that code.
    • The brepkit kernel is not a PR gate: the default gate runs occt-wasm only. Run npm run test:brepkit locally for brepkit-affecting changes (see kernel-abstraction).
    • apps/playground is outside root lint + vitest: only tsc -b (via playground-build) gates it in CI. See playground-examples.

    Stale docs — do not inherit

    CONTRIBUTING.md (~lines 222-235) lists coverage thresholds as 83/73/64/73 and claims "CI runs the full test suite with coverage enforcement." Both are wrong. Actual thresholds (vitest.config.ts): statements 85, branches 71, functions 91, lines 88. Coverage is main-only, informational, and continue-on-error — never a PR gate. Trust vitest.config.ts, not CONTRIBUTING.md.

    Additional resources

    Sibling skills (each fact lives in exactly one — link, don't duplicate):

    • release-publishing — release-please serialization (root-before-leaves), OIDC filename binding, per-package dispatch recipes, republish recovery, concurrency/label races.
    • quality-gates — check:patterns / knip / boundary rule details and baseline mechanics.
    • git-pr-workflow — hooks, conventional commits, worktrees, merge / auto-merge, lockfile surgery.
    • companion-packages — workspace deps, ETARGET / build order, workspace "*" specs.
    • writing-tests — test skeleton, shard/coverage authoring, kernel divergence skips.
    • adding-operations — the function-lookup gate and export surfaces.
    • playground-examples — the three playground gates (types, geometry, thumbnail).

    Frequently asked questions

    What to verify before installation and use

    What does the ci-triage source document cover?

    Diagnose a red or stuck brepjs GitHub Actions run. Triage in two moves: first classify which workflow and job failed and on what event (PR vs push-to-main vs manual dispatch vs deployment); then match the symptom to the table below.

    How do I install ci-triage?

    The source record exposes this install command: npx skills add https://github.com/andymai/brepjs --skill ".claude/skills/ci-triage". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged read-files in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 9660

    almanak-co/sdk

    almanak-strategy-builder

    Build, test, and deploy DeFi trading strategies using the Almanak SDK. ALWAYS use this skill when the user mentions almanak, DeFi strategy, trading strategy, yield farming, liquidity provision, token swap, borrowing, lending, perpetuals, staking, vault deposit, bridging tokens, backtesting, paper trading, or on-chain execution. Use for writing strategy.py files, composing intents (Swap, LP, Borrow, Supply, Perp, Bridge, Stake, Vault, Prediction), working with config.json strategy parameters, run

    Computed 9465

    brucesongs/kali-claw

    physical-security-testing

    Physical penetration testing covering mechanical lock bypass (pin-tubular/wafer), RFID/NFC badge cloning (Proxmark3/ESP-RFID-Tool/Walrus), HID iCLASS/Mifare duplication, drop box deployment (LAN Turtle/Packet Squirrel), USB weapons (Rubber Ducky/Bash Bunny), hidden camera placement, and on-site engagement operations including tailgating pretext preparation and physical-docs legal templates.

    Computed 9458

    kdeldycke/repomatic

    babysit-ci

    Monitor CI tests, lint, autofix, docs, and Nuitka binary-build workflows, diagnose failures, fix code, commit, and loop until all stable jobs pass. Ignores unstable failures.

    Computed 9357

    oaslananka/kicad-mcp-pro

    code-review

    Use this skill for GitHub Copilot pull request and code reviews in oaslananka/kicad-mcp-pro. Review Python MCP server changes, KiCad adapter and tool-contract changes, tests, npm/package wrappers, Tauri/Rust desktop code, GitHub Actions, security controls, documentation, generated metadata, and compatibility/release surfaces. Use it whenever reviewing a PR or diff in this repository, especially changes under src/, tests/, packages/, src-tauri/, .github/workflows/, or public MCP metadata/configur