Skip to content

Commit 9532bb3

Browse files
docs(miner-deployment): add laptop vs fleet deployment guide
Closes #2330 Document status/doctor walkthrough, fleet docker pattern, and invariants. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 29d59b6 commit 9532bb3

3 files changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Gittensory miner deployment
2+
3+
Two form factors for running `@jsonbored/gittensory-miner`: **laptop mode** (single machine, zero Docker) and **fleet mode** (containerized workers with a shared data volume). Both are 100% client-side for core operation — the miner never uploads source and never requires a hosted Gittensory callback to boot. Credentials (GitHub tokens, etc.) stay on the operator's machine or in their own secret store; nothing is baked into images.
4+
5+
| | Laptop mode | Fleet mode |
6+
|---|---|---|
7+
| **Best for** | One contributor machine, local experimentation | Many parallel miner attempts on a host or small cluster |
8+
| **Dependencies** | Node.js `>=22.13.0` only | Docker (or compatible runtime) + Node image or custom image |
9+
| **State** | SQLite files under `~/.config/gittensory-miner/` (override with `GITTENSORY_MINER_CONFIG_DIR`) | Same SQLite layout on a mounted `/data` (or `GITTENSORY_MINER_CONFIG_DIR`) volume |
10+
| **Setup** | `npm install -g @jsonbored/gittensory-miner` or workspace build | `docker run` with env + volume (see below) |
11+
| **Footprint** | One Node process, local disk for ledgers/queues | One container per worker; scale horizontally by adding containers |
12+
13+
## Laptop mode walkthrough
14+
15+
1. Install Node.js 22.13+ and the package:
16+
17+
```sh
18+
npm install -g @jsonbored/gittensory-miner@latest
19+
# or from a checkout:
20+
npm install && npm --workspace @jsonbored/gittensory-miner run build
21+
```
22+
23+
2. Inspect what is installed and where local state will live (no network calls):
24+
25+
```sh
26+
gittensory-miner status
27+
gittensory-miner doctor
28+
```
29+
30+
3. Expected layout after first use (default paths):
31+
32+
```text
33+
~/.config/gittensory-miner/
34+
claim-ledger.sqlite3 # soft issue claims (#2314)
35+
plan-store.sqlite3 # persisted MCP plan DAGs (#2318)
36+
portfolio-queue.sqlite3 # local portfolio queue
37+
event-ledger.sqlite3 # manage-loop audit trail
38+
governor-ledger.sqlite3 # governor decisions
39+
```
40+
41+
Override the directory with `GITTENSORY_MINER_CONFIG_DIR` or `XDG_CONFIG_HOME` (same resolution chain as `@jsonbored/gittensory-mcp`).
42+
43+
4. Optional per-repo miner goals: copy [`.gittensory-miner.yml.example`](../../.gittensory-miner.yml.example) to a target repo as `.gittensory-miner.yml`. See [`docs/miner-goal-spec.md`](docs/miner-goal-spec.md).
44+
45+
## Fleet mode walkthrough
46+
47+
There is no separate published miner fleet image yet. Run the same CLI inside a standard Node container, mount persistent state, and inject secrets at runtime (never bake them into the image):
48+
49+
```sh
50+
docker run --rm -it \
51+
-e GITTENSORY_MINER_CONFIG_DIR=/data/miner \
52+
-e GITHUB_TOKEN \
53+
-v miner-data:/data/miner \
54+
node:24-slim \
55+
bash -lc 'npm install -g @jsonbored/gittensory-miner@latest && gittensory-miner doctor && gittensory-miner status'
56+
```
57+
58+
- **`/data` volume** — holds all SQLite state so containers are disposable.
59+
- **`GITHUB_TOKEN`** — supplied by the operator at run time; the image contains no credentials.
60+
- **Scale** — launch additional containers with the same volume (or partitioned config dirs) for parallel attempts.
61+
62+
The repo-root [`docker-compose.yml`](../../docker-compose.yml) documents the **self-hosted review stack** (the `gittensory` API/orb), not the miner CLI. Miners are clients of that stack (or of github.com directly) and do not require it to run locally.
63+
64+
## Invariants
65+
66+
- Core miner bookkeeping (claims, plans, queues, ledgers) works offline after install.
67+
- `gittensory-miner status` and `gittensory-miner doctor` make **no network calls**.
68+
- Discovery/ranking primitives that touch GitHub only run when explicitly invoked and only perform documented GETs unless a future command says otherwise.
69+
- Operators own secret injection; images and packages ship without embedded tokens.

packages/gittensory-miner/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ no enforcement wiring yet. (#2328)
3232

3333
See [`docs/miner-goal-spec.md`](docs/miner-goal-spec.md) for the `.gittensory-miner.yml` field reference and [`.gittensory-miner.yml.example`](../../.gittensory-miner.yml.example) at the repo root.
3434

35+
See [`DEPLOYMENT.md`](DEPLOYMENT.md) for laptop vs fleet deployment.
36+
3537
From a local checkout:
3638

3739
```sh
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { readFileSync } from "node:fs";
2+
import { join } from "node:path";
3+
import { describe, expect, it } from "vitest";
4+
5+
const DEPLOYMENT_PATH = join(process.cwd(), "packages/gittensory-miner/DEPLOYMENT.md");
6+
const README_PATH = join(process.cwd(), "packages/gittensory-miner/README.md");
7+
8+
describe("miner deployment guide (#2330)", () => {
9+
it("documents laptop and fleet modes with required walkthrough sections", () => {
10+
const doc = readFileSync(DEPLOYMENT_PATH, "utf8");
11+
expect(doc).toContain("Laptop mode");
12+
expect(doc).toContain("Fleet mode");
13+
expect(doc).toContain("gittensory-miner status");
14+
expect(doc).toContain("gittensory-miner doctor");
15+
expect(doc).toContain("GITTENSORY_MINER_CONFIG_DIR");
16+
expect(doc).toContain("100% client-side");
17+
expect(doc).toContain("credentials");
18+
expect(doc).toContain("docker run");
19+
expect(doc).toContain("docker-compose.yml");
20+
});
21+
22+
it("is linked from the miner package README", () => {
23+
const readme = readFileSync(README_PATH, "utf8");
24+
expect(readme).toContain("DEPLOYMENT.md");
25+
});
26+
});

0 commit comments

Comments
 (0)