kylesnowschwartz/simpleclaude/sc-dirty-room

Claude Code and agent skill by kylesnowschwartz/simpleclaude

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Lift-and-shift port of a repository, library, API, protocol, or other software artifact to a different language, runtime, or platform, with the original source available as a reference. This skill SHOULD be used when the user says "port from X to Y", "lift and shift", "rewrite in Go", "rewrite in Rust", "translate this codebase", "convert to TypeScript", "language migration", "rewrite in another language", "carry over the algorithms", "borrow techniques from", "dirty room", "dirty-room design", "sc-dirty-room", or wants to reimplement an existing artifact while studying its internals to preserve algorithms, data structures, or idioms worth keeping. NOT for legally-constrained reimplementation — use /sc-clean-room when copyright isolation matters.

Install

npx vskill@latest install kylesnowschwartz/simpleclaude/sc-dirty-room

SKILL.md

Dirty-Room Design

This is a bastardization of the technique used by Compaq 1982 to clone the IBM PC BIOS.

A structured approach to porting a software artifact to a different language or platform while consulting its internals. A reading agent examines the original and produces discovery, fixtures, and a translation brief — notes on which algorithms, data structures, and idioms are worth carrying across the language boundary. The implementation agent receives all three artifacts and explicit permission to read the original source directly.

The clean-room skill builds a wall between specification and implementation to preserve copyright independence; the dirty-room takes notes through the open window because the constraints here are technical, not legal. Use this when the goal is a faithful port rather than an independent reimplementation.

EXECUTION MODEL

Phases 0 through 6 run in sequence. The core phases (1-4) MUST NOT be skipped or reordered.

  • Phase 0 establishes scope, target language, and pins the artifact version
  • Phase 1 (Read) examines the original via a Task() agent and produces discovery, fixtures, and a translation brief
  • Phase 2 (Refine) finalises the spec and translation brief for handoff
  • Phase 3 (Port) builds in a Task() agent that may consult the original directly
  • Phase 4 (Verify) confirms equivalence via spec compliance and fixture replay
  • Phases 5-6 present results and offer next steps

After each phase, present the output to the user and wait for approval before proceeding.

No isolation, by design

The implementation agent in Phase 3 receives the original artifact's path and may read it freely. The reading agent's notes flow through to the porter. This is the explicit difference from /sc-clean-room — the wall is gone because the work is a translation, not a clean reimplementation. Process-level separation between agents is preserved only for token efficiency; it is no longer load-bearing for independence.

Phase 0: Resolve Target, Scope, and Languages

Parse $ARGUMENTS. The first argument is the target, anything after is a scope, focus, or target-language hint.

Target resolution
ArgumentTargetVersion pin
Repository URLClone or fetch the repoRecord commit SHA
Local pathExamine directlyRecord git commit SHA; if not a git repo, record a checksum
Package nameLocate via registry (npm, PyPI, RubyGems, crates.io, etc.)Record exact package version
Protocol or API nameFetch public docs and specsRecord document revision or access date

Version pinning is mandatory. Record an immutable identifier so all artifacts reference the same version.

Scope and language negotiation

Use AskUserQuestion:

  • Source language and runtime
  • Target language and runtime (this is the defining input; if same as source, ask whether a direct implementation is a better fit)
  • Which parts to port (the whole thing, a subset, a single module)
  • Quality attributes that matter (performance parity, API compatibility, idiomatic target-language code)
  • What is explicitly out of scope
  • Licence check: confirm the user has rights to study the original and produce a port. If unclear, redirect to /sc-clean-room.

Tell the user: "Target: [what]. Scope: [boundaries]. Languages: [source] → [target]."

Run directory

Slug: <artifact-name>-<source-lang>-to-<target-lang> (lowercase, hyphens). Create with mkdir -p .agent-history/dirty-room/<slug>.

Run git check-ignore -q .agent-history/ — if it fails, warn the user to add the ignore rule.

If the directory already exists, ask: start fresh, resume, or abort.

