yuttfu
dsh-reprolab
dsh-reprolab — a deterministic bug-proof executor for DeepSeek Harness: frozen repro tests, RED/GREEN/REGRESSION gates, and replayable evidence. Complements session-level discipline plugins such as dsh-doublecheck.
- Stars
- 0
- Language
- TypeScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
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:
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):
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):
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, explicitcwd, 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/TOKENnames andDSH_*are stripped); output is redacted (tokens, Authorization, cookies, passwords, high-entropy strings) before records or reports are written.
Quick demo (node:test)
> 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. pytestandjestclassification is based on the documented output formats (no local pytest/jest installs were available);vitestandnode:testformats were captured from real runs. Python projects useunittest+ thegenericclassifier.- 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 DSH0.1.0-rc.6(third-party issue). Real-host lifecycle (install/enable/disable/uninstall/reinstall) was verified through the realdshCLI on a clean headless profile.
Uninstall
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. Security model: docs/security.md. Architecture: docs/architecture.md.
Development
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.