Pipebrain

How work moves from intent to done, and where a person has to decide. Product repositories point their agents at this page.

Delivery Workflow

Status: v11 · August 2026 (decision records live in the ledger’s decisions module — create_decision + decision_links — rather than as repo ADRs; the builder’s first read is get_work_context; the closing report’s Needs you: line gained the blocker and approval outcomes; the wiring checklist names the end-to-end harness in place of the retired acceptance suite. v10 made the header three fields written by a second call, set_issue_header; v9 gave acceptance criteria to work of any kind — an epic, a task and a bug alike) Audience: Operators and Claude Code agents working in product repositories. Link this document from every product repo’s CLAUDE.md. Also consumed by: the build of Pipebrain itself. This document and the in-app /help page are the living source of truth for the MCP tools referenced here; their names, statuses, and semantics match the Pipebrain MCP server exactly.


Division of labor

Two agent roles appear in the build loop: the builder (implements an epic) and the evaluator (a separate session that reviews the builder’s work).

The workflow at a glance

#StageModeGate to proceed
0Project inceptionManual + AI-assistedFoundational requirements approved
1Establish the source of truthManual + AI-assistedOperator: the source meets all user expectations
2Derive requirements from the sourceAI
3Review requirementsManualapprove_requirement on every touched document
4Slice into epics with linked requirements + criteriaAIOperator adjusts slices/criteria on the feature epic
5Build loop until greenAI (builder + evaluator)Evaluator clean + every auto criterion passed with evidence → verify (server-enforced)
6Verify against the criteria checklistManual where a criterion is manual, else AIAll criteria passed and every child closed → done (server-enforced)

Stage 0 runs once per project (revisited rarely); Stages 1–6 run per feature. Everything is markdown. Every issue lives in a project and an environment — feature work is created in dev (agents pass environment=dev explicitly, as Stages 1 and 4 do); bugs and feedback carry the environment where observed. An omitted environment resolves server-side to the parent issue’s environment when there is a parent, else the project’s default environment (prod); the dev convention is honored by passing it explicitly, not by a server rule. Requirements are project-scoped and carry no environment — they describe the product.


Stage 0 — Project inception (once per project)

When a project is created in Pipebrain — or Pipebrain is adopted for an existing product — author the foundational requirements before any feature work: product vision, hard constraints (legal, privacy, platform), non-functional requirements, and the conventions that bind everything (error-message standards, theming rules, accessibility bars). For an adopted product, derive these from what already exists (the running product and its code) rather than inventing them.

Cross-cutting documents need no links, ever. They are automatically part of every agent’s context — get_issue includes them at the latest approved revision (deliberately unpinned: constraints always apply in their current form). Everything downstream — mocks, slices, builders, evaluators — is bound by them.

Gate: the foundational documents are approved. Stage 1 designs against them.

Stage 1 — Establish the source of truth

Before any feature requirements are written — and within the Stage 0 constraints — establish the source of truth the requirements will be derived from. It is exactly one of:

In Pipebrain, create the feature epic — the anchor for everything that follows. Creating an issue takes two calls, and this is the first of them:

create_issue(type=epic, project, environment=dev, title="Feature: <name>", body=<intent + source location>)

set_issue_header(issue=<the new display id>, summary=<the change, one sentence>, why=<the reason a person cares>, affectedSurfaces=<what this touches, and who feels it>)

The feature epic carries no criteria of its own; it exists to parent the slices.

The header is a second call, and cannot be folded into the first. An issue’s header — summary, why, affectedSurfaces — is three fields on the issue rather than prose at the top of its body, and set_issue_header is the only way to write them. Pass any of the three to create_issue, update_issue, promote_feedback or promote_deliverable and the call is refused, naming the field, instead of dropping it silently. Two things make that refusal worth its friction:

The header records which body it was written from, so editing the body afterwards marks it stale: every read of the issue carries headerStale, and the needsHeader filter selects on the same comparison. Rewrite it with the same call. Issues written before this existed keep the header prose already sitting in their bodies — the two calls are how the next issue is written, not an instruction to rewrite the corpus.

Gate: the operator judges the source complete — it captures the intended experience — and says so in a comment.

Stage 2 — Derive requirements from the source (AI)

Derive requirements from the established source exhaustively: every screen, state, interaction, empty and error path, and the non-functional constraints the source implies (performance, offline behavior, permissions). How you derive depends on the source:

