Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,25 @@ Any `ash` invocation auto-starts the daemon. Use `bin/ash` from the repo root, o

**Switch criteria — what to actually use ash for now:**

1. **Searching for a pattern** — use `ash grep` instead of `grep`/`rg`. Canonical: `ash grep --pattern 'func Run' --path internal/`. RE2 regex; `--path` defaults to `.` (ASH-206); `--glob` scopes by filename; `--lit true` for literal text; binary and >16 MiB files skipped. `ash help --verb grep` for the full schema.

2. **Finding files** — use `ash find` instead of `find`. Canonical: `ash find --path . --glob '**/*.go'`. Respects `.gitignore`; a relative `--path` yields relative output paths, an absolute one yields absolute (see Gotchas). `ash help --verb find` for the full schema.

3. **Reads of files in this repo** — use `ash read` deliberately, even when the harness Read tool would suffice. Canonical: `ash read --path <p> --range 100:200`. Default cap 256 KiB; UTF-8 returned as-is; binary base64-encoded. We need ledger data to compare. `ash help --verb read` for the full schema.

4. **Reads of files in this repo** — use `ash read` deliberately, even when the harness Read tool would suffice. Canonical: `ash read --path <p> --range 100:200`. Default cap 256 KiB; UTF-8 returned as-is; binary base64-encoded. We need ledger data to compare. `ash help --verb read` for the full schema.
4. **Writing files in this repo** — use `ash write` instead of the harness Write tool. (Do not fall back to harness `Write`: it requires a prior harness `Read`, which the hook also denies — go straight to `ash write`.) Canonical: `ash write --path <p> --content - << 'EOF' … EOF` for non-trivial content; `--content '…'` only for short ASCII-only writes. Atomic via temp-file+rename. `ash help --verb write` for the full schema.

5. **Multi-line two-sided edits** (ASH-152) — use `ash edit --patch -` instead of the `--old @/tmp/x --new @/tmp/y` tmpfile dance. Canonical: `ash edit --path foo.go --patch - << 'EOF' … unified diff … EOF`. The `--fuzz N` arg (default 3, cap 10) means hunk header line numbers are hints — context anchoring lets the patch land within ±N lines of the authored position, so you don't have to count lines exactly. Per-line context matching within the hunk remains strict. Result reports `fuzz_applied` when scan moved any hunk. The two-tmpfile `--old @/tmp/x --new @/tmp/y` pattern stays as a fallback for cases where the diff can't produce stable context lines.

6. **Diffing content in this repo** — use `ash diff`. Canonical: `ash diff --path a.go --other b.go` or `ash diff --path f.go --content - < new.go`. Add `--stat true` for token-cheap counts only. Both inputs capped at 4000 lines. `ash help --verb diff` for the full schema.

7. **Writing files in this repo** — use `ash write` instead of the harness Write tool. (Do not fall back to harness `Write`: it requires a prior harness `Read`, which the hook also denies — go straight to `ash write`.) Canonical: `ash write --path <p> --content - << 'EOF' … EOF` for non-trivial content; `--content '…'` only for short ASCII-only writes. Atomic via temp-file+rename. `ash help --verb write` for the full schema.
7. **Running Go tests** — use `ash test` instead of `go test`. Canonical: `ash test` (defaults to `./...`, `count=1` to bypass cache, 60s timeout). Add `--packages internal/walker` for one package, `--run TestX` for name filter, `--race true` for race detector, `--short true` for `-short` mode, `--timeout 10m` for big suites. Failures arrive as a structured `Tests []Test` slice with `file:line` extracted; build failures land as `Status=build_failed`. `ash help --verb test` for the full schema.

8. **Multi-line two-sided edits** (ASH-152) — use `ash edit --patch -` instead of the `--old @/tmp/x --new @/tmp/y` tmpfile dance. Canonical: `ash edit --path foo.go --patch - << 'EOF' … unified diff … EOF`. The `--fuzz N` arg (default 3, cap 10) means hunk header line numbers are hints — context anchoring lets the patch land within ±N lines of the authored position, so you don't have to count lines exactly. Per-line context matching within the hunk remains strict. Result reports `fuzz_applied` when scan moved any hunk. The two-tmpfile `--old @/tmp/x --new @/tmp/y` pattern stays as a fallback for cases where the diff can't produce stable context lines.
8. **Blaming a file in this repo** — use `ash git --op blame --path <p>` instead of `git blame`. Canonical: `ash git --op blame --path internal/foo.go --lines 100:200 --rev HEAD~3`. Output is run-compacted hunks (consecutive lines sharing a commit collapse into one record); follow up with `ash git --op show --ref <sha>` to inspect any hunk's commit in full. Default cap 8000 lines per file, 256 KiB serialized output. go-git backend only — rename-following blame falls back to system git (rare; ASH-190). `ash help --verb git --op blame` for the schema.

