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
19 changes: 19 additions & 0 deletions .github/workflows/install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Installer controls
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
installer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Validate standalone entrypoint and refusal controls
run: |
sh -n install.sh
python3 scripts/test-install-release.py
112 changes: 18 additions & 94 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,22 @@ fewer repeated tool-call failures. It stores calls locally, ranks recurring
failures, and records mappings from mistaken tool names to real ones.**
The name comes from the trails people wear through grass: evidence of where a path is needed.

## Why you would want it

- Find repeated failures across sessions instead of reading each transcript.
- Compare mistaken tool names with known tools and record the intended mapping.
- Use the failure history to improve instructions, tool names, or integrations.

Read [how the workflow fits together](https://scbrown.github.io/desire-path/introduction.html).

## Install

**Debian and Ubuntu (amd64 and arm64):** install from the signed apt repository, which
republishes each checksum-verified release. The package puts `dp` in
`/usr/bin`. Check the signing key's fingerprint before trusting it; the
commands stop if it does not match:

```bash
curl -fsSL https://scbrown.github.io/apt/key.gpg -o scbrown-stack.gpg \
&& gpg --show-keys --with-colons scbrown-stack.gpg \
| grep -qx 'fpr:::::::::AB5625C5612F643BF76464DF0DC99924994EC959:' \
&& sudo install -D -m 0644 scbrown-stack.gpg /etc/apt/keyrings/scbrown-stack.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/scbrown-stack.gpg] https://scbrown.github.io/apt stable main" \
| sudo tee /etc/apt/sources.list.d/scbrown-stack.list \
&& sudo apt update && sudo apt install desire-path
```sh
curl -fsSL https://raw.githubusercontent.com/scbrown/desire-path/main/install.sh | sh
```

`apt upgrade` then picks up new releases. unattended-upgrades only installs
from origins it allows, so to have it upgrade desire-path too, add
`"origin=scbrown,codename=stable";` to `Unattended-Upgrade::Origins-Pattern`.
Channels, pinning and rollback:
[scbrown/apt](https://github.com/scbrown/apt#channels-and-pinning).
Python 3.9+, curl, and a Linux or macOS shell. Downloads the latest published archive, verifies SHA-256 and the executable
version before publishing command links in `~/.local/bin`. Add it to `PATH`.
The complete versioned bundle stays in `~/.local/lib/desire-path/TAG` for rollback.
Published targets: Linux and macOS, x86_64 and arm64.

Linux x86-64, pinned release with checksum verification:
Set `STACK_INSTALL_ROOT` on the receiving shell for another prefix.
Pinned releases, alternatives, configuration and removal are in the
[installation and usage reference](docs/installation-reference.md).

```bash
mkdir -p /tmp/dp-install && cd /tmp/dp-install
curl -fLO https://github.com/scbrown/desire-path/releases/download/v0.7.0/desire-path_0.7.0_linux_amd64.tar.gz
curl -fLO https://github.com/scbrown/desire-path/releases/download/v0.7.0/checksums.txt
sha256sum --check --ignore-missing checksums.txt
tar -xzf desire-path_0.7.0_linux_amd64.tar.gz dp
mkdir -p "$HOME/.local/bin" && install -m 755 dp "$HOME/.local/bin/dp"
export PATH="$HOME/.local/bin:$PATH"
dp version
```

Expected: `dp 0.7.0 (5ca33ba)`. If you see something else, check `command -v dp`.

From source (Go 1.24+): `go install github.com/scbrown/desire-path/cmd/dp@v0.7.0`,
then add `$(go env GOPATH)/bin` to PATH and run `dp version`.
See [installation](https://scbrown.github.io/desire-path/getting-started.html) for macOS, Windows, and source-checkout builds.

## First success in three commands
## Try it

Use a temporary database and one synthetic failed call; Python 3 formats the result:

Expand All @@ -87,56 +52,15 @@ read_file 1
The failure became a queryable pattern without configuring an agent or touching your usual database.
An optional-metrics diagnostic may also appear on stderr; see [troubleshooting](https://scbrown.github.io/desire-path/getting-started.html#troubleshooting).

## On your own data

After your agent has recorded calls:

| question | command |
|---|---|
| Which failures repeat? | `dp paths --top 5` |
| What happened for this tool? | `dp inspect read_file` |
| What tool might have been intended? | `dp similar read_file` |
| How do I record the intended mapping? | `dp alias read_file Read` |
| How do I export the failures? | `dp export --format json` |

An alias records a mapping. Active interception is a separate [pave setup](https://scbrown.github.io/desire-path/commands/pave.html).
See the [CLI reference](https://scbrown.github.io/desire-path/commands/) for flags and all commands.

## Wire it into your agent

For Claude Code, with `dp` on the agent's PATH:

```bash
dp init --source claude-code
dp sources
```

The installer merges hooks into `~/.claude/settings.json`. It installs ingestion
for successes and failures, plus signposting and correction hooks. Review that
file after installation. [Using agents](https://scbrown.github.io/desire-path/integrations/)
explains the installed hooks and the Codex, Cursor, and Kiro source plugins.

## Before you start

| requirement | support |
|---|---|
| Release archives | Linux, macOS, Windows; amd64 and arm64 |
| Source build | Go 1.24+; no CGo required |
| README demo | Bash-compatible shell and Python 3 |
| Local storage | SQLite at `~/.dp/desires.db`; override with `--db` |
| Hook capture | A supported agent and `dp` on its PATH |

Keep tool inputs and error messages in mind when sharing [exports](https://scbrown.github.io/desire-path/commands/export.html).

## What's next
## Next steps

- [Read the book](https://scbrown.github.io/desire-path/introduction.html)
- [Find every design and reference document](https://scbrown.github.io/desire-path/docs-map.html)
- [Configure capture for your agent](https://scbrown.github.io/desire-path/integrations/)
- [Tambo](https://github.com/scbrown/tambo): guided stack installation and verification.
- [Camayoc](https://github.com/scbrown/camayoc): governed memory and vocabulary.
- [Detailed examples and agent setup](docs/installation-reference.md).

## 🧺 The stack
**Load this repository’s graph:** public repository-pendant assets have not yet been verified. When a release supplies the archive, checksum and provenance, follow the [verified import workflow](https://scbrown.github.io/quipu/sharing/index.html): extract the share directory and use `quipu import SHARE_DIR --db repository.db`. Import stages knowledge; ROOT stays unchanged.

Caboodle installs these together and proves each one works; every tool also stands alone.
## The stack

<!-- stack-table:start -->

Expand All @@ -152,8 +76,8 @@ when.
| [camayoc](https://github.com/scbrown/camayoc) | prepares knowledge and vocabulary for Quipu, with checks before it is admitted |
| [quechua](https://github.com/scbrown/quechua) | shared vocabulary and shapes for interoperable knowledge |
| [chaski](https://github.com/scbrown/chaski) | reacts to graph changes and delivers governed notifications |
| [bobbin](https://github.com/scbrown/bobbin) | indexes your codebase and injects context from that index and Quipu knowledge |
| [yupana](https://github.com/scbrown/yupana) | shows code impact and can read policies from Quipu to govern agent actions |
| [bobbin](https://github.com/scbrown/bobbin) | searches your code and can include related knowledge from Quipu |
| [yupana](https://github.com/scbrown/yupana) | shows code impact and can read policies from Quipu to check changes |
| [desire-path](https://github.com/scbrown/desire-path) | turns agent mistakes into feature requests; works on its own without Quipu |
| [seeds](https://github.com/scbrown/seeds) | a work item tracker backed by the Quipu knowledge base |
| [shantytown](https://github.com/scbrown/shantytown) | runs crews of AI agents on work items, triggered by hand, on a schedule or by events; can share work and memory through Quipu |
Expand Down
174 changes: 174 additions & 0 deletions docs/installation-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<p align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/banner-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="docs/assets/banner-light.svg">
<img alt="Desire Path" src="https://raw.githubusercontent.com/scbrown/desire-path/main/docs/assets/banner-dark.svg" width="660">
</picture>
</p>
<h1 align="center">Desire Path</h1>
<p align="center"><em>👣 Find the tool calls your agents get wrong, and turn repeats into fixes.</em></p>
<p align="center">
<a href="https://github.com/scbrown/desire-path/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
<a href="https://github.com/scbrown/desire-path/actions/workflows/ci.yml"><img src="https://github.com/scbrown/desire-path/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<a href="https://github.com/scbrown/caboodle"><img src="https://img.shields.io/badge/stack-quipu-8B5E3C.svg" alt="Quipu stack"></a>
</p>

**Desire Path (`dp`) is a CLI and a set of agent hooks for developers who want
fewer repeated tool-call failures. It stores calls locally, ranks recurring
failures, and records mappings from mistaken tool names to real ones.**
The name comes from the trails people wear through grass: evidence of where a path is needed.

## Why you would want it

- Find repeated failures across sessions instead of reading each transcript.
- Compare mistaken tool names with known tools and record the intended mapping.
- Use the failure history to improve instructions, tool names, or integrations.

Read [how the workflow fits together](https://scbrown.github.io/desire-path/introduction.html).

## Install

**Debian and Ubuntu (amd64 and arm64):** install from the signed apt repository, which
republishes each checksum-verified release. The package puts `dp` in
`/usr/bin`. Check the signing key's fingerprint before trusting it; the
commands stop if it does not match:

```bash
curl -fsSL https://scbrown.github.io/apt/key.gpg -o scbrown-stack.gpg \
&& gpg --show-keys --with-colons scbrown-stack.gpg \
| grep -qx 'fpr:::::::::AB5625C5612F643BF76464DF0DC99924994EC959:' \
&& sudo install -D -m 0644 scbrown-stack.gpg /etc/apt/keyrings/scbrown-stack.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/scbrown-stack.gpg] https://scbrown.github.io/apt stable main" \
| sudo tee /etc/apt/sources.list.d/scbrown-stack.list \
&& sudo apt update && sudo apt install desire-path
```

`apt upgrade` then picks up new releases. unattended-upgrades only installs
from origins it allows, so to have it upgrade desire-path too, add
`"origin=scbrown,codename=stable";` to `Unattended-Upgrade::Origins-Pattern`.
Channels, pinning and rollback:
[scbrown/apt](https://github.com/scbrown/apt#channels-and-pinning).

Linux x86-64, pinned release with checksum verification:

```bash
mkdir -p /tmp/dp-install && cd /tmp/dp-install
curl -fLO https://github.com/scbrown/desire-path/releases/download/v0.7.0/desire-path_0.7.0_linux_amd64.tar.gz
curl -fLO https://github.com/scbrown/desire-path/releases/download/v0.7.0/checksums.txt
sha256sum --check --ignore-missing checksums.txt
tar -xzf desire-path_0.7.0_linux_amd64.tar.gz dp
mkdir -p "$HOME/.local/bin" && install -m 755 dp "$HOME/.local/bin/dp"
export PATH="$HOME/.local/bin:$PATH"
dp version
```

Expected: `dp 0.7.0 (5ca33ba)`. If you see something else, check `command -v dp`.

From source (Go 1.24+): `go install github.com/scbrown/desire-path/cmd/dp@v0.7.0`,
then add `$(go env GOPATH)/bin` to PATH and run `dp version`.
See [installation](https://scbrown.github.io/desire-path/getting-started.html) for macOS, Windows, and source-checkout builds.

## First success in three commands

Use a temporary database and one synthetic failed call; Python 3 formats the result:

```bash
DP_DEMO=$(mktemp -d)
printf '%s\n' '{"tool_name":"read_file","error":"unknown tool","session_id":"demo"}' | dp --db "$DP_DEMO/desires.db" ingest --source claude-code --json > "$DP_DEMO/record.json"
dp --db "$DP_DEMO/desires.db" paths --json | python3 -c 'import json,sys; p=json.load(sys.stdin)[0]; print(p["pattern"], p["count"])'
```

Expected stdout:

```text
read_file 1
```

The failure became a queryable pattern without configuring an agent or touching your usual database.
An optional-metrics diagnostic may also appear on stderr; see [troubleshooting](https://scbrown.github.io/desire-path/getting-started.html#troubleshooting).

## On your own data

After your agent has recorded calls:

| question | command |
|---|---|
| Which failures repeat? | `dp paths --top 5` |
| What happened for this tool? | `dp inspect read_file` |
| What tool might have been intended? | `dp similar read_file` |
| How do I record the intended mapping? | `dp alias read_file Read` |
| How do I export the failures? | `dp export --format json` |

An alias records a mapping. Active interception is a separate [pave setup](https://scbrown.github.io/desire-path/commands/pave.html).
See the [CLI reference](https://scbrown.github.io/desire-path/commands/) for flags and all commands.

## Wire it into your agent

For Claude Code, with `dp` on the agent's PATH:

```bash
dp init --source claude-code
dp sources
```

The installer merges hooks into `~/.claude/settings.json`. It installs ingestion
for successes and failures, plus signposting and correction hooks. Review that
file after installation. [Using agents](https://scbrown.github.io/desire-path/integrations/)
explains the installed hooks and the Codex, Cursor, and Kiro source plugins.

## Before you start

| requirement | support |
|---|---|
| Release archives | Linux, macOS, Windows; amd64 and arm64 |
| Source build | Go 1.24+; no CGo required |
| README demo | Bash-compatible shell and Python 3 |
| Local storage | SQLite at `~/.dp/desires.db`; override with `--db` |
| Hook capture | A supported agent and `dp` on its PATH |

Keep tool inputs and error messages in mind when sharing [exports](https://scbrown.github.io/desire-path/commands/export.html).

## What's next

- [Read the book](https://scbrown.github.io/desire-path/introduction.html)
- [Find every design and reference document](https://scbrown.github.io/desire-path/docs-map.html)
- [Configure capture for your agent](https://scbrown.github.io/desire-path/integrations/)

## 🧺 The stack

Caboodle installs these together and proves each one works; every tool also stands alone.

## Contributing

From a checkout, with [just](https://github.com/casey/just), Go, Python 3,
pre-commit, and mdBook installed:

```bash
just build
just test
just check
```

See the [development guide](https://github.com/scbrown/desire-path/blob/main/book/src/development/contributing.md).

## 📜 License

[MIT](https://github.com/scbrown/desire-path/blob/main/LICENSE).

Repeated failures can be measured with `dp failure-families --since <RFC3339> --until <RFC3339> --window 1h --max-records 10000 --json`. It groups by tool, parsed shell command-program shape and a bounded error class; compound commands are grouped as programs, without claiming which subcommand failed. Argument values, paths and error messages are absent from output. Unsupported wrappers and dynamic command identities are counted separately as UNKNOWN. Synthetic turn-pattern observations are excluded. `peak_window` measures the historical rolling maximum; `current_window` measures the window ending at `--until`. These are observations, not an alerting policy or a claim of complete capture.

`--max-records` defaults to 10000 and accepts 1 through 100000. The store query
loads at most the cap plus one sentinel; overflow returns an error without partial
counts. Future records after `--until` conservatively consume this candidate cap
because the existing store selector bounds only `--since`. JSON also identifies
the exact `since`/`until`, `max_records`, `input_records` and `complete: true`.
Complete means the candidate inventory fit the cap, not that normalization or
failure capture was complete: consumers must still inspect `unknown` and
`excluded`. A record cap bounds materialized rows, not total input bytes or query
latency. Prefer one current window for scheduled threshold evaluation; a historical
report requires its own bounded read-cost admission.

Local `failure-families` reads require an existing database at the current schema
version. The command opens it read-only: missing databases and schema mismatches
return an error without creating a store or migrating it. Configured remote
stores continue to use their existing read API.
4 changes: 2 additions & 2 deletions docs/knowledge/repository-knowledge.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"source": "README.md",
"subject": "http://aegis.gastown.local/ontology/doc/desire-path/README.md",
"summary": "Desire Path records tool-call failures, groups repeated desires and records mappings to real tool names. An alias records a mapping; active interception has separate setup.",
"source_sha256": "eb133a1842d47e1e64c5e6340479c0f39ec2bf58ef2f0ba3e5784e7082370d1e",
"source_sha256": "02ecab7b213451577521843dabc159c85a7e6bcd6e88f5d1fe0cbdaf82a4c51e",
"type": "Concept"
},
{
Expand Down Expand Up @@ -83,7 +83,7 @@
"source": "README.md",
"subject": "http://aegis.gastown.local/ontology/doc/desire-path/README.md",
"summary": "Start with the temporary-database failed-call example before installing agent hooks or sharing exports.",
"source_sha256": "eb133a1842d47e1e64c5e6340479c0f39ec2bf58ef2f0ba3e5784e7082370d1e",
"source_sha256": "02ecab7b213451577521843dabc159c85a7e6bcd6e88f5d1fe0cbdaf82a4c51e",
"properties": {
"startHereOrder": 1,
"glossaryTerm": "https://scbrown.github.io/quechua/ns#Tool"
Expand Down
Loading
Loading