Requirements are project-scoped living documents in Pipebrain, organized by product area — not one document per feature. For each area the feature touches:

Check list_requirements before creating — extend existing documents rather than fragmenting. Foundational and cross-cutting documents from Stage 0 rarely change here; feature work usually amends area documents. Finish with add_comment on the feature epic listing the requirement display IDs touched (e.g. Touches DWB-R3, DWB-R7 (new)).

Stage 3 — Review requirements (Manual)

The operator reads and edits the documents in Pipebrain (each edit appends a revision). Cut scope here, not in code.

Gate: approve_requirement on every touched document — this pins the revision everything downstream builds against. Agents must not proceed while any touched requirement is unapproved or amended-past-approval (get_requirement exposes the lifecycle).

Stage 4 — Slice (AI)

Decompose the approved requirements into cross-cutting slices: each slice is a vertical cut through UI, API, and data that delivers independently testable behavior. Never slice by layer (“the database part”) or by component.

Sizing: one focused builder session per slice — roughly half a day of human-equivalent work. Split anything larger.

For each slice, create it born with its contract:

create_issue(
  type=epic, parent=<feature epic>, status=backlog, environment=dev,
  title, body=<scope + explicit out-of-scope + ordering dependencies in prose>,
  milestone=<if the project tracks one, e.g. "M1">,
  requirement_links=[<touched requirement ids>],      ← pins each at its approved revision
  criteria=[<{text, verification, howTo}, ordered>]   ← itemized, individually checkable
)

Then write the slice’s header, which create_issue will not accept:

set_issue_header(issue=<the new display id>, summary, why, affectedSurfaces)

The criteria ride the create call; the header cannot. Criteria are the contract, and a slice created without them has nothing to build against, so they go in at creation. The three header lines are what the operator reads at this stage’s gate when deciding whether the cut is right, so they are written separately and in plain words — Stage 1 carries the whole reason. Write the header as soon as the slice exists; a slice that reaches the gate without one makes the operator open every child to see what the cut was.

Link, don’t copy. Requirement content is never pasted into epic bodies — links pin the approved revision, and agents fetch it with get_requirement. Copies drift; links don’t. Never add requirement_links to cross_cutting documents — they are in every agent’s context automatically.

Criteria are the contract. An epic, a task and a bug each carry criteria — the one kind that cannot is feedback, which is retyped into work (promote_feedback) before anything is built. Each criterion is one observable, verifiable behavior (“A status-changed event regenerates the page’s public JSON, debounced per account”) — not an implementation step. Each receives a stable id (AC-1, AC-2, …) at creation that survives reordering — tests, bugs, and evidence reference <ISSUE-KEY>/AC-{n}. Before assigning any mode, establish what this project can drive: look for an end-to-end test harness and the command that runs it, and name both in the epic body — if the project has none, say so in the body. Then tag each criterion with its verification mode: auto when an evaluator can drive the input and read the result against the running system (a row written to the database, an HTTP response shape, a generated artifact, or behavior in the interface wherever that harness exists); manual when the verdict itself needs a person’s judgment (whether a screen matches its design, whether the copy reads well, whether the flow feels right). The mode follows from what the project can drive, not from where the behavior appears, so a criterion is never manual merely for being visible. What qualifies a criterion as auto is the evaluator’s own run against the running system, never the existence of a test the implementer wrote. A criterion you cannot describe as drivable is usually worded too vaguely for anyone to check: reword it against the observable rather than marking it manual. Every manual row holds its issue open until a person sits down with it, so a row a machine could have checked spends the attention the rows that genuinely need judgment were meant to get. Every manual criterion also carries howTo: one or two sentences saying where to look, what to do, and what counts as passing, written for whoever checks it in Stage 6. An agent that writes or changes a manual criterion without it is refused, and instructions on an auto criterion are refused too — a machine checks that one. Criteria are the whole contract: they are the builder’s spec, the evaluator’s verification list, and the operator’s final checklist. Nothing else gates the work that carries them, which is why the Stage 4 review is the reading with the most riding on it.

Gate: the operator reviews on the feature epic — its slices, statuses, and each slice’s criteria expanded in place. Merge, split, re-scope, and edit criteria directly there.

Stage 5 — Build loop (AI)

