task: clarify project worktree layout (#296)

Clarify that new long-lived standalone repos belong under `.worktrees/project/<owner>/<repo>/`, while `.worktrees/agent/` is limited to harness agent branches and legacy agent-owned clones.

Document the concrete Mifune misplacement that triggered this clarification.

Docs-only; tests not run.

Closes #295
This commit is contained in:
Ryan Eggleston authored and GitHub committed 2026-05-15 13:31:05 -06:00
1 parent f536670f52
commit d3f747b849
2 files changed
+29 -19

No files matched your search

+28 -19
View File
@@ -15,41 +15,50 @@ subfolders mirror the harness branch prefix:
| `task/` | `task/<issue#>-...` — chores / maintenance |
| `audit/` | `audit/<issue#>-...` — review / audit branches |
| `skill/` | `skill/<issue#>-...` — skill authoring |
| `agent/` | `agent/<agent-name>` — agent worktrees or clones |
| `agent/` | `agent/<agent-name>` — harness agent branches only |
The `agent/` subfolder holds two patterns: harness branch worktrees
(legacy in-tree agents) and standalone agent-repo clones with their own
`.git` (post-graduation agents). Example: `dc-designer` is cloned from
`https://github.com/ryaneggz/dc-designer` to `.worktrees/agent/dc-designer/`
as a full clone. Both patterns coexist.
The `agent/` subfolder is for work tied to a named AI agent identity in
this harness: either a true harness branch worktree (`agent/<agent-name>`)
or a legacy agent-owned clone that has not yet graduated to the project
layout. Do **not** put new long-lived external repos here just because an
agent will work on them.
Why this needed clarification: the first Mifune extraction clone went to
`.worktrees/agent/mifune` because this README previously allowed
"standalone agent-repo clones" under `agent/`. Mifune is a standalone
`ryaneggz/mifune` project repo, so its durable home is now
`.worktrees/project/ryaneggz/mifune/`.
See `.claude/rules/git.md` § Worktrees for the canonical workflow,
including the stale-worktree policy.
## Project clones — `project/<project-name>/`
## Project clones — `project/<owner>/<repo>/`
Groupings of independent repos that have **their own git tracking** and
are NOT branches of the harness. Each `<project-name>/` is a workspace
for one project; the leaf repos inside it are full clones with their
own `.git`. Folder shape mirrors `agent/<agent-name>` — long-lived,
named, no issue prefix.
Durable clones of independent repos that have **their own git tracking**
and are NOT branches of the harness. Use this for collateral projects,
extracted packages, app repos, and anything whose long-term identity is a
GitHub repo rather than a harness agent branch.
Folder shape mirrors the remote owner/repo. This prevents collisions and
makes the remote obvious from the path.
Example layout:
```
project/
foo/
web/ # standalone repo, own .git
api/ # standalone repo, own .git
bar/
site/ # standalone repo, own .git
ryaneggz/
mifune/ # https://github.com/ryaneggz/mifune.git
portfolio-advisor/ # https://github.com/ryaneggz/portfolio-advisor.git
acme/
web/ # https://github.com/acme/web.git
api/ # https://github.com/acme/api.git
```
Create on demand:
```bash
mkdir -p .worktrees/project/<project-name>
git clone <url> .worktrees/project/<project-name>/<repo>
mkdir -p .worktrees/project/<owner>
git clone https://github.com/<owner>/<repo>.git .worktrees/project/<owner>/<repo>
```
The `project/` directory is gitignored — it materializes only when you
+1
View File
@@ -18,6 +18,7 @@ Update policy and release automation live in [`.claude/rules/git.md`](.claude/ru
- `.pi/overlays/docker-compose.slack.yml` and all references to it. The in-tree Pi extension at `.pi/extensions/slack/` reads `SLACK_APP_TOKEN` / `SLACK_BOT_TOKEN` directly from `process.env` at `session_start`, so the compose-time wiring overlay is redundant. `docs/integrations/slack.md`, `README.md`, `docs/architecture/container-runtime.md`, `docs/guide/bring-your-own-harness.md`, `.devcontainer/docker-compose.yml`, and `.devcontainer/.example.env` no longer reference the overlay; `.pi/overlays/` directory removed. Source of truth for Slack env wiring is `.pi/extensions/slack/README.md`.
### Changed
- `.worktrees/README.md` now reserves `.worktrees/project/<owner>/<repo>/` for durable standalone repo clones (e.g. `ryaneggz/mifune`) and narrows `.worktrees/agent/` to harness agent branches / legacy agent-owned clones, documenting why the Mifune extraction first landed in the wrong folder. ([#295](https://github.com/ryaneggz/open-harness/issues/295))
- `oh config slack` wizard UX overhaul. Token prompts now echo `●` per keystroke (was: silent — looked frozen) via a TTY-aware raw-mode `askSecret` that handles backspace, Ctrl-U, and Ctrl-C; piped/non-TTY stdin still uses the legacy readline fallback as `askSecretPiped` so `echo "" | oh config slack` keeps working. Flow is reframed into four numbered steps `[1/4] … [4/4]` with inline "Where:" hints and clickable URLs (OSC 8 hyperlinks; fall back to `label (url)` on legacy terminals). Each input shows `✓ valid prefix` / `✓ N user(s) accepted` after validation. A final summary screen lists the keys (tokens redacted, IDs visible) and gates the env-file write behind a `Proceed? [Y/n]` confirmation. New helpers exported from `apps/oh/src/lib/prompt.ts`: `step()`, `link()`, `bold()`. Zero new runtime dependencies. ([#290](https://github.com/ryaneggz/open-harness/issues/290))
- Migrate `.pi/extensions/slack/{index,tools}.ts` from the deprecated `@mariozechner/pi-coding-agent` (and `@mariozechner/pi-agent-core`) to the upstream-recommended successors `@earendil-works/pi-coding-agent` (and `@earendil-works/pi-agent-core`). Per `npm view @mariozechner/pi-coding-agent`'s deprecation notice, the old package is no longer maintained. The other two in-tree extensions (`path-guard.ts`, `plan-mode/index.ts`) had already migrated; slack was the laggard. `.devcontainer/Dockerfile`'s `[pi-coding-agent]` mapping in the `PKG` array, `docs/agents/pi.md`'s upstream link, `docs/installation.md`'s Pi row, and `.pi/UPSTREAM.md`'s lineage label all updated to match. ([#281](https://github.com/ryaneggz/open-harness/issues/281))
- `docs/integrations/slack.md` § 5 leads with the new `oh config slack` wizard; the manual `set -a; source ...; tmux new-session` ritual is demoted to a `<details>` "Manual fallback" collapsible. Sections renumbered (8→7, 9→8). The wizard explicitly **starts the Slack bridge for you** at the end — kills any existing `agent-pi` tmux session, launches a fresh one running `pi` with the new env sourced, and polls `tmux capture-pane` for the `connected and listening` log line. ([#281](https://github.com/ryaneggz/open-harness/issues/281))