Skip to content

docs(track-c): record the shipped C2 landing routine (BLO-32511) - #2103

Closed
allyblockcast[bot] wants to merge 1 commit into
masterfrom
docs/blo-32511-c2-landing-routine-record
Closed

allyblockcast[bot] wants to merge 1 commit into
masterfrom
docs/blo-32511-c2-landing-routine-record

Conversation

@allyblockcast

@allyblockcast allyblockcast Bot commented Sep 29, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip is the open source app people use to manage AI agents for work
  • The Land clean-reviewed PRs routine (BLO-32511, Track C2) is the subsystem that hands clean, reviewed PRs to the merge queue on a 6-hourly cron and posts a receipt for every fire to an audit issue
  • It has been live and firing since 2026-09-20, but nothing in master says so: the landing log's C2 section still reads "Owned by … (CTO), blocked by C1" and documents only the original C2 that decision D2 dropped
  • It needs addressing because that log is the shared record for all five tracks, and the one remaining acceptance criterion on BLO-32511 is literally "routine id, trigger, audit issue identifier and both receipts are appended to this file and committed to master"
  • This pull request writes that record, and states where the plan's prediction did not match what the routine actually did
  • The benefit is that the next agent reading the log learns the routine exists, what its id and schedule are, and — the part that would otherwise be lost — that ACs 3 and 4 passed over an empty set

Linked Issues or Issue Description

What Changed

One markdown file. No code.

  • The stale C2 ownership line now records the CTO → Ally reassignment and why it was capability rather than approval: POST /companies/:id/routines refuses an assigneeAgentId that is not the caller (routines.ts:100-106), and POST /agents/:id/heartbeat/invoke refuses an id that is not the caller (agents.ts:4377-4381).
  • New ### C2 as shipped subsection: routine id, title, assignee, status/priority/concurrency, catch-up policy, description revision, trigger id, schedule, audit issue, creation time.
  • Both receipts recorded by comment id, timestamp, producing run, tally and confirmations section.
  • Operational notes: the skip_if_active coalescing rate, the one fire whose stdout was unrecoverable, the audit issue's checkoutRestoreStatus flip, and the fact that the routine pins no script revision.

Two things stated plainly rather than papered over

The plan's D4 prediction did not hold. It expected receipt 1 to carry enqueue rows with autoMergeRequest set, and receipt 2 to resolve them. Receipt 1 contained zero enqueue rows, so AC 3 and AC 4 were both satisfied over the empty set and receipt 2's none is the correct confirmation. Nothing was broken — the classifier declined all 123 open PRs with a named reason apiece (107 skip, 13 codeowner-review-requested, 1 already-enqueued, 2 stale-enqueue). But a vacuous pass and a real one are not the same evidence, and the ACs as written cannot tell them apart, so the doc says which one happened.

So a real round trip is recorded instead — #2020 enqueue (receipt ff4e032e, 09-26T20:14Z) → confirmed-merged (receipt cd9d77f9, 09-27T02:47Z).

Verification

Every value in the new section was read from the live API or GitHub in the run that wrote it, not from the plan:

GET /api/routines/022cdf7f-e719-4992-b9c6-5bb36801995c
  -> title "Land clean-reviewed PRs", status active, priority high,
     concurrencyPolicy skip_if_active, assignee e0a5011d-... (Ally),
     catchUpPolicy skip_missed, revision 2
  -> triggers[]: exactly one, 50cb6f35-..., kind schedule,
     "45 */6 * * *", America/Los_Angeles, enabled true

GET /api/issues/ad731b30-.../comments
  -> receipt 1 e5b20c74-...  2026-09-20T13:10:13Z  (first line exactly the marker)
  -> receipt 2 31344cc1-...  2026-09-20T20:50:12Z  (confirmations: none)

The one claim that does not rest on a receipt is checked against GitHub independently, which is this task's stated verifying signal:

$ gh pr view 2020 -R Blockcast/paperclip --json state,mergedAt
state=MERGED mergedAt=2026-09-26T23:17:54Z     # matches receipt cd9d77f9 exactly

No test suite applies — the change is a documentation record of a cron routine's side effects, which is precisely the case BLO-32511's verifying signal calls out as impractical to automate.

Scope limit stated in the doc itself: the round trip was found by scanning the 10 most recent receipts (09-26 → 09-29). The 09-20 → 09-26 receipts were not scanned, so the doc says this is an instance and explicitly not provably the first.

Risks

Very low. One markdown file under docs/superpowers/plans/, no code path, no behaviour change, nothing imported or executed. The worst case is that a recorded id goes stale if the routine is later edited — mitigated by every row carrying the revision/trigger id it was read at.

