Skip to content
Skills Library
Programming · Testing

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.

Licence
MIT
Last repository change
26.05.2026

Assessment and security

100/ 100Class: good
Format25 / 25
Frontmatter with name and description, valid name, description up to 1,024 characters, name matching the folder.
Discoverability25 / 25
Description explains when to use the skill, has a reasonable length and uses third person.
Content35 / 35
At least 150 words and at most 500 lines, headings, step lists, examples or code.
Hygiene15 / 15
No placeholders such as TODO, no Windows paths, with a licence.
Riskno signals detected in the scan
Files in this package
1
Scripts
0
HTML comments
0
URLs in SKILL.md
0
Deprecation

No signals detected. Repository changed on 26.05.2026, without references to retired models or APIs.

Licence

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

I have an idea for php-srcprototype this idealetwhat if PHP supported …explore whether …
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

  1. Inputs
  2. What it produces
  3. Phases owned
  4. Workflow
  5. Boundaries
  6. Edge cases
  7. Quality checklist
  8. Out of scope
Original SKILL.md headings · 291 lines, 3,009 words
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.

Feedback and reports

Your message goes to Bartosz Sokoliński. An email address is needed only for a reply. See the privacy policy.