@tickernelz/wardmote 2026.1108.2 → 2026.1109.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,86 +1,154 @@
1
- # Wardmote Pro
2
-
3
- Wardmote Pro is a self-hosted control plane that runs a team of AI coding agents as an organisation: an org chart, tasks and approvals, scheduled heartbeats, budgets, and an audit trail, with a Node.js server, an embedded PostgreSQL, and a React board.
4
-
5
- It is a **hard fork** of [`paperclipai/paperclip`](https://github.com/paperclipai/paperclip), branched at upstream commit `7b7c4d417` and since diverged. It is not an upstream release and is not endorsed by Paperclip Labs, Inc. All workspace packages are renamed under the `@tickernelz/wardmote` scope, the CLI binary is `wardmote` (`paperclip-pro` still works for one release), and instance state lives under `~/.wardmote` instead of `~/.paperclip`, so this fork installs and runs beside an upstream instance instead of replacing it. An existing `~/.paperclip-pro` home keeps working without any action; `wardmote migrate-home` moves it to `~/.wardmote` when you choose. See [doc/RELEASE-NOTES-wardmote-rename.md](doc/RELEASE-NOTES-wardmote-rename.md).
6
-
7
- Report bugs in [this repository](https://github.com/tickernelz/wardmote/issues), never in the upstream tracker.
8
-
9
- ## What this fork adds
10
-
11
- | Addition | Where |
12
- | --- | --- |
13
- | **Built-in `omp_local` adapter.** Runs the local Oh My Pi (OMP) coding-agent CLI as a Wardmote agent runtime: server execution, CLI event formatting, model discovery through `omp models --json`, a UI transcript parser, and a startup-complete signal the run-concurrency gate reads. | [`packages/adapters/omp-local`](packages/adapters/omp-local), registered in `server/src/adapters/registry.ts` |
14
- | **Server-hosted Wardmote MCP.** `POST /api/mcp/paperclip` exposes the Wardmote API as MCP tools generated from the OpenAPI document. 675 operations generate tools: the `core` toolset is the default and lists 61 tools (~36 KB, ~9k tokens of context), `core,extended` lists 442 (~210 KB), and an agent with company authority sees 719 (~344 KB). Toolsets are selected per run with `?toolsets=`. Adapters that can mount an MCP client get the endpoint; the others get a REST fallback prompt instead of tool names that do not exist. | `server/src/routes/paperclip-mcp.ts`, `packages/mcp-server/src/generated/api-tools.json` |
15
- | **Role-based agent authority.** An agent actor carries work authority (`work:read`, `work:issues`, `work:routines`); an agent whose role is `ceo` additionally carries company authority over agents, projects, settings, members and approvals. Every generated MCP tool is tagged `agent` or `board` and gated on the same model. | `packages/shared/src/agent-authority.ts`, `server/src/services/authorization.ts` |
16
- | **Per-task model and thinking overrides.** A task can run on a different model or thinking level than its assignee's stored configuration, validated against the adapter's own published config schema, with optional inheritance to new or existing subtasks. No new column and no migration: it reuses `issues.assignee_adapter_overrides`. | `server/src/services/issue-run-model-override.ts`, `server/src/services/issue-model-override-inheritance.ts` |
17
- | **Batch model/thinking changes.** Select agents in the Agents list and change the model-selection fields their adapters share. The batch is atomic: one invalid value rejects the call with 422 and writes nothing. Up to 100 agents per call. | `POST /api/agents/batch/adapter-config`, `.../preview` |
18
- | **Local CLI run concurrency caps.** Local adapters are memory-hungry while booting; the queued-run claim point caps total local runs and simultaneous startups, and shows held-back runs as "Waiting to start". | `server/src/services/heartbeat.ts` |
19
- | **Mobile composer dock and bottom-sheet pickers.** The task and agent composers dock above the on-screen keyboard and reserve their own height, the bottom nav auto-hides while typing, and the model/thinking, agent and New Task pickers open as bottom sheets instead of being covered by the keyboard. | `ui/src/components/task-chat/composer-dock.ts`, `ui/src/components/ui/mobile-picker-sheet.tsx`, `ui/src/hooks/useMobileViewportInsets.ts` |
20
- | **`service restart --drain` and a live-run guard.** Restart and stop refuse while agent runs are executing unless you drain or force. A per-instance `service.env` the CLI never overwrites carries operator environment across unit rewrites. | `cli/src/commands/service.ts`, `cli/src/services/service-manager.ts` |
21
- | **Isolated home.** `PAPERCLIP_HOME` defaults to `~/.wardmote`; config, embedded PostgreSQL, logs, storage and backups all resolve under `~/.wardmote/instances/<id>`. | `packages/shared/src/home-paths.ts` |
22
- | **One lean CI and a tag-triggered release.** A single `ci.yml` (policy, typecheck, build, runner, sharded tests, E2E, mobile shell) plus a documentation-only fast lane that runs the static gates and the docs-reading suites, and a `release.yml` that publishes the whole package set to npm when a `v*` tag is pushed. | `.github/workflows/` |
23
-
24
- Operators: read [`docs/fork/OPERATIONS.md`](docs/fork/OPERATIONS.md).
25
-
26
- ## Install
27
-
28
- Requirements: Node.js 24.11 or newer, `npm`, macOS/Linux/WSL2. Nothing else — the published packages ship prebuilt.
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/banner-dark.svg">
4
+ <img src="docs/assets/readme/banner-light.svg" alt="Wardmote: run a company of AI agents" width="840">
5
+ </picture>
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/@tickernelz/wardmote"><img src="https://img.shields.io/npm/v/@tickernelz/wardmote?label=npm&color=4f4dd3" alt="npm version"></a>
10
+ <a href="https://github.com/tickernelz/wardmote/actions/workflows/ci.yml"><img src="https://github.com/tickernelz/wardmote/actions/workflows/ci.yml/badge.svg?branch=main" alt="CI"></a>
11
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-4f4dd3" alt="MIT licence"></a>
12
+ <img src="https://img.shields.io/badge/node-%E2%89%A5%2024.11-4f4dd3" alt="Node.js 24.11 or newer">
13
+ </p>
14
+
15
+ Wardmote is a self-hosted control plane that runs a team of AI coding agents as a company: an org chart, tasks and decisions, approvals, scheduled heartbeats, budgets and an audit trail. One Node.js server holds an embedded PostgreSQL and serves a React board, and every agent is a local [Oh My Pi (OMP)](https://github.com/can1357/oh-my-pi) process that reports back through Wardmote's own MCP endpoint.
16
+
17
+ ## Why Wardmote
18
+
19
+ - **One install, nothing else to run.** `npx @tickernelz/wardmote@latest install --yes` puts a verified, versioned payload in your home directory. PostgreSQL is embedded; there is no Docker, no external database and no cloud account.
20
+ - **Agents that work like staff.** Each agent has a role, a manager, a task queue and a budget. Work moves through tasks, decisions and approvals that you see in one inbox, on a phone or a desktop.
21
+ - **OMP-first.** The `omp_local` adapter is built in. Onboarding finds OMP on the machine, lists the models it reports and creates the first agent; Agent defaults sets OMP behaviour for every agent at once.
22
+ - **Safe to operate.** Updates back up the database first and roll back on a failed health check. Service restarts drain or adopt live agent runs instead of killing them.
23
+
24
+ ## Screenshots
25
+
26
+ Light and dark follow your GitHub theme. All screenshots come from a throwaway instance with demo data.
27
+
28
+ <table>
29
+ <tr><th>Desktop (1440 px)</th><th>Phone (360 px)</th></tr>
30
+ <tr><td colspan="2"><b>Inbox:</b> every task, decision and blocker that needs you</td></tr>
31
+ <tr>
32
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/inbox-desktop-dark.webp"><img src="docs/assets/readme/inbox-desktop-light.webp" alt="Inbox on a 1440 px desktop" width="640"></picture></td>
33
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/inbox-phone-dark.webp"><img src="docs/assets/readme/inbox-phone-light.webp" alt="Inbox on a 360 px phone" width="180"></picture></td>
34
+ </tr>
35
+ <tr><td colspan="2"><b>Onboarding:</b> finds OMP, picks a model and a project folder</td></tr>
36
+ <tr>
37
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/onboarding-desktop-dark.webp"><img src="docs/assets/readme/onboarding-desktop-light.webp" alt="Onboarding on a 1440 px desktop" width="640"></picture></td>
38
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/onboarding-phone-dark.webp"><img src="docs/assets/readme/onboarding-phone-light.webp" alt="Onboarding on a 360 px phone" width="180"></picture></td>
39
+ </tr>
40
+ <tr><td colspan="2"><b>Agent defaults:</b> OMP settings shared by every agent</td></tr>
41
+ <tr>
42
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/agent-defaults-desktop-dark.webp"><img src="docs/assets/readme/agent-defaults-desktop-light.webp" alt="Agent defaults on a 1440 px desktop" width="640"></picture></td>
43
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/agent-defaults-phone-dark.webp"><img src="docs/assets/readme/agent-defaults-phone-light.webp" alt="Agent defaults on a 360 px phone" width="180"></picture></td>
44
+ </tr>
45
+ <tr><td colspan="2"><b>Features:</b> turn product areas on or off without losing data</td></tr>
46
+ <tr>
47
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/features-desktop-dark.webp"><img src="docs/assets/readme/features-desktop-light.webp" alt="Features on a 1440 px desktop" width="640"></picture></td>
48
+ <td><picture><source media="(prefers-color-scheme: dark)" srcset="docs/assets/readme/features-phone-dark.webp"><img src="docs/assets/readme/features-phone-light.webp" alt="Features on a 360 px phone" width="180"></picture></td>
49
+ </tr>
50
+ </table>
51
+
52
+ ## Quick start
53
+
54
+ Requirements: Node.js 24.11 or newer with `npm`, on Linux, macOS or WSL2, and [OMP](https://github.com/can1357/oh-my-pi) 18.1.16 or newer for the agents. The published packages ship prebuilt.
29
55
 
30
56
  ```sh
31
57
  npx @tickernelz/wardmote@latest install --yes
58
+ export PATH="$HOME/.local/bin:$PATH"
32
59
  wardmote onboard --yes
33
60
  ```
34
61
 
35
- `install` resolves one exact version — the `latest` dist-tag of `@tickernelz/wardmote`, or `--version` — then verifies that all 31 packages of the release exist at that exact version before it downloads anything. A half-published release is refused with the missing package names; versions are never mixed across packages. It then installs the set into `~/.wardmote/cli/installs/npm/<version>`, smoke-tests the payload, and only then atomically flips `~/.wardmote/cli/current` and writes the `~/.local/bin/wardmote` and `~/.local/bin/paperclip-pro` shims. Measured on a WSL2 box: 44 s, against 11 m 38 s for the same commit through the git path.
36
-
37
- `latest` currently points at **2026.926.2**. Prefer it.
38
-
39
- `2026.926.0` is an incomplete release: its run left `@tickernelz/wardmote-server` in npm's staging queue, so `latest` was never moved and no GitHub release was created. npm has since published that package, so all 31 packages now exist at that version and the completeness check no longer refuses it — but the release was never validated end to end. Use `2026.926.2`.
40
-
41
- Releases up to and including `2026.926.1` cannot bootstrap under npm 12, which changed the shape of `npm view --json` and denies dependency install scripts by default. Under npm 11 — the version Node 24.18.0 bundles — the same command works. `2026.926.2` and later handle both.
62
+ `install` resolves one exact version (the `latest` dist-tag, or `--version`), checks that all 20 packages of that release are on npm before it downloads anything, installs them into `~/.wardmote/cli/installs/npm/<version>`, smoke-tests the payload, and only then flips `~/.wardmote/cli/current` and writes the `~/.local/bin/wardmote` shim. In an interactive bash or zsh session it offers to add `~/.local/bin` to `PATH` for you; otherwise it prints the `export` line above.
42
63
 
43
- Pin a published version:
64
+ `onboard --yes` writes `~/.wardmote/instances/default/config.json` for trusted local loopback and starts the server on `http://127.0.0.1:3100`. Open it and the onboarding page walks you through OMP, the model and the project folder. For an instance other machines can reach, choose a bind preset:
44
65
 
45
66
  ```sh
46
- wardmote install --version 2026.926.2 --yes
67
+ wardmote onboard --yes --bind lan
68
+ wardmote onboard --yes --bind tailnet
47
69
  ```
48
70
 
49
- `--canary` follows the `canary` dist-tag, which the release workflow does not publish today; it uses `next` and `latest`.
71
+ The current release is [`2026.1108.1`](https://github.com/tickernelz/wardmote/releases/tag/v2026.1108.1). Pin a version with `wardmote install --version 2026.1108.1 --yes`.
50
72
 
51
- `onboard --yes` writes `~/.wardmote/instances/default/config.json` for trusted local loopback and starts the server on `http://127.0.0.1:3100`. An embedded PostgreSQL is created automatically. For a reachable instance, pick a bind preset:
73
+ ### Coming from Paperclip Pro
52
74
 
53
- ```sh
54
- wardmote onboard --yes --bind lan
55
- wardmote onboard --yes --bind tailnet
56
- ```
75
+ `@tickernelz/paperclip-pro` is deprecated and receives no further releases; install `@tickernelz/wardmote` instead. The CLI also answers to `paperclip-pro` for this release. An existing `~/.paperclip-pro` home keeps working; `wardmote migrate-home` moves it to `~/.wardmote` after you stop the service. Details: [doc/RELEASE-NOTES-wardmote-rename.md](doc/RELEASE-NOTES-wardmote-rename.md).
57
76
 
58
- ### What an install replaces
77
+ ## Features and Advanced
59
78
 
60
- An install or update only ever writes inside `~/.wardmote/cli/` and the shim:
79
+ Settings → **Features** lists 24 product areas in five groups. Each has a plain-language summary and says what changes when it is on or off; turning one off hides it and deletes nothing. The Minimal, Standard and Everything presets set the whole list at once.
61
80
 
62
- | Path | What happens |
81
+ | Group | Features |
63
82
  | --- | --- |
64
- | `~/.wardmote/cli/installs/<npm\|git>/<id>/` | New payload directory; the two previous payloads are kept for rollback, older ones pruned |
65
- | `~/.wardmote/cli/current` | Symlink flipped atomically to the new payload |
66
- | `~/.wardmote/cli/install.json` | Install manifest, rewritten (previous records retained) |
67
- | `~/.local/bin/paperclip-pro` | Managed shim, rewritten with the validated Node executable |
68
- | `~/.bashrc` or `~/.zshrc` | A marked PATH block, only when `~/.local/bin` is not already on `PATH` |
83
+ | Working together | Decisions, Agent chat, Conference room, Pixels office, Status cards, Summaries, Inbox inside Tasks |
84
+ | Automation | Pipelines, Cases, Plan breakdown history, Plan before first task, Built-in agents, Fast replies |
85
+ | Integrations | Chat channels, Memory connectors, Assistant connections, GitHub review bots, OpenAI Dot, Linked objects, Beta skills |
86
+ | Workspaces | Environments, Isolated workspaces |
87
+ | Display | Goals in sidebar, Plain-English cards |
69
88
 
70
- Nothing under `~/.wardmote/instances/` is touched: the instance database, `config.json`, `service.env`, secrets, logs, storage, backups and workspaces survive a payload switch in either direction.
89
+ Settings → **Advanced** holds the switches for people who run or develop Wardmote itself:
71
90
 
72
- ### Installing an unreleased commit
91
+ | Group | Settings |
92
+ | --- | --- |
93
+ | Developer | Developer mode, Server info, Restart dev server when idle, Smoke lab |
94
+ | Runtime | Native runner, Managed environments only, Sandbox duplex bridge, Worktree run execution, Branch reconcile forward, Dirty workspace repair, Owner is instance admin |
95
+
96
+ The catalog lives in [`packages/shared/src/feature-catalog.ts`](packages/shared/src/feature-catalog.ts).
97
+
98
+ ## Configuring OMP
99
+
100
+ **For every agent.** Settings → **Agent defaults** sets Style (Balanced, Fast, Thorough), Model, Thinking, Backup models, Tools and the run time limit for every OMP agent, and shows how many agents follow each value. **All settings** opens every OMP setting that the installed OMP version reports.
101
+
102
+ **For one agent.** An agent's configuration page overrides any of those values for that agent alone; Agent defaults counts the agents that have their own values. A single task can also run on a different model or thinking level than its assignee, and pass that choice on to its subtasks.
103
+
104
+ **For many agents.** Select agents in the Agents list to change their model or thinking level in one atomic call: one invalid value rejects the whole batch and writes nothing.
105
+
106
+ ## Architecture
107
+
108
+ ```mermaid
109
+ flowchart LR
110
+ subgraph browser["Browser"]
111
+ board["Board UI<br/>React"]
112
+ end
113
+ subgraph host["Your machine"]
114
+ subgraph server["Wardmote server (Node.js)"]
115
+ api["REST API"]
116
+ mcp["MCP endpoint<br/>/api/mcp/paperclip"]
117
+ hb["Heartbeat scheduler<br/>and run queue"]
118
+ adapter["omp_local adapter"]
119
+ end
120
+ pg[("Embedded PostgreSQL<br/>~/.wardmote/instances/&lt;id&gt;/db")]
121
+ omp["omp CLI processes<br/>one per agent run"]
122
+ repo["Project folders<br/>and worktrees"]
123
+ end
124
+ board -- "HTTP + WebSocket" --> api
125
+ api --> pg
126
+ hb --> pg
127
+ hb --> adapter
128
+ adapter -- "spawns" --> omp
129
+ omp -- "tool calls with a run token" --> mcp
130
+ mcp --> api
131
+ omp -- "reads and edits" --> repo
132
+ ```
133
+
134
+ - **Server**: Express 5 serves the API, the built board UI and the MCP endpoint on one port (3100 by default).
135
+ - **Embedded PostgreSQL**: created on first start under the instance directory and migrated with Drizzle; database backups run hourly by default into `data/backups`.
136
+ - **Board UI**: React 19, installable as a PWA, laid out for both phone and desktop.
137
+ - **`omp_local` adapter**: starts one `omp` process per agent run, streams its transcript to the board and caps how many local runs start at once, because OMP is memory-hungry while it boots.
138
+ - **MCP**: agents reach Wardmote through `POST /api/mcp/paperclip` with a run-scoped token. The tools are generated from the OpenAPI document; the default `core` toolset gives an agent 67 tools, and `?toolsets=core,extended` gives 483. Each tool carries an `agent` or `board` authority, so a `ceo` agent sees more than an engineer.
73
139
 
74
- The git path builds a GitHub commit from source. It needs pnpm 9.15.4, `git`, `curl`, `tar` and `corepack`, and takes minutes rather than seconds. Use it for development only:
140
+ ## Operations
141
+
142
+ Instance state lives under `~/.wardmote/instances/<id>/`: `config.json`, `service.env`, the database, logs, storage, secrets and backups. An install or update only writes under `~/.wardmote/cli/` and the shim; instance data survives switching payloads in either direction.
75
143
 
76
144
  ```sh
77
- wardmote install --ref main --yes
78
- wardmote install --repo tickernelz/wardmote --ref <commit-sha> --yes
145
+ wardmote service install
146
+ wardmote service status
147
+ wardmote service logs
148
+ wardmote service restart --drain
79
149
  ```
80
150
 
81
- `--repo` defaults to `tickernelz/wardmote`. `--ref` cannot be combined with `--version` or `--canary`.
82
-
83
- ### Upgrade and rollback
151
+ `restart` keeps live agent runs by default; `--drain` stops admitting new runs and waits for the live ones first. On Linux the systemd user unit is `paperclip-pro.service` for the `default` instance.
84
152
 
85
153
  ```sh
86
154
  wardmote update --check
@@ -88,44 +156,26 @@ wardmote update --latest
88
156
  wardmote update --rollback
89
157
  ```
90
158
 
91
- `update` backs up the database first, installs the new payload, restarts the active service and validates it; a failed validation rolls the payload back automatically. `--rollback` returns to the retained previous payload instantly — it does not reverse database migrations.
92
-
93
- ## Configuration
94
-
95
- Instance configuration lives in `~/.wardmote/instances/default/config.json` and is edited with `wardmote configure`, not by hand while the service runs. `wardmote doctor` prints the resolved paths, and `wardmote env` prints the effective environment.
96
-
97
- Operator environment — `PATH` entries for adapter binaries, provider API keys, proxy settings — belongs in `~/.wardmote/instances/default/service.env`, one `KEY=value` per line. The systemd unit sources it with `EnvironmentFile=-`, and the CLI never rewrites it, while the unit file itself is re-rendered on every CLI-driven start.
159
+ `update` backs up the database, installs the new payload, restarts the service and validates it; a failed validation rolls back automatically. `--rollback` returns to the previous payload; it does not reverse database migrations. `wardmote doctor` checks the setup, and `wardmote configure` edits the instance config.
98
160
 
99
- | Variable | Default | Bounds | Meaning |
100
- | --- | --- | --- | --- |
101
- | `PAPERCLIP_MAX_CONCURRENT_LOCAL_RUNS` | 20 | 1–64 | Total local CLI runs this controller may have running at once. Never bypassed. The three local run limits can also be set under Settings → General; a variable set here overrides that setting. |
102
- | `PAPERCLIP_MAX_CONCURRENT_LOCAL_STARTS` | 4 | 1–64 | Local CLI runs allowed to be in their startup phase at once. |
103
- | `PAPERCLIP_LOCAL_START_WAIT_BYPASS_SEC` | 120 | 1–3600 | A queued local run that has waited this long starts anyway, ignoring the startup cap but still inside the total cap. The same window bounds the startup phase, so a hung boot cannot block the gate forever. |
104
- | `PAPERCLIP_LOCAL_MEMORY_RESERVE_PERCENT` | 20 | 1–90 | Memory gate, shadow only: no start is delayed. Share of host RAM that must stay available after counting the runs still starting; the verdict is only logged. Also settable under Settings → General. |
105
- | `PAPERCLIP_LOCAL_MEMORY_GATE_COOLDOWN_SEC` | 120 | 1–3600 | Memory gate, shadow only. Seconds after a host or service OOM kill during which the logged verdict is "would hold". Also settable under Settings → General. |
106
- | `PAPERCLIP_RUN_OOM_SCORE_ADJ` | 500 | -1000–1000 | Linux only. `oom_score_adj` written to every local run child right after spawn, so the kernel OOM killer picks run processes before the server. Lowering below the server's own value needs `CAP_SYS_RESOURCE`; a failed write is logged once and never stops the run. An invalid value falls back to 500. |
107
- | `PAPERCLIP_PDF_CHROMIUM_PATH` | unset | — | Chromium-family executable used for PDF export. `PUPPETEER_EXECUTABLE_PATH` and `CHROME_PATH` are also consulted. |
108
- | `PORT` | 3100 | — | HTTP listen port; overrides `server.port`. |
109
- | `PAPERCLIP_HOME` | `~/.wardmote` | — | Root of all instance state. |
110
- | `PAPERCLIP_INSTANCE_ID` | `default` | — | Selects the instance under `PAPERCLIP_HOME/instances/`. |
111
- | `PAPERCLIP_TELEMETRY_DISABLED` / `DO_NOT_TRACK` | unset | — | Disables anonymous usage telemetry, which is on by default and off automatically when `CI=true`. `telemetry.enabled: false` in the instance config also disables it. |
112
-
113
- ## Running as a service
114
-
115
- ```sh
116
- wardmote service install
117
- wardmote service status
118
- wardmote service logs -f
119
- wardmote service restart --drain
120
- ```
161
+ Operator environment such as `PATH` entries for adapter binaries, API keys and proxies goes in `service.env`, one `KEY=value` per line; the CLI never rewrites it.
121
162
 
122
- The unit is `paperclip-pro.service` for the `default` instance and `paperclip-pro-<id>.service` otherwise; on macOS the launchd label is `ing.paperclip.paperclip-pro`. `--drain` waits for executing agent runs; without it, `stop` and `restart` refuse while runs are in flight unless forced.
163
+ | Variable | Default | Meaning |
164
+ | --- | --- | --- |
165
+ | `WARDMOTE_HOME` | `~/.wardmote` | Root of all instance state |
166
+ | `WARDMOTE_INSTANCE_ID` | `default` | Instance under `WARDMOTE_HOME/instances/` |
167
+ | `PORT` | `3100` | HTTP port, overrides `server.port` |
168
+ | `WARDMOTE_MAX_CONCURRENT_LOCAL_RUNS` | `20` | Local agent runs allowed at once (also under Settings → General) |
169
+ | `WARDMOTE_MAX_CONCURRENT_LOCAL_STARTS` | `4` | Local runs allowed in their startup phase at once |
170
+ | `WARDMOTE_LOCAL_START_WAIT_BYPASS_SEC` | `120` | A queued run that waited this long starts past the startup cap |
171
+ | `WARDMOTE_RUN_OOM_SCORE_ADJ` | `500` | Linux `oom_score_adj` for run processes, so the kernel kills runs before the server |
172
+ | `WARDMOTE_TELEMETRY_DISABLED=1` or `DO_NOT_TRACK=1` | unset | Turns off anonymous usage telemetry (already off under CI) |
123
173
 
124
- Day-two operation — state layout, safe restarts, backups, admin bootstrap, public hostnames, release mechanics, sandboxed test runs — is in [`docs/fork/OPERATIONS.md`](docs/fork/OPERATIONS.md).
174
+ Day-two operation, backups, public hostnames and release mechanics are in [docs/fork/OPERATIONS.md](docs/fork/OPERATIONS.md); observability (OpenTelemetry, Sentry) is in [doc/observability.md](doc/observability.md).
125
175
 
126
176
  ## Development
127
177
 
128
- Node 24.18.0 and pnpm 9.15.4 (`packageManager` in `package.json`). Work in a git worktree per change; never point a development instance at `~/.wardmote`.
178
+ Node 24.18.0 and pnpm 9.15.4 (`packageManager` in `package.json`). Work in a git worktree per change and never point a development instance at `~/.wardmote`.
129
179
 
130
180
  ```sh
131
181
  git clone https://github.com/tickernelz/wardmote.git
@@ -137,42 +187,25 @@ pnpm dev
137
187
  | Command | What it does |
138
188
  | --- | --- |
139
189
  | `pnpm dev` | API and UI in watch mode on `:3100` |
140
- | `pnpm dev:mobile` | Serves the prebuilt UI on `:3101` and proxies `/api` to `:3100` |
141
190
  | `pnpm build` | Builds every package |
142
191
  | `pnpm typecheck` | Type-checks every package |
143
- | `pnpm test` | Vitest, the default gate (no Playwright) |
192
+ | `pnpm test` | Vitest, the default gate |
144
193
  | `pnpm test:e2e` | Playwright browser suite |
145
194
  | `pnpm db:generate` / `pnpm db:migrate` | Drizzle migrations |
146
195
 
147
- Source development also builds the native Wardmote Runner when enabled (the self-hosted default). Install a Rust toolchain, or set `PAPERCLIP_RUNNER_BINARY` to a compatible prebuilt runner.
148
-
149
- Tests and manual trials must never touch a live instance. Use an isolated data directory:
150
-
151
- ```sh
152
- node cli/node_modules/tsx/dist/cli.mjs cli/src/index.ts test-drive --data-dir /tmp/pcpro-trial --no-browser
153
- ```
196
+ The native runner builds from Rust source when enabled; install a Rust toolchain for it. Tests and manual trials must never touch a live instance; [doc/DEVELOPING.md](doc/DEVELOPING.md) shows how to run one on its own data directory.
154
197
 
155
- Each run without `--data-dir` gets a unique, retained temporary directory; its absolute path is printed at startup. Pass `--data-dir` to reuse one, or `--no-browser` to leave the initialized instance unopened. When invoked from a linked Git worktree, `test-drive` also enables task execution in that worktree.
198
+ More in [doc/DEVELOPING.md](doc/DEVELOPING.md), [doc/INSTALLING.md](doc/INSTALLING.md) and the CLI reference [doc/CLI.md](doc/CLI.md). Bugs go to [this repository's issues](https://github.com/tickernelz/wardmote/issues).
156
199
 
157
- Section 8 of [`docs/fork/OPERATIONS.md`](docs/fork/OPERATIONS.md) documents the sandbox rules for suite runs. The full development guide is [`doc/DEVELOPING.md`](doc/DEVELOPING.md); installation details are in [`doc/INSTALLING.md`](doc/INSTALLING.md) and the CLI reference in [`doc/CLI.md`](doc/CLI.md).
200
+ ## Releases
158
201
 
159
- ## Release
160
-
161
- Pushing a `v<YYYY.MDD.P>` tag triggers `.github/workflows/release.yml`, which builds once, packs each package once, publishes the set under the `next` dist-tag in dependency order, waits for npm to expose all of it, moves `latest`, and opens a GitHub release.
202
+ Pushing a `v<YYYY.MDD.P>` tag runs [`.github/workflows/release.yml`](.github/workflows/release.yml): it refuses a tagged commit that is not on `main` or has no green CI run, builds once, publishes the package set under the `next` dist-tag in dependency order, moves `latest` once npm serves all of it, and opens a [GitHub release](https://github.com/tickernelz/wardmote/releases). `scripts/tag-release.sh` picks the next free version and checks the same conditions before it pushes the tag.
162
203
 
163
204
  ```sh
164
205
  ./scripts/tag-release.sh --dry-run
165
206
  ./scripts/tag-release.sh
166
207
  ```
167
208
 
168
- `scripts/tag-release.sh` resolves the next free version, refuses a version whose tag already exists, and refuses to tag a commit whose `ci.yml` run is not green. The release job re-checks both: the tagged commit must be reachable from `origin/main` and must have a successful CI run. Reruns are idempotent, so a partial publish can be resumed. Section 9 of [`docs/fork/OPERATIONS.md`](docs/fork/OPERATIONS.md) has the dispatch inputs and the npm token setup.
169
-
170
- ## Observability
171
-
172
- OpenTelemetry tracing activates when `OTEL_EXPORTER_OTLP_ENDPOINT` is set; the SDK, auto-instrumentation and exporter packages are optional peer dependencies. Sentry activates with `SENTRY_DSN_BACKEND` and `SENTRY_DSN_FRONTEND`. See [`doc/observability.md`](doc/observability.md).
173
-
174
209
  ## Licence and attribution
175
210
 
176
- MIT. Upstream work is copyright Paperclip Labs, Inc ([paperclip.ing](https://paperclip.ing)); fork modifications are copyright the wardmote maintainers. Both notices are in [`LICENSE`](LICENSE).
177
-
178
- Upstream project, for reference only — do not file fork bugs there: [`paperclipai/paperclip`](https://github.com/paperclipai/paperclip), [docs.paperclip.ing](https://docs.paperclip.ing).
211
+ MIT, see [LICENSE](LICENSE). Wardmote is a **hard fork** of [paperclipai/paperclip](https://github.com/paperclipai/paperclip), branched at upstream commit `7b7c4d417` and developed separately since. Upstream work is copyright Paperclip AI; the fork's changes are copyright Zhafron Adani Kautsar. Both notices are in [LICENSE](LICENSE). Wardmote is not an upstream release and is not endorsed by the upstream authors, so please file Wardmote bugs here, not upstream.