| name | bug-context |
| description | Entry point for a php-src bug fix. Fetches a GitHub issue (and its linked PRs/commits) via the gh CLI, writes the Context phase of SPEC.md in the current directory, and stubs out the remaining phases. Use when the user says "fix GH-12345", "let's work on this php-src bug", "/bug-context", "start a bug fix for issue NN on php/php-src", "pull the context for php-src issue NN", or otherwise wants to begin a bug-fix workflow from a GitHub issue. Always invoke this skill FIRST in the bug flow — the bug-reproduce-test, bug-fix, and bug-verify skills refuse to run without a SPEC.md created here. |
bug-context
Entry point of the php-src bug-fix flow. Pulls the GitHub issue, synthesises it, and writes the Context phase of SPEC.md.
Inputs
- Issue identifier (required) — a GitHub issue number (
12345), GH-12345, or full URL (https://github.com/php/php-src/issues/12345).
PHP_SRC_DIR (required) — resolved per _shared/php-src-detection.md (auto-detect cwd inside checkout, or honour the env var override). Refuse if neither path resolves.
gh CLI (required) — must be authenticated (gh auth status). If unauthenticated, stop and tell the user.
What it produces
SPEC.md in the task directory (resolved per _shared/task-dir.md; default $PHP_SRC_DIR/.claude/php-core-dev/gh-<N>/SPEC.md) with:
- Frontmatter:
type: bug, linked: set to the GH issue URL, php_src_ref: set to the current git rev-parse HEAD of $PHP_SRC_DIR, target_branch: resolved per _shared/branch-detection.md (see step 6 below), created: today's date, status: in-progress.
## Context section with a synthesised problem statement.
- Phase skeletons (Reproduction, Analysis & Plan, Implementation, Verification) — all
status: todo, with their guardrails pre-declared.
- Empty
## Open Questions.
- A first Progress Log entry.
Workflow
1. Resolve PHP_SRC_DIR and validate environment
Resolve PHP_SRC_DIR using the algorithm in _shared/php-src-detection.md (env-var override or walk-up from $PWD). If neither path resolves, refuse with the detection doc's error message — do not guess.
gh auth status >/dev/null 2>&1 || { echo "gh CLI not authenticated. Run: gh auth login"; exit 1; }
2. Resolve issue identifier
Accept any of:
12345
GH-12345
https://github.com/php/php-src/issues/12345
https://github.com/<owner>/<repo>/issues/12345 (rare — non-php/php-src forks)
Default repo is php/php-src when only a number is given.
3. Fetch issue data
gh issue view <N> --repo php/php-src --json number,title,body,labels,state,url,comments,createdAt,author
Read every comment. Identify linked PRs/commits mentioned in the body or comments — pull each:
gh pr view <PR-N> --repo php/php-src --json title,state,url,body
git -C "$PHP_SRC_DIR" log --oneline --all --grep "GH-<N>"
4. Resolve task directory + re-invocation handling
Compute slug gh-<N>. Resolve task dir per _shared/task-dir.md:
- If
$PHP_CORE_TASK_DIR is set → use it.
- Else use
$PHP_SRC_DIR/.claude/php-core-dev/gh-<N>/.
Create the dir if missing. Ensure $PHP_SRC_DIR/.claude/php-core-dev/.gitignore exists with *\n!.gitignore\n. Write the slug to $PHP_SRC_DIR/.claude/php-core-dev/.current.
If SPEC.md already exists in the resolved dir:
- If its frontmatter
linked: matches the same GH issue → re-run idempotently: re-fetch latest issue state, refresh the Context section, append a Progress Log line. Don't touch phase statuses or other sections. Update .current.
- If it links a different issue → refuse with:
Slug gh-<N> is taken by <other-issue>. Pick a different working dir via PHP_CORE_TASK_DIR.
5. Synthesise Context
Write the ## Context section. Aim for a self-contained brief that a developer can act on without clicking back to GitHub:
- One-paragraph problem statement (from title + body, refined by comments)
- Affected PHP versions (from the issue's body and/or labels)
- Subsystem hint (extension name,
Zend/, main/streams/, etc. — derived from labels or by grepping the issue body for path-like strings)
- Reproduction snippet if the issue includes one (copy verbatim into a fenced PHP block)
- Linked PRs/commits with one-line summaries
- Any notable comments that change the picture (skip "+1" / "same here" without details)
No links to github.com — inline what the reader needs.
6. Resolve target branch
PHP supports several active branches in parallel. The fix should target the lowest maintained branch the bug affects. Resolve the value, don't punt it to the user:
-
Read the maintained-branch list per _shared/branch-detection.md § 1 (parse .github/matrix.php).
-
Parse the issue's "affected versions" hint per the resolver in _shared/branch-detection.md § 2 — labels like Version: 8.3, phrases like affects 8.3+, since 8.3, only 8.4.
-
Pick the lowest maintained branch ≥ the parsed minimum. Write it into SPEC.md frontmatter as target_branch: <PHP-x.y> (or master when only the unreleased branch is affected).
-
If parsing fails (no labels, no version mention in body or comments), set target_branch: null and raise one Open Question:
- Target branch — affected-version signal absent from the issue. Pick one of
<MASTER>, <HIGHEST-MAINTAINED>, …, <LOWEST-MAINTAINED> (literals resolved at runtime from .github/matrix.php). Downstream skills refuse until this is set.
If the issue body or comments unambiguously settle this beyond what step 2 captures (e.g. a maintainer's comment "land on 8.4 only"), prefer their value and record the reason in the Context body.
7. Write SPEC.md
Follow _shared/spec-md-format.md. Initial phase skeleton looks like:
## Phase: Research — status: todo
### Guardrails
- [ ] **pre**: Context phase done
- [ ] **post**: at least one source-step done or blocked with reason
### Steps
*(populated by /research — soft-gated; downstream phases warn but do not block)*
## Phase: Reproduction — status: todo
### Guardrails
- [ ] **pre**: `$PHP_SRC_DIR/sapi/cli/php` exists (build with `make -j$(nproc)` if missing)
- [ ] **post**: new `.phpt` fails on current build
### Steps
*(populated by /bug-reproduce-test)*
## Phase: Analysis & Plan — status: todo
### Guardrails
- [ ] **post**: every planned step references a concrete file path
### Steps
*(populated by /bug-fix)*
## Phase: Implementation — status: todo
### Guardrails
- [ ] **post**: `make -j$(nproc)` exits 0
- [ ] **post**: new `.phpt` PASSES
### Steps
*(populated by /bug-fix)*
## Phase: Verification — status: todo
### Guardrails
- [ ] **post**: related test directory passes
- [ ] **post**: no new compiler warnings vs `php_src_ref`
### Steps
*(populated by /bug-verify)*
Mark the Context phase done (it's the entry-point step).
8. Report
Short summary to the user:
Context written to <task-dir>/SPEC.md
Issue: <title> (GH-<N>)
Subsystem hint: <e.g. ext/standard/array>
Target branch: <PHP-x.y | master | null — see Open Questions>
Task dir: <task-dir>
.current: <slug>
Next: run /research (recommended) or jump to /bug-reproduce-test
Boundaries
- No code changes. No edits inside
$PHP_SRC_DIR. This skill is read-only against the source tree.
- No
gh mutations. Reads only. No commenting on the issue.
- No phase progression beyond Context. Don't try to be helpful by writing Reproduction or Analysis content — that breaks the resume contract for peer skills.
Edge cases
| Situation | Handling |
|---|
| Issue number doesn't exist | gh issue view exits non-zero — surface the error to the user, stop. |
Issue is on a non-php/php-src fork | Accept and proceed; record the repo in Context. |
| Issue body is empty | Write Context from title + comments; flag as Open Question if no reproduction info available. |
| User passes a PR URL instead of an issue URL | Treat the PR as the source; pull gh pr view instead and link the PR. Note in Context. |
gh auth status fails | Stop with Run: gh auth login. |
$PHP_SRC_DIR not on a recognisable branch | Note in Context; raise Open Question about target branch. |
| SPEC.md exists for a different issue | Refuse; tell the user to cd to a fresh directory. |
Quality checklist
Out of scope
- Reproduction —
/bug-reproduce-test
- Root cause analysis —
/bug-fix
- Posting to GitHub — never auto, only
/review-pr posts comments with user consent