| name | research |
| description | Search for prior discussion of a php-src bug or idea across four sources: the php.internals mailing list (via externals.io Algolia), GitHub issues and PRs on php/php-src, and the php-src git log. Use when the user says "/research", "look up prior discussion", "search internals for this", "has this been discussed before", "find related PRs", "any prior art on this", "check if someone tried this", or otherwise wants prior-art sweep before committing to an implementation. Works for both bug and idea SPEC.md flows — detects type, extracts keywords from the right section, populates the Research phase. Gating differs by flow: soft gate for bug (downstream warns if Research is todo); hard gate for idea (/idea-prototype refuses past Hypothesis & Metric until Research is done or explicitly skipped). |
research
Generic skill that owns the Research phase in both bug and idea SPEC.md flows. Sweeps four prior-art sources and writes synthesised findings into SPEC.md.
Inputs
- SPEC.md in the task directory resolved per
_shared/task-dir.md (env var → .current → cwd). Refuse if missing.
gh CLI authenticated (for issue + PR steps).
PHP_SRC_DIR resolvable (for git-log step + task-dir resolution).
- Network connectivity (for Algolia + gh steps).
If sub-2 of those are unavailable, the corresponding source-step is marked blocked with the reason and the skill continues with whatever sources do work. Partial findings are still useful — gating differs by flow (soft for bug, hard for idea; see below).
Phase owned
Research.
Position:
| SPEC type | Sits between |
|---|
bug | Context → Reproduction |
idea | Hypothesis & Metric → Survey & Plan |
Refuses to run before the upstream phase is done (Context for bug; Hypothesis & Metric for idea).
What it produces
Updated SPEC.md with the Research phase populated:
## Phase: Research — status: done
### Guardrails
- [x] **pre**: upstream phase done (Context for bug; Hypothesis & Metric for idea)
- [x] **post**: at least one source-step done or blocked with reason
### Steps
- [x] **keywords** — <comma-separated list of terms searched>
- [x] **algolia-internals** — <N> hits. <bullets>
- [x] **gh-issues** — <N> hits. <bullets>
- [x] **gh-prs** — <N> hits. <bullets>
- [x] **git-log** — <N> commits. <bullets>
### Notes
<2–4 sentence synthesis across all sources>
Workflow
1. Pre-checks
- Resolve task dir per
_shared/task-dir.md. SPEC.md exists in the resolved dir. Refuse otherwise — list existing task dirs under $PHP_SRC_DIR/.claude/php-core-dev/ and tell the user how to switch.
- SPEC.md has
type: bug or type: idea. Refuse otherwise.
- Required upstream phase is
done:
bug → Context phase done
idea → Hypothesis & Metric phase done
- Refuse if not — point at
/bug-context or /idea-prototype respectively.
- Research phase status check:
todo or missing → proceed; add the phase skeleton if missing.
in-progress → resume; only run the source-steps that aren't yet done.
done → idempotent re-run: refresh the steps' findings (the world may have moved). Backup existing body to a comment block in SPEC.md so the user can see the delta. Don't regress phase status.
blocked → refuse with reason; tell user to resolve the blocker.
skipped → refuse with Research phase was deliberately skipped. Reopen by editing SPEC.md if you want to run it.
2. Extract keywords
Follow _shared/search-strategies.md § 1. Read the right SPEC.md section per type:
| Type | Read |
|---|
bug | ## Context |
idea | ## Hypothesis & Metric + ## Context |
Aim for 3–5 specific terms. Drop stop words and PHP-generic terms. Prefer identifiers (function names, macros, types).
Record the chosen set as the keywords step. Example:
- [x] **keywords** — `array_filter`, `ARRAY_FILTER_USE_KEY`, `by-ref`, `php_array_filter`
3. Run four sources (sequential)
For each source, write the result into its step body. Format per _shared/search-strategies.md § 6. Always include the agent's "why this is relevant" annotation per hit.
algolia-internals
curl -sS -X POST "https://KSTITII7EC-dsn.algolia.net/1/indexes/v2_emails/query" \
-H "X-Algolia-API-Key: badccd205e578e64657ae7f880959824" \
-H "X-Algolia-Application-Id: KSTITII7EC" \
-d '{"query":"<KEYWORDS-JOINED-BY-SPACES>","hitsPerPage":10}'
Parse with jq. For each hit, emit one line: subject — fromName, date — https://externals.io/message/<objectID> — <why-relevant>.
If curl fails: step blocked with the error message. Continue.
gh-issues
gh issue list --repo php/php-src \
--search "<KEYWORDS-JOINED-BY-SPACES>" \
--state all --limit 20 \
--json number,title,state,url,labels,stateReason
For closed issues with stateReason: NOT_PLANNED, follow up with gh issue view <N> --comments to capture the maintainers' reason. Don't fetch comments for every hit — only the top 3 most relevant.
If gh auth status fails: step blocked with gh not authenticated. Continue.
gh-prs
gh pr list --repo php/php-src \
--search "<KEYWORDS-JOINED-BY-SPACES>" \
--state all --limit 20 \
--json number,title,state,url,baseRefName,createdAt,closedAt,mergedAt
For closed-without-merge PRs, follow up with gh pr view <N> --comments on the top 3 — the close reason is the value.
If gh auth status fails: step blocked with gh not authenticated. Continue.
git-log
for k in <KEYWORDS>; do
git -C "$PHP_SRC_DIR" log --all --oneline --grep "$k" -i | head -20
done | sort -u | head -50
Also try git log --all --grep "GH-<linked-issue-N>" if SPEC.md frontmatter linked points at a GitHub issue.
For high-value commits (those touching files mentioned in Context), git show <SHA> --stat to capture the scope.
If $PHP_SRC_DIR not set or not a git repo: step blocked. Continue.
4. Synthesise Notes
After the four source-steps, write a ### Notes subsection inside the Research phase body. 2–4 sentences max. Cover:
- Does prior discussion settle a BC or scope question?
- Is there a prior fix attempt (merged or abandoned) that informs this one?
- Is the change novel (no hits) or contested (lots of hits)?
This is the agent's value-add. The user reads Notes first.
5. Mark phase done
If at least one source-step is done (even with zero hits): phase done.
If every source-step is blocked (network down, no gh auth, no $PHP_SRC_DIR all at once): phase stays in-progress and the skill stops with a clear error explaining what to fix. Don't mark phase done when no sources actually ran.
6. Progress Log
Append one line:
2026-05-20 14:33 — research — Research phase done; <N> total hits across <K> sources; key takeaway: <one-line>
7. Report
Research phase populated.
- keywords: <comma list>
- algolia (intl): <N> hits
- gh issues: <N> hits
- gh PRs: <N> hits
- git log: <N> commits
Notes: <one-line synthesis>
Next: <skill> (per SPEC.md type)
Boundaries
- Read-only. No edits to
$PHP_SRC_DIR. No edits to anything except SPEC.md.
- No gh mutations. Reads only — no commenting, no labelling.
- No automatic follow-up calls.
gh issue view --comments runs only on the top 3 high-value hits per source. Don't sweep all 20 issues' comments — too slow, too much noise.
- No keyword fanout. Run each source once with the chosen keyword set. Don't run Algolia 5 times with each individual keyword — Algolia handles multi-term queries natively.
Edge cases
| Situation | Handling |
|---|
| SPEC.md has both Context and Hypothesis & Metric (e.g. someone manually authored an unusual file) | Use type frontmatter to pick. If type is bug, ignore Hypothesis & Metric. |
Upstream phase is blocked | Refuse; tell user to resolve the upstream blocker first. |
| Algolia returns >10 hits | Capped at 10. Mention in step body that more exist; suggest user refine keywords if relevant. |
| All four sources return zero hits | Phase done. Notes: No prior discussion found across all four sources. Change appears novel. |
Sub-2 sources blocked, the rest produce hits | Phase done. Notes lead with the blocked sources so the user knows which prior art might be missing. |
User passes args to /research (e.g. extra keywords) | Treat as keyword override — use those terms instead of the auto-derived ones. Record the override in the keywords step body. |
SPEC.md type is something other than bug/idea | Refuse — /research only knows the bug and idea schemas. |
Re-run on a done Research phase | Refresh; back up prior body as a markdown-comment block inside the phase. Don't regress status. |
Quality checklist
Out of scope
- Implementing the fix or prototype based on findings —
/bug-fix and /idea-prototype own that.
- Posting on the internals mailing list — never auto.
- Filing or commenting on GitHub issues/PRs — read-only.
- Drafting an RFC document — out of scope for this plugin entirely.