The operator starts a builder session per epic in the product repo. (V2: a local runner may start these headlessly; the protocol is unchanged.)

Builder protocol

  1. Gather context — one read: get_work_context with the item’s display id returns the full issue detail, the body text of every linked requirement at its pinned revision, the project’s cross-cutting requirements at latest approved, the binding guidance, and the placement: the branch, base and worktree already resolved. get_issue (paged reads of a long body or an older comment window) and get_requirement (a specific other revision) are follow-ups for what the pack capped, not the first call.
  2. claim_issue naming that branch and worktree — or, where the repository’s own instructions dictate one branch with no worktrees or the branch you are given is the base itself, the branch and tree you will actually use, so the record says where the work really is → set_status(in_progress). Naming them is what reserves them: a claim is refused placement_conflict when another live claim in the project already holds either. Reading before claiming is the order that works — a second claim on work you already hold is refused.
  3. Work on the branch and worktree you reserved, in a working tree of your own. The doctrine’s “A branch and a worktree are derived from the issue” states how each is derived, when a working tree is created rather than reused, and how the work leaves the branch once it is green: a pull request, a merge into the base, or neither, as the project’s settings say and the repository’s own instructions may override.
  4. Implement against the criteria; write and run the tests that prove them; iterate to green.
  5. add_comment with a handoff summary: what changed, how each criterion is satisfied and what proves it, and anything that smells. The “what smells” half is the part worth writing — it is knowledge that exists exactly once, in the session that just ended.
  6. add_comment("Ready for evaluation") and stop. The builder never sets a criterion state — author ≠ implementer ≠ evaluator: whoever specified the contract, whoever built against it, and whoever grades it are three roles, and the middle one owns no verdicts.

Questions — how an open decision reaches the operator

Evaluator protocol (a separate session — never the builder)

End-of-turn report. Every builder and evaluator session ends with exactly these two lines, and nothing else:

<ITEM-KEY> -> <new status>
Needs you: <one of: nothing | answer Q-n | answer the blocker on <KEY> | approve <proposal> | verify AC-n, AC-m>

answer Q-n names a question only the operator can settle. A question your own work settled you answer yourself, so it never reaches this line. verify AC-n names manual criteria only — the auto rows you drove carry their evidence already, and an item with no manual row left owes nothing here.

No blockquotes. No headings. No summary of what was done: the status change and the criterion evidence are the report. No sections titled notes, caveats, observations, things to know, or next steps. Do not read requirement or criterion text back — the operator has it one click away. If something does not fit in the two lines above, it belongs in a record, not in this reply. When nothing fits and nothing was filed, that is a complete and correct report.

This governs the closing report only. It does not restrict what a session says while it is working, and it does not shorten what goes into an issue body, a comment, or a decision record.

Hard rules for all agents

Amending the contract (humans, with one agent exception): the operator edits the criteria with set_criteria, on whichever piece of work carries them — an epic, a task or a bug. That the list is the operator’s is a convention rather than a refusal: set_criteria takes an agent’s call like any other. Editing a criterion’s text or verification mode resets its state, so the issue falls back out of the verify gate and the evaluator must re-verify it — which is the point. Those two fields are the whole list: rewriting a criterion’s howTo changes how it is checked, not what it asserts, so a criterion already marked passed stays passed with its original attribution. A criterion added mid-verification blocks done until it passes; that is how discovery fold-in stays honest. The exception is the evaluator raising a manual criterion to auto after driving it, above — it raises without asking and never lowers. Without that carve-out, an agent that automated a check would have to leave the criterion still saying a person has to do it by hand.

Stage 6 — Verify against the checklist

The operator opens the feature epic and exercises each slice against the mock, the linked requirements (one click away in the slide-over), and the criteria:

The feature epic goes done when every slice is done and an end-to-end pass over the whole feature holds up.

The completion review (epic close)

Every criterion has passed and nothing is left to check — which is the first moment the work can be read as one thing. The completion review is that reading. It runs after the epic’s criteria have all passed and before anyone sets it done, and a third fresh session runs it: not the builder that wrote the code, not the evaluator that checked each pass. Three roles, three contexts.

What it reads is the epic’s whole accumulated change as one body of work — every commit and every record that references it — never a single iteration’s diff. That is the first of three things separating it from the build loop’s evaluator. The second: it runs once the contract is green, so it is free to look for what no criterion ever asked about. The third: what comes out of it is filed work, not a verdict comment.