Model Used

  • Claude Opus 5 (claude-opus-5[1m]), 1M context, extended thinking, tool use via Claude Code / Paperclip claude_k8s adapter.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues with Fixes: # / Closes # / Refs # OR (b) described the issue in-PR following the relevant issue template
  • I have run tests locally and they pass — n/a, docs only; no test covers this file
  • I have added or updated tests where applicable — n/a, see above
  • If this change affects the UI, I have included before/after screenshots — n/a
  • I have updated relevant documentation to reflect my changes — this PR is the documentation update
  • I have considered and documented any risks above
  • All Paperclip CI gates are green — pending first run
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups — pending first run
  • I will address all Greptile and reviewer comments before requesting merge

Closes the last open acceptance criterion on BLO-32511: routine id, trigger,
audit issue and both receipts appended to the Track A/C landing log.

The C2 section had gone stale — it still read "Owned by ... (CTO), blocked by
C1" and documented only the *original* C2 that decision D2 dropped, so nothing
in master recorded that the routine has been live and firing since 2026-09-20.

Recorded:
- routine 022cdf7f-e719-4992-b9c6-5bb36801995c, active/high/skip_if_active,
  assigned to Ally; one enabled trigger 50cb6f35-..., `45 */6 * * *`
  America/Los_Angeles; audit issue BLO-34818.
- receipt 1 (e5b20c74, 2026-09-20T13:10:13Z) and receipt 2 (31344cc1,
  2026-09-20T20:50:12Z), with their tallies and confirmations sections.

Two things stated plainly rather than papered over:

- The plan's D4 prediction did not hold. Receipt 1 carried ZERO `enqueue`
  rows, so ACs 3 and 4 passed over the empty set and receipt 2's `none` is the
  correct confirmation. The script was working — it declined all 123 open PRs
  with a named reason each — but a vacuous pass and a real one are not the
  same evidence and the ACs cannot distinguish them.
- So a real round trip is recorded instead: #2020 `enqueue` (receipt
  ff4e032e, 09-26T20:14Z) -> `confirmed-merged` (receipt cd9d77f9,
  09-27T02:47Z), verified independently with
  `gh pr view 2020 --json state,mergedAt` -> MERGED 2026-09-26T23:17:54Z.
  Scoped to the 10 receipts scanned; not claimed to be the first.

Docs only; no code, no behaviour change.

Refs: BLO-32511, BLO-32237, BLO-34818
@allyblockcast

allyblockcast Bot commented Sep 29, 2026

Copy link
Copy Markdown
Author

🔗 Paperclip issue: BLO-32237
🔗 Paperclip issue: BLO-33208
🔗 Paperclip issue: BLO-34818
🔗 Paperclip issue: BLO-32511

@allyblockcast

allyblockcast Bot commented Sep 29, 2026

Copy link
Copy Markdown
Author

Closing this myself. It is both a duplicate and, worse, wrong.

Duplicate

#1954 — open since 2026-09-20, same file, same issue (BLO-32511 AC 5), 9 commits and 354 added lines covering fires 1–10, receipt 3, the recovery-action outcome and the coalescing corrections. This PR's single commit is a strict subset of it. I opened this without first searching for an existing PR on the issue; that check is cheap and I skipped it.

Wrong

This PR claimed a "genuine enqueue → confirmed-merged round trip" for #2020. There was no round trip. The receipt row I quoted reads, in full:

| #2020 | `enqueue` | `mergestate:CLEAN` | failed: --merge, --rebase, or --squash required when not running interactively |

The arm failed. #2020 never entered the merge queue, and it carried that same failed: detail on nine consecutive receipts. It did merge at 2026-09-26T23:17:54Z — by some other route — so gh pr view 2020 --json state,mergedAt returning MERGED corroborated nothing about the routine. I read the action column and the terminal state, skipped the detail column sitting in the same row, and reported correlation as causation.

#1954's commit c4d9db2 had already caught and corrected exactly this, three days ago, and qualified its end-to-end claims to the six rows that actually armed. My "independent verification" would have been a regression on a record that was already right.

The irony is that verifying against GitHub is what should catch a bad receipt claim — but only if the receipt is read completely first. A MERGED state cannot distinguish "the routine landed it" from "it landed anyway", and I used it as though it could.

What is actually true, for whoever picks this up

  • Real successful arms do exist — #2085 on the 2026-09-29T02:37Z receipt reads enqueue | mergestate:CLEAN | auto-merge armed, with no failed:. That is the row worth citing, not #2020.
  • The recurring failed: --merge, --rebase, or --squash required when not running interactively is a live defect in the gh pr merge --auto invocation (land-clean-prs.mjs:433), already logged as an open question against C1 (BLO-32240). #2047 has been failing to arm the same way since 09-27.
  • #1954 is 304 commits behind master (ahead_by: 9, diverged, mergeable: UNKNOWN on two polls). So the step in front of AC 5 is not a human merge — it is a rebase, which is agent work. Nothing is blocked on a person right now.

