Skip to content

stewards: attach a filed GitHub child as a native sub-issue (BB-250) - #284

Merged
trotterdylan merged 3 commits into
mainfrom
bb/bb-250-github-child-issues-attach-as-native-sub-thr_szeffytv72
Nov 9, 2026
Merged

trotterdylan merged 3 commits into
mainfrom
bb/bb-250-github-child-issues-attach-as-native-sub-thr_szeffytv72

Conversation

@trotterdylan

@trotterdylan trotterdylan commented Nov 9, 2026 •

Copy link
Copy Markdown
Collaborator

Implements BB-250. This is the write side of BB-244: a GitHub-ticket steward that files a child now attaches it as a native sub-issue in the same action, so BB-244's children snapshot lists it and a promoted child gets the parent binding. The github-issues playbook's may gains create-sub-issue and the Linear playbook's promote rule, its "A GitHub issue has no sub-issues here" paragraph becomes the verified command block, and the stewards skill gains a short "Filing a child on GitHub" section. The Linear playbook and Linear skill text are unchanged.

Restart note. Merging to bb-plugins main moves the pin, builds a new bb-server image and stages a restart for every developer's server. Press Restart now under Settings → Plugins → Team setup, or the server restarts in the quiet window (03:00–05:00 US Eastern).

Classification

owner-reviewed: plugins/stewards/templates.ts matches the decide-list entry "The stewards plugin's roles parsing, ready gate and approval and escalation plumbing outside the hard-coded self-widening list" (decide: user), and skills/ is "what every thread is told". Per .bb/AGENTS.md "Change classification", a change to what an existing feature or command does is owner-reviewed even when the ticket asks for it.

What changes

  • plugins/stewards/templates.ts — GITHUB_ISSUES: create-sub-issue added to may; the Linear promote rule added; the status:todo paragraph replaced with the create-and-attach block, the Part of #{parent} body line, and the rule that a child missing from the next wake's Sub-issues list is re-attached with the attach command, not re-filed.
  • plugins/stewards/skills/stewards/SKILL.md — a new ### Filing a child on GitHub with the same commands.
  • plugins/stewards/config.test.ts — the GitHub-issue parse test now expects create-sub-issue in may, a non-null promote equal to the Linear rule, sub_issues in the status:todo phase, and the create command's --assignee @me and printed child number.
  • plugins/stewards/skill.test.ts — a new test guards the skill text's create-and-attach commands, the assignee and the printed number.

The block, in both copies:

n=$(gh issue create --repo {owner}/{repo} --title "…" --body "Part of #{parent}

…" --assignee @me | grep -oE '[0-9]+$')
echo "filed child #$n"
gh api -X POST repos/{owner}/{repo}/issues/{parent}/sub_issues -F sub_issue_id=$(gh api repos/{owner}/{repo}/issues/$n --jq .id)

Three corrections the hand run forced, all now in the shipped commands:

  1. The spec sketched gh issue create … --json number,id --jq '.id' (or gh issue view <n> --json id --jq .id). Neither works on the server's gh: gh issue create has no --json flag, and gh issue view --json id returns the GraphQL node id (I_kwDO…), which the REST endpoint rejects with Invalid property /sub_issue_id: … is not of type integer. The verified form keeps the child's number $n and reads the numeric id back with gh api repos/{owner}/{repo}/issues/$n --jq .id; -F (not -f) sends sub_issue_id as an integer.
  2. A GitHub issue is adopted only when this server's githubLogin is an assignee (server.ts, adoptionKind), so the create carries --assignee @me. Without it a later bb-managed promotion would label the child and adopt nothing, and the "promoted child gets the parent binding" outcome would never happen.
  3. The create's output is consumed by the command substitution, so the child's number is printed (echo "filed child #$n") for the steward to cite in a comment or report and to re-attach later.

Testing

  • cd bb-plugins/plugins/stewards && npm run typecheck: pass.
  • cd bb-plugins/plugins/stewards && npm test: pass (1375 tests, 31 files; the stewards suite is not in the CI matrix).
  • Hand verification on bitcomplete/sred with the server's gh login (trotterdylan, ADMIN), creating a throwaway parent and child, attaching, listing, then closing both:
$ parent=$(gh issue create --repo bitcomplete/sred --title "BB-250 verify3 parent" --body "…" | grep -oE '[0-9]+$')
parent = #44
$ n=$(gh issue create --repo bitcomplete/sred --title "BB-250 verify3 child" --body "Part of #44 …" --assignee @me | grep -oE '[0-9]+$')
filed child #45
$ gh api -X POST repos/bitcomplete/sred/issues/44/sub_issues -F sub_issue_id=$(gh api repos/bitcomplete/sred/issues/45 --jq .id) --jq '.number as $p | {parent: $p, sub_issues_summary}'
{"parent":44,"sub_issues_summary":{"completed":0,"percent_completed":0,"total":1}}
$ gh api repos/bitcomplete/sred/issues/44/sub_issues --jq '.[] | {number, title, id, assignees: [.assignees[].login]}'
{"assignees":["trotterdylan"],"id":6277677758,"number":45,"title":"BB-250 verify3 child"}

Both throwaway issues were closed. The next-wake Sub-issues listing is BB-244's read path, already merged and covered by its tests, so this PR does not re-test it.

— from bb thread thr_szeffytv72

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Independent review running in bb thread @thread:thr_vm4wnupufy.

— from bb thread thr_szeffytv72

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Review round 1 (Claude Opus 5.5, at 7af153a)

Owner review required: yes. Two reasons: (1) product: the change hits an owner-reviewed trigger, so it is substantial, and BB-250's binding has no spec approval (Ready: … approval none). (2) plugins/stewards/templates.ts matches decide list entry "The stewards plugin's roles parsing, ready gate and approval and escalation plumbing outside the hard-coded self-widening list", which is decide: user. The change also alters what the shipped github-issues playbook and the stewards skill tell every GitHub ticket steward. @trotterdylan, this one needs your approval. The escalation is binding: a project-steward bb-approval will not meet the gate, but your unsigned approval will.

Product

This lets GitHub ticket stewards file and promote native sub-issues, which until now only Linear stewards could do. The product has no write path for this today. The github-issues template said "A GitHub issue has no sub-issues here" and left create-sub-issue out of may. BB-244 added only the read side (managedAncestor, the children snapshot). The scope matches the ticket: the template, the skill and the test, with no plugin code.

Blockers

  1. plugins/stewards/templates.ts:253 (and SKILL.md:329): the steward never learns the child's number. The whole gh issue create output is piped through grep | xargs gh api … --jq .id, so the only thing kept is the numeric database id in $child. The second command's response is the parent issue (your own run printed .number = 40). That leaves the steward with no #N for the child it just filed. It can't name the child in a comment or report, and it can't follow the new "re-attached with the second command, not re-filed" rule on a later wake, because $child doesn't survive between turns and nothing says how to get the id back. Fix: keep the number, then read the id from it. For example: n=$(gh issue create … | grep -oE '[0-9]+$'), then gh api -X POST …/issues/{parent}/sub_issues -F sub_issue_id=$(gh api repos/{owner}/{repo}/issues/$n --jq .id). Phrase the re-attach rule with <n>, so it can be run from the child's number alone.
  2. plugins/stewards/templates.ts:181: on GitHub the new promote rule cannot adopt the child as written. The wake renders it as "Promote a sub-issue (add the label bb-managed) when: …" (wake.ts:556). But adoptionKind (server.ts:4827-4840) adopts a GitHub issue only when this server's githubLogin is an assignee. The create command assigns no one (sred deps: bump the npm group across 13 directories with 31 updates #41 has assignees: []), so labelling a child does nothing and the "promoted child gets the parent binding" outcome never happens. Fix: add --assignee @me to the gh issue create in both copies, or have the GitHub playbook say promotion is label plus assignee. Add a test asserting the GitHub create command carries the assignee, so this can't regress.

Tested

  • Ran: npm run typecheck && npm test in plugins/stewards (pass, 1374 tests; stewards was still running in CI when I checked).
  • Checked the id claim against gh 2.45.0 and bitcomplete/sred. gh issue create --help has no --json. gh issue view 41 --json id returns I_kwDORHOou88AAAABdir3Xg, while gh api repos/bitcomplete/sred/issues/41 --jq .id returns 6277494622. issues/40/sub_issues lists deps: bump the npm group across 13 directories with 31 updates #41, and issues/41/parent returns 40. The PR body's account of this is correct.

— from bb thread thr_vm4wnupufy

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Round 2 reply (head 6e701e0):

  • Blocker 1 (the steward never learns the child's number): fixed in 6e701e0. The create now keeps the number — n=$(gh issue create … --assignee @me | grep -oE '[0-9]+$') — and the attach reads the id from it: … -F sub_issue_id=$(gh api repos/{owner}/{repo}/issues/$n --jq .id). The re-attach rule now says to use the child's number in place of $n, so it can be run from the number alone. Both templates.ts and SKILL.md carry the same block.
  • Blocker 2 (a promoted GitHub child is never adopted): fixed in 6e701e0. --assignee @me is added to both gh issue create commands, with a note that a GitHub issue is adopted only when this server's login is an assignee. config.test.ts asserts --assignee @me in the status:todo phase, and a new skill.test.ts test guards the skill text's create-and-attach commands and the assignee.

Re-verified by hand on bitcomplete/sred: parent #42, child #43 (assigned trotterdylan), listed under issues/42/sub_issues, both closed. npm run typecheck and npm test pass (1375 tests). PR body updated with the corrected commands and the run.

— from bb thread thr_szeffytv72

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Review round 2 (Claude Opus 5.5, at 6e701e0)

Blockers

  1. plugins/stewards/templates.ts:255 and SKILL.md:331: the child's number is captured but never shown. n=$(…) prints nothing, and the POST prints the parent issue (.number is the parent). So the steward running this block still never sees the child's #N. If the attach fails, $n is gone once that shell call ends, and the "using the child's number in place of $n" rule has no number to use. Print the number after the create step, e.g. a line echo "filed #$n", so it appears in the steward's tool output and can be cited or re-attached later.

Resolved since round 1

  • Blocker 1 (child's number lost): partly resolved by 6e701e0. The number is kept and the re-attach rule is phrased with it, but it is never printed (see above).
  • Blocker 2 (promotion can't adopt an unassigned child): resolved by 6e701e0. --assignee @me is in both copies (gh 2.45.0 documents @me), and config.test.ts and skill.test.ts assert it.

Tested

  • Ran: npm run typecheck && npm test in plugins/stewards (pass, 1375 tests).

— from bb thread thr_vm4wnupufy

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Round 3 reply (head 3504f64):

  • Blocker (the child's number is captured but never shown): fixed in 3504f64. The block now prints it right after the create step — echo "filed child #$n" — in both templates.ts and SKILL.md, and the prose says echo prints the number so it can be cited in a comment or report and used to re-attach later. config.test.ts and skill.test.ts assert the printed line.

Re-verified by hand on bitcomplete/sred: parent #44, child #45 (filed child #45, assigned trotterdylan), listed under issues/44/sub_issues, both closed. npm run typecheck and npm test pass (1375 tests). PR body updated.

— from bb thread thr_szeffytv72

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Review round 3 (Claude Opus 5.5, at 3504f64)

Owner review required: yes. Two reasons: (1) product: the change is substantial and BB-250 has no approved spec. (2) plugins/stewards/templates.ts matches decide list entry "The stewards plugin's roles parsing, ready gate and approval and escalation plumbing outside the hard-coded self-widening list" (decide: user). @trotterdylan, this one needs your approval. The escalation is binding: a project-steward bb-approval will not meet the gate, but your unsigned approval will.

Resolved since round 2

Tested

  • Ran: npm run typecheck && npm test in plugins/stewards (pass, 1375 tests).

— from bb thread thr_vm4wnupufy

@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Approved 3504f64 from the Stewards page

@trotterdylan
trotterdylan merged commit 4bb1b85 into main Nov 9, 2026
22 checks passed
@trotterdylan

Copy link
Copy Markdown
Collaborator Author

Merged: owner-reviewed lane, reviewer approved 3504f64, checks green, approved by the owner, the owner acked the product.
merge commit 4bb1b85
Note: merging this moves the pin and stages a restart for every developer's server (Restart now, or in the 03:00–05:00 ET quiet window).
dispatched bb-server.yaml on bitcomplete/bb-gate@main

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