open_review opens one{epic: <ISSUE-KEY>}, or {project, milestone} for the milestone form, exactly one of the two and never both. Either way it creates an ordinary task at ready carrying this checklist as its body. The epic form titles it Completion review — <ISSUE-KEY> <epic title> and files it as a child of the epic, inheriting its milestone; the milestone form titles it Completion review — milestone <token>, files it under no parent, and carries the token instead — nothing here models a milestone as complete, so that review is simply the same task with a token on it.

Read <EPIC>'s whole accumulated change as one body of work — every commit and record that references it — and judge it as a reviewer who did not build any of it.

- [ ] The change holds together as one design: no half-applied rename, no two patterns doing the same job introduced by different children.
- [ ] What the criteria never covered: error paths, permissions, isolation, concurrency, and the surfaces the children touched only incidentally.
- [ ] The published words still tell the truth about what shipped: README, help page, workflow and requirements documents, tool descriptions.
- [ ] The tests: nothing was weakened along the way, and the suite still fails when each invariant this work introduced is violated.
- [ ] Residue: leftover flags, dead code, stale comments, and TODOs introduced by this epic's own children.

File each finding as ordinary work — a child of <EPIC>, bug or task by the usual bar — so it holds the epic open until it is done or killed. Findings are siblings of this review, never its children: the done gate reads one level deep. Killing this review, or any finding, is the recorded waiver — deliberately ungated, written to the status history with who did it. When nothing is found, set this task done with a comment saying what was read.

What comes out of it, and what holds it. Each finding is filed as ordinary work, a child of the epic — a sibling of the review, one level deep, because that is the depth the done gate reads. Nothing new gates anything: the children clause that was already there is what holds them, and the epic cannot reach done while one of them is still open. Killing the review, or a finding, is the recorded waiver — ungated on purpose, and written to the status history with the actor who did it, so a waived finding is a decision on the record rather than a silence. No new refusal was added. An epic that never had a review closes exactly as it did before: the review earns its place by being run, not by being required.

Where the epic’s status ends up. Filing a finding under the epic moves the epic to in_progress, from whatever status it held, and writes that move to the epic’s status history under whoever filed the finding. That history row is the whole record of it: no notification is sent, and nothing else marks it. The move changes only the status — it gates nothing and refuses nothing, which is why the paragraph above still holds. It happens because the epic is being built again, and one left at verify would go on asking a person to judge work the review has just shown to be unfinished, while sitting in the waiting queue for that judgment.

Three cases leave the epic’s status alone. First, opening the review itself: open_review files its task under the epic and leaves its status alone, because the review is the gate the epic is waiting at, and an epic that left verify the moment a third reading was asked for would drop out of the waiting queue before the reading had happened. Second, a done or killed epic: it refuses an open child outright, so no finding can reopen closed work — reopen the epic deliberately, or file the work as its own item. Third, an epic that could not legally start — one that is blocked, or one carrying no milestone, which every status but triage and killed requires: it keeps the status it has and takes the finding anyway, so a finding can still be filed against blocked or unscheduled work. A finding that arrives already done or killed moves nothing either, since only open work restarts an epic. Nothing moves the epic back once the findings close: it sits at in_progress until someone moves it on, so closing it is always a deliberate act rather than something that happens on its own.


Folding in discoveries (during Stage 6 — or any time)

Verification surfaces things the mock and requirements missed. Capture without breaking flow: create a child task in triagecreate_issue(type=task, parent=<epic>, status=triage, title="Discovered: <what you saw>"), which inherits the parent epic’s environment since none is passed — and keep verifying. A capture like this has no header yet; writing one mid-verification is the interruption this step exists to avoid, so it stays in list_issues(needsHeader: true) until triage gives it one. Then triage each discovery into exactly one of three paths:

  1. Defect — the existing contract is violated. Retype to bug (parent epic, environment where observed) and run the normal fix loop. No requirements change.
  2. Missed criterion — the requirement covered it, but the contract didn’t. Add the criterion where that contract lives (set_criteria) — the epic, or the task or bug whose behavior it describes — and extend the tests to cover it. The guards already cohere: the new criterion arrives pending, so it blocks verify if it is auto and blocks done either way, until the evaluator confirms it with evidence.
  3. Genuinely new requirement — new scope, not a gap in the old contract. Amend the requirement document (a new revision), review, re-approve. Then spawn a new slice epic linked at the new revision and run a mini Stage 4→6 on it. Existing epics linked at the older revision show the staleness badge — decide per epic whether it matters.