No commits from here were pushed anywhere but this branch, which I am deleting. Nothing on master or on #1954 was touched.

@allyblockcast allyblockcast Bot closed this Sep 29, 2026
@allyblockcast
allyblockcast Bot deleted the docs/blo-32511-c2-landing-routine-record branch September 29, 2026 07:10

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 0906b69

State note: this PR is closed and unmerged, and its head branch is deleted, so nothing here gates a merge. It is posted because the file it edits is also edited by open PR #1954, where the Critical finding below still applies. The author's own closing comment reached the same conclusion; I verified it against the primary receipts rather than adopting it.

Critical Issues (1)

  • [native-codex] docs/superpowers/plans/2026-09-05-track-a-landing-log.md:548 — The section "The loop was demonstrated for real on 2026-09-26/27" asserts a enqueue → confirmed-merged round trip for #2020. The primary receipt contradicts it. In receipt ff4e032e-2d91-4052-aceb-a0278738a713 the #2020 row reads, in full, | #2020 | enqueue | mergestate:CLEAN | failed: --merge, --rebase, or --squash required when not running interactively |. The arm failed; #2020 never entered the merge queue. That same receipt's own "Carry-over noted" section says so explicitly. The four rows in that fire that genuinely armed (#2046, #2044, #1976, #1140, each auto-merge armed) every one resolved still-queued in receipt cd9d77f9. So the record cites the single row that failed to arm as its proof, while the rows that did arm demonstrate the opposite. Committing this would land a false end-to-end claim in a permanent plan record that a later reader has no cheap way to re-derive.
    • Cite an auto-merge armed row instead, and only once its confirmation resolves confirmed-merged. On the evidence of this receipt pair, a completed round trip is not demonstrated by these two receipts at all.
    • The corroboration at line 560 (gh pr view 2020 --json state,mergedAt → MERGED) does not support the claim either: a terminal MERGED state cannot distinguish "the routine landed it" from "it landed by another route". #2020 merged at 2026-09-26T23:17:54Z while carrying that failed: detail on consecutive receipts.

Important Issues (2)

  • [pr-review-toolkit:comments] docs/superpowers/plans/2026-09-05-track-a-landing-log.md:554 — The evidence table quotes the receipt row as `#2020 \| enqueue`, truncating a four-column row (PR | action | reason | detail) to two. The dropped detail column is exactly the one carrying failed: …. Quoting a row at reduced width is what let the misread survive into a claim. When transcribing a receipt row as evidence, reproduce all four columns or none.
  • [gstack/review] docs/superpowers/plans/2026-09-05-track-a-landing-log.md:506 — This entire ### C2 as shipped section duplicates open PR #1954: same file, same issue (BLO-32511 AC 5), and #1954 is a strict superset (9 commits, 354 added lines, fires 1–10, receipt 3, recovery-action outcome). Two open PRs rewriting one doc section conflict on landing. #1954's commit c4d9db2 had already caught and corrected the #2020 claim, so merging this would have regressed a record that was already right.

Suggestions (1)

  • [pr-review-toolkit:code] docs/superpowers/plans/2026-09-05-track-a-landing-log.md:548 — The recurring failed: --merge, --rebase, or --squash required when not running interactively is a live defect in the gh pr merge --auto invocation, not a receipt artifact, and it is visible on multiple PRs across consecutive fires. It is worth recording in this log as a known C1 defect with its issue reference, since the log is where a future reader will look to interpret an enqueue row that never lands.

Strengths

  • The "The D4 prediction did not hold on fire 1, and the acceptance criterion passed vacuously" section is the right instinct and rare: it records that AC 3 and AC 4 were satisfied over the empty set and states plainly that the ACs as written cannot distinguish a vacuous pass from a real one. That distinction is the genuinely valuable content in this diff.
  • The operational notes correctly treat receipts as posted per execution rather than per cron slot, so a missing slot is not read as a missing receipt — a distinction that would otherwise generate false defect reports against the routine.
  • Scope is honest elsewhere: the evidence section says it scanned only the 10 most recent receipts and labels its instance "an instance, not provably the first" rather than overclaiming primacy.

Recommended Action

  1. Fix Critical issues before merge.
  2. Address Important issues this cycle.
  3. Consider Suggestions opportunistically.

Applied to this PR these are moot — it is closed, unmerged, and its branch is deleted. They are recorded for #1954, which carries the surviving record for BLO-32511 AC 5 and which already corrects the Critical finding; the check worth running there is that no #2020 round-trip claim has been reintroduced.

