From test-pharaoh
Write tests for the current Android branch driven by a user story + ACs, adhering to the project's existing conventions. Run inside an Android project's branch.
How this skill is triggered — by the user, by Claude, or both
Slash command
/test-pharaoh:test-scribeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill (`test-pharaoh:test-scribe`) runs only in the main Claude Code session. It coordinates three review gates (feature understanding, plan review, escalation) that require direct user interaction — those gates cannot function from a subagent context.
This skill (test-pharaoh:test-scribe) runs only in the main Claude Code session. It coordinates three review gates (feature understanding, plan review, escalation) that require direct user interaction — those gates cannot function from a subagent context.
If you were dispatched as a subagent via the Agent tool — by another plugin, by a workflow coordinator, or even by one of this plugin's own subagents (architect, mason, physician) — STOP now. Return to your caller with:
/test-scribemust be invoked from the main session (it requires interactive review gates). Please exit this subagent and invoke/test-scribedirectly, or narrow your request to a specific subagent task.
Do not execute the workflow below from within a subagent.
You are the orchestrator for the test-pharaoh plugin. When the user invokes /test-scribe, follow this workflow in order. Do not skip gates. Do not deviate from the project's existing conventions.
Before starting the workflow, verify these prerequisites. If any fails, stop with a clear message — do NOT proceed into Step 1.
<plugin-dir>/scripts/kotlin-signatures/build/libs/kotlin-signatures.jar. If it's missing (fresh install, or post-/plugin update which wipes build/), build it yourself before continuing:
(cd <plugin-dir>/scripts/kotlin-signatures && ./gradlew shadowJar)
Tell the user you're doing a one-time ~30s build of the signature extractor. Requires JDK 17+. If the build fails (e.g., JDK not installed, no network for first-time Gradle dependency fetch), stop and report the error with a prompt for the user to install JDK 17+ or re-run with network access.<plugin-dir>/scripts/kotlin-signatures/bin/kotlin-signatures is executable (test -x). If not, tell the user to chmod +x it.git rev-parse --is-inside-work-tree). If not, stop — /test-scribe only operates on a branch.Before collecting the story + ACs, ask the user where tests should be written:
(a) Current branch — work on the branch already checked out. Generated tests land here. Pick this if you already have a feature branch ready.
(b) New branch — create a new branch off HEAD. Suggest a name based on the feature (e.g., tests/<feature-slug>); let the user override. Run: git checkout -b <name>.
(c) Worktree — create an isolated git worktree so the user's current workspace is untouched. Do this inline; do not invoke any other skill.
.worktrees/ at the repo root; otherwise existing worktrees/; otherwise default to creating .worktrees/.git check-ignore -q <parent>/probe. If not ignored, add the dir to .gitignore and commit that change BEFORE creating the worktree; otherwise generated content may leak into the user's git history.tests/<feature-slug> based on the story title; accept overrides.git worktree add <parent>/<dir-safe-name> -b <branch-name>. Replace / with - in the directory path only; keep the branch name as-is.cd into the new worktree. Continue to Step 1 from there.Do not proceed to Step 1 until the user has picked one and, for (b)/(c), confirmed the branch name.
/test-scribe with these inline, use them; otherwise stop and prompt. Never continue with a blank or inferred spec..claude/test-pharaoh/config.json. If parentBranch is set, use it.develop, main, master (in that order). Use the first one that exists.config.json.git diff <parent>...HEAD (three-dot syntax — commits unique to this branch).gradle/libs.versions.toml (SHA-256). If .claude/test-pharaoh/project-profile.json exists AND its versionCatalogHash matches, reuse it.architect subagent with the repo root as input. It writes a fresh profile.libs.versions.toml exists, the discoverer falls back to scanning build.gradle.kts files; if still nothing, prompt the user to confirm a minimal profile and proceed.scope = (classes changed in diff) ∩ (classes implicated by ACs). "Implicated by ACs" means concepts named in ACs whose matching class appears in the diff — be conservative.<plugin-dir>/scripts/kotlin-signatures/bin/kotlin-signatures <path/to/Class.kt>
.claude/test-pharaoh/runs/<timestamp>/extracts/<mirror-path>/<Class>.kt.EXTRACTOR FAILED — write tests for <Class> manually. Do NOT fall back to reading the body.Write a short inline summary (3–5 bullets) covering:
Ask: "Does this match what you intended? Anything I missed or misinterpreted?"
Loop until the user confirms. Only then proceed. Foundational misunderstandings caught here are cheap; at later gates they cost plan synthesis or generated tests.
For each class in scope and each applicable tier (unit, integration, roborazzi, cucumber), list the planned tests with traceability markers. Example format in .claude/test-pharaoh/runs/<timestamp>/TEST_PLAN.md:
### com.sample.auth.LoginViewModel (tier: unit)
- [ ] onSubmit_validCreds_emitsSuccess
source: AC-1
- [ ] onSubmit_invalidCreds_emitsInlineError_andClearsPassword
source: AC-2
- [ ] onSubmit_networkFailure_emitsBanner
source: AC-3 + catalog/retrofit.md#network-failure
- [ ] onSubmit_5xx_emitsGenericError
source: AC-4 + catalog/retrofit.md#5xx
- [ ] sealedStateBranches_exhaustivelyRendered
source: contract (LoginUiState sealed branches)
Additionally:
catalog/<framework>.md exists in the plugin, add a plan annotation: UNKNOWN: no catalog for <framework>; AC + contract only. The user can add a catalog file mid-flow or accept the narrower coverage.Tell the user the plan is written. They review, edit TEST_PLAN.md directly if they want, or answer clarifying questions. Do not dispatch the generator until the user approves.
For each approved (class × tier), dispatch a mason subagent in parallel where independent. Inputs to each:
signatureExtract: path to the extract for this class.tier.catalogPaths: catalog entries matched by profile frameworks × class imports/types visible in the extract.planExcerpt: the relevant slice of TEST_PLAN.md.projectProfilePath.existingTestPaths and existingFakePaths for this class (read-allowed).Aggregate the generator results. If any returned clarification requests, resolve them with the user and re-dispatch.
If a generator returns a context-limit error (the class under test is too large for the signature extract + catalog + plan excerpt to fit), split the work for that class — either by tier (dispatch one generator per tier) or by method (generate tests for a subset of methods at a time) — and redispatch. Do not skip the class silently.
For each module where tests were written, run the module-scoped task(s) from the profile:
./gradlew <module>:<task>
(Use profile.modules[module].testTasks mappings — e.g., unit → :test, roborazzi → :verifyRoborazziDebug, instrumented → :connectedDebugAndroidTest.)
If any instrumented tests were written, check adb devices first; if no device/emulator is connected, prompt the user to start one or skip the instrumented tier.
Capture output to .claude/test-pharaoh/runs/<timestamp>/run.log.
Apply a per-Gradle-task timeout (default 5 minutes). If a task hangs past the timeout, kill it and escalate directly to Gate 2 — do not retry a hung task, and do not loop-guard on hang (it's immediately substantive).
If there are failures, dispatch physician:
Write diagnosis.md under .claude/test-pharaoh/runs/<timestamp>/ containing:
N passed / M failed / K skipped.Tell the user the run is stopped and point them at the diagnosis. The run directory retains TEST_PLAN.md, generated files, run.log, and the diagnosis — they can resume manually.
On clean run, print the summary, commit the generated tests on behalf of the user only if they explicitly ask, and stop.
Guides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.
npx claudepluginhub rcosteira79/test-pharaoh --plugin test-pharaoh