Files
obsidian-vault/010 inbox/Paperclip board — operator notes and key model.md

5.4 KiB
Raw Blame History

type, proposed_folder, proposed_toc, proposed_tags, confidence, approved, proposed_for, created, tags, aliases, modified
type proposed_folder proposed_toc proposed_tags confidence approved proposed_for created tags aliases modified
note 200 projects/210 AI Resume 100 Table of Contents/Projects.md → AI Resume
ai-resume
board
operator
paperclip
keys
0.92 false 61e258687cd8 2026-10-26 20:05
paperclip
ai-resume
board
keys
2026-10-26 20:05

Paperclip board — operator notes and key model

Written after a failed board build on the Ai Resume project. The purpose is that nobody, human or agent, repeats it.

Two key types, and they are not interchangeable

  • Board key — prefix pcp_board_. This is Sam as operator. Creates, links, reassigns and deletes tasks. Can read agent configuration. Held in PAPERCLIP_BOARD_KEY.
  • Agent key — prefix pcp_. This is one named agent (Hub, Builder, System, Documenter, researcher, Chief of Staff). Works its own task and comments on it. Cannot write to other tasks — it returns Cross-issue writes need a run to attribute them to. Held in PAPERCLIP_API_KEY.

Both live in ~/.config/environment.d/10-secrets.conf. Do not put a board key in PAPERCLIP_API_KEY; agents expect that name to be an agent identity.

Machines carrying the board key: .13 (host), .27, .51. One key works on all of them because it belongs to the user, not the machine.

Minting a board key

There is no settings page for this. Board keys are created through a CLI auth challenge and approved in a browser that already has a session.

curl -s -X POST http://127.0.0.1:3100/api/cli-auth/challenges \
  -H 'Content-Type: application/json' \
  -d '{"command":"paperclipai connect --persona board --token-name operator","requestedAccess":"board"}'

The reply contains boardApiToken (inactive until approved) and approvalPath. Open the approval URL on the public hostname, not localhost:

https://paperclip.lab.audasmedia.com.au<approvalPath>

Approve, then confirm with GET /api/cli-auth/me. It should return "source":"board_key".

Do not use paperclipai connect interactively for this. It asks for an email and password first, and that is the step that fails.

The rule that broke the board

Never create a task and assign it in one action.

An assigned task is claimed by that agent's run within seconds. Paperclip then locks field writes to that run, so every other writer — including the board — gets 409 issue_write_assignee_run_lock. The dependency links then never get written, and the graph silently does not exist. Every task looks ready; they all start; phases run out of order.

Correct order, always:

  1. Create the task unassigned.
  2. PATCH blockedByIssueIds in a separate call.
  3. Assign.
  4. Verify.

blockedByIssueIds passed at creation is silently ignored. It must be PATCHed afterwards, and the PATCH response is the proof — the list endpoint does not return the field.

An agent cannot do steps 1–3 reliably. The operator does. Never instruct an agent to "decompose and wire the plan".

Where the agents' instructions actually live

/home/sam/.paperclip/instances/default/companies/<companyId>/agents/<agentId>/instructions/AGENTS.md

Read these before designing work for an agent. The Chief of Staff's own file says "create a child task, assign it, and set blockedByIssueIds" — in that order — which is the unworkable sequence above. Any instruction that says this will fail the same way every time.

When agents go silent

Check heartbeats. All six agents were created with heartbeat.enabled = false, so nothing advances between direct assignments.

curl -s -X PATCH -H "Authorization: Bearer $PAPERCLIP_BOARD_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"runtimeConfig":{"heartbeat":{"enabled":true,"maxConcurrentRuns":20}}}' \
  http://127.0.0.1:3100/api/agents/<agentId>

Builder, System and Documenter are now on. Hub, researcher and Chief of Staff are deliberately off — a coordinator that wakes with no job invents one.

Failure mode to never repeat

Never schedule a monitor to wait on your own failed write. A monitor that re-checks a condition which cannot change re-wakes the agent forever. That is what turned a one-off 409 into a loop of runs, each burning seventeen minutes and ending in execution_finalization_deadline_exceeded.

If a write returns a run-lock: report it and stop.

The board as it stands (2026-10-26)

  • AUD-140 — parent, holds the build brief
  • AUD-141 — content source of truth — done, 40 documents, make validate passing
  • AUD-142 — site skeleton and pages — in progress
  • AUD-143 — deploy to the server — waits on 142
  • AUD-144 — searchable index — waits on 141 and 142
  • AUD-145 — AI question box and safety rules — waits on 143 and 144

Working directory: /home/sam/paseo/projects/resume_ai_system_paperclip_build, which is the git working copy of sam/ai-resume.

What actually sources the content pipeline

Only content/ in that repository. Nothing in this vault is read by the pipeline, and nothing in Outline or Vikunja is either.

That is deliberate for now: one source, so the pages and the AI corpus cannot drift. Obsidian is the obvious second source later — but it should be an allow-list of chosen notes, never the whole vault, because the vault contains family and personal material.

Outline and Vikunja being offline does not block anything. No part of the build depends on them.