193 lines
9.5 KiB
Markdown
193 lines
9.5 KiB
Markdown
# Facts about this machine, checked 2026-11-09
|
|
|
|
Everything here was measured with a command. Anything not measured is marked unproven.
|
|
|
|
## Paperclip
|
|
|
|
- Running locally: `http://127.0.0.1:3100`. Public UI: `https://paperclip.lab.audasmedia.com.au`.
|
|
- Company: `d4921013-e5da-4d88-8016-57d5746e2d03`
|
|
- Agents, all running the Pi adapter (`pi_local`), all idle:
|
|
- `Hub` — `108c6220-c9e1-4b62-9e0a-6a763e0d28fd` (this is the identity of `PAPERCLIP_API_KEY`)
|
|
- `Builder` — `403de1f7-645c-4d35-bc7e-19b01d77bacc`
|
|
- `Chief of Staff` — `232f1f9e-bac0-4185-8a0e-eddbead33e04`
|
|
- `Documenter` — `706ffc88-120f-46c4-a5d9-ffa12e2ad5f0`
|
|
- `researcher` — `a6a2c0ee-570e-4f89-a977-83136b534a2f`
|
|
- `System` — `fe7a1881-1df9-481b-af74-87292fef288c`
|
|
- Writes need the user key: `PAPERCLIP_BOARD_KEY`. The agent key `PAPERCLIP_API_KEY` is
|
|
refused with 403 outside a heartbeat run.
|
|
- Blockers live at `GET /api/issues/{id}/diagnostics/blockers`, **not** on the task list.
|
|
|
|
## The sandbox project
|
|
|
|
- `spike-2026-11-09` is **archived**: status `cancelled`, renamed
|
|
`spike-2026-11-09 (deleted)`, id `9e3f61f6-cce9-49b1-8083-3130345a04a5`.
|
|
- `DELETE /api/projects/{id}` returned 500, so it was archived instead. Its two tasks
|
|
(`AUD-157`, `AUD-158`) remain inside the archived project. **Deleting an archived project
|
|
is still untested.**
|
|
- Its scratch repo `/tmp/pc-sandbox` was removed.
|
|
- To make a fresh sandbox, use the payload recorded in `PAPERCLIP-API-NOTES.md`:
|
|
`POST /api/companies/{companyId}/projects` with `name`, `status: "backlog"` and
|
|
`workspace: { name, sourceType: "git_repo", cwd, isPrimary: true }`.
|
|
|
|
## Does a heartbeat wake an agent? PROVEN, 2026-11-10
|
|
|
|
It does, and the wake is not a timer. Assigning a task woke `Builder` within one tenth of
|
|
a second, with no call to `heartbeat/invoke`.
|
|
|
|
Measured on `spike-2026-11-10` / `AUD-159`:
|
|
|
|
```
|
|
00:01:24.891Z PATCH /api/issues/AUD-159 {"assigneeAgentId":"403de1f7-..."} -> 200 todo
|
|
00:01:24.937Z wake request recorded: source=assignment reason=issue_assigned
|
|
00:01:25.036Z run aae77e89-... claimed, adapter pi_local, issue -> in_progress
|
|
00:01:51.351Z agent comment posted (commit b093301)
|
|
00:01:53.153Z issue -> done
|
|
00:01:59.377Z run -> succeeded
|
|
```
|
|
|
|
So the four documented wake sources all reach an agent: a timer tick, an assignment or a
|
|
new comment on its own task, a person clicking wake, and a routine firing. The timer is
|
|
opt-in and is off for most agents; `Builder` currently has `heartbeat.enabled: true`, so
|
|
it also polls. Assignment alone is enough.
|
|
|
|
`POST /api/agents/{id}/heartbeat/invoke` was never needed and remains untested. The
|
|
documented manual wake is `POST /api/agents/{id}/wakeup` with
|
|
`{"source":"on_demand","triggerDetail":"manual","forceFreshSession":...}`.
|
|
|
|
A wake can still be refused without any error reaching us. Read
|
|
`GET /api/issues/{id}/diagnostics/wakes` — it shows each wake request, its claimed run,
|
|
and a plain-English diagnosis. Refusal reasons seen in the documentation: the agent is
|
|
paused, its budget is exhausted, its cooldown has not elapsed, or its run slot is full.
|
|
|
|
## Isolated workspaces: switched on 2026-11-10, and measured working
|
|
|
|
The instance first had them off. With the flags off, the project's request for a git
|
|
worktree per task was silently ignored: `AUD-159` worked in `/tmp/pc-sandbox-2026-11-10`
|
|
on `main`, and the task's `executionWorkspaceId` read `null`.
|
|
|
|
Then, with the person's approval, two experimental settings were switched on:
|
|
|
|
```
|
|
PATCH /api/instance/settings/experimental
|
|
{"enableIsolatedWorkspaces": true, "enableWorktreeRunExecution": true}
|
|
→ 200
|
|
```
|
|
|
|
`enableIsolatedWorkspacesByDefault` was deliberately **left off**. That flag would give
|
|
every project without a policy of its own a worktree, which would change the other nine
|
|
projects on this instance. Only projects that ask for one now get one.
|
|
|
|
The next task (`AUD-160`) made a real worktree, and Paperclip posted a "Workspace Ready"
|
|
comment on the task naming it:
|
|
|
|
```
|
|
strategy git_worktree
|
|
branch AUD-160-milestone-1-t2-read-hello-txt
|
|
cwd /tmp/pc-sandbox-2026-11-10/.paperclip/worktrees/AUD-160-milestone-1-t2-read-hello-txt
|
|
baseRef main
|
|
deliveryState merged_by_ancestry (no commit was needed; the branch equals main)
|
|
```
|
|
|
|
`git worktree list` in the sandbox repository shows that path on that branch. So the
|
|
worktree is Paperclip's job after all, once the instance allows it, and the terminal
|
|
program never needs to run `git worktree` itself.
|
|
|
|
## Fonts, 2026-11-10
|
|
|
|
Measured, because the answer was "I thought I had installed them":
|
|
|
|
- No Nerd Font was installed (`fc-list | grep -i nerd` returned nothing) and no JetBrains
|
|
Mono either. Ghostty ships a plain JetBrains Mono of its own, which is why a terminal can
|
|
look right while every icon renders as a box.
|
|
- Starship is **not installed**, and there is no `~/.config/starship.toml`.
|
|
- TUIOS has four glyph sets — `ascii`, `default`, `heavy`, `unicode` — and `default` is
|
|
active, which is ordinary Unicode, not Nerd Font icons.
|
|
- TUIOS has 30 themes including six Catppuccin variants, and **no look is applied**:
|
|
`tuios look show` says "No look is applied". The session is not on Catppuccin.
|
|
|
|
What was changed:
|
|
|
|
- `fonts.packages = [ nerd-fonts.jetbrains-mono ]` and `fonts.fontconfig.enable = true` in
|
|
`/etc/nixos/configuration.nix`, so every machine built from this flake gets it: `.13`,
|
|
`.27`, `.51`. `nix build --dry-run` evaluates and wants
|
|
`nerd-fonts-jetbrains-mono-3.4.0+2.304`. **The rebuild is still to be run** (`sudo`
|
|
needs a password here).
|
|
- `~/.config/ghostty/config` sets `font-family = "JetBrainsMono Nerd Font"`.
|
|
- Rebuilt by the person on 2026-11-10: `fc-list | grep -ci nerd` now returns 96, and
|
|
`JetBrainsMonoNerdFont-Regular.ttf` is present in the store. The font is installed on
|
|
`.13`; `.27` and `.51` get it from the same flake on their next rebuild.
|
|
- The theme is now set: `theme = 'catppuccin_mocha'` in `~/.config/tuios/config.toml`.
|
|
`tuios set-config` refused for the running session ("would change this machine, not the
|
|
session"), so the running session keeps its old chrome until it is restarted.
|
|
|
|
## Toolchain
|
|
|
|
- **Go is installed** (2026-11-10), by `nix profile install nixpkgs#go` → `go1.26.5` at
|
|
`/home/sam/.nix-profile/bin/go`. That is the quick path: it works now, and it is not part
|
|
of the system closure.
|
|
- The durable path is also prepared: `go` and `gopls` were added to
|
|
`environment.systemPackages` in `/etc/nixos/configuration.nix`. `nix flake check` passes
|
|
and the dry-run build evaluates. **The rebuild has not been run**, because `sudo` needs a
|
|
password here. One command finishes it: `sudo nixos-rebuild switch --flake /etc/nixos#nixos-desktop`.
|
|
Until then the profile copy is what runs.
|
|
|
|
## The new repository
|
|
|
|
- Local git repo only, one commit, no remote. It is not on Gitea. Push it somewhere before
|
|
relying on it, or accept that only this machine has it.
|
|
|
|
## NixOS alignment for Pi, measured 2026-11-12
|
|
|
|
Goal: the same Pi on all three machines. `pi-coding-agent` comes from nixpkgs, so aligning used to
|
|
mean bumping the whole system on each machine. That is what broke `.13`: `nixos-rebuild switch`
|
|
restarts every changed unit in place, the network units restarted, the default route did not come
|
|
back, and every service that needs the network died with it. Exit code 4 meant "units failed to
|
|
start", not "the build failed" - the generation had already switched.
|
|
|
|
**The rule that follows: on a machine someone is using, a nixpkgs-sized change goes in with
|
|
`nixos-rebuild boot` and a reboot, never `switch`.**
|
|
|
|
### What was done instead, and why it is safe
|
|
|
|
Pi is one package. Instead of moving a whole system to a new nixpkgs, a second flake input pinned
|
|
to one revision provides only that package:
|
|
|
|
```nix
|
|
nixpkgs-pi.url = "github:NixOS/nixpkgs/f4a03c008967841f2a0b3cb7c436fc6fc31671f6";
|
|
# in the let block
|
|
piPkgs = import nixpkgs-pi { inherit system; config.allowUnfree = true; };
|
|
# in home-manager users.${user}.home.packages
|
|
piPkgs.pi-coding-agent
|
|
```
|
|
|
|
and `pi-coding-agent` was removed from `home/sam/home.nix` so exactly one `pi` is on `PATH`. The
|
|
system pin on those machines did not move, so nothing else in the system changes and no network or
|
|
service unit is restarted. Remove the input once the system pins are aligned for real.
|
|
|
|
### State, verified by building, not switching
|
|
|
|
| machine | method | pi in the built system | store path |
|
|
|---|---|---|---|
|
|
| `.13` nixos-desktop | full nixpkgs bump (2026-11-07), **running** | 1.5.0 | `4yxlfj0sw5hlk7x1hiv0igm0dckg8rv9` |
|
|
| `.27` sam-4screen-desktop | `nixpkgs-pi` input, built, **not yet switched** | 1.5.0 | `4yxlfj0sw5hlk7x1hiv0igm0dckg8rv9` |
|
|
| `.51` sam-thinkpad | `nixpkgs-pi` input, built, **not yet switched** | 1.5.0 | `4yxlfj0sw5hlk7x1hiv0igm0dckg8rv9` |
|
|
|
|
One store path on all three: the same bytes of Pi, not merely the same version number.
|
|
|
|
### Two other things measured on the way
|
|
|
|
- `programs.zsh.initExtra` is `initContent` in home-manager 2026-11. Both names evaluate on the
|
|
older home-manager, so the rename is safe in either direction.
|
|
- **lan-mouse 0.11.0 panics** when `LIBGIT2_NO_VENDOR` is set and no system libgit2 exists; nixpkgs
|
|
2026-11-07 sets it. An overlay on `pkgs.lan-mouse` does **not** help. Building the flake's own
|
|
package with the variable off does:
|
|
|
|
```nix
|
|
lm = lan-mouse.packages.${system}.default.overrideAttrs (o: { LIBGIT2_NO_VENDOR = "0"; });
|
|
```
|
|
|
|
`.13` now lists `lm` in `systemPackages` instead of `lan-mouse`.
|
|
- `.27`'s full-system bump failed in `home-manager.users.sam.fonts.fontconfig.configFile.fonts.settings`
|
|
(`recursiveUpdateUntil` / `head values`). The `nixpkgs-pi` route avoids it entirely; it is still
|
|
an open item for the day the system pins are aligned.
|