# progress


## US-005 — 2026-05-17
- **Status**: PASS
- **Commit**: pending
- **Change**: Inserted `### 📦 For forks / self-host` subsection into `README.md` after the closing paragraph of `## 📦 Install`, before `## 🚀 Use it`.
- **Verified**: line 17 unchanged; blockquote callout present; same `<your-org>/<your-fork>` placeholder in both URL path and `OH_GITHUB_REPO` env var; branch/trust/footnote content present; 10 balanced code fences (5 pairs).

## US-006 — 2026-05-17
- **Result**: PASS
- **Story**: docs/installation.md env-overrides table + Forking section
- **Changes**:
  - Added OH_GITHUB_REPO and OH_GITHUB_REF rows to env-overrides table
  - Annotated OH_INSTALL_REF row as back-compat alias of OH_GITHUB_REF
  - Added "Forking this harness" subsection (4 lines + code block) after env-overrides section
  - Added "Forkers: substitute your fork URL here." comment above git clone in Manual Installation
- **Verified**: git diff -- docs/quickstart.md shows no changes; grep confirms curl line present
- **grep -c '^|' docs/installation.md**: 40

## US-001 — 2026-05-17 UTC

**Title**: OH_GITHUB_REPO env var parameterizes the clone
**Files changed**: scripts/install.sh, tasks/fork-friendly-install/prd.json, tasks/fork-friendly-install/progress.txt
**Commit**: dbf8623
**Result**: PASS

### What I did
Inserted `OH_GITHUB_REPO="${OH_GITHUB_REPO:-ryaneggz/open-harness}"` with bash `=~` regex validation immediately after `REPO_DIR="$HOME/.openharness"` on line 180 and before the migration block comment at line 182. Added a fork-warn `if [ "$OH_GITHUB_REPO" != "ryaneggz/open-harness" ]` block. Replaced both hardcoded clone URLs at old lines 241 and 244 with `"https://github.com/${OH_GITHUB_REPO}.git"` in lockstep.

### Learnings for future iterations
- The local-run detection at line 173 fires when script is run from within the harness directory (SCRIPT_DIR parent has .devcontainer/docker-compose.yml). Our validation lives in the `else` branch — only fires for real-world installs, not local test runs from the repo root.
- Both clone URL lines (with and without `--branch`) must be replaced in the same edit — missing one is a silent partial fix.
- shellcheck baseline: 11 warnings (pre-existing). Post-edit: 11 (no regression).
- bash `[[ =~ ]]` anchors `^...$` match the full string; grep substring matching is forbidden per AC and Critic A H1/H2.

---

## US-002 — 2026-05-17 UTC

**Title**: OH_GITHUB_REF aliases OH_INSTALL_REF
**Files changed**: scripts/install.sh, tasks/fork-friendly-install/prd.json, tasks/fork-friendly-install/progress.txt
**Commit**: (pending)
**Result**: PASS

### What I did
Inserted OH_GITHUB_REF alias resolution block (lines 191-195 in install.sh) immediately after the fork-warn `fi` block and before the population/migration classification comment. The precedence warn fires before alias resolution: when both `OH_GITHUB_REF` and `OH_INSTALL_REF` are non-empty and differ, the warn "OH_GITHUB_REF and OH_INSTALL_REF both set with different values; OH_GITHUB_REF wins." is emitted. Then `OH_GITHUB_REF="${OH_GITHUB_REF:-${OH_INSTALL_REF:-}}"` resolves the canonical var. Updated the branch-clone guard at the fresh-clone block from `if [ -n "${OH_INSTALL_REF:-}" ]` to `if [ -n "$OH_GITHUB_REF" ]` and updated the `--branch` argument and ok message to use `$OH_GITHUB_REF`.

### Acceptance criteria verification
- **Alias resolution**: `OH_GITHUB_REF="${OH_GITHUB_REF:-${OH_INSTALL_REF:-}}"` present at line 195.
- **Clone guard**: `if [ -n "$OH_GITHUB_REF" ]` at line 255 — fires when either variable is set.
- **Back-compat**: `OH_INSTALL_REF=v1.2.3` with OH_GITHUB_REF unset → alias resolves OH_GITHUB_REF=v1.2.3 → clone gets `--branch v1.2.3`. Code path verified by inspection.
- **Precedence**: `OH_GITHUB_REF=v2.0 OH_INSTALL_REF=v1.0` → warn fires (both non-empty, differ) → alias keeps OH_GITHUB_REF=v2.0 → clone gets `--branch v2.0`. Code path verified by inspection.
- **No deprecation warning**: only the precedence warn (on differing values) is added; no deprecation warn.
- **bash -n**: PASS.
- **shellcheck**: 11 warnings (no regression vs baseline of 11).

---

