doesitarm/docs/research/private-public-repo-sync-patterns-2026-04-04.md
ThatGuySam 1248c705b0 docs(plan): add discovery and deploy follow-up research
Capture the next discovery, security, compatibility-data, and dual-deploy planning work, and ignore local Vercel/env state that should not be committed. This keeps the operational research with the repo while avoiding accidental local-config churn.

Constraint: Must not alter production runtime behavior
Rejected: Fold research notes into the runtime fix commit | obscures the user-facing app-test correction with planning-only material
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep .omx local state untracked even when committing broad workspace updates
Tested: Document review only
Not-tested: No runtime verification required for docs and ignore rules
2026-04-04 15:38:39 -05:00

222 lines
9.7 KiB
Markdown

# Private/Public Repo Sync Patterns For doesitarm
Tease: Git can push to a second remote, but it does not natively maintain a safe long-lived branch that "merges everything except `docs/`."
Lede: For `doesitarm` on 2026-04-04, the best-fit pattern is a second repo/remote plus an automated one-way export from `origin/master` that rewrites out `docs/` and force-pushes the result.
Why it matters:
- `docs/` is already present on `origin/master`, so excluding it from a future mirror does not make it private retroactively.
- `docs/` does not appear to participate in the app build, which makes export-time exclusion low-risk.
- Cross-repo automation on GitHub needs separate auth; the default workflow token is not enough for another private repo.
Go deeper:
- Simple one-way sync: fresh clone -> `git filter-repo --path docs/ --invert-paths` -> force-push to a second remote.
- Faster repeated projection: evaluate `splitsh-lite` if export speed or repeatability becomes important.
- Advanced bidirectional filtered views: `josh` is the serious option, but it is heavier than this repo likely needs.
Date: 2026-04-04
## Scope
Research whether `doesitarm` should support a `private-main`-style branch or
remote that automatically tracks the public default branch while excluding
paths such as `docs/`, and identify better patterns if they exist.
## Short Answer
Yes, you can push to a different remote from the public repo.
No, the durable pattern is not a long-lived `private-main` merge branch that
keeps deleting `docs/` after every merge. Git branches and merges are full-tree
operations, and sparse checkout does not change that.
For this repo, the cleanest pattern is:
1. Keep `origin/master` as the source branch.
2. Add a second remote or second repository for the private target.
3. Run a one-way export job on each push to `master`.
4. In that job, create a sanitized tree/history with `docs/` removed.
5. Force-push the sanitized result to the private remote branch.
If the real requirement is that future docs stay private, the better topology
is the reverse: keep the canonical repo private and generate the public export.
Inference:
That last recommendation is based on the current repo state: `docs/` is already
committed on `origin/master`, so a private mirror without `docs/` only changes
future distribution, not past public exposure.
## What The Repo Already Knows
- The default remote today is only `origin`, pointed at the public GitHub repo.
- The default tracked branch is `origin/master`, not `main`.
- There is no checked-in `.github/` workflow that already handles cross-repo
sync.
- `docs/` currently contains repo-local planning and research material:
[docs/app-flow.md](/Users/athena/Code/doesitarm/docs/app-flow.md),
[docs/plans/app-test-typescript-refactor.md](/Users/athena/Code/doesitarm/docs/plans/app-test-typescript-refactor.md),
and dated research memos under
[docs/research](/Users/athena/Code/doesitarm/docs/research).
- `docs/` is already present in `origin/master` history as of 2026-04-04.
- The build surface in
[package.json](/Users/athena/Code/doesitarm/package.json)
does not appear to depend on `docs/`.
## What The Evidence Says
- Different remote from the public repo:
yes. Git supports separate remotes, and the `git remote` docs explicitly say
that when fetch and push use different locations, you should use two separate
remotes rather than pretending they are the same remote.
- Long-lived branch with path exclusions:
not a native Git capability. Git merges operate on full trees, not
"everything except these directories."
- Sparse checkout:
not the answer here. The `git sparse-checkout` docs describe it as a working
directory reduction feature, and they note that operations such as merge or
rebase may still materialize paths outside the sparse specification.
- `git filter-repo`:
good fit for one-way export. The Git project now recommends it instead of
`filter-branch`, and its docs support `--invert-paths` for "keep everything
except these paths" rewrites. That matches "mirror the repo except `docs/`."
- `splitsh-lite`:
promising when you want repeatable projections into standalone repos and care
about performance. Its README supports split prefixes that can include
exclusions and uses a history cache, which is more appropriate than a manual
merge branch when this becomes a repeated sync lane.
- `josh`:
the advanced option. Its repo describes a proxy Git server that exposes
filtered histories as standalone repos and synchronizes between original and
filtered views. This is the closest thing to a "real" selective mirror
system, but it adds operational weight.
- GitHub Actions auth:
the default `github.token` is scoped to the current repository. If a workflow
in the public repo needs to push to a different private repo, you need a PAT,
deploy key, or GitHub App token instead.
## What Works
- A second remote or second repository for the private target.
- A one-way generated branch or repo, not a hand-maintained merge branch.
- Rebuilding the private export from `origin/master` every run.
- Treating the private mirror as generated output with force-pushes allowed.
- Keeping development on one source branch and one source-of-truth repo.
## What To Avoid
- Do not maintain `private-main` by repeatedly merging `master` and deleting
`docs/`. That creates unnecessary churn and eventual conflict debt.
- Do not use sparse checkout as if it were a publishing filter.
- Do not make the generated private mirror a peer source of truth unless you
also adopt a projection system designed for bidirectional sync.
- Do not rely on the default GitHub Actions token for pushes to another repo.
- Do not assume this setup hides `docs/` historically; those files are already
in the public remote history.
## Best Patterns
## 1. Best Fit For This Repo: one-way export to a second remote
Use a second remote, for example `private`, pointing at a separate private
GitHub repository. On each push to `origin/master`, run an automation that:
1. checks out `master`
2. authenticates to the private repo with a PAT, deploy key, or GitHub App
3. creates a fresh export clone or export worktree
4. rewrites out `docs/` and any other excluded paths
5. force-pushes the sanitized result to the private repo branch
Why this is the best fit:
- it matches the repo's current single-source workflow
- it does not depend on path-aware merges that Git does not have
- it keeps excluded-path logic in one place
- it is easy to reason about and recover from
Tradeoffs:
- exported commit SHAs will differ from public `master`
- the private mirror should be treated as generated/read-only
## 2. Better If Repeated Projection Becomes Core: `splitsh-lite`
If you end up publishing multiple filtered mirrors or need fast repeated
updates, `splitsh-lite` is worth a spike. It is built for turning repository
views into standalone histories and caching the work.
Tradeoffs:
- more specialized operational knowledge
- less obvious to future maintainers than a simple export script
## 3. Better Only For Advanced Bidirectional Partial Views: `josh`
If the real requirement becomes "developers commit through filtered views and
changes synchronize both directions," `josh` is the pattern to study.
Tradeoffs:
- significant infrastructure/runtime overhead
- far more complexity than `doesitarm` appears to need today
## 4. Adjacent But Not The Same Problem: GitHub Private Mirrors
GitHub's `private-mirrors` app is relevant if the goal is to collaborate
privately around a public repository and upstream later. It is not the right
answer for "same repo minus `docs/`," but it is worth noting as a neighboring
pattern.
## Recommendation
For `doesitarm`, use a separate private repository plus a generated sync job.
Name the target branch after the actual default branch in this repo, for
example `private-master` or simply `master` on the private remote.
Do not implement this as a merge branch.
If the aim is just "same code, different remote, minus `docs/`," a generated
one-way mirror is the right level of machinery.
If the aim is "keep future internal docs private," move the source of truth to
a private repo and generate the public mirror from that private origin.
## Missing Information
- Whether the private target is intended to be read-only/generated or whether
anyone will commit directly to it.
- Whether `docs/` is the only excluded path or just the first example.
- Whether the real goal is secrecy, deployment hygiene, or private-only
collaboration before publishing.
## Source Links
- Git remote docs:
https://git-scm.com/docs/git-remote
- Git sparse-checkout docs:
https://git-scm.com/docs/git-sparse-checkout
- `git-filter-repo` repository:
https://github.com/newren/git-filter-repo
- `git-filter-repo` manual:
https://www.mankier.com/1/git-filter-repo
- `splitsh-lite` repository:
https://github.com/splitsh/lite
- `josh` repository:
https://github.com/josh-project/josh
- `actions/checkout` README:
https://github.com/actions/checkout
- GitHub App auth in GitHub Actions:
https://docs.github.com/en/enterprise-cloud@latest/apps/creating-github-apps/authenticating-with-a-github-app/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow
- GitHub deploy keys:
https://docs.github.com/v3/guides/managing-deploy-keys
- GitHub Private Mirrors app:
https://github.com/github-community-projects/private-mirrors
- Stack Overflow, partial sharing of Git repositories:
https://stackoverflow.com/questions/278270/partial-sharing-of-git-repositories
## Source Quality Notes
- HN and Lobsters searches on 2026-04-04 did not surface a clearly better
mainstream pattern than the Git/GitHub docs plus the specialized projection
tools above.
- Primary docs and project READMEs were materially more useful than forum
commentary for this question.