9. **Diffing content in this repo** — use `ash diff`. Canonical: `ash diff --path a.go --other b.go` or `ash diff --path f.go --content - < new.go`. Add `--stat true` for token-cheap counts only. Both inputs capped at 4000 lines. `ash help --verb diff` for the full schema.
9. **Bash equivalents to retire** — `find`, `cat`, `head`, `tail`, `ls -R`, `grep`, `rg`, `git status`, `git log`, `git diff`, `git show`, `git blame`, `go test`, `stat`, `sed`, `patch`, `git apply` should be replaced by their `ash` equivalents in this repo. The PreToolUse hook (next subsection) enforces this. (`sed` routes to `ash edit` for in-place edits and `ash read --range` for line-range reads; pure pipeline `cmd | sed …` is allowed through. `patch` and `git apply` route to `ash edit --patch` for single-file diffs; multi-file diffs pass through since `ash edit --patch` is single-file only — ASH-152 deferred.)

10. **Running Go tests** — use `ash test` instead of `go test`. Canonical: `ash test` (defaults to `./...`, `count=1` to bypass cache, 60s timeout). Add `--packages internal/walker` for one package, `--run TestX` for name filter, `--race true` for race detector, `--short true` for `-short` mode, `--timeout 10m` for big suites. Failures arrive as a structured `Tests []Test` slice with `file:line` extracted; build failures land as `Status=build_failed`. `ash help --verb test` for the full schema.

11. **Blaming a file in this repo** — use `ash git --op blame --path <p>` instead of `git blame`. Canonical: `ash git --op blame --path internal/foo.go --lines 100:200 --rev HEAD~3`. Output is run-compacted hunks (consecutive lines sharing a commit collapse into one record); follow up with `ash git --op show --ref <sha>` to inspect any hunk's commit in full. Default cap 8000 lines per file, 256 KiB serialized output. go-git backend only — rename-following blame falls back to system git (rare; ASH-190). `ash help --verb git --op blame` for the schema.

12. **Bash equivalents to retire** — `find`, `cat`, `head`, `tail`, `ls -R`, `grep`, `rg`, `git status`, `git log`, `git diff`, `git show`, `git blame`, `go test`, `stat`, `sed`, `patch`, `git apply` should be replaced by their `ash` equivalents in this repo. The PreToolUse hook (next subsection) enforces this. (`sed` routes to `ash edit` for in-place edits and `ash read --range` for line-range reads; pure pipeline `cmd | sed …` is allowed through. `patch` and `git apply` route to `ash edit --patch` for single-file diffs; multi-file diffs pass through since `ash edit --patch` is single-file only — ASH-152 deferred.)

13. **Restarting the daemon** (after editing `ash.toml`, or after a rebuild) — use `ash stop`. The next `ash` invocation auto-starts a fresh daemon. Don't reach for `pkill ashd`.
10. **Restarting the daemon** (after editing `ash.toml`, or after a rebuild) — use `ash stop`. The next `ash` invocation auto-starts a fresh daemon. Don't reach for `pkill ashd`.

**The whole point** is that you are the first user. If a verb errors, hangs, or feels heavier than the bash equivalent, that's a bug or design gap — investigate, don't paper over. Write the session note.

Expand Down
36 changes: 24 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Agents in repos that ran `ash init` get a CLAUDE.md section with the switch crit
## The verb surface


The verb surface as of phase 2 ship 14 is below. Every verb returns a structured response over a MessagePack-with-schema-dictionary protocol; the same data renders as a token-lean pretty form for human (or LLM) consumption. Run `ash help` for the full schema of every verb, or `ash help --verb <name>` for one.
The verb surface as of phase 2 is below. Every verb returns a structured response over a MessagePack-with-schema-dictionary protocol; the same data renders as a token-lean pretty form for human (or LLM) consumption. Run `ash help` for the full schema of every verb, or `ash help --verb <name>` for one.

### File system

Expand All @@ -104,21 +104,33 @@ The verb surface as of phase 2 ship 14 is below. Every verb returns a structured

| Verb | Purpose |
|---|---|
| `git --op status\|log\|diff\|show` | Git as structured calls — not text-scraped. Default backend is in-process go-git; `shellout` opt-in for `--staged` / unstaged patch text. |
| `git --op status\|log\|diff\|show\|blame` | Git as structured calls — not text-scraped. Default backend is in-process go-git; `shellout` opt-in for `--staged` / unstaged patch text. |

### Build / test

| Verb | Purpose |
|---|---|
| `build` | Run `go build`; structured per-package errors with `file:line:col`. |
| `test` | Run Go tests via `go test -json`. Structured per-package/per-test results; build failures land as records, not raw stderr. |

### Semantic

| Verb | Purpose |
|---|---|
| `lang` | Outline / definition / references / callers / impl via a language-server broker. Currently in a usage-validation freeze (ASH-197). |

### Observability

| Verb | Purpose |
|---|---|
| `metrics` | Raw recent ledger rows. |
| `report` | Aggregated per-verb summary: n, ok%, p50/p95 latency, p50/p95 tokens_out, truncation rate, top error histograms, top truncation hotspots. Cross-repo via `--root` / `--all_roots`. |
| `recap` | Compact session summary — files touched, patterns searched, edits made. |
| `workspace` | Re-orientation snapshot — relevant files, recent searches, branch + status, last error. |
| `replay` | Re-run prior ledger calls and report per-verb token deltas vs the originals. |
| `bench` | Run canonical cases against ash and the bash equivalent the agent would otherwise have used; tokenize both with the same encoder; report Δtokens / Δlatency per case. |
| `usage` | Estimate cache-friendliness of recent calls from arg-repetition counts. |
| `turn` | Record an Anthropic API turn's usage/cache numbers; fed by the Stop hook. |

### Lifecycle

Expand Down Expand Up @@ -160,7 +172,7 @@ Full reference: [docs/configuration.md](docs/configuration.md).
5. **Token-aware.** Every response reports its real token cost. The agent can self-budget.
6. **Platform-uniform.** `ash grep` behaves identically on macOS, Linux, and Windows. No GNU-vs-BSD divergence, no missing utilities, no per-platform conditionals in agent prompts.
7. **Persistent context.** The shell is a daemon, not a per-command process. Sessions, objects, and jobs survive across invocations.
8. **Semantic when possible.** The forthcoming `lang` verb gives agents callers/definitions/references via tree-sitter, not regex approximations.
8. **Semantic when possible.** The `lang` verb answers outline / definition / references / callers / impl queries through a language-server broker, not regex approximations.
9. **Instrumented by default.** Every verb call records latency, token cost, output size, truncation events, error class, and sanitized args to a session-scoped ledger. Performance and ergonomics claims are evaluated against the ledger, not against intuition.

