.agents/skills/rstack-eco-ci-debug/SKILL.md
Use this skill to debug Rstack ecosystem CI failures without over-blaming the first Rspack commit that appears red in status data.
This version covers the Rspack stack.
Before starting, ask the user which local checkout paths they have available. Do not assume machine-specific paths.
git -C <rspack-path> command.pnpm.overrides to test specific Rspack versions (for example, during canary bisect). Ask for it before making approved temporary reproduction edits to package.json, pnpm-lock.yaml, or equivalent package-manager files.rstack-ecosystem-ci checkout — optional. If available, use its data/rspack.json as the first local status source. Pass the checkout path to local helpers that read git refs, for example scripts/rspack-status.sh --repo <ecosystem-ci-path>.gh for web-infra-dev/rspack and rstackjs/rstack-ecosystem-ci. If gh is unavailable, use origin/data:rspack.json from a local rstack-ecosystem-ci checkout, workflow/job URLs, and the GitHub connector or public pages where available; state any evidence gap in the report.Fetch the local Rspack repo before resolving commits:
git -C <rspack-path> fetch origin main --tags
Rspack eco-ci runs a downstream project matrix against a freshly built Rspack artifact. A suite turning red means that a specific combination failed:
current downstream project state + tested Rspack artifact
It does not automatically mean the visible Rspack pivot PR is the true root cause. Downstream dependency updates, snapshot changes, test logic changes, and Rspack release/canary windows can all create misleading pivots.
Some eco-ci failures are flaky even when they appear as a clean green-to-red transition. Repeated selector timeouts, browser navigation waits, dev-server readiness failures, and network-idle waits must be checked against old commit comments, old failed runs, and automation memory before attributing them to the current pivot.
Always distinguish:
Surface attribution: the Rspack commit/PR where status data first shows the suite red.Actual source: the PR, version window, or downstream change that actually introduced the failing condition.Failure signature: the stable error text, command, assertion diff, stack, or log block used to compare runs.Read the linked reference before using any of these tools. Do not ask the user generically "which tool do you want"; instead, suggest the specific tool that matches the situation. Only invoke a tool when its strict trigger conditions are met; do not run it "just in case".
Rspack status helper — use scripts/rspack-status.sh --repo <ecosystem-ci-path> when you need the latest and previous rows from data/rspack.json, including failed suite names, job URLs, and suite-set delta. Pass a JSON file path instead when you already have a local snapshot. This helper only summarizes status data; it does not inspect logs or attribute root causes.
Canary date bisect — use in Phase 1 only when the Rspack commit window is too coarse to attribute a PR and downstream causes have already been ruled out. Trigger this when all of the following are true:
Rsbuild config debug — use in Phase 1 or Phase 2 only when deciding whether the failing case is related to the current PR requires generated Rsbuild/Rspack config evidence. Trigger it when the user mentions DEBUG=rsbuild, asks whether a config is active, or the candidate PR changes behavior controlled by an option, plugin, loader, target, devtool, SSR setting, cache mode, or other config-gated path. Do not run it just because the suite is Rsbuild-based. Read references/rsbuild-config-debug.md before using it.
Automation daily triage — use instead of the local quick path when the request is a recurring/daily automation, asks for today's/latest Rspack eco-ci status, provides an automation id/memory, or requires delivery to a user/chat. Read references/automation-daily-triage.md before inspecting runs.
Deep PR debug — use in Phase 2 only after a specific Rspack source PR or version window has been identified and the user wants the technical reason behind the failure. Trigger this when all of the following are true:
PR report comment — use only after strict attribution identifies a merged source PR as the cause and the user wants to notify the PR author. The source PR can be in Rspack or in the downstream project under test. Trigger this only when:
Eco-ci debugging has two phases. Do not mix them up.
Use this path for local/manual runs, such as a provided workflow run/job, PR, commit window, or specific suite. For daily automation or latest-status monitoring, read references/automation-daily-triage.md instead.
reused: same suite and same failure signature as prior memory.new-signature: current signature differs from prior memory or baseline.new investigation: no reliable prior conclusion exists for this scope.flaky/pre-existing: the same signature predates the candidate PR or appears intermittently.inconclusive: evidence is insufficient or conflicting.new-signature / new investigation item.pr-report-comment.md guardrails are satisfied and the user explicitly asks to comment. Otherwise report no PR comment: <reason>.Goal: identify the actual source PR, date window, or downstream change that caused the suite to become red.
Run these checks first before doing deep pivot analysis. If any check fires with high confidence, produce the Phase 1 output immediately and skip unnecessary steps.
Same Rspack commit, different outcome
Actual source: downstream/test change (same Rspack SHA <sha> succeeded in run <green-id> and failed in run <red-id>).Known flaky or recurring failure signature
flaky or pre-existing recurring failure unless new evidence proves the PR made it deterministic.modernjs pure-esm-project client navigation timeouts waiting for #data have appeared before; do not attribute that signature to a surface pivot just because the latest visible pivot looks plausibly related.Actual source: flaky/pre-existing (same selector timeout was reported before candidate PR #<n>).Surface PR diff is unrelated to the failure signature
Actual source: not surface PR #<n> (diff only touches <unrelated-paths>; failure signature is <signature>).Config-gated hypothesis not active
Actual source: not surface PR #<n> (generated config does not enable <required option>, but the hypothesis requires it).Failure signature directly maps to surface PR changed files and active config
Actual source: surface PR #<n> (failure signature <signature> matches changed files <paths>).Only continue with the full process below if none of the fast-exit checks gives a clear answer.
Use these evidence sources:
@rspack-canary/core overrides in the downstream repo when the date or PR window is still too coarse.Process:
Phase 1 output:
Surface attribution: <PR shown by eco-ci pivot>
Actual source: <real PR, downstream PR, or version window>
Failure signature: <short signature>
Evidence: <run URLs, logs, canary results, or green/red pivots>
Confidence: high | medium | low
Notes: <why surface attribution is or is not responsible>
Only move to Phase 2 when there is a specific source PR or version window with enough evidence to inspect deeply.
Goal: explain why the identified PR caused the observed behavior.
Use this phase after Phase 1 has identified a candidate source. Read references/deep-pr-debug.md when the user asks for root cause, mechanism, or a fix direction.
Process:
Phase 2 output:
Candidate PR: <pr-number> <title>
Suite: <suite>
Verdict: caused | likely caused | not caused | inconclusive
Mechanism: <3-5 sentence explanation>
Evidence: <log URLs, code refs, reproduction results>
Confidence: high | medium | low
Next action: <fix in Rspack | fix downstream expectation | gather more evidence>
Use gh for specific job logs when available:
gh run view --job <job-id> --repo rstackjs/rstack-ecosystem-ci --log
For noisy logs, first isolate likely terminal failure blocks:
gh run view --job <job-id> --repo rstackjs/rstack-ecosystem-ci --log \
| grep -E -i -C 3 'error|fail|panic|✖' \
| head -200
Fall back to full logs when the filtered output misses the real failure.
Use combination testing in Phase 1 to separate Rspack changes from downstream changes.
Start with four conceptual combinations:
old downstream + old Rspack
old downstream + new Rspack
new downstream + old Rspack
new downstream + new Rspack
Keep the downstream command fixed and use the narrowest failing command possible.
For finer Rspack windows, ask whether to use the canary date bisect tool, then follow references/canary-date-bisect.md.
If the downstream project changed during the same window, test these pairs when practical:
old downstream + bad-window Rspack
old downstream + fixed Rspack
new downstream + bad-window Rspack
new downstream + fixed Rspack
This prevents wrongly attributing a downstream dependency/snapshot update to a later unrelated Rspack PR.
Keep reports compact and evidence-based:
For triage reports, use this structure for daily automation and local/manual runs:
Scope: <latest completed status | workflow run/job | PR | commit window | suite>.
Current run/job: <run-url>, testing <sha> — "<commit msg>". Omit fields that do not apply.
Comparison baseline: <previous run | previous green | prev release | provided baseline | none>.
Failing suites in scope: <suite list>.
Delta: <new-suite/new-signature/recovered/unchanged/not applicable>.
PR comments: <posted links or "none: <reason>">.
### <suite> — <new investigation | reused | updated | flaky/pre-existing>
Attribution: <exact attribution line>
Root cause: <3-5 sentences. Separate confirmed facts from likely inference. If flaky or pre-existing, say so in the first sentence and do not force a PR root cause.>
Evidence: <log URLs actually read; include current and pivot/baseline URLs when used>
Use exactly one attribution line shape per suite:
This failure started from <sha> — "<commit msg>". PR: <url>; author: <author>; date: <date>.
The prev release 66e23b5 was already failing with this same error.
This specific failure started from <sha> — "<commit msg>"; before that the suite was failing for a different reason already at prev release 66e23b5. PR: <url>; author: <author>; date: <date>.
This is a known flaky/pre-existing failure; the same signature appeared before <candidate-sha-or-pr>.
The current evidence is inconclusive; <candidate> is only a surface pivot because <missing-or-conflicting-evidence>.
Do not present a candidate PR as caused/likely-caused in the triage report unless the flaky-history check and any relevant config-gated check have both passed. Prefer inconclusive over a weak attribution.