You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This umbrella PRD is delivered by the feature issues above (rescope 2026-08-24: Milestone > PRD > Feature > Task). It closes when the last of them ships.
Problem
This fork carries deliberate divergence from block/buzz — including product-code changes, not just cohort process files — and nothing owns the job of keeping it current. Upstream moves daily; the fork has not merged upstream since 2026-08-17.
That leaves two costs. The gap compounds: every day of drift makes the eventual merge larger and its conflicts harder, on a ~3,800-file upstream. And the cost lands on the wrong person at the wrong time — a contributor part-way through a feature discovers a conflict that has nothing to do with their work, in files they did not touch and whose divergence they may not know the reason for.
What is needed is a change agent that owns the block/buzz → launchpad-26/buzz relationship: it keeps the mirror current, absorbs the conflict work, resolves what it can safely resolve, and escalates the rest with enough context for a human to decide quickly. Contributors should learn about upstream only when they need to act on it.
Conflict resolution is the product here, not a side effect of syncing. The fork's divergence is intentional and expected to grow.
Evidence
Measured against launchpad-26/buzz and block/buzz on 2026-08-21:
launchpad is 255 ahead, 60 behindupstream/main. Merge-base is 2026-08-17; upstream committed as recently as 2026-08-20. No upstream commit has been merged into launchpad in that window.
All 255 divergent commits are cohort-authored (Serina 192, tucktuck101 53, joshuavial 4, Ben Mitchell 6). None came from upstream.
Of 324 files the fork has changed, 282 are inside the launchpad/ scope and 42 are upstream files: ~17 process/meta (AGENTS.md, CONTRIBUTING.md, issue templates, .claude/skills/*), ~9 build/tooling (Justfile, lefthook.yml, bin/lefthook, scripts/instance-env.sh, ci.yml), ~5 deployment (Dockerfile, docker.yml, deploy/compose/*), and 9 product code (crates/buzz-cli/src/commands/pack.rs, crates/buzz-persona/src/resolve.rs, 6× desktop/src-tauri/**).
A reason is recorded for 7 of those 42. ADR-0005 documents five deployment files; ADR-0017 documents the two lefthook pins. The other ~35, including all nine product-code files, have no recorded statement of why they diverge or which side should win a conflict.
git rerere is not enabled. Every recurring conflict is re-resolved from scratch, every time.
.gitattributes sets only * text=auto eol=lf. No merge drivers, so files the fork permanently owns still conflict on every sync.
launchpad-26/main is a clean, unmodified ancestor of upstream/main — 0 ahead, 221 behind. Confirmed intentional: it is the mirror through which updates arrive before being worked on locally.
The 60-commit gap test-merges with exactly three conflicts.git merge-tree launchpad upstream/main auto-merges AGENTS.md, Justfile, crates/buzz-cli/src/lib.rs and desktop/src-tauri/src/managed_agents/restore.rs cleanly, and conflicts on only:
lefthook.yml — divergence documented (ADR-0017), so the winner is already known
One conflict in each of the three resolution classes this PRD proposes: register-driven, mechanical, and semantic. The backlog is small today and the mechanism can be proven against a real case immediately.
The only sync automation that exists today runs on a contributor's personal fork and merges launchpad-26/main, which is itself 416 commits behindlaunchpad. It syncs from a stale mirror.
Success criteria
The mirror is never stale by more than one cadence period.launchpad-26/main fast-forwards from upstream/main unattended; a failure to do so is visible, not silent.
A clean upstream merge reaches a reviewable PR with no human involvement — no model invoked, no contributor prompted.
Every one of the 42 diverged upstream files has a recorded reason and a stated conflict winner, in a register a resolver can consult. New divergence is added to it in the PR that creates the divergence.
A conflict already resolved once does not require resolving again, by way of rerere and/or merge drivers. Demonstrated by a repeat sync over the same file pair.
A semantic conflict escalates with context: which files, which register entries apply, what upstream changed, and a one-command local entry point that reproduces the merge with the full toolchain available.
just ci gates every sync PR before it is mergeable. A sync that breaks the build is a failed sync, not a merged one.
A contributor mid-feature is never the first to discover an upstream conflict in files they did not touch.
The agent never merges to launchpad itself — see non-goals.
Non-goals
No unilateral merging. The agent opens PRs; a human with write access merges them. This is a hard constraint, not a default: the cohort has already lost a repository to an agent taking an irreversible action with legitimately granted privilege.
No unattended resolution of semantic conflicts in CI. Resolving a Rust or TSX conflict without being able to build and test it produces confidently broken merges. Mechanical resolution (register-driven, rerere, merge drivers) is in scope; judgement is escalated.
No PRs sent back to block/buzz. ADR-0017 records that the cohort is not currently sending changes upstream. If that changes it is a separate decision.
No rebasing of shared branches.launchpad has eleven people working off it, and rebasing would defeat rerere. Merge only.
Not a reduction in deliberate divergence. The fork's product-code changes are intentional and this PRD does not propose reverting them.
Impacted components
.gitattributes merge drivers for fork-owned files
.github/workflows/launchpad-upstream-sync.yml new — scheduled mirror + merge attempt
launchpad/upstream-sync/DIVERGENCE-REGISTER.md new — the 42 files, reasons, conflict winners
launchpad/upstream-sync/ new — resolution scripts and skill
launchpad/decisions/ ADRs this PRD raises (below)
Justfile local entry point for the escalation path
Security implications
The agent holds write access to shared branches on a public repository and takes actions on them. That is the same risk class as buzz-infrastructure#103, and the mitigations are the ones ADR-0015 already established for host access: the agent never holds a credential of its own beyond the workflow's scoped GITHUB_TOKEN, destructive or irreversible steps are proposed rather than taken, and every action is attributable.
Three specifics:
Token scope. The workflow needs contents: write and pull-requests: write and nothing else. It must not carry the ability to delete branches, delete the repository, or alter settings.
Branch protection is the backstop, and it is currently thin.launchpad requires one approval and has no required status checks, so success criterion 6 (just ci gates the merge) needs the check to be required, not merely present — otherwise a red sync PR is one click from landing.
Upstream content is untrusted input. The agent reads and merges code authored outside the cohort, and a resolution prompt containing upstream diff text is attacker-influenceable in the same way launchpad/review-agent/CONTAINMENT.md describes for PR-authored text. That containment contract should be reused, not reinvented.
Conflict-winner policy for the ~35 undocumented divergences — per-file, or per-category with named exceptions.
Cadence — daily is assumed (small deltas conflict far less than large ones); the alternative is upstream-tag-triggered.
How far mechanical resolution may go before escalating — rerere replay and merge=ours are clearly mechanical; a three-way merge the agent believes is unambiguous is the boundary case.
Filed by an AI agent (Claude Opus 5) on behalf of @tucktuck101, from direction given in session on 2026-08-21. Verified today against the GitHub API and the local clone: all branch divergence counts, the 324/282/42/9 file breakdown and its categories, commit authorship of the 255, the absence of rerere configuration, the contents of .gitattributes, that launchpad-26/main is an unmodified ancestor of upstream/main, and that ADR-0005 and ADR-0017 between them document 7 of the 42 files. Not verified: whether the three conflicts resolve to a correct merge — merge-tree reports textual conflicts, not semantic ones, and the four files that auto-merged cleanly could still be wrong in behaviour. just ci on a real merge branch is what would establish that, and it has not been run.
Delivered through
This umbrella PRD is delivered by the feature issues above (rescope 2026-08-24: Milestone > PRD > Feature > Task). It closes when the last of them ships.
Problem
This fork carries deliberate divergence from
block/buzz— including product-code changes, not just cohort process files — and nothing owns the job of keeping it current. Upstream moves daily; the fork has not merged upstream since 2026-08-17.That leaves two costs. The gap compounds: every day of drift makes the eventual merge larger and its conflicts harder, on a ~3,800-file upstream. And the cost lands on the wrong person at the wrong time — a contributor part-way through a feature discovers a conflict that has nothing to do with their work, in files they did not touch and whose divergence they may not know the reason for.
What is needed is a change agent that owns the
block/buzz→launchpad-26/buzzrelationship: it keeps the mirror current, absorbs the conflict work, resolves what it can safely resolve, and escalates the rest with enough context for a human to decide quickly. Contributors should learn about upstream only when they need to act on it.Conflict resolution is the product here, not a side effect of syncing. The fork's divergence is intentional and expected to grow.
Evidence
Measured against
launchpad-26/buzzandblock/buzzon 2026-08-21:launchpadis 255 ahead, 60 behindupstream/main. Merge-base is 2026-08-17; upstream committed as recently as 2026-08-20. No upstream commit has been merged intolaunchpadin that window.All 255 divergent commits are cohort-authored (Serina 192, tucktuck101 53, joshuavial 4, Ben Mitchell 6). None came from upstream.
Of 324 files the fork has changed, 282 are inside the
launchpad/scope and 42 are upstream files: ~17 process/meta (AGENTS.md,CONTRIBUTING.md, issue templates,.claude/skills/*), ~9 build/tooling (Justfile,lefthook.yml,bin/lefthook,scripts/instance-env.sh,ci.yml), ~5 deployment (Dockerfile,docker.yml,deploy/compose/*), and 9 product code (crates/buzz-cli/src/commands/pack.rs,crates/buzz-persona/src/resolve.rs, 6×desktop/src-tauri/**).A reason is recorded for 7 of those 42. ADR-0005 documents five deployment files; ADR-0017 documents the two lefthook pins. The other ~35, including all nine product-code files, have no recorded statement of why they diverge or which side should win a conflict.
git rerereis not enabled. Every recurring conflict is re-resolved from scratch, every time..gitattributessets only* text=auto eol=lf. No merge drivers, so files the fork permanently owns still conflict on every sync.launchpad-26/mainis a clean, unmodified ancestor ofupstream/main— 0 ahead, 221 behind. Confirmed intentional: it is the mirror through which updates arrive before being worked on locally.The 60-commit gap test-merges with exactly three conflicts.
git merge-tree launchpad upstream/mainauto-mergesAGENTS.md,Justfile,crates/buzz-cli/src/lib.rsanddesktop/src-tauri/src/managed_agents/restore.rscleanly, and conflicts on only:lefthook.yml— divergence documented (ADR-0017), so the winner is already known.github/workflows/ci.yml— divergence undocumented, configdesktop/src-tauri/src/managed_agents/runtime.rs— divergence undocumented, product codeOne conflict in each of the three resolution classes this PRD proposes: register-driven, mechanical, and semantic. The backlog is small today and the mechanism can be proven against a real case immediately.
The only sync automation that exists today runs on a contributor's personal fork and merges
launchpad-26/main, which is itself 416 commits behindlaunchpad. It syncs from a stale mirror.Success criteria
launchpad-26/mainfast-forwards fromupstream/mainunattended; a failure to do so is visible, not silent.rerereand/or merge drivers. Demonstrated by a repeat sync over the same file pair.just cigates every sync PR before it is mergeable. A sync that breaks the build is a failed sync, not a merged one.launchpaditself — see non-goals.Non-goals
rerere, merge drivers) is in scope; judgement is escalated.block/buzz. ADR-0017 records that the cohort is not currently sending changes upstream. If that changes it is a separate decision.launchpadhas eleven people working off it, and rebasing would defeatrerere. Merge only.Impacted components
Security implications
The agent holds write access to shared branches on a public repository and takes actions on them. That is the same risk class as
buzz-infrastructure#103, and the mitigations are the ones ADR-0015 already established for host access: the agent never holds a credential of its own beyond the workflow's scopedGITHUB_TOKEN, destructive or irreversible steps are proposed rather than taken, and every action is attributable.Three specifics:
contents: writeandpull-requests: writeand nothing else. It must not carry the ability to delete branches, delete the repository, or alter settings.launchpadrequires one approval and has no required status checks, so success criterion 6 (just cigates the merge) needs the check to be required, not merely present — otherwise a red sync PR is one click from landing.launchpad/review-agent/CONTAINMENT.mddescribes for PR-authored text. That containment contract should be reused, not reinvented.buzz-infrastructuregroup_vars must sit beside the inventory, and role defaults are not cross-role scope #103. It is the favourable case for that ADR — human present, explicit per-action instruction — but it should be decided there, and the workflow half ships independently of it.Decisions this PRD raises
To be filed as child ADRs, not decided here:
rererereplay andmerge=oursare clearly mechanical; a three-way merge the agent believes is unambiguous is the boundary case.buzz-infrastructuregroup_vars must sit beside the inventory, and role defaults are not cross-role scope #103.Filed by an AI agent (Claude Opus 5) on behalf of @tucktuck101, from direction given in session on 2026-08-21. Verified today against the GitHub API and the local clone: all branch divergence counts, the 324/282/42/9 file breakdown and its categories, commit authorship of the 255, the absence of
rerereconfiguration, the contents of.gitattributes, thatlaunchpad-26/mainis an unmodified ancestor ofupstream/main, and that ADR-0005 and ADR-0017 between them document 7 of the 42 files. Not verified: whether the three conflicts resolve to a correct merge —merge-treereports textual conflicts, not semantic ones, and the four files that auto-merged cleanly could still be wrong in behaviour.just cion a real merge branch is what would establish that, and it has not been run.