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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Troubleshooting
url: https://github.com/ado11231/ss/blob/master/docs/TROUBLESHOOTING.md
url: https://github.com/ado11231/ally/blob/master/docs/TROUBLESHOOTING.md
about: Most error messages are explained here, with the fix.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/problem.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ Paste the full output here.
* Client operating system:
* Agent operating system:
* How they connect: same network, tailnet, or different networks
* Output of `slingshot health`, if the Agent can be reached:
* Output of `ally health`, if the Agent can be reached:
8 changes: 4 additions & 4 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

## Docs

- [ ] [USAGE.md](https://github.com/ado11231/ss/blob/master/docs/USAGE.md) for a new or changed command or option.
- [ ] [TROUBLESHOOTING.md](https://github.com/ado11231/ss/blob/master/docs/TROUBLESHOOTING.md) for a new or changed message.
- [ ] The [file reference](https://github.com/ado11231/ss/blob/master/docs/ARCHITECTURE.md#file-reference) for a new or moved file.
- [ ] [ROADMAP.md](https://github.com/ado11231/ss/blob/master/docs/ROADMAP.md) for what now works, with the date.
- [ ] [USAGE.md](https://github.com/ado11231/ally/blob/master/docs/USAGE.md) for a new or changed command or option.
- [ ] [TROUBLESHOOTING.md](https://github.com/ado11231/ally/blob/master/docs/TROUBLESHOOTING.md) for a new or changed message.
- [ ] The [file reference](https://github.com/ado11231/ally/blob/master/docs/ARCHITECTURE.md#file-reference) for a new or moved file.
- [ ] [ROADMAP.md](https://github.com/ado11231/ally/blob/master/docs/ROADMAP.md) for what now works, with the date.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ jobs:
run: cargo test --workspace
- name: Menu bar app
if: runner.os == 'macOS'
run: swift build -c release --package-path crates/slingshot-cli/menubar
run: swift build -c release --package-path crates/ally-cli/menubar
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/target

/crates/slingshot-cli/menubar/.build
/crates/ally-cli/menubar/.build
34 changes: 17 additions & 17 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

1. [Accountability](#1-accountability)
2. [Read First](#2-read-first)
3. [What Slingshot Is](#3-what-slingshot-is)
3. [What Ally Is](#3-what-ally-is)
4. [Rules That Are Never Broken](#4-rules-that-are-never-broken)
5. [Out Of Scope](#5-out-of-scope)
6. [Before Writing Code](#6-before-writing-code)
Expand Down Expand Up @@ -51,13 +51,13 @@

---

## 3. What Slingshot Is
## 3. What Ally Is

* Slingshot lets a light machine use the CPU, RAM, and GPU of a powerful one.
* Ally lets a light machine use the CPU, RAM, and GPU of a powerful one.
* The user keeps their own editor, terminal, and browser. Builds, servers, databases, containers, coding agents, and small AI models run on the powerful machine.
* It must feel local. There is no virtual machine and no remote desktop.
* **Goal:** a public open source tool a stranger can install and set up in minutes. Setup friction is a bug.
* **Name:** Slingshot. The command is `slingshot`. It was called borrow until September 22, 2026.
* **Name:** Ally. The command is `ally`. It was called Slingshot until October 16, 2026, and borrow until September 22, 2026.
* **Languages:** Rust, except the macOS menu bar app, which is SwiftUI.
* **Roles:** the **Client** is the machine the user works on. The **Agent** is the machine with the resources.

Expand All @@ -67,7 +67,7 @@

1. **The Client stays light.** Never move heavy work onto the Client. If a change makes the Client do real work, the change is wrong.
2. **Always state where work runs.** Every remote command prints its location, such as `▶ Running on archbox via tailnet`.
3. **Wrap existing tools. Never rebuild them.** Slingshot wraps `ssh`, `rsync`, `tmux`, `docker`, `ollama`, `nvidia-smi`, and the `iroh` library. Never write your own ssh, file transfer, terminal multiplexer, container engine, inference engine, relay server, or NAT traversal.
3. **Wrap existing tools. Never rebuild them.** Ally wraps `ssh`, `rsync`, `tmux`, `docker`, `ollama`, `nvidia-smi`, and the `iroh` library. Never write your own ssh, file transfer, terminal multiplexer, container engine, inference engine, relay server, or NAT traversal.
4. **Keep setup simple.** One program per machine, one pairing step, one command to use. Reject designs that add setup steps.
5. **Stay platform neutral.** Describe everything as Client and Agent, never as Mac and Linux. Mac to Linux and Linux to Linux must both work. Only the menu bar app may be macOS specific.
6. **Design for a stranger.** Anything easy only on the author's machine becomes a setup check or an installer step. Every failed check prints the exact fix. Detect and instruct. Never install without asking: show exactly what will run, then ask once.
Expand All @@ -87,7 +87,7 @@
| Treating environment files as source | `.env`, `.env.*`, `*.env`, and `.envrc` never enter a sync, and their contents never appear in arguments. |
| Assuming a package manager | The main test Agent runs Arch Linux, which uses `pacman`, not `apt`. Detect and instruct. |
| Fixed system paths in shared code | Never write `/Users/...` or `/home/...`. Use the `directories` crate. |
| New operations on the pairing port | The TCP port only pairs. Every other request uses `slingshot internal-control` over ssh. |
| New operations on the pairing port | The TCP port only pairs. Every other request uses `ally internal-control` over ssh. |
| A custom way to run commands | ssh carries all work. `run`, `attach`, and `rsync` always go through it. |

---
Expand All @@ -97,7 +97,7 @@
1. **Understand the request.** If it is unclear or has more than one meaning, ask. Never guess about anything that changes behavior, deletes data, or affects security.
2. **Read the code you will change, and its callers.** Find both in the [file reference](docs/ARCHITECTURE.md#file-reference). Never edit a file you have not read.
3. **Look for existing helpers.** Search before writing anything new. See the table below.
4. **Choose the right crate.** Rules both machines apply go in `slingshot-core`, Agent only code in `slingshot-agent`, and commands and Client code in `slingshot-cli`. `slingshot-cli` uses the other two, `slingshot-agent` uses `slingshot-core`, and `slingshot-core` uses neither.
4. **Choose the right crate.** Rules both machines apply go in `ally-core`, Agent only code in `ally-agent`, and commands and Client code in `ally-cli`. `ally-cli` uses the other two, `ally-agent` uses `ally-core`, and `ally-core` uses neither.
5. **Plan the smallest change** that solves the problem and keeps everything working end to end.

| Need | Existing Helper |
Expand Down Expand Up @@ -130,7 +130,7 @@
* Match the surrounding code's names, structure, and idioms.
* Use plain English names. Never names like `mgr`, `ctx2`, `tmp_data`, or `handle_stuff`.
* Errors use `anyhow`. Every visible error says what went wrong and what to do, in one sentence, with the exact command when there is one.
* A failing user command is not a Slingshot error. Report its exit code faithfully.
* A failing user command is not an Ally error. Report its exit code faithfully.
* Never use `unwrap()` outside tests. Use `?`, or `expect("reason this cannot fail")` for true invariants only.
* Never use `unsafe` unless existing code already does the same thing, and explain why.
* Never add `#[allow(...)]` to silence a warning. Fix the cause, or ask.
Expand All @@ -149,9 +149,9 @@

### Formats And Versions

* **Control messages:** any change to a `Request` or `Response` shape in `slingshot-core/src/control.rs` raises `control::VERSION`, currently 14.
* **Menu bar lines:** if a field in `slingshot-cli/src/watch/event.rs` changes meaning or is removed, raise `watch::event::VERSION` and change `slingshot-cli/menubar/Sources/Model.swift` in the same commit.
* **Pairing messages:** a change to the pairing messages in `slingshot-core/src/protocol.rs` means both machines must update before the next link. A change to `Specs` or `Health`, which are saved or sent after pairing, forces every user to link again. Say which one explicitly.
* **Control messages:** any change to a `Request` or `Response` shape in `ally-core/src/control.rs` raises `control::VERSION`, currently 14.
* **Menu bar lines:** if a field in `ally-cli/src/watch/event.rs` changes meaning or is removed, raise `watch::event::VERSION` and change `ally-cli/menubar/Sources/Model.swift` in the same commit.
* **Pairing messages:** a change to the pairing messages in `ally-core/src/protocol.rs` means both machines must update before the next link. A change to `Specs` or `Health`, which are saved or sent after pairing, forces every user to link again. Say which one explicitly.

### Security

Expand All @@ -169,7 +169,7 @@

### The Menu Bar App

* Swift only displays information and posts notifications. All thresholds, rules, and wording live in Rust, in `crates/slingshot-cli/src/watch/`.
* Swift only displays information and posts notifications. All thresholds, rules, and wording live in Rust, in `crates/ally-cli/src/watch/`.
* Confirm an SF Symbol name exists before using it. A wrong name draws nothing and reports no error.
* macOS only Rust code sits behind `#[cfg(target_os = "macos")]`, with a clear message on other systems.

Expand All @@ -193,12 +193,12 @@

## 8. Output Style

* All output goes through `slingshot-core/src/presentation.rs` and `slingshot-core/src/step.rs`.
* All output goes through `ally-core/src/presentation.rs` and `ally-core/src/step.rs`.
* Slow work is a step: a spinner in a terminal, then a line such as `✓ Synced 3 files 0.4s`.
* Status symbols: `✓`, `!`, `✗`, and `▶`.
* Color marks only what needs attention: symbols, the Agent and path in `▶` lines, and warning or failing values. Healthy values stay plain, headings are bold, and details are dimmed.
* Messages use sentence case. CPU, RAM, GPU, and VRAM are always capitals.
* `--color auto|always|never` controls color. Slingshot's options come before `run`. Everything after `run` belongs to the user's command.
* `--color auto|always|never` controls color. Ally's options come before `run`. Everything after `run` belongs to the user's command.

---

Expand All @@ -215,7 +215,7 @@ cargo test --workspace
* If you changed the menu bar app, also run:

```sh
swift build -c release --package-path crates/slingshot-cli/menubar
swift build -c release --package-path crates/ally-cli/menubar
```

* Every rule or decision you add or change gets a unit test in the same file's `tests` module.
Expand Down Expand Up @@ -255,7 +255,7 @@ swift build -c release --package-path crates/slingshot-cli/menubar
* Commit messages follow `type: summary`, with type `feat`, `fix`, `refactor`, `docs`, or `test`. The body explains why.
* Make small commits that each build and pass tests.
* **No AI attribution.** Never add `Co-Authored-By` lines, "Generated with" lines, or tool names. Commits belong to the person who asked for them.
* Never commit secrets, build output, or anything in `crates/slingshot-cli/menubar/.build/`.
* Never commit secrets, build output, or anything in `crates/ally-cli/menubar/.build/`.

---

Expand Down Expand Up @@ -310,6 +310,6 @@ swift build -c release --package-path crates/slingshot-cli/menubar
* **Phases 1, 3, and 4 are complete.** Phase 5 is in progress: the menu bar app, notifications, and the fixes from the October 7, 2026 fresh install test are built, and automatic port forwarding is not.
* **Next:** port forwarding (#9), then local models (#20, #38 to #40). Every finding from the October 7, 2026 fresh install test is fixed.
* **All tests, formatting, and Clippy pass on `master`.** CI checks every pull request on Linux and macOS.
* **The rename from borrow has no migration.** Both machines must run `slingshot link` again after updating.
* **The renames from borrow and Slingshot have no migration.** Both machines must run `slingshot uninstall`, install Ally, then run `ally link`.
* Everything under [known limitations](docs/ROADMAP.md#known-limitations) does not work yet. Never describe it as working.
* The full [test record](docs/ROADMAP.md#test-record) is in the roadmap.
1 change: 0 additions & 1 deletion CLAUDE.md

This file was deleted.

40 changes: 20 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing

* How to set up Slingshot, make a change, and get it merged.
* How to set up Ally, make a change, and get it merged.

## Contents

Expand All @@ -26,20 +26,20 @@

| Tool | Machine | Purpose |
| --- | --- | --- |
| Rust, latest stable | Both | Builds Slingshot. |
| Rust, latest stable | Both | Builds Ally. |
| `rsync` | Both | Copies project files. |
| An ssh server | Agent | Carries all work and requests. |
| `tmux` | Agent | Keeps sessions running. |
| Xcode command line tools | Mac Client | Builds the menu bar app. |

```sh
git clone https://github.com/ado11231/ss.git slingshot
cd slingshot
cargo install --path crates/slingshot-cli
slingshot menubar
git clone https://github.com/ado11231/ally.git ally
cd ally
cargo install --path crates/ally-cli
ally menubar
```

* `cargo install --path` installs your build as `slingshot`. `slingshot menubar` builds the app on a Mac, and rebuilds it when its source changed.
* `cargo install --path` installs your build as `ally`. `ally menubar` builds the app on a Mac, and rebuilds it when its source changed.

## Building And Testing

Expand All @@ -51,24 +51,24 @@ cargo clippy --workspace --all-targets
cargo test --workspace
```

* After changing the menu bar app, also run `swift build -c release --package-path crates/slingshot-cli/menubar`.
* After changing the menu bar app, also run `swift build -c release --package-path crates/ally-cli/menubar`.
* CI runs the same checks on Linux and macOS for every pull request.
* Unit tests sit in a `tests` module at the bottom of the file they test. Tests of the finished program are in `crates/slingshot-cli/tests/`.
* Unit tests sit in a `tests` module at the bottom of the file they test. Tests of the finished program are in `crates/ally-cli/tests/`.
* Every rule or decision needs a test, such as which files are source, what a sync copies, when a notification is sent, or how an error is worded. Code that only starts another program, such as `ssh`, is tested on real machines.

## Testing On Two Machines

* Test changes to running, syncing, sessions, or connections on two real machines:

1. `slingshot start` on the Agent, and `slingshot link <code>` on the Client.
2. Use the changed feature, such as `slingshot run cargo build`, `slingshot sync`, or `slingshot attach`.
3. Test failures: stop `slingshot start`, drop the network, or restart the Agent.
1. `ally start` on the Agent, and `ally link <code>` on the Client.
2. Use the changed feature, such as `ally run cargo build`, `ally sync`, or `ally attach`.
3. Test failures: stop `ally start`, drop the network, or restart the Agent.

* List exactly what you ran and what happened in the pull request. Never call something working unless you ran it.

## Making A Change

1. **Find the place** in the [file reference](docs/ARCHITECTURE.md#file-reference). Shared rules go in `slingshot-core`, Agent only code in `slingshot-agent`, and commands and Client code in `slingshot-cli`.
1. **Find the place** in the [file reference](docs/ARCHITECTURE.md#file-reference). Shared rules go in `ally-core`, Agent only code in `ally-agent`, and commands and Client code in `ally-cli`.
2. **Keep it focused.** The smallest change that solves the problem. Unrelated improvements go in another pull request.
3. **Match what is there:** naming, structure, and comment style.
4. **Test it,** and run the changed command at least once.
Expand All @@ -91,22 +91,22 @@ cargo test --workspace

## Code Standards

* `slingshot-core` uses neither other crate. `slingshot-agent` uses `slingshot-core`. `slingshot-cli` uses both.
* `ally-core` uses neither other crate. `ally-agent` uses `ally-core`. `ally-cli` uses both.
* Wrap existing tools such as `ssh`, `rsync`, `tmux`, `docker`, and `iroh`. Never write your own.
* Say Client and Agent, never Mac and Linux. Only the menu bar app may be macOS specific.
* No fixed paths such as `/Users/...`. Use the `directories` crate.
* Never assume a package manager. Detect, print the install command, and ask once before running anything.
* Errors use `anyhow`, and every visible error says how to fix it. A failing user command is not a Slingshot error; pass its exit code through.
* Errors use `anyhow`, and every visible error says how to fix it. A failing user command is not an Ally error; pass its exit code through.
* Use `tokio` for async, `tracing` for logs, and `clap` for arguments. No `unwrap` outside tests.
* Quote each argument sent to the Agent on its own. Never stop a process by ID alone; check its start time.
* Changing a control message raises `control::VERSION`. Changing the menu bar line format raises `watch::event::VERSION`, and `Sources/Model.swift` changes with `watch/event.rs`.
* Swift only displays and notifies. Thresholds and rules stay in `crates/slingshot-cli/src/watch/`.
* Swift only displays and notifies. Thresholds and rules stay in `crates/ally-cli/src/watch/`.
* Comments go above an item, only when its purpose is not obvious, and say why. No comments in function bodies, commented out code, or `TODO` notes.
* Explain every new crate in the pull request, and use its latest version.

## Output Standards

* Use `slingshot-core/src/presentation.rs` and `step.rs`. Never raw color codes.
* Use `ally-core/src/presentation.rs` and `step.rs`. Never raw color codes.
* Slow work shows a spinner, then a line such as `✓ Synced 3 files 0.4s`.
* Symbols: `✓` success, `!` warning, `✗` failure, `▶` remote work. Every remote command says where it runs, such as `▶ Running on archbox via tailnet`.
* Color marks only what needs attention. Headings are bold, and details dimmed.
Expand Down Expand Up @@ -136,12 +136,12 @@ cargo test --workspace
| --- | --- |
| Sharing RAM over the network | A network is about a hundred thousand times slower than RAM. |
| Remote desktop or screen streaming | Sunshine and Moonlight already do this. |
| Copying or mounting build output | `target`, `node_modules`, virtual environments, and caches stay on the Agent. Copying them makes Slingshot too slow. |
| Copying or mounting build output | `target`, `node_modules`, virtual environments, and caches stay on the Agent. Copying them makes Ally too slow. |
| Syncing environment files as source | `.env`, `.env.*`, `*.env`, and `.envrc` often hold secrets. |
| Requiring an account or VPN | A VPN is used when present, never required. iroh needs no account and no open router port. |
| Custom `ssh`, `rsync`, `tmux`, or relay servers | Slingshot wraps these tools and never replaces them. |
| Custom `ssh`, `rsync`, `tmux`, or relay servers | Ally wraps these tools and never replaces them. |

## Reporting A Problem

1. Check [TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md) first.
2. Open an issue with the Problem template. It asks for the exact command, what you expected, the full output, each machine's system and how they connect, and `slingshot health` output if the Agent answers.
2. Open an issue with the Problem template. It asks for the exact command, what you expected, the full output, each machine's system and how they connect, and `ally health` output if the Agent answers.
Loading
Loading