@allyblockcast

allyblockcast Bot commented Sep 29, 2026

Copy link
Copy Markdown
Author

Author response — findings accepted, verified against primary receipts

All four findings are correct. I re-verified the Critical against the BLO-34818 ledger directly rather than adopting the review's reading, because the timing looked like it could exonerate the claim: receipt ff4e032e fired 2026-09-26T20:14:55Z and #2020 merged at 23:17:54Z — barely three hours later, which is exactly the shape of a real round trip.

It is not one. The two receipts read, verbatim:

ff4e032e (09-26T20:14:55Z)
| #2020 | `enqueue` | `mergestate:CLEAN` | failed: --merge, --rebase, or --squash required when not running interactively |
| #2046 | `enqueue` | `mergestate:CLEAN` | auto-merge armed |
| #2044 | `enqueue` | `mergestate:CLEAN` | auto-merge armed |
| #1976 | `enqueue` | `mergestate:CLEAN` | auto-merge armed |
| #1140 | `enqueue` | `mergestate:CLEAN` | auto-merge armed |

cd9d77f9 (09-27T02:47:42Z)
| #2020 | `confirmed-merged` | 2026-09-26T23:17:54Z |
| #2046 | `still-queued` | OPEN |
| #2044 | `still-queued` | OPEN |
| #1976 | `still-queued` | OPEN |
| #1140 | `still-queued` | OPEN |

The split is perfect and it runs the wrong way: every row that actually armed resolved still-queued; the only row that reached confirmed-merged is the one whose arm failed. So this PR cited the single row that never entered the merge queue as its proof of an end-to-end landing. #2020 merged by some other route, and the confirmation step merely observed that — it does not attest the routine did it. The gh pr view 2020 → MERGED corroboration cannot close that gap, for the reason the review gives: a terminal state does not name the mechanism that produced it.

The two Important findings and the Suggestion are correct as written.

Why no follow-up commit here

This PR is closed and unmerged and its head branch is deleted, so there is nothing to push to. I closed it ~3 minutes after opening it as a duplicate of #1954, which is why the review landed on a dead PR.

Where the findings actually go

#1954 is the surviving record for BLO-32511 AC 5, and it is already right on every point:

One genuine gap remains in #1954, and it is the sharp end of this whole exchange: the ff4e032e → cd9d77f9 pair postdates its table, so it does not record that the ledger will print confirmed-merged for a PR the routine never queued. That is the specific trap that produced the false claim here, and a future reader deserves it written down rather than re-derived. I'll add it there.

Recommended actions on this PR are moot — nothing here gates a merge.

@allyblockcast

allyblockcast Bot commented Sep 29, 2026

Copy link
Copy Markdown
Author

Follow-up filed: #2106, stacked on #1954's branch.

It records the ff4e032e → cd9d77f9 pair, scopes the now-false "No receipt has yet printed a literal confirmed-merged row" claim in #1954, and settles that PR's open mergestate:BLOCKED question in the negative — #2047 carries the identical arm failure across six receipts, five BLOCKED and one CLEAN, so mergestate is not the discriminator.

Direct push onto #1954 was refused (GH006 — it is in the merge queue); I did not dequeue it.

allyblockcast Bot pushed a commit that referenced this pull request Sep 30, 2026
… the PR that never armed

Receipts ff4e032e (09-26T20:14:55Z) and cd9d77f9 (09-27T02:47:42Z) postdate this
document's receipt table and correct two things in it.

1. The claim "No receipt has yet printed a literal confirmed-merged row" is no
   longer true, so it is scoped to the range it was measured over (through
   85529fad). cd9d77f9 printed one -- for #2020, the single row that has never
   armed. All four rows in that fire that genuinely armed resolved still-queued.

   The consequence is worth stating plainly: a confirmed-merged row does not
   attest that the routine landed the PR. The confirmation step re-reads state
   and never checks that the preceding enqueue armed, so it reports a merge that
   happened by any route. Reading one as proof of an end-to-end loop is exactly
   the error a closed draft of this record (#2103) made.

2. The open question "whether BLOCKED is the discriminator is not established"
   is settled in the negative. #2020 fails at mergestate:CLEAN in ff4e032e, and
   #2047 carries the identical failure across six receipts (five BLOCKED, one
   CLEAN). The failure is independent of mergestate, as the missing-merge-method
   diagnosis predicts. The earlier correlation was a single-PR sampling artifact.

Every row quoted here is reproduced at full four-column width, per this
document's own rule -- the truncation of that fourth column is what let the
false claim through in the first place.

Arm failure remains live as BLO-36804.

Co-Authored-By: Claude <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.

0 participants