Domain Modeling
fossasia/eventyay-interpretation
Build and sharpen a project's domain model. An agent skill from fossasia/eventyay-interpretation.
Interactive Q&A over an existing recap document. An agent skill from sd0xdev/sd0x-harness.
$ npx skills add sd0xdev/sd0x-harness --skill recap-ask -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install sd0xdev/sd0x-harness recap-ask --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/sd0xdev/sd0x-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/recap-ask .claude/skills/recap-ask && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "recap-ask" agent skill from https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-ask into .claude/skills/recap-ask/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "recap-ask", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-askType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add sd0xdev/sd0x-harness --skill recap-ask -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install sd0xdev/sd0x-harness recap-ask --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sd0xdev/sd0x-harness.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/recap-ask .agents/skills/recap-ask && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "recap-ask" agent skill from https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-ask into .agents/skills/recap-ask/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "recap-ask", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add sd0xdev/sd0x-harness --skill recap-ask -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install sd0xdev/sd0x-harness recap-ask --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sd0xdev/sd0x-harness.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/recap-ask .cursor/skills/recap-ask && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "recap-ask" agent skill from https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-ask into .cursor/skills/recap-ask/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "recap-ask", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/sd0xdev/sd0x-harness.git --path skills/recap-ask--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add sd0xdev/sd0x-harness --skill recap-ask -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install sd0xdev/sd0x-harness recap-ask --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sd0xdev/sd0x-harness.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/recap-ask .gemini/skills/recap-ask && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "recap-ask" agent skill from https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-ask into .gemini/skills/recap-ask/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "recap-ask", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install sd0xdev/sd0x-harness recap-askInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add sd0xdev/sd0x-harness --skill recap-ask -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/sd0xdev/sd0x-harness.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/recap-ask .github/skills/recap-ask && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "recap-ask" agent skill from https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-ask into .github/skills/recap-ask/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "recap-ask", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add sd0xdev/sd0x-harness --skill recap-ask -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install sd0xdev/sd0x-harness recap-ask --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/sd0xdev/sd0x-harness.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/recap-ask .opencode/skills/recap-ask && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "recap-ask" agent skill from https://github.com/sd0xdev/sd0x-harness/tree/main/skills/recap-ask into .opencode/skills/recap-ask/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "recap-ask", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
recap-askInteractive Q&A over an existing recap document. An agent skill from sd0xdev/sd0x-harness.
Recap Ask is an agent skill from sd0xdev/sd0x-harness. Interactive Q&A over an existing recap document. Use when: user wants to ask follow-up questions about a briefing-recap-<date.md produced by /recap-doc, with recap-bounded context + out-of-scope redirect + optional promote-to-request. Not for: generating a new recap (use /recap-doc), general project Q&A (use /ask), code tracing (use /code-explore). Output: per-turn answer referencing file:line + end-of-session promote prompt.
Its SKILL.md is about 3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/qa-prompt.md`).
It sits in Development, covering Domain-driven design. The repository describes itself as: The harness layer for Claude Code — a reference implementation of harness engineering with hook-enforced dual review, state-machine gates that survive context compaction, and… The licence is MIT.
4 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit c9a2036. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadGrepGlobBash(git:*)Bash(node:*)SkillAskUserQuestionWriteFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
gitFrom the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md. Its commands use git, which can reach the network depending on how they are called.
From URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
FEATURE_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Recap Ask loads about 3k tokens when it runs, and up to ~4.8k if it reads all its reference files. Until then it costs about 110 tokens; SKILL.md has 1,135 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from sd0xdev/sd0x-harness at commit c9a2036, republished under its MIT licence (© sd0xdev). 1,135 words, ~2,954 tokens.
.claude/skills/recap-ask/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub./recap-ask — Recap-Bounded Q&A| Scenario | Alternative |
|---|---|
| Generate a new recap doc from scope | /recap-doc |
| Full flow (detect + doc + Q&A) | /post-dev-recap wrapper |
| General project Q&A, no recap in hand | /ask |
| Deep multi-source investigation | /deep-research |
| Systematic code tracing across modules | /code-explore |
| First-principles reasoning about a doc | /fp-brief |
/recap-ask <question> --context <recap-doc-path> [--continue <threadId>] [--lazy-fetch]| Flag | Default | Description |
|---|---|---|
<question> | required | Free-text user question |
--context | required | Absolute or repo-relative path to a briefing-recap-<YYYY-MM-DD>.md file |
--continue | null | Reuse an existing Codex threadId for follow-up turns |
--lazy-fetch | true | Allow Read on files listed in the recap §7 Evidence during synthesis. When false, Codex answers from recap text only (no code-verification reads); citations still reference <path>:<line> from §7 but are not re-opened |
sequenceDiagram
participant U as Caller (user or /post-dev-recap)
participant A as /recap-ask
participant R as Recap doc
participant C as Codex
participant SR as scripts/security-redact.js
participant CR as /create-request
U->>A: /recap-ask "<q>" --context <path>
A->>A: Phase 1: Validate path + load recap as primary context
A->>A: Phase 2: Intent classification → {recap-scoped, out-of-scope, ambiguous}
alt recap-scoped
A->>R: Lazy-fetch file:line refs (bounded by recap Evidence)
A->>C: Codex synthesis with recap as primary
else out-of-scope
A->>A: Emit "此問題超出本輪 recap 範圍" + /ask example
else ambiguous
A->>U: AskUserQuestion to clarify intent
end
A->>SR: Phase 3: Redact response
SR-->>A: Redacted text (abort on high-confidence secret)
A->>U: Emit answer with file:line citations
opt End of session
A->>U: Prompt: "Promote this Q&A to a request ticket?"
U-->>A: Yes
A->>CR: /create-request --update <existing> (append Q&A digest)
endValidate --context path: resolve relative paths against repo root (git rev-parse --show-toplevel).
Enforce path boundary (NFR-8) on --context: resolved real path must satisfy startsWith(repo_root + "/") or live under <tmp> (same allowlist as /recap-doc Path Security — users who moved the recap out of sd0x-dev-flow-recap/ must still land within tmp). Reject .. segments and external symlinks (use fs.realpathSync on the first existing ancestor).
Read the recap file in full; this is the primary context. Extract the §7 Evidence file-index as the lazy-fetch allowlist.
Validate every Evidence entry before adding to the allowlist: apply the same boundary check to each <path>:<line> in §7 — the canonical (realpath-resolved) target must satisfy startsWith(repo_root + "/") or lie inside <tmp> (i.e. repo-or-<tmp>, identical to step 2), with .. segments and external symlinks rejected. Entries that fail validation are silently dropped from the allowlist (a recap cannot smuggle out-of-repo paths into Phase 3 reads).
4b. scan_error gate: read the recap's > **Corpus scan**: metadata line (written by
/recap-doc from feature_context.scan_error). Only the exact value complete proceeds.
Every other reading takes the ⚠️ Need Human exit, and each one takes it on its own account:
| Marker | Reading | Consequence |
|---|---|---|
complete | the recap records scan_error === false | proceed to Phase 2 |
unknown | the recap records scan_error !== false — the source sets behind it are unknown, not empty | say so, ⚠️ Need Human exit |
| absent | the recap predates the field, so nothing was recorded either way | say so, ⚠️ Need Human exit |
| anything else | an unrecognised producer wrote it; the value means nothing here | say so, ⚠️ Need Human exit |
The absent row is the one that reads as pedantic and is not. Silence is the default state of
every recap written before the marker existed, so "warn and answer anyway" is not a lenient
reading of one edge case — it is the fail-open path for the whole back catalogue, and it is
precisely the misreading the marker was added one document upstream to close. An answer built on
an evidence index whose corpus completeness is unknown is the failure, whether the recap said
unknown or said nothing.
Gate on !== false, not === true, and on === 'complete' rather than "not unknown":
a payload from a shell fallback or an older producer carries no such field at all, and
a non-null key is not evidence the sets are complete — scan_error rides alongside a
resolved key.
If the recap is older than 7 days, warn the user — recaps are ephemeral by default and the source code may have drifted. The 7-day threshold is a heuristic; callers may override in future versions.
Classify the question into one of three classes before synthesis. See references/qa-prompt.md for full prompt + decision rules.
| Class | Signal | Action |
|---|---|---|
recap-scoped | Question refers to files / decisions / terms that appear in the recap | Proceed to synthesis. Lazy-fetch referenced files via the §7 allowlist only. |
out-of-scope | Question clearly targets code or docs not covered by the recap | Emit the fixed redirect block (see below) — no Codex synthesis. |
ambiguous | Partial overlap, unclear whether recap covers it | Trigger AskUserQuestion with 2-3 framed options to disambiguate. |
Out-of-scope redirect block (verbatim template — keep concise):
此問題超出本輪 recap 範圍。建議改用
/ask "<原始問題>",它會從整個專案重新收集上下文。
Follow-up turns on the same thread (--continue <threadId>) re-run classification per new question — the prior turn's class does not carry over. The Codex reply-turn prompt in references/qa-prompt.md enforces this.
Bind every placeholder before writing prompt.md — the template is body-only and evaluates
nothing. ${FEATURE_KEY} becomes session when the recap resolved no feature key.
recap-scoped: dispatch to Codex per @skills/codex-code-review/references/codex-transport.md § Start (first turn) or its § Resume (subsequent turns). Prompt must follow @rules/codex-invocation.md — independently research, no leading conclusions. See references/qa-prompt.md.scripts/security-redact.js → redact(text). On AbortError (high-confidence secret) emit the fingerprint and refuse to respond.file:line citations. Every claim about code must cite a recap-evidenced location.When the user signals session end (e.g. /recap-ask --end or an explicit "結束" / "done"):
AskUserQuestion: "Promote this Q&A thread to the existing request ticket so the context survives for future sessions?"Yes: resolve the parent request doc from the recap's feature_context.docs_path. Invoke /create-request --update <request-path> with a Q&A digest appended under a new ## Follow-up Q&A (<date>) heading.No: emit the thread id so the user can resume later via --continue.Target: NFR-3 — Q&A first-token p95 ≤ 10s (excluding external LLM network latency, measured from question receipt to first emitted token). Phase 1 context load should be cached across turns within the same thread.
| Rule | Implementation |
|---|---|
| Context path boundary | fs.realpathSync on first existing ancestor; reject if the resolved ancestor is neither inside the repo root (git rev-parse --show-toplevel) nor inside <tmp> (same allowlist as /recap-doc) |
| Lazy-fetch allowlist | Only files appearing in the recap's §7 Evidence index; no arbitrary Read during synthesis |
| Symlink guard | Reject any ancestor whose real path escapes both roots |
| Secret redaction (NFR-7) | Every outbound response run through scripts/security-redact.js — abort on high, mask on medium |
| Input trust | Treat --context as untrusted; no shell interpolation |
Each Q&A turn emits:
### Q: <user question>
**Intent**: recap-scoped | out-of-scope | ambiguous
**Answer**:
<synthesized text with inline `file:line` citations>
**Sources**:
- `<path>:<line>` — <what this ref demonstrates>
- ...
**Thread**: <codex threadId> <!-- enables --continue -->On session end, append:
### Promote?
Promote this Q&A thread to `<parent-request-path>` so the context survives future sessions? (y/N)--context path validated against repo-or-tmp allowlist before any read (NFR-8)recap-scoped / out-of-scope / ambiguoussecurity-redact.js run on every outbound response (NFR-7)@rules/codex-invocation.md (independent research mandate)/create-request --update call on Yes (AS-11)references/qa-prompt.md — Codex prompt + intent classification rules (obeys @rules/codex-invocation.md)@skills/ask/SKILL.md L76-92 — Phase 2 context-gathering pattern (upstream reuse anchor, NFR-5)@skills/recap-doc/SKILL.md — Upstream producer of recap doc (Evidence §7 defines the lazy-fetch allowlist)scripts/security-redact.js — Pre-emit secret redaction (T1)scripts/detect-scope.js — ScopeReport v1 (consumed indirectly via the recap's feature_context)@rules/codex-invocation.md — Codex must independently research; no leading conclusions@rules/auto-loop.md — Fix → re-review → pass loopInput: /recap-ask "Why did we gate the watcher on --interval?" --context /tmp/sd0x-dev-flow-recap/briefing-recap-2026-04-17.md
Action: Load recap → classify recap-scoped → Codex reply citing recap §3 Design Decisions entries → redact → emit answer with file:line refs
Input: /recap-ask "How does the router module work?" --context docs/features/post-dev-recap/briefing-recap-2026-04-17.md
Action: Load recap → router not in §2/§7 → classify out-of-scope → emit redirect block pointing to /ask — no Codex call
Input: /recap-ask "Does this affect auth?" --context ...
Action: Load recap → ambiguous (auth mentioned in §5 Blind Spots but not explained) → AskUserQuestion: "Which auth path — the scope-file write permission, or the downstream Codex auth?"© sd0xdev, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file (references) in skills/recap-ask of sd0xdev/sd0x-harness.
Open the folder on GitHubat commit c9a2036
Recap Ask next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Recap Ask this skillsd0xdev/sd0x-harness | 192 | — | ~3k | Automated safety check: Pass | MIT | |
| Domain Modelingfossasia/eventyay-interpretation | 1.6k | 29 repos | ~821 | Automated safety check: Pass | Apache-2.0 | |
| Architecture Governancezai-org/ZCode | 7.5k | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| Evolutionary Modular Architecturetech-leads-club/agent-skills | 7k | — | ~3.7k | Automated safety check: Pass | CC-BY-4.0 | |
| Domain Modelingbrim-borium/spotify_sdk | 166 | 5 repos | ~806 | Automated safety check: Pass | Apache-2.0 | |
| Domain Modeling and Glossarywindmill-labs/windmill | 18k | — | ~622 | Automated safety check: Pass | Custom licence |
fossasia/eventyay-interpretation
Build and sharpen a project's domain model. An agent skill from fossasia/eventyay-interpretation.
zai-org/ZCode
Apply the repository's architecture policy to code changes by generating a bounded context package, checking module and layer boundaries, and reporting baseline-aware violations.
tech-leads-club/agent-skills
Guides design of modular-monolith platforms with DDD, flat-by-aggregate modules, anti-corruption layers, outbox events and resilience, plus an architecture document with SVG diagrams.
brim-borium/spotify_sdk
Build and sharpen a project's domain model. An agent skill from brim-borium/spotify_sdk.
windmill-labs/windmill
Actively challenges vague or conflicting terminology as you design, and keeps a living domain glossary file up to date in real time.
swamp-club/swamp
Domain Driven Design guidance for TypeScript/Deno codebases.
sd0xdev/sd0x-harness
Write an Architecture Decision Record (ADR) for a feature — Context / Decision / Status / Consequences / Alternatives, filed as docs/features/<feature/adr-<NNN-<title.md with a 3-digit zero-padded…
sd0xdev/sd0x-harness
Load GitHub PR review comments into AI session — analyze, triage, plan.
sd0xdev/sd0x-harness
Change-aware next step advisor. An agent skill from sd0xdev/sd0x-harness.
sd0xdev/sd0x-harness
Obsidian vault integration via official CLI. An agent skill from sd0xdev/sd0x-harness.
sd0xdev/sd0x-harness
Agent-driven workflow orchestration (v1 report-only). An agent skill from sd0xdev/sd0x-harness.
sd0xdev/sd0x-harness
Post friendly review comments to a GitHub PR — prepare locally, preview, then submit as atomic review.
Categories
Interactive Q&A over an existing recap document. An agent skill from sd0xdev/sd0x-harness. Recap Ask is an agent skill from sd0xdev/sd0x-harness. Interactive Q&A over an existing recap document.
Recap Ask fits situations like: : user wants to ask follow-up questions about a briefing-recap-<date.md produced by /recap-doc; with recap-bounded context + out-of-scope redirect + optional promote-to-request.
Run `npx skills add sd0xdev/sd0x-harness --skill recap-ask -a claude-code`. Or copy the skill folder (skills/recap-ask in sd0xdev/sd0x-harness) into .claude/skills/recap-ask in your project. Claude Code loads it when a task matches its description.
Run `npx skills add sd0xdev/sd0x-harness --skill recap-ask -a codex`. Or copy the skill folder (skills/recap-ask in sd0xdev/sd0x-harness) into .agents/skills/recap-ask in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add sd0xdev/sd0x-harness --skill recap-ask -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/recap-ask, .gemini/skills/recap-ask, .github/skills/recap-ask and .opencode/skills/recap-ask in your project.
Going by SKILL.md and its folder, Recap Ask needs the command-line tools its instructions call (git) and credentials named FEATURE_KEY. Our summary lists: A credential in FEATURE_KEY. Its frontmatter pre-approves these tools: Read, Grep, Glob, Bash(git:*), Bash(node:*), Skill, AskUserQuestion, Write.
SKILL.md contains no URLs. Its commands use git, which can reach the network depending on how they are called. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Recap Ask is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.8k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Recap Ask: Domain Modeling (fossasia/eventyay-interpretation, 1.6k stars), Architecture Governance (zai-org/ZCode, 7.5k stars), Evolutionary Modular Architecture (tech-leads-club/agent-skills, 7k stars) and Domain Modeling (brim-borium/spotify_sdk, 166 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
sd0xdev (a GitHub user) maintains it in sd0xdev/sd0x-harness, which has 192 GitHub stars. The repository holds 91 skills in this directory. The repository was last updated on October 6, 2026.
Source: sd0xdev/sd0x-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.