Classify the artifact
TypeReading focus
Library/PackageExported functions, types, behaviour contracts, internal algorithms
CLI ToolCommand interface, input/output formats, exit codes, argument parsing strategy
API/ServiceRoutes, request/response schemas, error codes, middleware ordering
ProtocolMessage types, sequencing, state transitions, framing
Data FormatSyntax, semantics, edge cases, error recovery, parser strategy
AlgorithmInputs, outputs, invariants, complexity, optimisations worth preserving
Run State

Before leaving Phase 0, fix the following named variables.

Substitution contract. Two grammars appear in this skill and must not be confused:

  • Tokens of the form <UPPER_SNAKE> are Run State variables. The orchestrator MUST replace them with the resolved value before sending any prompt to a Task() agent. Every Phase 1 and Phase 3 prompt body performs this literal substitution before invocation.
  • Tokens of the form [brief description] inside example artifact templates (the discovery.md, fixtures.md, specification.md, and verification.md blocks) are human-readable scaffolds the spawned agent fills with its findings — do NOT replace these.
VariableDefinitionDerivation rule
ARTIFACT_NAMEShort canonical name of the original artifactLowercase, hyphens; strip versions, namespaces, and registry decorations. For repo URLs, use the repo's basename; for packages, the registry name without scope (@org/foo → foo); for protocols, the common abbreviation (e.g. http2, grpc).
SOURCE_LANG / TARGET_LANGCanonical language tokensLowercase, hyphens. Use the canonical short names: go, rust, python, typescript, javascript, ruby, java, kotlin, swift, c, cpp, csharp, elixir, erlang, scala, clojure, haskell, ocaml. Pick the closest match for variants (ts → typescript, py → python).
SLUGRun identifier<ARTIFACT_NAME>-<SOURCE_LANG>-to-<TARGET_LANG>
RUN_DIRRun directory (absolute path)<repo-root>/.agent-history/dirty-room/<SLUG>/
SOURCE_PATHAbsolute path to the materialised originalSet by Phase 0 Materialisation, below.
TARGET_PATHAbsolute path where the port will be writtenConfirm with the user; default to <repo-root>/<ARTIFACT_NAME>-<TARGET_LANG>/ if unspecified.
SOURCE_VERSIONImmutable version pin of the materialised sourceRead after Materialisation; this is the version_pin field recorded by the Materialisation recipe in <RUN_DIR>provenance.json.
SCOPENegotiated scope of the portCaptured during Phase 0 scope negotiation. A short prose summary of which parts are in scope and out of scope.
IMPL_PREFSPorter's preferred architecture, test strategy, librariesCaptured at the start of Phase 3, immediately before the porting Task() is launched, via AskUserQuestion.
APPROVAL_SIGNALWhat counts as user approval at each blocking gateAn explicit affirmative from the user — "yes", "approved", "proceed", "lgtm", "go ahead", or equivalent. Silence, partial approval ("looks mostly good but…"), or any qualified response does NOT count; re-ask explicitly until you receive an unambiguous affirmative or an explicit halt.

Echo the Run State back to the user as a compact block before Phase 1 so they can confirm:

SLUG=<resolved>
RUN_DIR=<resolved>
ARTIFACT_NAME=<resolved>
SOURCE_LANG=<resolved>
TARGET_LANG=<resolved>
SOURCE_PATH=<resolved>
TARGET_PATH=<resolved>
SOURCE_VERSION=<resolved>
SCOPE=<resolved>

(IMPL_PREFS is filled in at Phase 3.)

Phase 0 Materialisation

After resolving Run State, the orchestrator MUST materialise the source on disk and record its version pin to <RUN_DIR>provenance.json before proceeding to Phase 1. Run exactly one row from the table below — the row whose target type matches what the user supplied.

provenance.json shape (uniform across all rows):

