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.
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
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
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.
npx skills add https://github.com/andymai/brepjs --skill ".claude/skills/ci-triage"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
- 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… - 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). - 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). - 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: - 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
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
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 91/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 90 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated 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).
| Job | Command(s) | Event / gate |
|---|---|---|
typecheck | npm run typecheck | PR+push, code |
lint | npm run lint + format:check | PR+push, code |
quality | check:boundaries + check:patterns + knip | PR+push, code |
build | npm run build + docs:api + function-lookup staleness gate | PR+push, code |
playground-build | build root + brepjs-bim + brepjs-sheetmetal + apps/playground (mirrors Vercel) | PR+push, playground |
packages-viewer / -sheetmetal / -bim | typecheck+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:standalone | PR+push, code |
voxel-wasm-rust | cargo test + cargo clippy -D warnings | PR+push, voxel only |
test | test:ci --shard=N/4, matrix [1,2,3,4] | PR+push, code |
coverage | test:full (maxWorkers=2, timeout 180s) | push-only, continue-on-error |
size | size-limit-action | PR-only |
benchmark | compare vs main, 25% regression threshold | PR-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:
- release-please re-pin: the node-workspace plugin repins a leaf's
brepjsdep 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.<older>range excludes the next0.(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-lookup → prettier --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 atrelease-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_rundefaults 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
coveragered on main: informational only (continue-on-error, push-only, out ofci-pass). Not a gate.- benchmark "main install failed" warning:
continue-on-erroron 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.
skippedjobs: a skippedneedsresult passesci-pass— onlyfailure/cancelledfail it.
Blind spots — things CI never runs
alwaysExcludetests 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, plusbenchmarks/, 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:brepkitlocally for brepkit-affecting changes (seekernel-abstraction). - apps/playground is outside root lint + vitest: only
tsc -b(viaplayground-build) gates it in CI. Seeplayground-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
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
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.
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.
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