Bundle
dsh-reprolab
dsh-reprolab — a complete bug-to-proof workflow for DeepSeek Harness: frozen repro tests, RED/GREEN/REGRESSION gates, and replayable evidence.
- Source
- yuttfu
- License
- MIT
- Updated
- Updated 2 days ago
Readme
# dsh-reprolab
> A complete bug-to-proof workflow for DeepSeek Harness: frozen repro tests, RED/GREEN/REGRESSION gates, and replayable evidence.
`dsh-reprolab` (ReproLab) turns an issue, an error message or reproduction steps into auditable fix evidence:
```text
baseline code + frozen repro test → must fail (RED)
candidate fix + the SAME frozen test → must pass (GREEN)
regression check → no new failures (REGRESSION)
evidence report → replayable, redacted (REPORT)
```
ReproLab is a deterministic bug-proof executor that complements session-level discipline plugins such as dsh-doublecheck. Your Harness session writes the tests and the fix; ReproLab isolates worktrees, freezes inputs, runs the quality gates and produces the evidence.
## The nine tools
| Tool | Purpose | Key result |
|---|---|---|
| `reprolab_start` | Resolve repo, freeze baseline, create `control`/`candidate` worktrees, optionally record the baseline regression failure set | `runId`, worktree paths, baseline, `baselineRegression` |
| `reprolab_set_test` | Freeze the repro test patch + the target test command | `testPatch` hash, command hash |
| `reprolab_verify_red` | Run the frozen command in `control` and prove a genuine test failure | `verdict: valid_red`, failure `fingerprint` |
| `reprolab_set_fix` | Freeze the production-only fix patch from `candidate` | `fixPatch` hash, changed files |
| `reprolab_verify_green` | Run the exact same frozen command in `candidate` and prove it passes | `verdict: valid_green` |
| `reprolab_verify_regression` | Compare candidate failures with the recorded baseline set | `pass` / `pass_with_baseline_failures` / `regression` / `inconclusive` |
| `reprolab_status` | Structured run state, frozen hashes, report staleness, next legal actions | `nextActions` — no prose to parse |
| `reprolab_report` | Generate/refresh `report.json` + `report.md` from one shared model | report path + recomputable sha256 |
| `reprolab_abort` | Abort and keep the scene for inspection | retained paths |
A nonzero exit code alone is **never** RED: test-not-discovered, syntax errors, missing imports, timeouts, crashes and cancellations are all excluded, and RED/GREEN must use identical test-patch and command hashes.
## Installation
DeepSeek Harness `0.1.0-rc.6`, Node `^22.19.0 || >=24.0.0`.
From a packed artifact (built `dist/` included):
```sh
pnpm pack # → dsh-reprolab-0.1.0.tgz
dsh plugin --profile <profile> add ./dsh-reprolab-0.1.0.tgz
dsh --profile <profile>
```
From the repository directory (dev):
```sh
dsh plugin --profile <profile> add ./dsh-reprolab
```
Both forms require the host's in-box `tools` and `subprocess` services (provided by `dsh-base` in every profile).
## Configuration
All fields are optional and defaulted by the Schemastery schema. Bundle patch rows replace the whole config per row, so restate every key when overriding.
| Key | Type | Default | Meaning |
|---|---|---|---|
| `runDir` | string | `.reprolab` | Directory (relative to repo root) for runs, worktrees, patches and reports |
| `graceMs` | number (≥50) | `5000` | SIGTERM→SIGKILL grace when terminating child process trees |
| `maxOutputBytes` | number (≥1024) | `1048576` | In-memory output cap per stream; overflow keeps the tail and spills the full stream |
| `spillMaxBytes` | number (≥1 MiB) | `16777216` | Whole-stream spill cap per stream |
| `lockStaleMs` | number (≥1000) | `300000` | Repo write-lock staleness threshold (stealing still requires a dead owner) |
## Permissions and external side effects
ReproLab writes **only inside the target repository**: `runDir/` (default `.reprolab/`) with run state, patches, reports, and `git worktree` directories. Side effects:
- **Filesystem**: creates `runDir/runs/<run-id>/`, `runDir/worktrees/<run-id>-{control,candidate}/`, `baseline.patch`, `test.patch`, `fix.patch`, `report.json`, `report.md`; reads repository files.
- **Processes**: executes Git (structured `argv`, explicit `cwd`, no shell) and the test commands **you declare** (argv arrays only, never shell strings). Cancellation/timeout kills the whole process tree.
- **Git**: creates/removes worktrees registered under `runDir/worktrees`; **never** resets, checks out, cleans or commits on your current branch. Cleanup is a separate explicit primitive (not a tool).
- **Network / telemetry / keys**: none. The plugin makes no network calls, sends no telemetry and needs no API keys.
- **Credentials**: child environments start from the host's scrubbed base (`KEY/PASSWORD/SECRET/TOKEN` names and `DSH_*` are stripped); output is redacted (tokens, Authorization, cookies, passwords, high-entropy strings) before records or reports are written.
## Quick demo (node:test)
```text
> reprolab_start { repoPath: "/path/to/repo", baselineCommand: { argv: ["node","--test"], framework: "node:test" } }
→ runId run_…, state baseline_checked, control + candidate worktree paths
# you write the repro test in the candidate worktree
> reprolab_set_test { runId, declaredTestFiles: ["bug.test.mjs"], command: { argv: ["node","--test","bug.test.mjs"], framework: "node:test" } }
→ state test_frozen, testPatch hash
> reprolab_verify_red { runId }
→ verdict valid_red, failure fingerprint, state red_verified
# you fix the production code in candidate
> reprolab_set_fix { runId } → state fix_frozen
> reprolab_verify_green { runId } → verdict valid_green
> reprolab_verify_regression { runId, command: { argv: ["node","--test"], framework: "node:test" } }
→ verdict pass (or pass_with_baseline_failures), state regression_verified
> reprolab_report { runId } → reportPath, reportHash (sha256 of report.json)
> reprolab_status { runId } → state reported, nextActions []
```
Report staleness: if any evidence input changes after reporting (e.g. the tests are re-frozen), `reprolab_status` reports `report.stale: true`.
## Compatibility
| Component | Version |
|---|---|
| DeepSeek Harness | `0.1.0-rc.6` |
| @deepseek-ai/cordis | `^4.0.1` (peer) |
| @deepseek-ai/dsh-subprocess / dsh-tools / dsh-brand | `0.1.0-rc.6` |
| @deepseek-ai/schemastery | `^3.18.1` |
All host contracts were verified first-hand against the installed official packages and the official docs snapshot.
## Known limitations
- One active (non-terminal) run per repository at a time; the write lock is fail-fast (`RUN_ALREADY_ACTIVE`), not queued.
- `pytest` and `jest` classification is based on the documented output formats (no local pytest/jest installs were available); `vitest` and `node:test` formats were captured from real runs. Python projects use `unittest` + the `generic` classifier.
- Test-runner cache artifacts (`__pycache__`, `.pyc`, `.pytest_cache`, `.coverage`, `htmlcov`, `.vite`, `node_modules/.cache`) are ignored by change detection — an allowlist, not an ignore-all.
- The repository needs at least one commit (worktrees require a baseline commit).
- `dsh-windtunnel`'s scripted adapter is currently incompatible with DSH `0.1.0-rc.6` (third-party issue). Real-host lifecycle (install/enable/disable/uninstall/reinstall) was verified through the real `dsh` CLI on a clean headless profile.
## Uninstall
```sh
dsh plugin --profile <profile> remove dsh-reprolab
```
This removes the bundle row and package. Run artifacts (`runDir/` and worktrees) are **not** deleted by uninstall — remove them explicitly with `git worktree remove` after inspecting them. Active runs terminate their child processes on plugin unload (host subprocess service disposal).
## Troubleshooting
Recovery guidance for every error code, worktree cleanup, stale locks and invalidated runs: [`docs/troubleshooting.md`](docs/troubleshooting.md). Security model: [`docs/security.md`](docs/security.md). Architecture: [`docs/architecture.md`](docs/architecture.md).
## Development
```sh
pnpm install
pnpm run check # lint + typecheck + build + verify:manifest
pnpm pack # → dsh-reprolab-0.1.0.tgz (dist/, cordis.patch.yml, README, LICENSE)
```
MIT License.
Install
dsh plugin --profile web add github:yuttfu/dsh-reprolab
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-reprolab from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.