idea-prototype
/idea-prototype
Turn a one-line hypothesis about php-src into a measurable prototype that proves or disproves the idea. Use when the user says "I have an idea for php-src", "prototype this idea", "/idea-prototype", "let's see if X would speed up Y", "what if PHP supported …", "explore whether …", or otherwise wants to test feasibility/sense of a php-src change before committing to an RFC. Drives a SPEC.md through Context → Hypothesis & Metric → Survey & Plan → Prototype → Measurement & Verdict. Resumable — re-run the same command to advance to the next phase.
- Author
- pronskiy ↗
- Repository
- php-src-developer ↗
- Licence
- MIT
- Last repository change
- 26.05.2026
Assessment and security
- Files in this package
- 1
- Scripts
- 0
- HTML comments
- 0
- URLs in SKILL.md
- 0
No signals detected. Repository changed on 26.05.2026, without references to retired models or APIs.
MIT, open: use and modify while retaining author attribution.
What it does and when to use it
Turn a one-line hypothesis about php-src into a measurable prototype that proves or disproves the idea. Use when the user says "I have an idea for php-src", "prototype this idea", "/idea-prototype", "let's see if X would speed up Y", "what if PHP supported …", "explore whether …", or otherwise wants to test feasibility/sense of a php-src change before committing to an RFC. Drives a SPEC.md through Context → Hypothesis & Metric → Survey & Plan → Prototype → Measurement & Verdict. Resumable — re-run the same command to advance to the next phase.
Triggers from the description
Original author description
Turn a one-line hypothesis about php-src into a measurable prototype that proves or disproves the idea. Use when the user says "I have an idea for php-src", "prototype this idea", "/idea-prototype", "let's see if X would speed up Y", "what if PHP supported …", "explore whether …", or otherwise wants to test feasibility/sense of a php-src change before committing to an RFC. Drives a SPEC.md through Context → Hypothesis & Metric → Survey & Plan → Prototype → Measurement & Verdict. Resumable — re-run the same command to advance to the next phase.
How it works
- Inputs
- What it produces
- Phases owned
- Workflow
- Boundaries
- Edge cases
- Quality checklist
- Out of scope
SKILL.md preview
---
name: idea-prototype
description: >-
Turn a one-line hypothesis about php-src into a measurable prototype that
proves or disproves the idea. Use when the user says "I have an idea for
php-src", "prototype this idea", "/idea-prototype", "let's see if X would
speed up Y", "what if PHP supported …", "explore whether …", or otherwise
wants to test feasibility/sense of a php-src change before committing to an
RFC. Drives a SPEC.md through Context → Hypothesis & Metric → Survey & Plan
→ Prototype → Measurement & Verdict. Resumable — re-run the same command to
advance to the next phase.
---
# idea-prototype
Single skill that drives a php-src idea prototype from a one-liner to a verdict. Like the bug flow, it's phased and resumable; unlike the bug flow, one skill owns all phases. Each invocation advances one phase forward (or resumes a blocked phase).
## Inputs
1. **A one-line hypothesis** (required on first run only) — e.g. *"caching common `zend_string` parameter names could speed up function calls"*, *"adding pattern syntax X would simplify Y"*, *"replacing the linear scan in `zend_hash_str_find` with sorted lookup helps tiny tables"*.
2. **`$PHP_SRC_DIR`** with built `sapi/cli/php`.
3. **SPEC.md** in the task directory (resolved per `_shared/task-dir.md`) — created on the first run, read on subsequent runs.
## What it produces
- `SPEC.md` (`type: idea`) in the task directory resolved per `_shared/task-dir.md` (default `$PHP_SRC_DIR/.claude/php-core-dev/idea-<slug>/SPEC.md`). Tracks the hypothesis end to end.
- Prototype C-code changes under `$PHP_SRC_DIR` — explicitly throwaway, not production-ready.
- Benchmark scripts and/or `.phpt` examples demonstrating the idea.
- A `pursue-as-rfc` / `reframe` / `kill` verdict in the final phase.
## Phases owned
| # | Phase | Post-guardrail |
|---|---|---|
| 1 | Context | Hypothesis restated in own words; subsystem identified |
| 2 | Hypothesis & Metric | Success metric is concrete and **falsifiable** |
| 3 | Research | At least one prior-art source ran (owned by `/research`, **hard-gated** for idea flow) |
| 4 | Survey & Plan | Smallest viable prototype change identified |
| 5 | Prototype | `make -j$(nproc)` exits 0 with the patch applied; build is clean |
| 6 | Measurement & Verdict | Numbers (or examples) recorded; honest verdict written |
This skill owns all six phases **except Research**, which is owned by `/research`. On each invocation `/idea-prototype` picks up the first non-done phase and advances it; when the next phase is Research it **refuses** and instructs the user to run `/research` (or to mark the phase `skipped` in SPEC.md with a reason). Research is **hard-gated** for the idea flow — Survey & Plan will not start until Research is `done` or `skipped`. This differs from the bug flow, which soft-warns and proceeds.
## Workflow
### 0. Resume logic
Resolve task dir per `_shared/task-dir.md`. On first run (no SPEC.md anywhere reachable):
- Hypothesis argument is required.
- Derive slug `idea-<kebab>` from the first ~5 significant words of the hypothesis (lowercased, kebab-cased). Example: `"caching common zend_string parameter names …"` → `idea-caching-common-zend-string-parameter`.
- Create `$PHP_SRC_DIR/.claude/php-core-dev/<slug>/`, ensure the leaf `.gitignore`, write the slug to `.current`.
On subsequent runs:
- Resolve task dir (env var → `.current` → cwd).
- If SPEC.md exists with `type: idea`: read it, find first non-done phase, run that phase. The hypothesis argument is ignored.
- If SPEC.md exists with `type: bug`: refuse — `idea-prototype expects an idea SPEC; current task is a bug. Switch tasks or use PHP_CORE_TASK_DIR.`
- If SPEC.md does not exist at the resolved dir: treat as first run (require hypothesis).
### Phase 1 — Context
Write SPEC.md with frontmatter (`type: idea`, `title:` set to the hypothesis, `php_src_ref:` from `git -C "$PHP_SRC_DIR" rev-parse HEAD`).
Write `## Context` with the following required subsections (each a markdown heading or bolded label inside the Context body):
1. **Restate** — hypothesis as a problem or opportunity, not an echo of the one-liner.
2. **Who benefits** — runtime perf, DX, code clarity, maintenance. Name concrete user groups.
3. **Who pushes back** — internals contributors, BC-sensitive consumers, anyone whose existing code or workflow this disrupts. Keep this even when the next subsection lists adversarial points — this subsection is about *people*, the next is about *arguments*.
4. **Userland today** — how people accomplish this today **without** the proposed change. 2–4 concrete examples from frameworks, extensions, PECL, polyfills, or composer packages. Include verbatim signatures or a short code snippet for at least one, with a link to the source. If no userland workaround exists, state so explicitly — that itself is evidence.
5. **Cross-language precedent** — closest analogue in 2–3 other runtimes (Rust, Python, Ruby, JS, Go, Elixir, Swift, …). For each: name + one-line description + link to its docs/PEP/RFC. "None — no major language has this" is a valid answer and worth recording; it changes the RFC framing materially.
6. **Pros vs Cons** — explicit two-column or two-list table of expected arguments **for** and **against** the change, 3–5 each. This is the controversy preview the eventual RFC will need anyway. Be honest with the cons — a thin AGAINST list is a smell, not a strength. Suggested format:
```markdown
| Pro | Con |
|---|---|
| <argument for> | <argument against> |
| ... | ... |
```
7. **Subsystems involved** — name the directories/files (`Zend/`, `ext/<name>/`, opcache, jit, …) and one-line per subsystem on what role it plays.
8. **Out of scope for this prototype** — what the prototype deliberately won't tackle (configurability, RFC drafting, fancier dumpers, etc.). Future-proofs the Survey & Plan against scope creep.
Pre-declare the remaining four phase skeletons with their guardrails. Mark Context `done`.
Post-guardrail (in addition to the existing one): subsections 1–8 are all present and non-empty. If any subsection is genuinely N/A for this hypothesis, write the reason in one line — don't silently omit.
Progress Log: `<datetime> — idea-prototype — Context written from hypothesis`.
Report: `Context written. Run /idea-prototype again to advance to Hypothesis & Metric.`
### Phase 2 — Hypothesis & Metric
The most important phase. The metric must be **falsifiable** — defined sharply enough that the Measurement phase can return a clean yes/no.
Examples of good metrics:
- *"≥5% reduction in time-per-iteration on `Zend/bench.php`'s `simple_call` benchmark, repeated 5 runs, 95% CI excludes 0%"*
- *"Two example scripts that today produce error X compile cleanly and produce the obvious result"*
- *"Zero new compiler warnings, RSS delta < 1 MB on the same `Zend/bench.php` workload"*
Examples of bad metrics:
- *"It's faster"* — no number, no workload
- *"It feels cleaner"* — not falsifiable
- *"It might help"* — not measurable
Steps:
- `metric` — record the metric.
- `workload` — record the workload (specific script, specific inputs, specific PHP version).
Post-guardrail: re-read the metric. If it could be defended both ways no matter what the prototype produces, **refuse** — block, raise an Open Question, stop. Don't accept fuzzy metrics.
### Phase 3 — Research
**Owned by the `/research` skill, not this one. Hard-gated for the idea flow.** When `/idea-prototype` reaches a Research phase that is `todo`, it refuses to continue and tells the user:
```
Research phase is required before Survey & Plan in the idea flow.
Run /research now to sweep prior art, or mark the phase `skipped`
in SPEC.md with a reason to bypass.
```
When the user runs `/research`, it populates the Research phase (keywords + 4 source-steps + Notes) and marks it `done`. See `skills/research/SKILL.md` and `_shared/search-strategies.md` for details.
If Research is `done` or `skipped`, this skill advances to Survey & Plan and consults the Research findings while planning. (The skipped path requires a reason recorded in SPEC.md — `/idea-prototype` reads it but doesn't enforce content.)
### Phase 4 — Survey & Plan
Pre-guardrail: Research phase status is `done` or `skipped`. Otherwise refuse with the Phase 3 message above — do not start Survey & Plan with Research still `todo`.
Steps:
- `subsystem-map` — read the relevant files (Grep + Read) and identify the **smallest** code change that exercises the hypothesis. Throwaway by design — not production-ready. List the files you intend to touch. Cite Research findings where relevant (e.g. `Per Research's gh-prs step, PR #54322 attempted this in 2022; the closer's comment names a BC concern we should avoid.`).
- `design-space` — enumerate the design dimensions this idea has in its full-RFC form, and for each one record **the option this prototype is taking** vs **the options deferred to RFC discussion**. Format as a table:
```markdown
| Dimension | Prototype takes | Deferred to RFC |
|---|---|---|
| <e.g. function name> | `dd` | `debug_dump`, `dump_die`, `\Debug\dd` |
| <e.g. exit code> | 0 (matches `exit()` default) | 1 (matches Laravel/Symfony) |
| <e.g. output format> | byte-identical to `var_dump` | colored, structured, depth-limited |
| <e.g. INI configurability> | none | depth limit, string truncation, colorization |
| <e.g. SAPI behaviour> | uniform | HTTP 500 on web; `<pre>` wrapping |
```
Purpose: document what the prototype is *not* deciding, so the Verdict can honestly say "the prototype validated dimensions X, Y; dimensions Z, W are still open." Without this, prototypes silently take positions on N dimensions and the RFC inherits all of them as faits accomplis.
- `counter-position-binding` — for each AGAINST argument recorded in Context's Pros vs Cons subsection and each objection surfaced in the Research phase's Notes (by name where the objector is named — e.g. *"Grekas's freeze-innovation argument"*, *"Vollebregt's namespace-collision argument"*), record explicitly:
- **addressable by prototype evidence?** yes / partially / no
- **what evidence would address it?** one sentence
Purpose: forces the prototype to know in advance which objections its output can answer and which it cannot. An objection marked `no` is a known dead-zone — the Verdict should not claim to have answered it.
- `plan-1`, `plan-2`, … — concrete planned edits.
Post-guardrail: every plan step references a concrete file. Smallest viable prototype, not a full implementation. `design-space` and `counter-position-binding` are both populated.
### Phase 5 — Prototype
Steps:
- `test-modification-check` — if any `impl-N` step writes to an existing `.phpt` (anything not freshly added by this SPEC), run the provenance lookup in `_shared/test-modification-policy.md` and add the `## Test-modification justification: <path>` section to SPEC.md before applying changes. Block the phase if any of the five required bullets is missing.
- `impl-1`, `impl-2`, … — one per `plan-N`. Apply the changes with `Edit`. Match existing style (`_shared/php-coding-standards.md`) even for throwaway code — a wildly off-style prototype distorts review. Existing `.phpt` modifications are gated by the `test-modification-check` step above.
- `build` — `make -j$(nproc)` exits 0.
- `commit` — stage every modified php-src path from `impl-*` steps and commit on the current branch:
```bash
git -C "$PHP_SRC_DIR" add <each-impl-path>
git -C "$PHP_SRC_DIR" commit -m "$(cat <<'EOF'
idea(<slug>): prototype <one-line subject>
<one-paragraph body from Hypothesis & Metric — what is being tried
and what would prove it. Mark explicitly as prototype / throwaway.>
Prototype-of: <slug>
EOF
)"
```
Record the commit SHA in the `commit` step body and Progress Log.
Don't worry about test coverage or BC. Worry about: does the patch compile, does it produce a binary, can the metric be measured against it.
Post-guardrail: `make -j$(nproc)` exits 0; no new compiler errors; commit SHA recorded.
### Phase 6 — Measurement & Verdict
Depends on the metric type:
**Performance metric**:
- Write a benchmark script (or reuse `Zend/bench.php` / `ext/opcache/tests/bench`). Place it under `<task-dir>/bench/` (inside the gitignored task dir) for transient runs, or at a stable path under `$PHP_SRC_DIR/benchmark/` if it should be committed.
- Run baseline (no patch): undo the Prototype commit's changes temporarily with `git -C "$PHP_SRC_DIR" checkout <prototype-parent-sha> -- <impl-paths>` (paths only — keep the bench script in place). Rebuild, run 5+ times, capture mean/stddev.
- Restore the prototype: `git -C "$PHP_SRC_DIR" checkout <prototype-commit-sha> -- <impl-paths>`. Rebuild, run benchmark same way.
- Compute delta. If the metric defines a CI, compute it (e.g. with `bc`/`python`/`awk`).
Steps:
- `baseline-run` — numbers recorded.
- `patched-run` — numbers recorded.
- `delta` — computed; verdict pre-recorded.
**DX/syntax metric**: write 2–4 `.phpt` examples (or `.php` scripts) that exercise the idea. Run them on the patched build. Record output. Steps: `examples` + `verify`.
Finally:
- `verdict` — `pursue-as-rfc` / `reframe` / `kill`.
- `rfc-scaffold` — **required iff `verdict` is `pursue-as-rfc`; skip with status `skipped` otherwise.** A scaffold of notes the user can copy into the wiki.php.net RFC. This is explicitly **not the RFC** — no proposed-PHP-Version line authoring, no formal vote section, no full prose. Just the structured stub the user pastes in and fleshes out. Required subsections:
```markdown
### RFC scaffold (notes for wiki.php.net)
- **Proposed title**: <one line>
- **Target PHP version**: <e.g. 8.6, 9.0 — pick the conservative choice>
- **Selling points** (3–5): pull from Context's Pro list + measured prototype evidence. Each one references the specific Measurement step that supports it.
- **Hardest objections to pre-empt** (2–3): pull from Context's Con list + Research-surfaced objector names. For each, the prototype's evidence-stance — "addressed by `delta` step showing X", or "not addressed; needs separate discussion".
- **Alternative names / namespacings considered**: pull from Survey & Plan's `design-space` "Deferred to RFC" column.
- **Open dimensions for RFC discussion**: every row in `design-space` whose Prototype-takes column is a free choice (not forced by measurement). The RFC author needs to argue for each.
- **References**:
- The internals@ thread(s) found in Research (URLs verbatim).
- The prototype commit SHA(s).
- The cross-language precedents named in Context.
```
Boundary: `rfc-scaffold` records notes; it does **not** generate the wiki page text, does **not** write a "Proposed PHP Version" header, does **not** draft a vote section. If the user wants RFC drafting, that's the human's job — see *Out of scope*.
Verdict guidance:
- `pursue-as-rfc` — the metric held up cleanly; the idea is worth a wiki.php.net RFC and `internals@` discussion. Drafting the RFC itself is **out of scope** for this skill (but `rfc-scaffold` notes are required to bridge to the wiki).
- `reframe` — the metric held up partially or the metric itself was off; record what the next version of the hypothesis should be. `rfc-scaffold` is skipped.
- `kill` — the metric failed and you don't see a path to make it hold. Negative results are valuable. `rfc-scaffold` is skipped.
Be honest. A "kill" verdict after a clean Measurement is a success of the skill.
Post-guardrail: the verdict is one of the three values; the evidence (numbers or examples) is recorded in SPEC.md.
**Commit benchmark + DX artifacts** (only if there is anything stageable under php-src — bench scripts under `$PHP_SRC_DIR/benchmark/` or example `.phpt`s under the relevant tests dir):
```bash
git -C "$PHP_SRC_DIR" add <bench-script-paths> <example-phpt-paths>
# Skip the commit if nothing is staged:
git -C "$PHP_SRC_DIR" diff --cached --quiet || git -C "$PHP_SRC_DIR" commit -m "$(cat <<'EOF'
idea(<slug>): bench + verdict <pursue-as-rfc|reframe|kill>
<one-paragraph: hypothesis, metric, observed delta or example outcome,
verdict reasoning>
Verdict: <pursue-as-rfc|reframe|kill>
Prototype-of: <slug>
EOF
)"
```
Record the commit SHA (if a commit happened) in the `delta` / `verify` step body. If nothing was stageable (all evidence lives only in the gitignored SPEC.md), record "no commit — evidence in SPEC.md only" and proceed.
Mark Measurement & Verdict `done`. Flip SPEC.md top-level `status: done`.
## Boundaries
- **Throwaway prototype, not production code.** Don't refactor surrounding code, don't add tests, don't worry about BC. Document this in plan steps.
- **No silent modification of existing `.phpt` files.** Throwaway status does NOT exempt prototypes from the test-modification policy. Any change to a pre-existing test goes through `_shared/test-modification-policy.md` and requires a justification block. Most prototypes should not need to touch existing tests; if a prototype does, that is itself a signal worth recording in the verdict.
- **No RFC drafting.** Wiki.php.net RFC writing is explicitly out of scope for v1. If the verdict is `pursue-as-rfc`, the user takes the SPEC.md to the wiki themselves.
- **No remote git mutations.** No `git push`, no `git remote add/remove/set-url/rename/prune/update`, no `git pull`, no `git request-pull`. Local `commit` is used per phase (Prototype, Measurement) on whatever branch is currently checked out — never creates new branches.
- **No benchmark beyond `Zend/bench.php` complexity** unless the user provides one. Don't fabricate elaborate benchmark harnesses; reuse what php-src already has.
## Edge cases
| Situation | Handling |
|---|---|
| Hypothesis is too vague to restate ("PHP should be faster") | Block Context with: `Hypothesis must be specific enough to identify one subsystem and one mechanism.` |
| Prior-art search shows a declined RFC | Record it in `prior-art`; raise Open Question: should this iteration try a different angle? |
| Prototype doesn't compile at all | Mark `build` step `blocked` with the error; stop. Don't paper over with `#ifdef`s. |
| Benchmark noise exceeds the claimed delta | Verdict is `kill` or `reframe` (smaller real effect than claimed). Be honest. |
| Idea requires JIT/opcache changes the user doesn't have built | Note in `subsystem-map`; if unavoidable, raise Open Question for the user to enable. |
| Hypothesis is really a bug, not an idea | Refuse during Context; suggest `/bug-context` instead. |
| Multiple competing prototypes | One SPEC.md per prototype. Cross-link via a sibling `EPIC.md` if the user wants to manage them together. |
## Quality checklist
- [ ] Context has all 8 required subsections (Restate, Who benefits, Who pushes back, Userland today, Cross-language precedent, Pros vs Cons, Subsystems, Out of scope)
- [ ] Pros vs Cons table has 3–5 entries on each side; AGAINST list is honest
- [ ] Cross-language precedent names 2–3 runtimes (or explicitly records "none")
- [ ] Metric is falsifiable (could fail), not aspirational
- [ ] Workload is named (specific script + inputs)
- [ ] Prior art was searched (git log + gh issue/pr list + internals ML)
- [ ] Survey & Plan has `design-space` table covering ≥3 dimensions
- [ ] Survey & Plan has `counter-position-binding` for every AGAINST argument + every Research-surfaced objection
- [ ] Prototype is the smallest change that exercises the hypothesis
- [ ] `make -j$(nproc)` exits 0 with prototype applied
- [ ] Baseline and patched numbers (or examples) are recorded verbatim
- [ ] Verdict is one of `pursue-as-rfc` / `reframe` / `kill` and matches the evidence
- [ ] If verdict is `pursue-as-rfc`, `rfc-scaffold` step is `done` with all required subsections
- [ ] If verdict is `reframe` or `kill`, `rfc-scaffold` step is `skipped`
- [ ] SPEC.md top-level `status: done` when Measurement & Verdict is `done`
## Out of scope
- Writing a wiki.php.net RFC document (the `rfc-scaffold` step produces notes, not the wiki page text — no "Proposed PHP Version" header, no vote section, no full prose)
- Implementing the production version of the idea
- Sending a PR to php/php-src
- Posting on the internals mailing list
Versions
The database has no other skills named idea-prototype.
Database snapshot: 13.11.2026 · package version 3ce8a71d3700 (SHA-256 digest of the entire package)
Downloads in the last 30 days: 0 · ranking
Report a problem with this skill: harmful content, incorrect descriptions or an author’s removal request.
Similar skills
- 100bug-context
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",… - 100research
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… - 90prototype
Build a throwaway HTML or in-app prototype that answers one design question. Use when the user wants to try a state model or UI idea before committing, or says "mock it up", "prototype", "what should this look like". - 90prototype
Use to rough out a working thing fast, zero ceremony, before committing to the pipeline — the prototype IS the spec. Triggers — "/engineer.prototype", "prototype this", "quick prototype", "spike it", "rough it out", "throwaway version", "let's prototype". - 90prototype-spike
Build or plan an explicitly throwaway prototype to answer a design, API, UX, performance, or integration question, then capture findings and cleanup. Use when the user asks for a spike, prototype, proof of concept, or experiment before committing to production design. - 90prototype
Build a throwaway prototype to answer a focused logic, state-model, or UI question before committing to production design. Use when the user asks to prototype, sanity-check a model, mock up UI, explore design options, or try a few designs.