json
{
"target_type": "repo_url | local_path | package | protocol",
"identifier": "<the original argument as supplied>",
"version_pin": "<commit SHA, package version, or doc revision/access date>",
"captured_at": "<ISO-8601 UTC timestamp>",
"source_path": "<absolute path>"
}
Target typeMaterialisation recipe
Repository URLgit clone <url> <RUN_DIR>source/<ARTIFACT_NAME> then capture git -C <RUN_DIR>source/<ARTIFACT_NAME> rev-parse HEAD as version_pin. source_path = <RUN_DIR>source/<ARTIFACT_NAME>.
Local pathNo copy. source_path = absolute path of <SOURCE_INPUT>. If git -C <SOURCE_INPUT> rev-parse HEAD succeeds, use its output as version_pin. Otherwise compute `find <SOURCE_INPUT> -type f -exec sha256sum {} \; \sha256sum and use that digest as version_pin`.
Package nameResolve and unpack into <RUN_DIR>source/<ARTIFACT_NAME>/ per ecosystem, then record the resolved version as version_pin: <br>• npm: npm pack <pkg>@<ver> then tar -xzf <pkg>-<ver>.tgz -C <RUN_DIR>source/<ARTIFACT_NAME> --strip-components=1 <br>• PyPI: pip download --no-deps --no-binary=:all: -d <RUN_DIR>source/ <pkg>==<ver> then unpack the sdist into <RUN_DIR>source/<ARTIFACT_NAME>/ <br>• RubyGems: gem fetch <pkg> -v <ver> then gem unpack <pkg>-<ver>.gem --target=<RUN_DIR>source/ <br>• crates.io: cargo download <pkg>==<ver> -x -o <RUN_DIR>source/<ARTIFACT_NAME>/ (or fetch the .crate and tar -xzf it)
Protocol / APIcurl -fsSL <spec-url> -o <RUN_DIR>source/<ARTIFACT_NAME>/<filename> (repeat per document). version_pin = the document's published revision if stated in the spec, otherwise the ISO-8601 fetch date. source_path = <RUN_DIR>source/<ARTIFACT_NAME>.

Update SOURCE_PATH and SOURCE_VERSION in Run State from <RUN_DIR>provenance.json (the source_path and version_pin fields, respectively). From Phase 1 onward, all agent prompts derive <SOURCE_PATH> and <SOURCE_VERSION> from <RUN_DIR>provenance.json.

Phase 1: Read the Source

Examine the original to document what it does, how it does the parts worth preserving, and capture behavioural fixtures for verification.

BLOCKING: Complete the reading before moving to Phase 2.

Launch as a Task() agent. This agent reads the original freely. Its output goes to disk; the orchestrator reads those files afterward. Unlike clean-room, there is no contamination concern — the implementation agent will see the same source material itself.

Per the substitution contract above, replace every <UPPER_SNAKE> token in the prompt body with its Run State value before invoking. Leave the [bracket] scaffolds inside the example artifact templates untouched — those are for the spawned agent to fill.

Task(
description: "Dirty-room reading: examine original artifact for port",
prompt: """
## Role: Reading Agent
Examine the original artifact and produce three deliverables:
1. A discovery document (behaviour and noteworthy internals)
2. A behavioural fixtures file
3. A translation brief (how to carry this across the language boundary)
Target: <ARTIFACT_NAME>
Scope: <SCOPE>
Provenance: <RUN_DIR>provenance.json is authoritative for SOURCE_PATH and SOURCE_VERSION; read it before starting.
Source version: <SOURCE_VERSION>
Source language: <SOURCE_LANG>
Target language: <TARGET_LANG>
Source path: <SOURCE_PATH>
Run directory: <RUN_DIR>
## What to capture in discovery.md
- Public interface: function signatures, types, config options, error types
- Behavioural contracts: input/output mappings, side effects, edge cases
- Integration surface: dependencies, consumers, environment expectations
- Non-functional characteristics: performance envelope, concurrency model
- **Internal techniques worth noting**: algorithms, data structures,
optimisation tricks, ordering of operations, invariants the code relies on

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
103
Repository forks
15
7-day trend score
23

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/kylesnowschwartz/simpleclaude/sc-dirty-room/badge)](https://verified-skill.com/skills/kylesnowschwartz/simpleclaude/sc-dirty-room)

Something wrong with this skill or its page? Tell us.