The reopen rule: an epic at verify or earlier can absorb new criteria; an epic at done never reopens. New scope after done becomes a new epic — this keeps done meaning done, and keeps the activity log honest. (This is a workflow rule, not a server guard — genuine mistakes can still be corrected.)

Decisions along the way: when a discovery forces a choice with a real tradeoff, record it with create_decision, one decision per record, and attach it to the work it governs with decision_links on update_issue (or update_requirement, for a requirement it informs). A proposed record is still being written: correct it with update_decision and accept it with accept_decision, yourself if the choice was yours to make; from accepted on it is superseded rather than edited. A decision is cited by that link, never by pasting its text; read the existing records (list_decisions) before re-opening a settled question.


Continuous flows

Requirements over the lifecycle. Requirements are living documents: amend them whenever understanding changes (each edit is a revision; nothing is lost), and re-approve when the amendment is settled. Staleness badges on linked epics show exactly which shipped or in-flight work was built against a superseded revision — triage them with the fold-in paths above. Cross-cutting documents propagate instantly on re-approval: every agent’s next get_issue carries the new text. If a new cross-cutting revision materially conflicts with an epic’s criteria or in-progress work, the evaluator set_blockeds the epic with the reason (the cross-cutting change), comments the conflict, and the operator decides per epic: amend the criteria, or defer the new rule.

Org instructions over the lifecycle. Every agent session starts with the shipped doctrine, composed into the guidance get_work_context returns and published as the doctrine page. Org-level agent instructions are optional additions to it: never seeded, empty in most organizations, and written only where an organization has a rule of its own that the doctrine lacks (decision record PIPE-D49, organization instructions are optional additions to plain product guidance, and nothing is seeded). A saved scope’s text is appended to the doctrine under a heading naming its scope (general, requirements, content, one per work type) and arrives once, as one document; no tool description carries any of it, and the server-level instructions field carries only a bounded index naming that call, because the agent client truncates that field at 2KB. Every other read carries a one-line pointer back to the same call. Edit them under Settings → Organization → Agent instructions or with the *_org_instruction tools — ADMIN-only, deliberately including admin-owned pbt_ tokens (an accepted risk, recorded here: instruction text becomes every future session’s standing orders with no approval gate, so treat an admin token’s blast radius accordingly). Channel boundary: product constraints and cross-cutting acceptance rules stay in cross-cutting requirements (project-scoped, approval-gated, delivered always-current via get_issue); the static agent-rules block the pipebrain skill writes into a repo’s CLAUDE.md is a repo-local channel — keep durable guidance in Pipebrain, where it cannot drift per-clone. Freshness: the composed guidance is a per-session snapshot — an edit reaches the next session, never a running one (unlike cross-cutting requirements, which propagate on the next get_issue).

Content over the lifecycle. Content is raw material with its own lifecycle that links to work — a sibling of requirements, not an issue type. A captured topic becomes a draft (create_content; the passive-capture rule targets this tool). Each draft carries an optional author byline — a first-class, filterable field (create_content/update_content set it; list_content filters by author), distinct from the actor that made the write — so a content project shared by several authors keeps them separate (“never mix authors”) by a real filter, not just discipline. A draft accrues revisions (update_content) and grows per-platform deliverables (create_deliverableupdate_deliverable), one deliverable per platform, each carrying its own versioned post text. Platforms are configured per project — the defaults are bsky/x/reddit/hn/blog, but a project edits the list under Project Settings → Deliverable targets (or the *_deliverable_target tools); create_deliverable rejects a slug that is not an active target for the project. Content itself is passive — no approval gate, no status, no board. Flow happens in work, once a draft is promoted.

