Apply PR #284's doc updates selectively — cloudflared, SSH overlays, host-bind overlays, SANDBOX_PASSWORD, and openssh-server references removed everywhere. Postgres mentions preserved; postgres compose overlay restored. Doc edits: - AGENTS.md / CLAUDE.md (symlink): drop /cloudflared-tunnel skill row, rewrite "Exposing apps" to mention generic tunnels/proxies. - README.md, docs/installation.md: drop SANDBOX_PASSWORD, cloudflared, openssh-server, host-overlay references. - docs/quickstart.md: keep postgres link, drop cloudflare link, mention postgres overlay is opt-in. - docs/integrations/github.md: drop SSH-overlay section. - docs/integrations/cloudflare.md: deleted. - docs/agents/{deepagents,opencode}.md: drop host-overlay sections. - context/rules/git.md: drop "Advanced opt-ins" SSH section. - Makefile: drop _check-jq / _check-config gates; jq invocation is now defensive (only runs when jq + config.json both present). - apps/docs/src/pages/index.tsx: keep postgres in "composable substrate" copy, drop cloudflare tunnels / Caddy gateway mentions. - .claude/skills/{agent-browser,harness-audit,strategic-proposal}/SKILL.md and .claude/agents/command-builder.md: drop cloudflared references (strategic-proposal infra row keeps PostgreSQL 16). - CHANGELOG.md [Unreleased] § Removed: new entry for #283 listing the 10 deleted overlays + companion infrastructure; note postgres was kept. Infra: - Restored .devcontainer/docker-compose.postgres.yml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6.3 KiB
Git Workflow
Issue Titles
Format: <prefix>(<issue#>): <shortdesc>
<prefix> ∈ feat · bug · task · audit · skill · agent
(matches .github/ISSUE_TEMPLATE/<prefix>.md)
Example: feat(#42): slack thread replies
Create issue first so
<issue#>exists, then branch.
Branch Names
Format: <prefix>/<issue#>-<short-desc>
<short-desc>: kebab-case, ≤5 words- Base off default target branch (see below)
Example: feat/42-slack-thread-replies
Default Target Branch
Use first existing in repo:
development(preferred)main(fallback)master(fallback)
Detect via git show-ref --verify --quiet refs/heads/<name> (or remote refs/remotes/origin/<name>). PRs target this branch; new branches cut from it.
Git Authentication
Inside sandbox, run gh auth login && gh auth setup-git during onboarding. GitHub CLI installs credential helper — git push / git fetch use your GitHub token — no SSH keys required.
PR Titles
Format: FROM <source-branch> TO <target-branch> (literal)
Example: FROM feat/42-slack-thread-replies TO development
PR Bodies
- Link issue:
Closes #<issue#>(orFixes/Resolves) - Target default target branch (
development→main→master, whichever exists)
Commit Messages
Format: <type>: <description> where <type> ∈ feat · fix · task · audit · skill
Changelog
Root CHANGELOG.md follows Keep a Changelog with CalVer tags.
Every PR with user-visible impact MUST add entry under ## [Unreleased] heading, in same commit as change. Categories: ### Added · ### Changed · ### Fixed · ### Removed · ### Deprecated · ### Security.
Skip entries only for pure chores with no runtime or workflow effect (internal refactors, test-only changes, typo fixes). When in doubt, add entry.
Entry format: one line, imperative mood, link PR or issue.
### Added
- Slack thread replies in multi-channel mode ([#42](https://github.com/ryaneggz/open-harness/pull/42)).
At release time, /release promotes [Unreleased] to new ## [<VERSION>] - YYYY-MM-DD section and re-seeds empty [Unreleased] block. Do not hand-edit versioned sections after tag ships.
Worktrees
Default path: .worktrees/<branch> at project root. Create .worktrees/ if missing. Independent project clones (own .git, not harness branches) live under .worktrees/project/<project-name>/<repo>/ — see .worktrees/README.md.
mkdir -p .worktrees
git worktree add .worktrees/<branch> <branch> # existing branch
git worktree add -b <prefix>/<issue#>-<short-desc> \
.worktrees/<prefix>/<issue#>-<short-desc> $BASE # new branch off $BASE
Example path: .worktrees/feat/42-slack-thread-replies
Cleanup: git worktree remove .worktrees/<branch>.
.worktrees/ gitignored (see .gitignore); only .worktrees/README.md tracked.
Stale worktree policy
Worktrees older than 30 days without a corresponding open PR may be removed via git worktree remove; corrupted worktree directories may be removed with rm -rf after confirming they are not valid git worktree list entries. The /harness-audit skill flags stale-worktree candidates for review before cleanup.
Isolating in-flight work
When main checkout has unstaged changes you shouldn't commit in current PR, do not stash-and-switch-branches (risk of losing context). Instead:
- Cut worktree off target base:
git worktree add -b <new> .worktrees/<new> $BASE. - Copy in-flight files into worktree: plain
cppreserves main checkout's working tree untouched. - Commit in worktree. Main checkout stays exactly as-is.
Before discarding duplicated state from main checkout, verify byte-equivalence with committed branch:
for f in <changed-files>; do
a=$(md5sum "$f" | awk '{print $1}')
b=$(git show <branch>:"$f" | md5sum | awk '{print $1}')
[ "$a" = "$b" ] && echo "same: $f" || echo "DRIFT: $f"
done
Only after all files show same: run git restore / rm -f to clean main checkout.
Stacked PRs
When PR needs work from another open PR (e.g. feature depending on in-flight docs or infra changes), stack instead of waiting:
git fetch origin <parent-branch>- In worktree:
git rebase origin/<parent-branch>. Resolve conflicts; tests may need re-running. git push --force-with-leasegh pr edit <pr#> --base <parent-branch>gh pr edit <pr#> --title "FROM <branch> TO <parent-branch>"
When parent PR merges, GitHub auto-rebases stacked PR's base to parent's target (development). Do not force-push again after parent merges — let GitHub handle retarget.
Keep stacks shallow: one level routine, two levels rare, three levels means something wrong with sequencing.
Releases
Versioning: CalVer YYYY.M.D for first release of day, then YYYY.M.D-N (N starts at 2) for subsequent releases.
Release branch: release/<VERSION> (e.g., release/2026.4.18-2).
Pushing tag triggers .github/workflows/release.yml — runs lint + type-check + tests, builds ghcr.io/ryaneggz/openharness:<VERSION>, pushes to GHCR, creates GitHub Release.
Pre-flight before tagging:
- On intended source branch, no uncommitted changes
Procedure:
VERSION=$(date '+%Y.%-m.%-d') # append -N if tag exists
git checkout -b "release/$VERSION"
git push origin "release/$VERSION"
git tag "$VERSION" && git push origin "$VERSION" # triggers CI release
After pushing tag, monitor .github/workflows/release.yml and verify both GitHub Release and GHCR image. Use /release skill for full automated procedure (version detection, pre-flight, tag, CI polling, verification).
After Push
If .claude/skills/ci-status/ exists, invoke /ci-status after every git push to confirm pipeline green before declaring work done. Push failing CI is not done.
Workflow
Let $BASE = default target branch (detected per rule above).
- Create GitHub issue → record
<issue#> git checkout -b <prefix>/<issue#>-<short-desc> $BASE- Add
CHANGELOG.mdentry under## [Unreleased](see § Changelog) — unless change is pure chore - Commit with
<type>: <description> git push -u origin <branch>→ then/ci-status(if skill exists)gh pr create --base $BASE --title "FROM <branch> TO $BASE" --body "Closes #<issue#>"