| name | sdcorejs-debug |
| description | Systematic debugging skill for root-cause/fix of concrete bugs and failing tests. Use for debug, investigate, resolve, fix, root-cause, wrong behavior, flaky/CI/prod-only failure, runtime/build error, or performance anomaly. Use sdcorejs-test for write/run/plan tests without fix intent. Runtime-localized. |
| allowed-tools | Read, Write, Edit, Glob, Grep, Bash |
Debug - Evidence-Driven Root-Cause Workflow
Purpose
sdcorejs-debug owns safe root-cause analysis for concrete failures:
- reproduce locally or evidence-confirm the bug;
- isolate the smallest failing case;
- classify
debug_mode, bug_class, stack_profile, repro_status, and environment;
- form and falsify hypotheses with a visible Hypothesis Ledger;
- add temporary diagnostic instrumentation only when needed and track it;
- apply the smallest safe fix for the confirmed root cause;
- add or update a focused regression test when feasible;
- verify the original repro and regression surface;
- hand off to
sdcorejs-ship before any commit, PR, changelog, or release flow.
It does not own broad feature implementation, unrelated test-plan generation,
large new test suites, new test infrastructure, speculative fixes, direct Git
artifacts, destructive production reproduction, or weakening tests to get a
green result.
Shared Protocols
Before executing this skill:
- Read and apply
_refs/shared/tasklist.md for non-trivial execution tasks.
- Read and apply
_refs/shared/persona.md if a project persona exists.
- Read and apply
_refs/shared/project-context.md for project memory, resume checkpoints, summaries, specs/plans, tasks, and relevant memories.
- Current user request, current files, diffs, logs, failing tests, and command output override stored context.
- Before presenting user-facing choices, approval gates, yes/no questions, or mode selections, read and apply
_refs/shared/user-choice-prompt.md so options are presented as sequential numbered choices.
After the shared protocols and before edits, read these debugging refs:
_refs/shared/debugging-discipline.md
_refs/shared/debug-command-discovery.md
_refs/shared/debug-environment-guard.md
_refs/shared/debug-context.md
Routing Boundary
Use sdcorejs-debug for root-cause analysis and fixing bugs, including failing
tests when the user asks to debug, fix, investigate, resolve, or find root
cause.
Correct routing:
- "debug this failing test", "fix this failing Jest test", "root-cause this test failure", "investigate flaky test" ->
sdcorejs-debug.
- "write tests for X", "add unit tests", "run the test suite", "create UAT cases", "what should be tested?" ->
sdcorejs-test.
sdcorejs-test may do read-only failing-output triage only when the user asks to explain, classify, or summarize output without changes.
- When failing output implies a production bug or needs source changes,
sdcorejs-test hands off to sdcorejs-debug with test_context, test_evidence, and the smallest failing command.
sdcorejs-debug may add or update a small focused regression test during a bug fix when the existing runner and test style are clear. Large suites, new infrastructure, multiple test levels, complex UAT/e2e coverage, dependency installs, or browser binary installs belong to sdcorejs-test.
Do not invoke for feature requests phrased as new behavior, broad performance
tuning without a concrete anomaly, review findings sets that belong to
sdcorejs-repair-loop, or readiness/delivery checks that belong to
sdcorejs-ship.
Step 0 - Working-Tree And Context Preflight
Before any source edit, inspect and record:
git branch --show-current
git rev-parse HEAD
git status --short
git diff --staged --stat
git diff --staged --name-status
git diff --stat
git ls-files --others --exclude-standard
Preflight output must include:
working_tree_preflight:
branch:
current_HEAD:
staged_diffstat:
unstaged_diffstat:
untracked_files:
allowed_edit_scope:
unrelated_dirty_files:
generated_vendor_build_outputs:
Rules:
- If unrelated dirty files exist and this task did not already approve the dirty baseline, stop and ask one numbered choice:
- Continue but restrict edits to bug-scoped files.
- Continue and allow touching selected dirty files.
- Stop so the user can clean or stash changes first.
- If the workflow already approved dirty state for this task, record the baseline and proceed inside the allowed edit scope.
- Do not stage, commit, push, or create PRs from
sdcorejs-debug.
- Do not modify generated, vendor, build, coverage, cache, or runner output unless the bug is explicitly in generated artifacts and the repo convention supports editing them.
Step 1 - Classify The Debug Session
Classify before applying stack-specific guidance or editing files. Unknown is
valid when evidence is insufficient, and classifications may change when new
evidence arrives.
Required debug_mode values:
runtime-error | failing-test | wrong-behavior | flaky | ci-only | prod-only |
performance-anomaly | environment-config | dependency-regression |
security-sensitive | data-integrity | build-compile |
browser-device-specific | unknown
Required bug_class values:
null-or-undefined | async-race | state-lifecycle | validation |
permission-authz | authentication | routing | database-query |
transaction-consistency | serialization-deserialization | caching-staleness |
timezone-locale | dependency-version | configuration | environment |
network-third-party | type-contract | test-contract |
performance-regression | memory-leak | unknown
Required stack_profile values:
core-ui-angular | legacy-core-ui-angular | plain-angular |
sdcorejs-nestjs | plain-nestjs |
nextjs-build-website | plain-nextjs |
react-vite | react-cra | react-next-generic |
node-general | general
Required repro_status values:
local-confirmed | evidence-confirmed | flaky-confirmed | blocked
Environment values:
local | dev | staging | prod | unknown | mock
Classification rules:
- Evidence decides the label. Do not choose stack-specific bug classes or stack probes unless the target project uses that stack or dependency.
- For mixed or unknown stacks, use
general or node-general and shared debugging rules.
- Do not let
unknown become an excuse to patch. Gather evidence until a hypothesis is testable or mark repro_status: blocked.
Step 2 - Profile-Aware Stack Detection
Detect the target stack from files, dependencies, imports, test files, runner
config, approved plans, and current error evidence.
Angular:
- Detect Angular from
angular.json, @angular/core, components, modules, routes, or Angular tests.
- Use
core-ui-angular only if @sdcorejs/angular is installed or the target code imports/uses it.
- Use
legacy-core-ui-angular only if @sd-angular/core is installed or the target code imports/uses it.
- Use
plain-angular when Angular is present but neither Core UI package is detected.
- Do not assume Core UI components,
Sd* services, SD_API_CONFIGURATION, src/libs/**/features/**, or admin portal patterns for plain-angular.
NestJS:
- Detect NestJS from
nest-cli.json, @nestjs/* dependencies, modules, controllers, providers, or Nest tests.
- Use
sdcorejs-nestjs only if @sdcorejs/nestjs or strong SDCoreJS Nest conventions are detected.
- Use
plain-nestjs when NestJS is present without SDCoreJS Nest evidence.
- Do not assume TypeORM, PostgreSQL, Zod,
SdContext, @HasPermission, or @sdcorejs/nestjs for plain-nestjs unless detected.
- For plain NestJS, inspect the actual stack first: Prisma, Mongoose, TypeORM, class-validator/class-transformer, Zod, Fastify/Express, Passport/JWT, guards, interceptors, and pipes.
Next.js:
- Detect Next.js from
next.config.*, next dependency, app/pages router files, page.tsx, layout.tsx, route.ts, or Next tests.
- Use
nextjs-build-website only with strong build-website/public-site evidence such as [locale] i18n routing, typed i18n navigation, content/public-site structure, or prior sdcorejs-nextjs build-website context.
- Use
plain-nextjs otherwise.
- Do not assume
[locale], setRequestLocale, typed i18n navigation, sitemap/public-site metadata, or build-website caching rules for plain-nextjs.
React and general:
- Use
react-vite, react-cra, or react-next-generic only when the project signals that profile.
- Use
node-general for Node tools, libraries, CLIs, scripts, or servers without a stronger framework profile.
- Use
general for unsupported or mixed projects and debug from direct evidence only.
Step 3 - Command Discovery And Environment Guard
Use _refs/shared/debug-command-discovery.md as the canonical command policy.
Before running repro or verification, discover the package manager, lockfiles,
workspace config, relevant package.json scripts, runner configs, original
failing command, and CI output. Prefer focused repro first, focused regression
second, and broader existing checks last. Do not mix package managers, invent
scripts, assume npm/npx/tsc commands, install tools, or run browser installs
without explicit approval; record missing, unsafe, or environment-blocked
commands in commands_skipped.
Use _refs/shared/debug-environment-guard.md as the canonical environment
policy. Before any repro touches browsers, APIs, databases, external systems,
or persistent state, classify the environment as local | dev | staging | prod | unknown | mock, block destructive production/external side effects, and
record seed/setup/cleanup or blocked evidence in debug_context.
Step 4 - Reproduce Or Evidence-Confirm
Use evidence-aware reproduction, not a rigid "must run locally" rule:
| repro_status | Definition | Verification rule |
|---|
local-confirmed | The bug reproduces locally with a focused command or manual step. | Prefer 3/3 consistent repro when cheap and appropriate. |
evidence-confirmed | Local execution is unavailable, but stack traces, CI logs, production logs, screenshots, sanitized payloads, or failing output isolate a likely root cause. | Mark confidence and do not claim the original environment is fixed until verified there. |
flaky-confirmed | Repeated runs or logs show nondeterministic failure. | Treat nondeterminism as the bug; record pass/fail counts and do not claim fixed from one passing run. |
blocked | Evidence is insufficient or required environment/data/access is unavailable. | Do not patch speculatively. Ask for missing evidence or propose safe instrumentation. |
Capture:
- observed behavior: exact redacted error, stack, command output, network response, screenshot summary, or input;
- expected behavior in the user's words or the contract;
- input/data/environment that triggered it;
- confidence:
high, medium, or low.
Step 5 - Maintain The Hypothesis Ledger
Before any fix, create and update a visible Hypothesis Ledger:
| ID | Observation | Hypothesis | Predicted evidence | Falsification probe | Result | Status |
|---|
| H1 | Stack trace points to user.name | user is undefined when lookup returns 404 | missing-user repro throws before guard | run focused missing-user test | confirmed | ROOT |
Rules:
- Do not patch until at least one hypothesis is confirmed, unless the user explicitly approves a tactical mitigation.
- Do not keep more than 3 live hypotheses without gathering new evidence.
- Mark hypotheses as
confirmed, falsified, inconclusive, or root.
- If all hypotheses are inconclusive, gather more evidence or escalate.
- Avoid shotgun debugging. Apply one coherent root-cause fix at a time.
- The final report must identify the root hypothesis or explain why root cause remains uncertain.
Step 6 - Track Diagnostic Instrumentation
When adding logs, probes, temporary assertions, breakpoints, tracing, throw
probes, or debug-only assertions, maintain this ledger:
Diagnostic Instrumentation Ledger:
- file:
- line_or_scope:
- purpose:
- sensitive_values_redacted:
- cleanup_required:
- cleanup_done:
- permanent_observability_approved:
Rules:
- Temporary instrumentation must be removed before final verification unless the user explicitly approves permanent observability.
- Do not leave noisy logs in production code.
- Do not log secrets, tokens, cookies, credentials, PII, full request bodies, or raw SQL parameter dumps.
- Permanent observability must be intentional, minimal, redacted, and consistent with project logging conventions.
- Final report must state whether diagnostic instrumentation remains.
Step 7 - Fix Scope And Regression Tests
Fix the root cause with the smallest safe patch:
- Do not perform broad refactors during debugging.
- Do not apply multiple unrelated fixes in one pass.
- Do not hide symptoms with optional chaining, default values, catch-and-swallow blocks, retries, or null guards unless the confirmed hypothesis proves that this is the correct contract.
- Do not change public API, schema, security, permissions, migration behavior, or product contract without explicit approval.
- If the bug reveals a broader design issue, apply only the minimal safe mitigation and propose follow-up planning.
Regression test ownership:
- Add or update a small focused regression test when the existing runner and style are clear, the repro is cheap to capture, the file scope is obvious, and no new infrastructure is needed.
- Delegate to
sdcorejs-test when new infrastructure, multiple test levels, a broad suite, complex UAT/e2e coverage, dependency installs, or browser binaries are needed.
- Do not add test dependencies from
sdcorejs-debug without explicit approval.
- Do not weaken tests, delete tests, skip tests, loosen assertions, increase timeouts blindly, or mock away the behavior under test.
- If an existing test is wrong because of an approved contract change, require explicit approval before updating the expectation.
Step 8 - Mode-Specific Rules
Flaky:
- Treat nondeterminism as the bug.
- Run repeated focused repro when cheap and record pass/fail counts.
- Look for shared state, timing, clock, random, order dependency, retries, race conditions, external services, and cleanup leaks.
- Do not claim fixed from a single passing run.
CI-only:
- Use CI logs, config, and environment differences as evidence.
- Compare package manager, Node/browser/OS versions, env vars, timezones, caches, parallelism, workspace paths, and lockfiles.
- If local repro is impossible, use
evidence-confirmed and require CI verification before claiming fixed.
Prod-only:
- Require sanitized logs and payloads.
- Prefer safe instrumentation or feature-flagged diagnostics.
- Do not use raw production secrets/data or destructive production repro.
- Mark the fix unverified until production or staging confirmation exists.
Performance-anomaly:
- Debug only concrete wrong behavior or regression, not broad optimization.
- Use measured evidence such as timings, profiles, query plans, traces, or before/after command output.
- Avoid broad rewrites unless root cause requires them and the user approves.
Security-sensitive:
- Redact aggressively.
- Avoid printing exploit payloads, secrets, or sensitive identifiers unnecessarily.
- Consider a follow-up
sdcorejs-review security review after the fix.
- Do not weaken auth, permission, validation, or crypto checks to make a path pass.
Data-integrity:
- Treat migrations, schema changes, backfills, deletions, and transactional fixes as high risk.
- Prefer read-only inspection first.
- Do not run destructive data changes without explicit approval plus backup/rollback strategy.
Dependency-regression:
- Isolate version and config changes before changing dependencies.
- Do not update or downgrade dependencies casually.
- If a dependency change is required, route delivery through
sdcorejs-ship dependency-update discipline when present.
- Record lockfile, package manager, and changelog/migration evidence.
Step 9 - Redaction Protocol
Never echo secret or PII values from .env, local config, CI files, shell
output, source files, stack traces, network logs, request payloads, cookies,
authorization headers, JWTs, refresh tokens, database URLs, API keys,
passwords, private keys, customer PII, production data, or git diffs.
Rules:
- Never print full lines that contain likely secret values.
- For suspected secrets, report only file path, line number when available, key/category name, risk reason, and redacted evidence such as
API_KEY=[REDACTED].
- If a
grep/rg command would print secret values, do not run it raw. Use safer summaries or redacted inspection.
- Do not include secret values in
debug_context, final summaries, auto-docs, task tracker, commit messages, PR bodies, or changelog entries.
- If suspected secrets are part of the bug, stop before shipping and require remediation.
Step 10 - Verify And Tail Chain
After the fix:
- Re-run the original repro or evidence-equivalent focused repro.
- Run the focused regression test if available.
- Run broader existing checks when appropriate and available.
- Remove or explicitly approve diagnostic instrumentation.
- Emit final
debug_context.
- Run auto-docs, task tracker, and memories only when durable debug knowledge
or changed artifacts justify them and normal tail policy allows it.
- Run
sdcorejs-ship (verify-before-done mode) when acceptance criteria, a
bug contract, or source changes exist.
- Run
sdcorejs-ship (branch-ready mode) as the final read-only gate over the
final diff before any Git artifact path. No writes after branch-ready unless
branch-ready is run again.
- Invoke
sdcorejs-git only after ship and branch-ready gates have passed for the current HEAD or diff and the user explicitly asks for commit, PR, changelog, release-note, or workspace artifacts.
If invoked from sdcorejs-repair-loop, preserve repair_source,
review_context, original finding ID/source, package-manager evidence, and
verification commands. After the debug fix, return to the caller's tail chain.
If verification is blocked, say blocked/unverified and do not claim the bug is
fixed. If repro_status is evidence-confirmed or blocked, do not overclaim
confidence.
Required Output
Every sdcorejs-debug session ends with a redacted debug_context block. The
canonical schema lives in _refs/shared/debug-context.md; do not duplicate or
drift it in this skill body. The final block must include at minimum:
source, debug_mode, bug_class, stack_profile, repro_status, observed, expected,
root_cause, root_hypothesis_id, confidence, files_touched,
diagnostic_instrumentation, regression_tests, commands_run, commands_skipped,
package_manager, environment, secret_redaction, verification, ship_handoff
Rules:
commands_run includes only commands actually run.
- Do not claim tests, build, lint, repro, or CI passed unless they were actually run and passed.
- If verification was skipped or blocked, record why.
debug_context must not contain secrets, PII, raw production data, or full secret-bearing lines.
Rules
MUST DO
- Run working-tree preflight before edits.
- Classify
debug_mode, bug_class, stack_profile, repro_status, and environment before stack-specific probes.
- Use package-manager/script-aware command discovery.
- Redact secrets and PII in logs, stack traces, network output, grep output, diffs, and final reports.
- Maintain the Hypothesis Ledger and Diagnostic Instrumentation Ledger.
- Confirm or evidence-confirm the bug before patching, or mark
blocked.
- Fix the root cause, not the symptom.
- Add/update focused regression coverage when feasible, or delegate to
sdcorejs-test.
- Verify original repro plus regression surface.
- Run
sdcorejs-ship (verify-before-done mode) and sdcorejs-ship (branch-ready mode) before Git artifacts when source or contract changes exist.
MUST NOT
- Patch speculatively when
repro_status: blocked.
- Use shotgun debugging.
- Silence errors with broad
try/catch, optional chaining, default values, retries, or null guards without a confirmed root-cause contract.
- Disable, skip, weaken, or rewrite tests only to make output green.
- Run destructive production repro or use production data unsafely.
- Leave temporary diagnostic logs behind.
- Hardcode one package manager or invent scripts.
- Use
--no-verify to bypass hooks.
- Stage, commit, push, or create PRs.
Cross-references
sdcorejs-test - owns writing/running/planning tests without root-cause/fix intent and receives delegated large test work.
sdcorejs-ship - consumes debug evidence for verify-before-done and branch-ready gates.
sdcorejs-review - optional follow-up review, especially for security/performance-sensitive fixes.
sdcorejs-repair-loop - can call debug for a single verified bug while preserving repair_source and review_context.
sdcorejs-git - creates artifacts only after ship gates pass and the user explicitly requests them.