## US-003 — 2026-05-17 UTC

**Title**: Pull path validates remote against OH_GITHUB_REPO
**Files changed**: scripts/install.sh, tasks/fork-friendly-install/prd.json, tasks/fork-friendly-install/progress.txt
**Commit**: (pending)
**Result**: PASS

### What I did
Added `normalize_gh_slug()` helper function (lines 16-33) immediately after the `die()` helper in the colours/helpers block. The function strips `https://github.com/` or `git@github.com:` prefix and trailing `.git` suffix using bash parameter expansion, yielding an `owner/repo` slug.

In the pull branch (`if [ -d "$REPO_DIR/.git" ]`, now lines 264-296), inserted the remote-check block before the clean-tree diff check:
1. Reads `git -C "$REPO_DIR" remote get-url origin 2>/dev/null || true` into `__ORIGIN_RAW` — the `|| true` is required because `set -e` would otherwise abort if no `origin` exists.
2. Normalizes `__ORIGIN_RAW` and `OH_GITHUB_REPO` to slugs via `normalize_gh_slug`.
3. If origin is empty or slugs don't match: emits 5-line multi-part WARN (raw URL, skip notice, 3 numbered steps, rm -rf state note) and skips pull entirely.
4. If match: delegates to the existing clean-tree pull path (no behavior change for upstream users).
5. Cleans up temp vars with `unset`.

### Acceptance criteria verification
- **git remote get-url with 2>/dev/null || true**: present at line 266.
- **Normalize all 4 forms**: tested — `https://github.com/owner/repo.git`, `https://github.com/owner/repo`, `git@github.com:owner/repo.git`, `git@github.com:owner/repo` all normalize to `owner/repo`. PASS (5/5).
- **Empty origin → mismatch**: `[ -z "$__ORIGIN_RAW" ]` guard at line 269 routes to warn+skip path. PASS.
- **Multi-line recovery message**: 5 warn() calls covering raw URL, skip notice, 3 numbered steps (backup, rm -rf, re-run), and rm -rf state note. PASS.
- **git pull skipped on mismatch**: `git pull --ff-only` is in the `else` branch (line 280); unreachable when mismatch condition is true. Verified by code-path inspection. PASS.
- **No remote modification**: no `git remote set-url` anywhere in the block. PASS.
- **bash -n**: PASS.
- **shellcheck**: 11 warnings (no regression vs baseline of 11). PASS.

---

## US-004 — 2026-05-17 UTC

**Title**: Help text documents the new env vars
**Files changed**: scripts/install.sh, tasks/fork-friendly-install/prd.json, tasks/fork-friendly-install/progress.txt
**Commit**: (pending)
**Result**: PASS

### What I did
Added two lines to the `Env vars:` block inside the `print_help` heredoc in `scripts/install.sh`:
- `OH_GITHUB_REPO       GitHub repo to clone (default: ryaneggz/open-harness)`
- `OH_GITHUB_REF        Git ref to clone (alias: OH_INSTALL_REF)`

Added one fork-flow example to the `Examples:` block:
```
OH_GITHUB_REPO=myorg/my-harness curl -fsSL \
  https://raw.githubusercontent.com/myorg/my-harness/main/scripts/install.sh | bash
```

### Acceptance criteria verification
- **Env vars block**: both OH_GITHUB_REPO and OH_GITHUB_REF present with correct descriptions. PASS.
- **Examples block**: fork-flow example present with correct raw-GitHub URL pattern. PASS.
- **Usage line preserved**: `grep -c 'oh.mifune.dev' scripts/install.sh` returns 3. PASS.
- **bash -n**: PASS.
- **shellcheck**: 62 lines (no regression vs baseline of 62). PASS.
- **--help output**: verified both vars and fork example appear in `bash scripts/install.sh --help`. PASS.

---

## US-007 — 2026-05-17 UTC

**Title**: CHANGELOG.md [Unreleased] records the change
**Files changed**: CHANGELOG.md, tasks/fork-friendly-install/prd.json, tasks/fork-friendly-install/progress.txt
**Commit**: (pending)
**Result**: PASS

### What I did
Added two entries to the `## [Unreleased]` block in `CHANGELOG.md`:
- `### Added`: `OH_GITHUB_REPO` and `OH_GITHUB_REF` env vars for fork-friendly installs ([#309](https://github.com/ryaneggz/open-harness/pull/309)).
- `### Changed`: README and `docs/installation.md` add a "For forks / self-host" section; canonical upstream `oh.mifune.dev` URL unchanged ([#309](https://github.com/ryaneggz/open-harness/pull/309)).

Both entries prepended to their respective sections (first after `### Added` header, first after `### Changed` header), matching existing one-line imperative-mood Keep-a-Changelog style with PR link at end.

---

STATUS: COMPLETE