Promotion. Two paths create work from a deliverable, both pinning the deliverable’s current revision. (a) Agent-driven links: create_issue a type=task whose body references the draft (DWB-C3), passing deliverable_links: ['DWB-C3/bsky'] (or add/remove them later with update_issue); these links are removable. Existing issues can also be linked/unlinked manually from the deliverable page (and issues↔requirements from the requirement page). (b) Promote-to-issue (promote_deliverable, or the deliverable page’s Promote to issue dialog): creates the issue and a protected link that cannot be unlinked — the issue exists to ship that deliverable. The task then rides the existing issue status enum — no new statuses: candidate → backlog · drafting → in_progress · awaiting human edit/post → verify · posted → done · abandoned → killed. When the human posts, capture the fact with record_post (the deliverable’s url + postedAt) and move the task to done. Pipebrain never posts — a human posts; record_post only records it. If you amend a deliverable (update_deliverable) after linking, the linked task shows a staleness badge (pinned revision < current) — re-scope, re-link, or ignore, exactly like a requirement link that has gone stale. Attachments: files (images, mockups) are assets — upload them via the web UI, ppb assets upload, or the MCP upload_asset tool (all path-based — the bytes never cross a tool argument), then link_asset them to a deliverable revision or to the draft itself (content_draft); pull an asset’s bytes back to a local file with download_asset to read or view it. upload_asset and download_asset exist on a LOCAL MCP server only — they act on the filesystem of the machine running the server, so the hosted endpoint at api.pipebrain.dev/mcp does not register them and ppb assets upload|download is the path there; a draft’s linked assets snapshot onto a deliverable when it is created (independent thereafter), and an amendment carries a deliverable’s links forward so a post never loses its image. In the web UI, linked markdown/text assets preview in a side panel and images show inline thumbnails.

Watching the burndown. The project overview (feature epics with children counts by status, criteria progress, per-milestone totals) and the activity log (status flips grouped by day, defaulting to done) are the roadmap and the runlog — derived from live state instead of maintained by hand. The narrative half of a runlog lives on the epics themselves: the builder’s handoff summary, criterion evidence, comments. When a burndown number matters, it is always current.

Feedback triage. Widget submissions arrive as type=feedback, status=triage in the reporting project and environment. Sweep daily (first operator in) or ad hoc. For each: junk → killed; real → retype to bug or task, set priority and environment, move to backlog (or ready), and optionally parent it under a feature epic.

Bugs outside a feature. create → (triage) → backlog → ready → claim → in_progress → fix → verify → done. Who confirms the fix follows the rule above: a bug carrying a manual criterion waits for a person, and one carrying none is closed by the session that fixed it. A regression test for the bug is welcome.

Claiming etiquette. Claim before working. Release with a comment if you stop. Claims are visible on the Work page; never work someone else’s claim. Claim state is orthogonal to status — a backlog item can be claimed to signal intent.


Trust model — read this honestly

Evidence is agent-reported. Nothing in Pipebrain independently executes anything: an evaluator that says it drove an endpoint and saw the right row is, at this layer, believed. What the evidence buys you is that a claim is specific enough to check — “covered by tests” is not evidence, and a criterion whose evidence reads that way is the one to spot-check. Criterion states split by mode: auto states are agent-verified observables with recorded evidence — set by the evaluator (convention: author ≠ implementer ≠ evaluator) and server-limited to auto rows; manual states are human assertions that only a web session can set (server-enforced). What actually protects quality, in order: criteria that say something falsifiable, the evaluator driving the real paths in a session separate from the builder’s, and the human’s manual checklist. The V2 runner adds independent test execution so green becomes machine-verified before a human ever looks.


Wiring a product repo (checklist)

Pipebrain MCP tool arguments are camelCase on the wire (requirementLinks, crossCutting, criterionNumber, claimedBy, …); where prose here shows snake_case (e.g. cross_cutting) it is illustrative — pass camelCase keys.

  1. Pipebrain tools are global — the pipebrain MCP server is registered at user scope by your agent tooling’s bootstrap; the repo needs no .mcp.json. (A repo-level server named pipebrain shadows the user-scope one — ppb doctor warns.)
  2. The repo’s end-to-end harness, where one exists, is named in the CLAUDE.md block — the runner and the exact command that drives it (the pipebrain skill detects and records this; a repo with none states that instead, and criteria about interface behavior stay manual there).
  3. Web products: embed the widget snippet with the product’s pk_ key.
  4. Run Stage 0 if the project is new to Pipebrain (foundational + cross-cutting requirements approved).
  5. CLAUDE.md: the pipebrain skill in your agent tooling owns the wiring-block template and writes/updates it idempotently between its own start/end markers — say “set up pipebrain here” in a Claude Code session inside the repo. It interviews for the project key; do not hand-maintain a divergent copy of the block here.