The REACH DSL
A .reach file is a domain-specific language. The domain is intent — what to reach into, over what timeframe, with what analysis goal. The language doesn't know about COM Interop, NuGet packages, or SQL client libraries. Those are implementation. The DSL knows about sources, qualifiers, and outputs.
You write the vocabulary. Claude compiles the implementation.
Syntax Shape
reach <source>
<qualifier> <value>
<qualifier> <value>
<action> <value>
output <format>Multiple sources compose with +:
reach <source-a> + <source-b> + <source-c>
since <timeframe>
analyze <intent>
output <format>Everything lowercase. Indentation two spaces. Quoted strings for values with spaces.
Source Vocabulary
Outlook
reach outlook.inbox
where subject contains "[PROJECT]"
since start-of-year
group by month
output cadencereach outlook.calendar
since 10-weeks-ago
analyze density
group by week
output summaryreach outlook.sent
where subject contains "[PROJECT]"
since start-of-year
group by month
output cadencereach outlook.folder "Deleted Items"
count all
output summaryGit
reach git.commits
since 10-weeks-ago
analyze after-hours
benchmark 15%
output reportreach git.log
since start-of-month
format author + date + message
output tableScreen
reach screen
save as snapshot
reach screen.window "Chrome"
save as snapshot
reach screen.region 0 0 1920 1080
save as snapshotBrowser
reach browser.page "https://staging.internal/deployments"
wait for ".deployment-status"
extract text
output summaryreach browser.auth "https://internal-tool/login"
field "#username" "myuser"
field "#password" "mypass"
submit "button[type=submit]"
then browser.page "https://internal-tool/dashboard"
extract text
output summaryDatabase
reach db.query
env staging
sql "SELECT TOP 100 * FROM Equipment WHERE Status = 'Active'"
output jsonreach db.table Equipment
env staging
sample 20
output summaryFiles
reach file.read "attachments/report.docx"
extract text
output plainreach file.merge "attachments/*.txt"
separator "---"
output "merged_context.txt"reach file.watch "C:\reach\attachments"
on new signal "file-arrived"
output logUI Automation
reach ui.window "OUTLOOK"
find name "Inbox"
read items
output listHTTP
reach http.get "https://internal-api/deployment/status"
output jsonQualifier Vocabulary
| Qualifier | Applies to | Meaning |
|---|---|---|
where | outlook., db. | Filter condition |
since | outlook., git., calendar | Time range start |
until | outlook., git., calendar | Time range end |
group by | any | Group results by dimension |
analyze | any | Named analysis intent |
benchmark | git.commits, any metric | Target value for comparison |
wait for | browser.* | CSS selector to wait for |
extract | browser., file. | What to pull — text, table, links |
find | ui.* | Control to locate by name or type |
env | db.* | Named environment (dev/staging/prod) |
sample | db.* | Number of rows to sample |
save as | screen.* | Output filename |
on new | file.watch | Event trigger |
merge | file.* | Combine multiple file outputs |
count | any | Count items instead of listing them |
Output Vocabulary
| Output | What you get |
|---|---|
summary | Claude narrates what it found |
cadence | Frequency pattern over time — counts by period |
report | Structured findings with interpretation |
json | Raw JSON to stdout |
table | Formatted table |
list | Line-by-line items |
plain | Plain text extraction |
snapshot | Image file — Claude reads inline |
log | Append to run log |
signal | Write signal file for another reach |
Analyze Vocabulary
Named analysis intents Claude understands:
| Value | What Claude does |
|---|---|
cadence | Groups by time period, identifies patterns, gaps, spikes |
after-hours | Splits activity by time of day, calculates % outside core hours |
density | Measures concentration — meetings per week, emails per day |
rpm | Reads combined signal across sources, calls green/yellow/red/all-red |
velocity | Rate of output over time |
sentiment | Tone pattern across communications |
recovery | What it would take to normalize current state |
summary | Plain language synthesis |
Timeframe Vocabulary
| Value | Meaning |
|---|---|
today | Current day |
this-week | Monday to now |
last-week | Previous full week |
start-of-month | First day of current month |
start-of-year | January 1 |
10-weeks-ago | N weeks before today |
30-days-ago | N days before today |
"2026-01-01" | Explicit date |
Composition — The Most Powerful Operator
+ between sources is the most powerful operator in the language. Each source reaches independently; Claude holds all results in context and synthesizes across them.
reach outlook.inbox + outlook.calendar + git.commits
since 10-weeks-ago
analyze rpm
benchmark after-hours 15%
output reportThis is the sprint cadence review in one block. Claude reaches into all three sources, reads the combined signal, calls the RPM state, flags the after-hours against the benchmark, and delivers a narrative report.
The Pause Layer — Prompts and Gates
REACH has three modes. The pause layer is what separates reads from writes:
READ → runs freely, no prompt
ACT → low risk, may run freely
PAUSE → write gate — Windows UI surfaces, human approvesprompt.confirm
reach outlook.draft
to "team@company.com"
subject "Sprint Summary — {date}"
body from git.commits since today
then prompt.confirm
title "Send this email?"
on yes outlook.send
on no outlook.save-draftprompt.preview
reach outlook.draft
to "team@company.com"
subject "Daily Summary — {date}"
body from git.commits + outlook.inbox since today analyze summary
then prompt.preview
title "Email draft ready"
actions send | edit | save-draft | discard
on send outlook.send
on save-draft outlook.saveprompt.form
reach timesystem.timesheet
then prompt.form
title "Review timesheet entries"
fields
request-id text "Request ID"
start-time time "Start"
end-time time "End"
description textarea "Description"
on submit timesystem.post
on cancel outlook.save-draftThe prompt layer is the conscience of the automation. Reads run freely. Writes pause. no-prompt is an explicit override — never a default.
Named Reaches — Reusable Patterns
# sprint-review.reach
name sprint-cadence-review
description Read sprint health across email, calendar, and commits
reach outlook.inbox + outlook.calendar + git.commits
since 10-weeks-ago
analyze rpm
benchmark after-hours 15%
output reportRun it:
dotnet reach sprint-review.reachShare it. Fork it. Someone changes the project filter and runs it against their data. The pattern travels as a file.
The Compilation Model
You write → sprint-review.reach
Claude reads DSL → understands intent per source block
Claude generates → typed C# per source (NuGet chosen per block)
dotnet run → executes each reach
prompt surfaces → if write action — Windows UI appears, human decides
results flow back → Claude synthesizes across all sources
artifact written → sprint-review.reach-artifactYou never see the NuGet package names, the COM Interop calls, the Playwright instantiation, or the WinForms boilerplate. Just intent. Just results. Just the right pause at the right moment.
Design Principles
Reads like intent, not code — Anyone can read a .reach file and understand what it does. No training required.
Sources are the vocabulary, not the implementation — outlook.inbox is a concept. How Claude reaches it is Claude's decision, not yours.
Composition is first-class — + between sources is the most powerful operator. The sprint review, the timesheet draft, the deployment check — all compositions of simple sources.
Artifacts outlast sessions — Every meaningful reach produces a .reach-artifact. The finding is permanent even though the script is ephemeral.
Benchmarks make findings actionable — benchmark after-hours 15% turns a number into a verdict. Claude doesn't just report 30% — it calls it against the target.
Writes pause by default — The prompt layer is not optional. It is the design.