Skip to content

docs(repo): propose one Linear release pipeline for all bots - #220

Merged
haydenshively merged 6 commits into
mainfrom
feature/bots-140-linear-release-pipeline
Sep 15, 2026
Merged

haydenshively merged 6 commits into
mainfrom
feature/bots-140-linear-release-pipeline

Conversation

@haydenshively

@haydenshively haydenshively commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Why

Production trails main per bot, and nothing outside git records the gap. Since the release-intent gate landed (#210), a merge redeploys every staging bot but deploys to production only the bot named in an approved Releases <bot> line — so "merged" and "live" are different facts, and only the second is recorded. quoter-bot cut nine releases in the three weeks to 2026-08-31 and none since; blue-liq has cut one in two months.

What

A TIB proposing that production deploys sync into a single continuous Linear release pipeline named Bots, so an issue shows which release shipped it and for which bot.

The load-bearing choice is one shared pipeline rather than one per bot. linear-release's --include-paths and --base-ref are per-invocation CLI flags, so per-bot attribution is a CI concern, not a pipeline concern — which matters because the workspace is capped at 15 pipelines with 5 already used, and per-bot would cost 4 now and 7 once the vault bots and kill-switch onboard. Path filters come from the workspace dependency graph rather than a blanket packages/ wildcard, which narrows cross-bot ambiguity without removing it — every package with more than one consumer still matches several filters. The deeper limit, which review sharpened and the TIB now states, is that attribution is per pull request rather than per path: a filter admits a commit, and the issues then come from the PR on that commit, so any PR spanning two bots attributes all of its issues to whichever releases first.

Records why a staging pipeline, the org's catch-all pipeline, a linked-issue status check, and deriving filters in code were all rejected.

Docs only — no behavior change. The implementation lands separately under BOTS-140.

Notes for the reviewer

  • Releases <bot> is already reserved in this repo as the deploy keyword; the TIB opens by separating that from Linear Releases, the tracker feature. Worth checking that the distinction reads clearly.
  • The console side is already done and verified: pipeline Bots exists, and the linear-release GitHub Environment holds LINEAR_ACCESS_KEY behind a main-only branch policy.
  • Status automation (MergedDone on release) is deferred, not rejected — it is Linear dashboard config and needs no repo change. Recorded as an Open Question.

Closes BOTS-140 only once the implementation lands; this PR is the decision record.

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Sep 15, 2026

Copy link
Copy Markdown

BOTS-140

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-15T05:19:22.929043Z 075ef5f Draft marked ready
🔒 Security Review Completed 2026-09-15T05:10:46.363785Z 075ef5f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

2 flags not posted on this PR by your GitHub settings — view them in Devin Review. (Configure)

Devin Review

Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
@haydenshively
haydenshively force-pushed the feature/bots-140-linear-release-pipeline branch from 075ef5f to 8e71bbc Compare September 15, 2026 05:08
@haydenshively
haydenshively added this pull request to stack #223 September 15, 2026 05:08
@github-actions

github-actions Bot commented Sep 15, 2026

Copy link
Copy Markdown

Size

Area Files + Net
docs 2 +233 −0 +233
total 2 +233 −0 +233

Changed files at head: 0 code, 276 comments, 73 blanks. tokei counts Markdown prose as comments, so a docs PR honestly reports near-zero code.

haydenshively added a commit that referenced this pull request Sep 15, 2026
Drive-by cleanup found while writing #220.

## Why

The repo is `morpho-org/morpho-bots`, `package.json#name` is
`@morpho-org/morpho-bots`, and the Linear team is `Bots`. It also holds
a market maker now alongside the liquidation and reallocation bots, so
"curator bots" is stale as a name *and* as a description of what is in
here. `services/quoter-signer` was deleted in #214; only untracked build
residue remains on disk.

## What

Seven one-line edits across `README.md`, `AGENTS.md`,
`docs/CONVENTIONS.md`, `.claude/agents/product-manager.md`,
`.claude/commands/create-issue.md`, and `packages/ci-scripts/README.md`.

## Deliberately left alone

- **`packages/swaps/src/constants.ts`** — `LIFI_INTEGRATOR =
'morpho-curator-bots'` is a wire value sent to LiFi on every quote, not
prose. Changing it changes outbound attribution and needs coordination
on their side; a venue that 4xxs on a bad param reads as `no_route` and
sidelines itself silently.
- **`docs/decisions/**`** — TIBs are immutable once accepted, and
`TIB-2026-04-16-bootstrap-curator-bots.md` is a link target from
`README.md`, `docs/INDEX.md`, and the kill-switch TIB.
- **`docs/retros/README.md`** — its example filename names that
historical artifact, not the repo.

No ticket: this ships as it was found rather than being deferred.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
haydenshively and others added 3 commits September 15, 2026 00:16
Production trails main per bot and only git records the gap. Wire deploys into
Linear Releases so an issue shows which release shipped it.

One shared continuous pipeline rather than one per bot: --include-paths and
--base-ref are per-invocation CLI flags, so per-bot attribution is a CI concern.
Filters come from the workspace dependency graph, which narrows the ambiguity to
bot-kit and utils. Records why per-bot pipelines, a staging pipeline, the org's
catch-all pipeline, and a linked-issue status check were not adopted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Surfaced while implementing: .github, ci-scripts, and docs changes fall outside
every bot's path filter, so those issues never attach to a release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Path filters gate commits; issues come from the PR number on the commit, so a
PR spanning two bots attributes all its issues to whichever releases first. No
filter fixes that. Also records root build inputs as every bot's code, and the
root-commit base for a bot with no predecessor tag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@haydenshively
haydenshively force-pushed the feature/bots-140-linear-release-pipeline branch from 8e71bbc to a6992af Compare September 15, 2026 05:18

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 075ef5f344

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Comment thread docs/decisions/TIB-2026-09-14-linear-releases-pipeline.md Outdated
Ambiguity is not limited to the all-four packages: swaps and contracts have
multiple consumers too. The scan base is the newest ancestor tag, not the newest
tag, because Release is not serialized and reruns exist. Issue linkage is a
convention until the review instruction is actually written. Credential recovery
is bounded only while no status automation is wired.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@dev-carapulse dev-carapulse Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the current documentation head as the base of the #220 -> #221 stack, including BOTS-140 and the existing review discussions.

The revised decision records the load-bearing limitations: path filtering admits whole commits/PRs rather than individual linked issues; multi-consumer packages remain ambiguous; issue-link enforcement is not implemented here; and recovery must account for downstream state changes if release-completion automation is added later. The ancestor-based scan policy is now consistent with the implementation reviewed in #221. The broader deployment ordering problem remains BOTS-128, not additional scope for this stack.

Checks run locally on the combined stack: changed-file formatting and git diff --check passed. The documentation bytes in the child match this head. GitHub's current Test job was still running at the last check, so this is a code/design approval, not a full-CI or deployment-completion claim.

Nonblocking wording nit: the PR description still says ambiguity narrows to only bot-kit/utils; the corrected TIB is broader. Update that summary when convenient.

@dev-carapulse

dev-carapulse Bot commented Sep 15, 2026

Copy link
Copy Markdown

Approved this reviewed head: #220 (review). Stack implementation and execution evidence are in the #221 approval; wording note in the review is nonblocking. Full CI remains incomplete at this review snapshot: Test jobs are still running. No merge performed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@haydenshively

Copy link
Copy Markdown
Collaborator Author

Fixed the wording nit — the description said ambiguity narrows to bot-kit and utils, which the corrected TIB no longer claims. It now says every package with more than one consumer stays ambiguous, and names the deeper limit: attribution is per pull request rather than per path.

The scan-base bullet also moved from "newest ancestor tag" to "nearest reachable tag", matching the git describe rule the implementation switched to in #221.

Applies the Microsoft Writing Style Guide: shorter sentences carrying one idea,
active voice, contractions, and second person where the text gives guidance.
Cuts em-dash asides from twenty to four and spells out numbers under ten.

No decision content changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@haydenshively
haydenshively merged commit 644c3f4 into main Sep 15, 2026
6 checks passed
@haydenshively
haydenshively deleted the feature/bots-140-linear-release-pipeline branch September 15, 2026 05:59
haydenshively added a commit that referenced this pull request Sep 15, 2026
Implements BOTS-140. Decision record: #220 (TIB-2026-09-14).

## Why

"Merged" and "live" are different facts here, and only the second is
recorded — in Railway and in `<bot>-<PR#>` tags. During an incident the
question is per bot: is this fix running? This records each production
deploy as a Linear release, so the issue itself carries the answer.

## What

A `Linear` job in `deploy-bot.yml`, after `Release`, syncing one release
per production deploy into the `Bots` pipeline.

Per-bot attribution inside a single shared pipeline comes from two
per-invocation flags:

- `base_ref` — that bot's previous `<bot>-*` tag. `prev` was already
computed for the GitHub release notes; it moves above the idempotency
branch and excludes the current tag, so a rerun emits it too.
- `include_paths` — a new `paths` field on
`packages/ci-scripts/manifest.json`, holding the bot's own directory
plus every workspace package it depends on, transitively. It reaches the
workflow as the `linear_paths` matrix leg, alongside `publish_image`.

A test asserts each bot's `paths` against the real dependency graph,
walking `package.json` files. That is the guard that matters: a bot that
gains a workspace dependency without gaining the path keeps producing
releases, just missing the work it shipped — a failure that looks like
nothing at all. Verified it fails by removing `packages/swaps/**` from
`blue-liq` and watching it go red.

## Safety

Not funds-at-risk — it touches no calldata, signing, or sizing, and runs
strictly after a deploy and tag that already succeeded.

- The job runs at `permissions: contents: read` and `continue-on-error:
true`. The action fetches and executes a prebuilt CLI at runtime, which
is why it is not in `Release` alongside `contents: write` and
`GH_TOKEN`, and why a Linear outage cannot break the chain
`publish-quoter-bot-npm.yml` keys off the `<bot> / Release` job name
for.
- `LINEAR_ACCESS_KEY` lives in the `linear-release` GitHub Environment
with a `main`-only deployment branch policy, not as a repo secret —
`checks.yml` runs on `pull_request`, so repo-level secrets are reachable
from a branch PR that edits a workflow.
- The action is pinned by commit SHA and `cli_version` pinned
explicitly.
- A guard step fails the job on an empty `linear_paths`, because an
unfiltered sync would attribute every bot's commits to this bot's
release.
- The pipeline key is scoped to one pipeline; it cannot reach code,
Railway, signing keys, or funds.

## Verified

- `pnpm --filter @repo/ci-scripts run typecheck`, `pnpm lint`, `pnpm
format:check`, `pnpm knip` — all clean.
- `pnpm test` — 2952 passed. The 4 failing files are the fork/e2e suites
that need `RPC_URL_8453`, which is absent locally and unrelated to this
diff.
- `bots/quoter-bot/test/scripts/railway.utils.test.ts` passes unchanged.
It slices `deploy-bot.yml` by job markers, which is why the new job sits
between `Notify:` and `Image:` — both slices stay byte-identical.

## Rollout

Nothing to stage: the first real release is the test. A wrong or empty
release row is deletable in Linear, no status automation fires from it,
and the job fails open, so there is nothing to protect with a dry run —
while a temporary `dry_run: true` that outlives its revert would leave
the sync silently writing nothing, which looks exactly like working.

Backfill is expected and wanted on the first sync per bot: `prev` is
still a CalVer tag, so quoter-bot's first release sweeps everything
since `quoter-bot-2026.08.31-1` — commits that genuinely have not
reached production.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant