Context

The 361-coders-nz org hosted two siblings that drifted apart in scope but overlapped in content:

  • oxflow — deployed static hub at oxflow.design.3sixtyone.co. Landing index.html linking to four self-contained sub-apps (app/, flows-app/, presentation/, prototypes/). Also collected 43 stray PNGs from Playwright MCP sessions and a 9.5 MB rev1/ archive of superseded design work.
  • oxflow-docs — knowledge repo with CLAUDE.md, TEAM.md, BRANDING.md, templates/, docs/ (85 formal specs across 5 entity layers), research/, meetings/, status/, and a vanilla-JS SPA doc viewer at /app/ on port 8910.

Byte-level inventory showed the docs/ trees, plus presentation/, prototypes/, proposal/, and app/ folders, were identical copies between the two repos. Two places to write the same content invites drift; four team members working with AI agents would inevitably diverge. No ADRs existed to record why things were split.

We want a single source of truth for both planning decisions (research, ADRs, meetings) and implementation progress (specs, BMAD sync from the codebase).

We will merge oxflow and oxflow-docs into a single 361-coders-nz/oxflow monorepo, with history from both preserved via git-filter-repo.

Decision

Merge using git-filter-repo:

  1. Clone each repo into a temporary _rewrite/ workspace.
  2. Rewrite oxflow’s history: drop the redundant docs/ (canonical copy stays in oxflow-docs), drop local .claude/, then --to-subdirectory-filter apps/site.
  3. Leave oxflow-docs structure unchanged.
  4. git init a fresh oxflow-mono. Fetch + merge both rewritten repos with --allow-unrelated-histories.
  5. In a single reorg commit, flatten apps/site/ into the repo root — the duplicate folders (presentation/, prototypes/, proposal/, app/) were byte-identical to the oxflow-docs copies, so only index.html, vercel.json, .vercelignore, and flows-app/ needed to move up. apps/site/ was then removed.
  6. Move root PNGs → archive/screenshots/, .playwright-mcp/archive/mcp-snapshots/, rev1/archive/rev1/.
  7. Unify README.md (combined content of both) and .gitignore (adopt the broader oxflow rules + add Quartz build exclusions). Rewrite .vercelignore to exclude docs/, research/, decisions/, meetings/, status/, prompts/, raw-dumps/, templates/, meta/, apps/, archive/ from the static-site build.

Result: repo root matches the live Vercel serve path, so the existing Vercel project needs no configuration change. apps/ is reserved for the Quartz wiki (Phase 2).

Alternatives considered

  • Keep the two repos, sync with CI — rejected because two-PR workflow for cross-cutting changes creates drift and slows multi-agent work. Sync is harder than merge at this stage.
  • git subtree add — simpler than filter-repo but doesn’t rename tags cleanly and leaves a messier graph log. filter-repo deduplicated empty commits (commits that only touched dropped paths) automatically, which subtree doesn’t.
  • New repo, copy files, no history preserved — rejected; we wanted git log --follow to work on every file.

Consequences

Positive

  • One PR per change. One review flow. One CODEOWNERS. One Vercel project (+ a second for the wiki in Phase 2).
  • git log --follow traces every file back to its original commit in either source repo.
  • apps/ cleanly hosts future build-step apps (Quartz, and anything else) without polluting the deployed static hub.

Negative

  • filter-repo pruned commits from the oxflow side that only touched the redundant docs/ (e.g. “Add DevOps & Infrastructure design spec” + its revert). That’s fine because the canonical copy of those changes is in the oxflow-docs history, but it means a git log --all shows 28 commits instead of 31.
  • The two old repos should be archived in GitHub to prevent confused contributors pushing there.

Follow-up

  • Archive 361-coders-nz/oxflow (old) and 361-coders-nz/oxflow-docs in GitHub with a README pointer to the new repo.
  • Update the Vercel project to pull from the new monorepo.
  • Phase 2: deploy Quartz from apps/wiki/ on a new subdomain.
  • Phase 2: wire the BMAD sync GitHub Action once the real codebase repo exists (see 0003-bmad-sync-contract).

References