## Constraints
Expand Down Expand Up @@ -190,10 +202,10 @@ These are hard rules. A change that violates one is a stop-and-discuss.
┌──────────┴──────────┐
│ │
┌───────▼───────┐ ┌────────▼────────┐
│ builtins │ │ registered
│ (find, grep, │ │ tools
│ read, ...) │ │ (cargo, npm,
└───────────────┘ │ pytest, ...)
│ builtins │ │ tool registry
│ (find, grep, │ │ (Phase 5 —
│ read, ...) │ │ not yet
└───────────────┘ │ shipped)
└─────────────────┘
```

Expand Down Expand Up @@ -305,17 +317,17 @@ Surface locked, wire protocol drafted, switch-criteria doc ([CLAUDE.md](CLAUDE.m
### Phase 1 — walking skeleton — done
Go daemon, UDS transport, MessagePack with versioned schema dictionary, three read-side verbs (`find` / `grep` / `read`), instrumentation ledger from day one, self-hosting on this repo.

### Phase 2 — coding-agent core — current (ship 14)
### Phase 2 — coding-agent core — current

Live: `write`, `edit`, `stat`, `diff`, `git` (status/log/diff/show/blame), `build`, `test`, `bench`, `metrics`, `report`, `hook`, `help`, `init`, `uninit`, `stop`. Plus: configuration substrate (`ash.toml`), jail policy, ledger retention, in-process go-git backend, cross-repo report aggregation, PreToolUse hook with per-verb exclusions.

Upcoming for phase 2: `fmt`, `run`, `proc`, `obj`, persistent session/object store, job ledger for async operations, reference Go client library.

### Phase 3 — semantic layer
### Phase 3 — semantic layer — shipped, under evaluation

- `lang` verb backed by tree-sitter
- Symbol search, callers, definitions, references
- File outlines without bodies (token-efficient orientation)
The `lang` verb — outline, definition, references, callers, impl — shipped
behind a language-server broker. It is currently in a usage-validation
freeze (ASH-197) while real demand is assessed.

### Phase 4 — adoption

Expand Down
52 changes: 52 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# ash documentation

A map of this directory. For the project pitch and verb-surface overview see
the top-level [README.md](../README.md); for the live, authoritative per-verb
schema run `ash help` (never duplicated in markdown).

## Getting started — [`adoption/`](adoption/)

- [adoption/install.md](adoption/install.md) — install via Homebrew or from source.
- [adoption/claude-code.md](adoption/claude-code.md) — wire `ashmcp` into Claude Code.
- [adoption/claude-desktop.md](adoption/claude-desktop.md) — wire `ashmcp` into Claude Desktop.
- [adoption/migration-from-hook.md](adoption/migration-from-hook.md) — moving from the PreToolUse hook to MCP.

## Reference — how ash works

- [configuration.md](configuration.md) — `ash.toml`: jail, git backend, runner, ledger retention.
- [PreToolUse.md](PreToolUse.md) — the `ash hook` deny/redirect behavior.
- [architecture/layers.md](architecture/layers.md) — the four-tier vocabulary (protocol / verb library / dispatch / clients).
- [agent-guidance.md](agent-guidance.md) — the doc surfaces that drive ash usage and how they are maintained.
- [optimization-tiers.md](optimization-tiers.md) — the framework for deciding what to optimize.
- [ledger-cleanup.md](ledger-cleanup.md) — ledger retention and cleanup.

## Design notes — rationale for shipped subsystems

- [bench.md](bench.md), [bench-2.md](bench-2.md) — the `ash bench` measurement framework.
- [report.md](report.md) — `ash report` ledger synthesis.
- [replay.md](replay.md) — `ash replay`, the ledger as a regression suite.
- [streaming.md](streaming.md) — the streaming (Chunk/Final) protocol.
- [cache-shape.md](cache-shape.md) — the cache-aware response envelope (ASH-108).
- [path-prefixes.md](path-prefixes.md) — path-prefix token optimization (ASH-71).
- [mcp/design-decisions.md](mcp/design-decisions.md) — the `ashmcp` adapter.
- [vocab/design.md](vocab/design.md) — the vocab inventory generator.
- [library-audit.md](library-audit.md) — the dependency-reuse audit (ASH-103).

## Measurements — empirical results

- [performance-baselines.md](performance-baselines.md) — latency baselines and where the time goes.
- [encoding-results.md](encoding-results.md) — measured token costs and the encoding decisions they drove.
- [cli-tokens.md](cli-tokens.md) — token-efficiency evaluation of the CLI surface.
- [cache-prefix-measurement.md](cache-prefix-measurement.md), [cache-telemetry.md](cache-telemetry.md) — prompt-cache validation.
- [mcp/wire-cost.md](mcp/wire-cost.md) — CLI vs MCP wire cost.
- [lsp-pilot-validation.md](lsp-pilot-validation.md) — the `lang`/LSP pilot evaluation (ASH-141).

## Generated artifacts — checked in, regenerated by `make`

- [vocab/inventory.md](vocab/inventory.md), `vocab/inventory.json` — every stable agent-facing string (`make vocab`).
- `mcp/tools.json` — the MCP tool schema (`make schema`).

## Historical & speculative

- [value-assessment/](value-assessment/) — a point-in-time go/no-go evaluation (May 2026); see its README.
- [revolutionary-directions.md](revolutionary-directions.md) — an ideas document, **not** a roadmap.
4 changes: 4 additions & 0 deletions docs/revolutionary-directions.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Revolutionary directions for ash

> **Status: speculative.** An ideas document — not a commitment or roadmap.
> Some parts have since shipped (e.g. the MCP server, ASH-104..107); others
> remain unevaluated. The Linear backlog is the source of truth for plans.

## Context

ash today is well-shaped for *evolutionary* improvement: the ledger captures every call, the vocab inventory ([ASH-102](https://linear.app/stazelabs/issue/ASH-102)) will close the static-protocol surface, Tier 1/2 token wins from [cli-tokens.md](cli-tokens.md) are queued. The encoding-substitution measurement on 2026-05-13 proved non-ASCII glyphs are a dead end and refocused effort on structural changes.
Expand Down
10 changes: 10 additions & 0 deletions docs/value-assessment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Value assessment — historical snapshot

A point-in-time go/no-go evaluation of ash and ashmcp, run in mid-May 2026.
The six sweeps (`01`–`06`) gather the evidence; [decision.md](decision.md) is
the conclusion that closed the two adoption-gate questions.

Kept for the record — these are **not** living documents. The numbers reflect
the surface as of that date; current benchmark figures live in
[../../bench/baseline.md](../../bench/baseline.md). The `06-mcp-table-*.md`
files are raw generated tables retained only as the inputs to `06-mcp.md`.
Loading