# Build plan — adopt upstream domain reorg `8356eb34` (#1726) into the Sea Haven open-swe fork Date: 2026-07-17. Base: `dev` (clean, `a518a129`). Scoping report: `reorg-scoping-report.md` (same directory: `docs/upstream-sync/domain-reorg/`). ## Goal & strategy Adopt upstream's 298-file domain reorg as a **file-move exercise applied to the fork's tree**: fork file contents, upstream layout. Never take upstream file contents except the 21 verified thin structural "A" shims (`agent/graphs/*`, `agent/runtime/*`, `agent/api/*`, `agent/webhooks/{common,*_routes}.py` skeletons, package `__init__.py`s). Rationale: the fork has settled permanent divergences (sync sandbox lifecycle + 4-case `__creating__` sentinel, workflow-token security model, bun toolchain, Atlassian integration, plan-mode #130, TID-COLLIDE-01 guard) — adoption is layout convergence, not content convergence. Payoff: kills the per-pick path-remap tax on all future upstream cherry-picks; 8 of 19 deferred ledger rows become clean/near-clean, including priority security pick #1736 (written against `agent/webhooks/common.py`, which only exists after this exercise). ## Approved decisions (Adam, 2026-07-17) 1. **FastAPI/webapp split: APPROVED.** Fork's 2,590-line `agent/webapp.py` splits into `agent/webhooks/common.py` (shared verify/dispatch helpers), `agent/api/{app,health}.py`, and per-source `{github,linear,slack,jira,confluence}_routes.py`; `webapp.py` remains a compatibility shim. `/sh-security-review` required on that commit before merge. 2. **Atlassian placement (re-confirmed by Adam 2026-07-17):** fork-only `jira_routes.py` + `confluence_routes.py` mirroring upstream's per-source pattern; **Atlassian Connect lifecycle/descriptor routes (`/connect/*`) fold into `confluence_routes.py`** (Connect is the Confluence trigger; Jira uses Automation webhooks). JWT/qsh machinery stays in `agent/utils/atlassian_connect.py` (unmoved). Split out a `connect_routes.py` later only if Jira migrates to Connect. 3. `langgraph.json` graph entrypoints retarget to `agent.graphs.*` shims; add fork-only `agent/graphs/ci_monitor.py` shim for symmetry. `http.app` stays `agent.webapp:app`. 4. Reviewer modules → `agent/review/` package (9 pure moves; fork reviewer content rides along). 5. CI-autofix cluster (upstream-deleted): keep-baseline; wire its webhook triggers through the split `github.py`/`common.py`; tests → `tests/github/`. 6. UI `ported/` → `features/agents/experiments/` + single tsconfig/eslint exclude glob; bun stays; delete stray `ui/pnpm-workspace.yaml`. 7. Sequencing: reorg lands **before** #1736. ## Hard rules (from fork-maintenance playbook + scoping hazards) - **Content-source discipline:** upstream content only for the 21 "A" shims. `agent/webhooks/{github,linear,slack}.py`, `tests/conftest.py`, `tests/e2e/harness.py` exist on both sides with different content — always fork content + replicated import rewires; never `git checkout upstream` on them. - Handlers keep **module-attribute access style** (`common.X`, `service.X`) exactly as upstream did, so the 240 `monkeypatch.setattr(webapp, ...)` test sites retarget cleanly and no re-import rebind hazard is introduced. - Every moved test keeps its impl-side pairing (impls mostly don't move; 13 fork-only tests get the placements from scoping §2c: Atlassian webhook tests → `tests/webhooks/`, `test_atlassian_connect.py` → `tests/auth/`, client-util tests → `tests/tools/`, `test_repo_binding_isolation.py` → `tests/sandbox/`, `test_auth_error_leak.py` → `tests/auth/`, `test_app_bot_identity.py`/autofix tests → `tests/github/`). - Verify wheel packaging ships `agent/resources/default_prompt.md` (hatchling `packages=["agent"]` should carry it — build and inspect the wheel in C1; add explicit include only if missing). - No secrets/config placement changes anywhere in this exercise (no new env vars, no Secrets Manager/SSM changes). - CI ladder per commit: `ruff check` + `ruff format --check` → `pytest --co -q` → full unit → E2E (Playwright + real LangGraph dev server) where the commit touches wiring; `bunx tsc --noEmit` + bun build for UI commits. `make dev` boot-check for C3 (all graphs + FastAPI app load). ## Jira linkage No Jira issue tracks this work; per handbook `git-workflow.md`, the branch omits the issue key and uses a plain description. (If Adam cuts a ticket, rename branch to `refactor/-domain-reorg-adoption` before the PR opens.) ## Commit sequence (branch `refactor/domain-reorg-adoption` off dev; one PR; **merge-commit merge ONLY** — squash and rebase are explicitly forbidden for this PR to preserve per-cascade bisectability; dev ruleset allows merge commits) - **C1 — docs/resources/assets** (~1h): `git mv` `INSTALLATION.md`/`CUSTOMIZATION.md` → `docs/`, `static/` → `assets/` (fix README refs), `default_prompt.md` → `agent/resources/` + apply the `importlib.resources` loader hunk to fork's `prompt.py` + `__init__.py`. Gate: ruff + unit + **wheel build inspection**. - **C2 — `agent/review/` package** (~half day): mv 9 reviewer/style modules per map, rewrite 38 importer files, `agent/review/__init__.py` with fork's export surface. Gate: ruff + `pytest --co` + reviewer unit suite. - **C3 — graphs/runtime/providers shims + `langgraph.json` + CI hardening** (~2h): adopt the 21 upstream A-shims (verify each delegates to fork modules), add `agent/graphs/ci_monitor.py`, retarget `langgraph.json`; **pin `bun-version` in `.github/workflows/ci.yml`** (removes the setup-bun latest-resolution flake documented in project memory). Gate: `pytest --co` + `make dev` boots all graphs (incl. `ci_monitor`) + FastAPI app. - **C4 — FastAPI split** (~1–1.5 days, critical): split fork `webapp.py` per approved decisions 1–2; sed handler modules `webapp.` → `common.`; retarget the 240 monkeypatch sites, `tests/conftest.py`, `tests/e2e/harness.py`; keep `webapp.py` shim. Gate: full unit + **full E2E** (the only layer catching wiring drift) + **residual-importer sweep**: `git grep -l 'agent\.webapp\|from agent import webapp'` across the whole tree must return only the shim and intentional compat references, so the shim cannot silently mask missed rewires. **`/sh-security-review` on this commit's diff. Failure path: findings are addressed as NEW commits on top of the branch (e.g. "C4a: address security-review findings") — no history rewrite or force-push once any review (security or PR) has started, preserving the review/CI trail; the PR must not merge until the review passes — no exceptions.** - **HARD GATE:** C5 must not begin until C4 has full unit + E2E green **and** `/sh-security-review` passed. (C1–C3 may proceed independently before C4.) - **C5 — `tests//` moves** (~half day): mechanical map moves + remaining R<100 monkeypatch retargets + the 13 fork-only placements. Gate: `pytest --co` + full unit. - **C6 — UI `features/` moves** (~half day–1 day): `git mv` per map incl. `ported/` → `experiments|chat`, rewrite `@/` imports (54 importers + moved files), exclude-glob swap, AgentPromptBar shim retarget, delete `ui/pnpm-workspace.yaml`. Gate: `bunx tsc --noEmit` + bun build + Playwright E2E. - **C7 — docs + ledger + memory** (~2h): update fork `CLAUDE.md`/`README.md`/`AGENTS.md` path references (CLAUDE.md architecture sections name `agent/webapp.py` and old test paths); flip `8356eb34` → Landed in `triage.jsonl` + re-triage notes on the 8 unblocked rows + `make triage-render`. **Documentation/memory obligations (owned by the C7 executor, i.e. Claude in this conversation):** (a) update the `open-swe-upstream-triage-status` and project memory entries **including a summary of the new module layout** (`agent/{graphs,runtime,api,review,resources,webhooks/*_routes}`, `tests//`, `ui/src/features/`); (b) perform the Confluence check — search IT-space pages for any repo module-map documentation; update it if found, and **record the outcome either way ("updated page " or "no Confluence change required — no IT page documents the module map") in the PR description and in project memory**. The AWS Architecture Map is unaffected (no AWS resource changes). **Fallback per standing policy: if Confluence is inaccessible, state so explicitly in the PR description and project memory — the documentation update is then outstanding, not silently skipped.** C7's doc/ledger changes ship inside the PR, so they are covered by the PR review; memory-file updates are summarized in the PR description for the same visibility. ## Merge & deployment - PR from `refactor/domain-reorg-adoption` → `dev`; CI green (all layers) → `@openswe` review (or Adam-delegated review) → **merge commit only** (no squash/rebase). PR review scope must explicitly name the C2 reviewer-module moves (review-automation surface) and the C4 auth-surface split so the reviewer examines both. - `/sh-security-review` must have run on C4 with confirmed critical/highs resolved (or machine-suppressed with justification) before merge — see C4 failure path. GPT-4.1 cross-family review: not strictly triggered (no IAM/policy or Lambda-signature change — `publish_review`-style tool contracts untouched; `langgraph.json` strings are deployment manifest, not IAM), but run as **opt-in on the C4 diff** given webhook-verification code movement. - **Post-deploy verification checklist (explicit, before declaring done):** LangGraph deployment redeploys with the retargeted `langgraph.json`; all graphs (agent, reviewer, analyzer, chat, scheduler, ci_monitor) registered; `/health` OK; `GET /connect/atlassian-connect.json` serves the descriptor; one webhook round-trip per source (GitHub PR comment, Slack mention, Linear, Jira Automation test-fire, Confluence comment) where feasible. Note: external registrations (GitHub App webhook URL, Slack event URL, Jira Automation rule, Connect descriptor URL) are verified UNCHANGED by this exercise — the HTTP surface and all routes keep their paths — so no external system updates are required; the checklist confirms this empirically rather than assuming it. - **Rollback:** revert the merge commit restores the pre-reorg layout wholesale; because the HTTP surface and external registrations are unchanged, a rollback requires NO external-system reverts — re-verify with the same checklist after any rollback. C1–C3 independently revertible pre-merge; C5/C6 path-only. - **Post-merge cleanup (git-workflow convention):** delete `refactor/domain-reorg-adoption` on origin after merge; delete local copies and prune worktrees. - **Verification records:** post-deploy checklist results are recorded in the PR description (or a comment) as the traceability artifact — **responsibility: the C7 executor (Claude in this conversation)**. After any rollback, normal operation does not resume until the same checklist fully passes. - **Confluence-outstanding follow-up:** if Confluence is inaccessible at merge time, the outstanding update is recorded in project memory with an explicit "outstanding as of " marker so it surfaces at the next session on this project — it does not defer indefinitely. - **Severity clarification for the C4 failure path:** fixes are stacked as new commits regardless of severity, full stop. If the security review reveals a *fundamental design flaw* in the split (not a fixable finding), the response is not a history rewrite — the PR is closed, the plan returns to the drafting stage, and a revised plan goes back through `/sh-plan-review` on a fresh branch. - **Shim lifetime:** `webapp.py` (and the `agent/graphs/*` shims) mirror upstream's own permanent compatibility shims — they are kept for as long as upstream keeps theirs, since layout parity is the goal; revisit only if upstream removes them. - **bun-version pin:** permanent policy (version bumped deliberately like any dependency), not a temporary workaround — resolves the setup-bun latest-resolution flake class permanently. ## Post-merge follow-ups (separate work, not this PR) 1. Pick #1736 (GitHub token binding) — near-clean post-split; still gated by its ledger row: GPT-4.1 cross-family review + `/sh-security-review`. 2. Re-triage the 5 now-clean picks (#1732, #1761, #1744, #1748, #1742) — cheap batch. 3. Update `sh-openswe` deployment notes/memory if the redeploy surfaces anything. ## Rollback story Single revert of the merge commit restores pre-reorg layout wholesale. Before merge: each cascade commit is independently droppable except C4→C5 ordering (C5 assumes post-split monkeypatch targets). Working artifacts for the build agents: `docs/upstream-sync/domain-reorg/{movemap-m50.txt, cross.json, forkonly.json}`.