- **Date:** 2026-08-23 - **Type:** process - **Scope:** `skills`, `docs` - **PR:** [#428](https://github.com/Prism-Shadow/penguin-harness/pull/428) [中文版](2026-08-23-manual-test-skill.zh.md) `.agents/skills/penguin-harness-manual-test/SKILL.md` is a new repo-development skill covering how to bring the app up on a developer machine so a change can be tried by hand: the four dev entry points (`pnpm dev`, `pnpm desktop`, `pnpm dev:landing`, `pnpm dev:docs`) with their fixed ports, and the environ...
Scanned 9/2/2026
Install to Claude Code
npx -y skills add Prism-Shadow/penguin-harness --skill 0.2.6 --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of 0.2.6?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/prism-shadow-0-2-6)More formats (shields.io, HTML) on the badges page.
# A skill for standing the app up to test by hand
- **Date:** 2026-08-23
- **Type:** process
- **Scope:** `skills`, `docs`
- **PR:** [#428](https://github.com/Prism-Shadow/penguin-harness/pull/428)
[中文版](2026-08-23-manual-test-skill.zh.md)
`.agents/skills/penguin-harness-manual-test/SKILL.md` is a new repo-development
skill covering how to bring the app up on a developer machine so a change can be tried by hand: the four dev entry points (`pnpm dev`, `pnpm desktop`,
`pnpm dev:landing`, `pnpm dev:docs`) with their fixed ports, and the environment traps that make a
working setup read as a broken one. Two neighbouring documents were corrected to match it.
## Details
- Data roots are stated per entry point: `resolveRoot()` is `PENGUIN_HOME ?? ~/.penguin/data`, and
`desktopDataRoot()` sends a packaged build to that same CLI-shared root while only an unpackaged
run takes `~/.penguin/dev-data`. The skill also names the startup lines that report the root
actually taken (`Data root: <root>`, `[shell] dev instance '<name>' on data root <root>`).
- `scripts/run-with-env.mjs` applies `VAR=value` with `${VAR:-value}` semantics, so every dev
default is a default and an inherited `PENGUIN_HOME` silently wins. The rule the skill gives is
never to export it and to prefix a single command
(`PENGUIN_HOME=~/.penguin/dev-data-<topic> pnpm dev`) when an isolated root is needed, plus the
asymmetry an empty value creates between that script and `resolveRoot()`'s `??`.
- `<root>/server.lock` admits one server per data root, refusing with
`Another PenguinHarness server is already running on this data root (pid N)` and exit 3 regardless
of `PORT`. The instruction is to move to a distinct root, not to kill what usually is the user's
own desktop app.
- An environment proxy routes loopback `curl` through itself and answers 502 while the server is
healthy; browsers and the server's own outbound path are unaffected. The skill gives
`curl --noproxy '*'` / `NO_PROXY` and says to suspect the proxy before debugging the server.
- Two more surfaces that read as failures: `/api` on `127.0.0.1` is the Workspace-preview host and
answers 401 by design, and the dev backend on 7368 serves the last-built `packages/web/dist`
rather than what Vite is serving on 7365.
- Sign-in is covered for scripted runs: the seeded `admin` notice, `<root>/initial-admin-password`,
`PENGUIN_SEED_ADMIN_PASSWORD`, and the `packages/web/e2e/` harness for chat flows on a root with
no model credential.
- `CONTRIBUTING.md`'s data-root paragraph now tells contributors to pass `PENGUIN_HOME` inline for
the one command that needs it rather than exporting it, and names both the unset-or-empty rule
that makes an exported value win and the collision an exported `~/.penguin/data` produces.
- `penguin-harness-dev` dropped its claim that a remote branch literally named `docs` makes
`docs/<topic>` branch names impossible in this repo: no such branch is on the remote, and the
slashed form pushes normally. The `docs-<topic>` names left over from that period are explained
where the rule is stated, with `git ls-remote --heads origin` as the check if it ever recurs.
## The override says so now
`scripts/run-with-env.mjs` keeps applying its `VAR=value` arguments as defaults — an inherited value
still wins, which is what makes `PENGUIN_HOME=/somewhere pnpm dev` work at all, since a child
process cannot tell an inline assignment from an exported one. What changed is that it no longer
happens in silence: any default the environment displaced is named on stderr before the command
runs, so a shell-wide export cannot quietly redirect a dev script at another data root.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!