بنقرة واحدة
bugfix
End-to-end bug fix workflow — report, analyze, fix, verify, ship (PR + merge + deploy + knowledge capture)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
End-to-end bug fix workflow — report, analyze, fix, verify, ship (PR + merge + deploy + knowledge capture)
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Parallel pipeline orchestrator — launch multiple /proceed sessions concurrently across REQs, monitor progress, and report status. Use when the user says "sprint", "run these REQs in parallel", "proceed with all approved REQs", "launch a sprint", or wants to advance multiple requirements simultaneously.
Codebase health audit — identify technical debt, quality issues, and improvement opportunities
End-to-end ADLC pipeline that takes a requirement from spec through to deployed. Takes a REQ number as argument and runs validate → fix → architect → fix → implement → verify (reflect + review) → create PR → wrapup (merge, deploy, knowledge capture). Use when the user says "proceed", "proceed with REQ-xxx", "run the pipeline", "take REQ-xxx to completion", "implement REQ-xxx end to end", or wants to advance a drafted requirement all the way through to deployment in one shot.
Write requirement specs from feature requests
Close out a completed feature — update ADLC artifacts, log knowledge, and summarize
Bootstrap .adlc/ structure in a new repo or subdirectory
| name | bugfix |
| description | End-to-end bug fix workflow — report, analyze, fix, verify, ship (PR + merge + deploy + knowledge capture) |
| argument-hint | Bug description or BUG-xxx ID |
You are fixing a bug using a streamlined workflow that skips the full spec ceremony but follows the same deployment strategy as a feature: changes land via PR, ride the project's CI/CD pipeline (staging-first if the project has one), and aren't marked resolved until every declared deploy target is confirmed.
!sh .adlc/partials/ethos-include.sh 2>/dev/null || sh ~/.claude/skills/partials/ethos-include.sh
cat .adlc/config.yml 2>/dev/null || echo "No config — single-repo legacy mode"cat .adlc/templates/bug-template.md 2>/dev/null || cat ~/.claude/skills/templates/bug-template.md 2>/dev/null || echo "No bug template found"cat .adlc/context/conventions.md 2>/dev/null || echo "No conventions found"ls .adlc/bugs/ 2>/dev/null || echo "No bugs directory found"Bug report: $ARGUMENTS
Before proceeding, verify that .adlc/bugs/ exists. If it doesn't, stop and tell the user: "The .adlc/ structure hasn't been initialized. Run /init first."
~/.claude/.global-next-bug (shared across all repos for unique IDs, mirroring the REQ counter — see LESSON-004). The counter is now a cache, not the authority — the remote is the source of truth (REQ-518): allocation derives the remote high-water, takes max(remote, local) + 1, and fast-forwards the local counter, all inside the existing mkdir lock. Allocate via the shared partials/id-alloc.sh helper (BR-5 — the lock block + its REQ-416/LESSON-014 rationale live in the partial). Source it and call adlc_alloc_id in the same fenced block (the cross-fence-fn rule — see conventions.md "Bash in skills"):
. .adlc/partials/id-alloc.sh 2>/dev/null || . ~/.claude/skills/partials/id-alloc.sh
BUG_NUM=$(adlc_alloc_id bug)
# `exit 1` inside adlc_alloc_id's subshell terminates only the subshell — BUG_NUM
# would be silently empty. Guard the parent context (REQ-416 verify D-pass).
[ -n "$BUG_NUM" ] || { echo "ERROR: failed to allocate BUG number — aborting before writing malformed bug report" >&2; exit 1; }
# If ADLC_ALLOC_DEGRADED=1 (remote unreachable), the helper warned on stderr — note
# "id allocated without remote verification — verify before PR" (BR-3). Never block.
adlc_alloc_id bug handles the absent-counter bootstrap scan internally (highest BUG-xxx under $ADLC_REPOS_ROOT; bug reports are .md files so the scan uses -type f), the mkdir lock that serializes concurrent sessions, and the remote high-water max. Single-machine behavior is unchanged when the remote has no higher allocation (BR-7).
Note: the legacy per-repo .adlc/.next-bug counter is deprecated and no longer consulted — existing files can be left in place but should not be read or written.BUG-<id> against the remote — a colleague on another machine may have pushed the same id since allocation. Source partials/id-recheck.sh and call adlc_recheck_id in the same fenced block; a collision halts with the renumber instruction rather than pushing a duplicate:
. .adlc/partials/id-recheck.sh 2>/dev/null || . ~/.claude/skills/partials/id-recheck.sh
BUG_ID=$(printf 'BUG-%03d' "$BUG_NUM")
if ! adlc_recheck_id bug "$BUG_ID"; then
echo "Halting: $BUG_ID collides on the remote — renumber before pushing (see message above)." >&2
exit 1
fi
.adlc/bugs/BUG-xxx-slug.md (always in the current repo — this becomes the "primary" for the bug) using the template from .adlc/templates/bug-template.mdopen, severity based on impact.adlc/config.yml declares siblings AND the bug's fix likely lives in a sibling (e.g., a frontend symptom whose root cause is in a backend repo), add a repo: <sibling-id> field to the bug frontmatter. If the fix spans multiple repos, add a touched_repos: [<id>, <id>] field. The repo: field determines where Phase 3's commit and Phase 4's PR land.repo: or touched_repos: field for routing.repo: and it names a sibling (not this repo), cd into that sibling's path from .adlc/config.yml and do all fix work there. For touched_repos: [...], cd into each in turn — one commit per repo, on a shared branch name. Otherwise fix in the current repo.npm test (or appropriate test command)resolved yet — that happens in Phase 6 after the fix is merged and deployed):
open (or set to in-review if your project uses that value)updated dateFor each touched repo (just the current repo in single-repo mode; each entry in touched_repos: in cross-repo mode):
git -C <worktree> push -u origin fix/bug-xxx-slugadlc_forge_pr_create (source partials/forge.sh in the same fence; run from inside the worktree, or pass -R <owner/repo>). All PR ops route through the forge adapter, never direct gh (REQ-520 BR-1). In cross-repo mode, create the primary repo's PR last so its body can link every sibling.
fix(BUG-xxx): short description — when cross-repo, scope to the repo (e.g., fix(api): null deref in user serializer [BUG-042]).## Summary
[1-2 lines describing what broke and what was fixed in THIS repo]
## Bug
BUG-xxx: [bug title]
Severity: [critical | high | medium | low]
Primary repo: <primary-repo-id>
## Root Cause
[Pulled from the bug report's Root Cause section]
## Files Changed (this repo)
- `path/to/file.ts` — what changed and why
## Related PRs (cross-repo)
[Omit in single-repo mode. Otherwise list each sibling PR URL — back-fill
sibling bodies via `adlc_forge_pr_edit` once every URL is known.]
## Test Plan
- [ ] Unit/integration tests pass locally
- [ ] CI green on this PR
- [ ] Staging deploy succeeded (verified in Phase 6)
- [ ] Production deploy succeeded (verified in Phase 6)
adlc_forge_pr_edit <prUrl> --body ...) to fill in the Related PRs section.gh pr checks <prUrl>. If CI fails, diagnose and re-push — never bypass with --no-verify or admin-merge.This is the equivalent of /proceed's Phase 8 / /wrapup steps, condensed for bugs.
Step 1 — Merge each PR.
adlc_forge_pr_view <prUrl> --json mergeable,mergeStateStatus should report MERGEABLE (on GitHub; ADO normalizes via pr_view). If main has advanced, rebase the fix branch onto origin/main, force-push with lease, and wait for CI to re-pass.adlc_forge_pr_merge <prUrl> --squash --delete-branch. In cross-repo mode, walk touched_repos: order (or merge_order: from .adlc/config.yml if not specified on the bug).Step 2 — Confirm deploys (this is the staging-first gate when the project has one — same model as features).
Skip this step entirely if the project doesn't deploy via Cloud Run (i.e., stack.backends in .adlc/config.yml doesn't include cloud-run and there's no gcp: block).
Otherwise, for each touched service that has a services: entry in .adlc/config.yml, look up gcp.staging_project and gcp.production_project from the config and confirm both:
# Staging
gcloud run services describe <service> \
--project=<gcp.staging_project from config> \
--region=<services[<id>].region or gcp.default_region> \
--format="value(status.latestReadyRevisionName,status.traffic[0].revisionName)"
# Production
gcloud run services describe <service> \
--project=<gcp.production_project from config> \
--region=<services[<id>].region or gcp.default_region> \
--format="value(status.latestReadyRevisionName,status.traffic[0].revisionName)"
Confirm the merge SHA's revision is serving 100% traffic in each. If gcp.production_project is omitted (no separate prod project), only confirm staging.
If staging deployed but production has NOT yet been promoted, wait — the pipeline runs them sequentially. If either fails, surface to the user with the failed deploy log link before claiming the bug resolved.
iOS deploy (only when stack.frontends in .adlc/config.yml includes ios AND the fix touched the iOS repo):
ios.deploy_targets, ios.derived_data_clean, and ios.deploy_command from .adlc/config.yml.ios.derived_data_clean is true: rm -rf ~/Library/Developer/Xcode/DerivedData/*<ios.deploy_command> and deploy to every device in ios.deploy_targets — never skip one. Don't leave this as a follow-up for the user.If stack.frontends doesn't include ios, skip this section entirely.
Step 3 — Update the bug report.
resolvedupdated dateStep 4 — Capture knowledge (NEVER skip — per memory feedback_wrapup_knowledge_capture.md).
Evaluate honestly: did this bug reveal something a future implementer should know?
If yes, write a lesson to .adlc/knowledge/lessons/LESSON-xxx-slug.md using the global atomic counter ~/.claude/.global-next-lesson (shared across all repos for unique IDs, mirroring the REQ/BUG counters — see LESSON-004). The counter is now a cache, not the authority — the remote is the source of truth (REQ-518): allocation derives the remote high-water, takes max(remote, local) + 1, and fast-forwards the local counter, all inside the shared mkdir-lock (~/.claude/.global-next-lesson.lock.d, shared with /wrapup so concurrent /bugfix and /wrapup runs mutually exclude). Allocate via the shared partials/id-alloc.sh helper (BR-5 — the lock block + its LESSON-014 symlink pre-check live in the partial). Source it and call adlc_alloc_id in the same fenced block (the cross-fence-fn rule — see conventions.md "Bash in skills"):
. .adlc/partials/id-alloc.sh 2>/dev/null || . ~/.claude/skills/partials/id-alloc.sh
LESSON_NUM=$(adlc_alloc_id lesson)
# `exit 1` inside adlc_alloc_id's subshell terminates only the subshell — LESSON_NUM
# would be silently empty. Guard the parent context (REQ-416 verify D-pass).
[ -n "$LESSON_NUM" ] || { echo "ERROR: failed to allocate LESSON number — aborting before writing malformed lesson" >&2; exit 1; }
adlc_alloc_id lesson handles the absent-counter bootstrap scan internally (highest LESSON-xxx under $ADLC_REPOS_ROOT; lessons are .md files so the scan uses -type f), the shared mkdir lock, and the remote high-water max. Single-machine behavior is unchanged when the remote has no higher allocation (BR-7). Note: the legacy per-repo .adlc/.next-lesson counter is deprecated and no longer consulted — existing files can be left in place but should not be read or written.
Pre-push recheck (BR-4, BR-8). Before the lesson file is committed on a branch for push, re-verify LESSON-<id> against the remote — a colleague on another machine may have pushed the same id since allocation. Source partials/id-recheck.sh and call adlc_recheck_id in the same fenced block; a collision halts with the renumber instruction rather than pushing a duplicate:
. .adlc/partials/id-recheck.sh 2>/dev/null || . ~/.claude/skills/partials/id-recheck.sh
LESSON_ID=$(printf 'LESSON-%03d' "$LESSON_NUM")
if ! adlc_recheck_id lesson "$LESSON_ID"; then
echo "Halting: $LESSON_ID collides on the remote — renumber before pushing (see message above)." >&2
exit 1
fi
Use the lesson template (.adlc/templates/lesson-template.md, fall back to ~/.claude/skills/templates/lesson-template.md). Filename format is LESSON-xxx-slug.md only — no date prefixes, no bare-numeric prefixes. Include domain, component, and tags so future runs of /spec, /architect, /reflect, and /review can filter by relevance.
If the bug genuinely produced no useful lesson (one-line typo, etc.), say so explicitly in the final summary — don't silently skip.
Step 5 — Clean up.
git -C <main-worktree> checkout main && git -C <main-worktree> pullgit -C <main-worktree> worktree remove <fix-worktree-path>git branch -D fix/bug-xxx-sluggit fetch --pruneStep 6 — Final ship summary.
## BUG-xxx: Bug Title — Resolved
**Severity**: <severity>
**PR(s)**: #nn (and siblings if cross-repo)
**Merged**: YYYY-MM-DD
### Root cause
- 1-2 lines
### Fix
- 1-2 lines
### Deployment
- Staging: <service> revision <hash> @ 100% traffic
- Production: <service> revision <hash> @ 100% traffic
- iOS: deployed to <list of ios.deploy_targets from config> (or "n/a — backend-only fix")
### Lessons captured
- `.adlc/knowledge/lessons/LESSON-xxx-slug.md` — one-line hook
(or "None — fix was straightforward and revealed no new pattern")
Use fix/bug-xxx-slug for the branch name. In cross-repo bugs, use the same branch name in every touched repo so PRs can be linked visually.
fix(BUG-xxx): short description of the fix
When a bug's fix spans repos (via touched_repos: in the bug frontmatter):
/bugfix was invoked from (the "primary" for this bug).fix/bug-xxx-slug).touched_repos:. If the bug report doesn't specify an order, use the merge_order from .adlc/config.yml./proceed instead.