--- phase: 01-foundation plan: 02 type: execute wave: 1 depends_on: [] files_modified: - .planning/ZONE-TAXONOMY.md - .git/hooks/commit-msg - .planning/REBASE-RUNBOOK.md autonomous: true requirements: [FOUND-02, FOUND-03, FOUND-04] must_haves: truths: - "A zone taxonomy document exists classifying every rename target as DISPLAY, CODE, or STORED" - "Commits without [nexus] prefix are rejected by the commit-msg hook" - "Merge commits bypass the hook without error" - "git rerere is enabled for the repository" - "A rebase runbook documents the git range-diff verification workflow" artifacts: - path: ".planning/ZONE-TAXONOMY.md" provides: "Classification of every rename target by zone" contains: "DISPLAY" - path: ".git/hooks/commit-msg" provides: "Commit message prefix enforcement" min_lines: 8 - path: ".planning/REBASE-RUNBOOK.md" provides: "Step-by-step rebase workflow with range-diff verification" contains: "range-diff" key_links: - from: ".git/hooks/commit-msg" to: "git commit workflow" via: "git hook execution" pattern: "\\[nexus\\]" - from: ".git/config" to: "rerere cache" via: "rerere.enabled = true" pattern: "rerere" --- Create the zone taxonomy document, install the commit-msg git hook enforcing [nexus] prefix, enable git rerere, and write the rebase runbook. These three artifacts establish commit discipline and rebase safety before any upstream files are modified. Purpose: Prevent accidental code/stored-value renames in future phases, ensure all fork commits are identifiable during rebase, and automate conflict re-resolution. Output: ZONE-TAXONOMY.md, commit-msg hook, REBASE-RUNBOOK.md, git rerere enabled. @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/01-foundation/01-RESEARCH.md Task 1: Create zone taxonomy document and rebase runbook .planning/ZONE-TAXONOMY.md, .planning/REBASE-RUNBOOK.md /Volumes/UsbNvme/agent/.planning/phases/01-foundation/01-RESEARCH.md 1. Create `.planning/ZONE-TAXONOMY.md` with the following structure and content. This document classifies every rename target at the occurrence level (not just term level) into three zones: **Header:** ```markdown # Nexus Zone Taxonomy Classifies every Paperclip-to-Nexus rename target by zone. Zones determine which occurrences are safe to change and which must stay unchanged for upstream sync. **Zones:** - **DISPLAY** — User-facing strings safe to rename (UI text, banners, tooltips, help text, button labels) - **CODE** — TypeScript identifiers, import paths, route segments, env vars — do NOT touch - **STORED** — DB column/table names, stored enum values — do NOT touch ``` **DISPLAY zone table (safe to change):** | Target | Location | Current Value | Nexus Value | Phase | |--------|----------|---------------|-------------|-------| | Company display string in JSX | ~16 UI files in `ui/src/` | "Company" | "Workspace" | 3 | | Companies plural in JSX | UI files | "Companies" | "Workspaces" | 3 | | CEO display string in JSX | `ui/src/components/agent-config-primitives.tsx`, `AgentProperties.tsx`, etc. | "CEO" | "Project Manager" | 3 | | Board display string in JSX | Various UI files | "Board" | "Owner" | 3 | | Hire button text | UI dialogs | "Hire" | "Add" | 3 | | Fire button text | UI dialogs | "Fire" | "Remove" | 3 | | `AGENT_ROLE_LABELS.ceo` value | `packages/shared/src/constants.ts` | `"CEO"` | `"Project Manager"` | 2 | | PAPERCLIP ASCII banner | `server/src/startup-banner.ts` | "PAPERCLIP" | "NEXUS" | 2 | | PAPERCLIP ASCII banner (CLI) | `cli/src/utils/banner.ts` | "PAPERCLIP" | "NEXUS" | 2 | | App title in browser tab | `ui/index.html` or layout | "Paperclip" | "Nexus" | 3 | | Top-left logo text | UI layout component | "Paperclip" | "Nexus" | 3 | | CLI help text brand name | `cli/src/` command descriptions | "Paperclip" | "Nexus" | 3 | | paperclip.ing URL references | `ui/src/pages/CompanyExport.tsx` | "paperclip.ing" | Nexus URL | 3 | | Favicon and logo assets | `ui/public/` or assets dir | Paperclip branding | Nexus branding | 3 | **CODE zone table (do NOT touch):** | Target | Location | Rationale | |--------|----------|-----------| | `companyService`, `companyId`, `selectedCompanyId` | Throughout server/ui/cli | TypeScript identifiers — hundreds of import references | | `companies` table name | `packages/db/src/schema/` | DB table — migration required to rename | | `company_id` FK columns | `packages/db/src/schema/` | DB columns — migration required | | `/api/companies` route segment | `server/src/routes/companies.ts` | API contract — client/server must match | | `COMPANY_STATUSES` / `CompanyStatus` type | `packages/shared/src/constants.ts` | Upstream shared type — plugin API contract | | `@paperclipai/*` package names | All `package.json` files | Import paths throughout monorepo | | `PAPERCLIP_*` env vars | Server/CLI config | Breaks existing deployments | | `board_api_keys` table / `board` actor type | DB schema, auth code | Auth token format, DB schema | | `pcp_board_*` token prefixes | Auth code | Would invalidate issued tokens | | `.paperclip.yaml` export format | Import/export code | Upstream compatibility | **STORED zone table (do NOT touch):** | Target | Location | Stored Where | Rationale | |--------|----------|-------------|-----------| | `"ceo"` in `AGENT_ROLES` | `packages/shared/src/constants.ts` | `agent_role` DB column | Existing rows contain this value | | `"hire_agent"` approval type | `packages/shared/src/constants.ts` APPROVAL_TYPES | `approval_type` DB column | Existing approvals reference this | | `"approve_ceo_strategy"` | `packages/shared/src/constants.ts` APPROVAL_TYPES | `approval_type` DB column | Existing approvals reference this | | `"bootstrap_ceo"` invite type | `packages/shared/src/constants.ts` | `invite_type` DB column | Existing invites reference this | | `company_id` FK values | All FK columns | PostgreSQL foreign keys | Data integrity constraint | **Zone Summary:** | Zone | Count | Rule | |------|-------|------| | DISPLAY | ~40 surface points | Safe to rename in Phases 2-4 | | CODE | Many hundreds | Never rename — upstream sync priority | | STORED | ~8 enum/column values | Never rename — DB integrity | **Decision rule:** When the same term appears in multiple zones (e.g., "ceo" is both STORED as `AGENT_ROLES[0]` and DISPLAY as `AGENT_ROLE_LABELS.ceo` value), classify each occurrence independently. The key stays, only the display value changes. 2. Create `.planning/REBASE-RUNBOOK.md` with the following content: ```markdown # Nexus Rebase Runbook Step-by-step workflow for rebasing Nexus fork commits onto new upstream Paperclip releases. ## Prerequisites - `git rerere` enabled: `git config rerere.enabled true` - `git range-diff` available (git 2.19+, confirmed 2.39.5 on this machine) - Upstream remote configured: `git remote add upstream https://github.com/paperclipai/paperclip.git` (if not already) ## Pre-Rebase Checklist 1. Ensure working tree is clean: `git status` 2. Fetch upstream: `git fetch upstream` 3. Record current tip: `git log --oneline -1` (save this SHA as OLD_TIP) 4. Verify all tests pass before rebase: `pnpm test:run` ## Rebase Procedure ```bash # 1. Fetch latest upstream git fetch upstream # 2. Rebase nexus commits onto upstream/master git rebase upstream/master # 3. If conflicts arise: # - git rerere will auto-apply previously recorded resolutions # - For new conflicts: resolve manually, then `git add` + `git rebase --continue` # - rerere automatically records new resolutions for future use # 4. Verify rebase integrity with range-diff # ORIG_HEAD is the pre-rebase tip (set automatically by git) git range-diff upstream/master ORIG_HEAD HEAD ``` ## Post-Rebase Verification 1. **range-diff check:** `git range-diff upstream/master ORIG_HEAD HEAD` - Every nexus commit should show as "equivalent" (minor offset changes only) - Flag any commit showing significant diff changes for manual review 2. **Test suite:** `pnpm test:run` — all tests must pass 3. **Type check:** `pnpm typecheck` (if available) or `pnpm -r run typecheck` 4. **Branding spot check:** `pnpm vitest run --project packages/branding` ## Handling Common Scenarios ### Upstream changed a file we also changed (DISPLAY zone) - Most common: string changes in UI components - rerere should handle if previously resolved - If new: resolve keeping Nexus display string, `git add`, continue ### Upstream added new constants to packages/shared/src/constants.ts - Our changes are in `packages/branding/` (separate file) — no conflict expected - If AGENT_ROLE_LABELS format changes upstream, update the DISPLAY zone mapping ### Upstream restructured a file entirely - range-diff will show the affected nexus commit as "changed" - Manually verify the nexus change still applies correctly - Update zone taxonomy if file paths changed ## rerere Cache Notes - Cache lives in `.git/rr-cache/` (not tracked by git) - Cache is machine-local — lost on re-clone - After a fresh clone, first rebase may require manual resolution - Subsequent rebases at the same conflict points will auto-resolve ## Hook Re-installation After a fresh clone, the commit-msg hook must be reinstalled: ```bash # From repo root: cp scripts/nexus-commit-msg-hook.sh .git/hooks/commit-msg chmod +x .git/hooks/commit-msg ``` Or if a setup script exists: ```bash bash scripts/install-hooks.sh ``` ``` 3. Also create `scripts/install-hooks.sh` (tracked, so it survives clones): ```bash #!/bin/sh # Install Nexus git hooks REPO_ROOT="$(git rev-parse --show-toplevel)" cp "$REPO_ROOT/scripts/nexus-commit-msg-hook.sh" "$REPO_ROOT/.git/hooks/commit-msg" chmod +x "$REPO_ROOT/.git/hooks/commit-msg" echo "Nexus commit-msg hook installed." ``` test -f /Volumes/UsbNvme/repos/nexus/.planning/ZONE-TAXONOMY.md && test -f /Volumes/UsbNvme/repos/nexus/.planning/REBASE-RUNBOOK.md && echo "OK" - .planning/ZONE-TAXONOMY.md contains "DISPLAY" - .planning/ZONE-TAXONOMY.md contains "CODE" - .planning/ZONE-TAXONOMY.md contains "STORED" - .planning/ZONE-TAXONOMY.md contains "Workspace" - .planning/ZONE-TAXONOMY.md contains "Project Manager" - .planning/ZONE-TAXONOMY.md contains "AGENT_ROLES" - .planning/ZONE-TAXONOMY.md contains "company_id" - .planning/ZONE-TAXONOMY.md contains "hire_agent" - .planning/REBASE-RUNBOOK.md contains "range-diff" - .planning/REBASE-RUNBOOK.md contains "rerere" - .planning/REBASE-RUNBOOK.md contains "upstream/master" - .planning/REBASE-RUNBOOK.md contains "ORIG_HEAD" - scripts/install-hooks.sh contains "commit-msg" Zone taxonomy document exists with all three zones populated. Rebase runbook documents the complete range-diff workflow. Hook installer script exists in tracked scripts/ directory. Task 2: Install commit-msg hook and enable git rerere .git/hooks/commit-msg, scripts/nexus-commit-msg-hook.sh /Volumes/UsbNvme/repos/nexus/.git/hooks/commit-msg.sample 1. Create `scripts/nexus-commit-msg-hook.sh` (tracked source of truth for the hook): ```sh #!/bin/sh # Nexus fork: enforce [nexus] prefix on all fork commits # Allows upstream merge commits and rebase-generated commits through MSG_FILE="$1" FIRST_LINE=$(head -1 "$MSG_FILE") # Skip merge commits (git generates these automatically during rebase/merge) if echo "$FIRST_LINE" | grep -qE "^Merge (branch|pull request|remote-tracking)"; then exit 0 fi # Skip fixup/squash commits (used during interactive rebase) if echo "$FIRST_LINE" | grep -qE "^(fixup|squash)!"; then exit 0 fi # Enforce [nexus] prefix if ! echo "$FIRST_LINE" | grep -qE "^\[nexus\]"; then echo "ERROR: Commit message must start with [nexus]" echo " Got: $FIRST_LINE" echo " Example: [nexus] feat: add branding package" exit 1 fi ``` 2. Copy that script to `.git/hooks/commit-msg` and make it executable: ```bash cp scripts/nexus-commit-msg-hook.sh .git/hooks/commit-msg chmod +x .git/hooks/commit-msg ``` 3. Make the source script executable too: ```bash chmod +x scripts/nexus-commit-msg-hook.sh chmod +x scripts/install-hooks.sh ``` 4. Enable git rerere: ```bash git config rerere.enabled true git config rerere.autoupdate true ``` 5. Verify the hook works by testing it directly: ```bash # Test rejection (should fail with exit 1): echo "bad commit message" > /tmp/test-commit-msg .git/hooks/commit-msg /tmp/test-commit-msg; echo "exit=$?" # Expected: ERROR message, exit=1 # Test acceptance (should pass with exit 0): echo "[nexus] feat: test commit" > /tmp/test-commit-msg .git/hooks/commit-msg /tmp/test-commit-msg; echo "exit=$?" # Expected: exit=0 # Test merge commit bypass (should pass with exit 0): echo "Merge branch 'upstream/master'" > /tmp/test-commit-msg .git/hooks/commit-msg /tmp/test-commit-msg; echo "exit=$?" # Expected: exit=0 ``` 6. Verify rerere: ```bash git config --get rerere.enabled # Expected: true ``` cd /Volumes/UsbNvme/repos/nexus && echo "bad" > /tmp/test-msg && (! .git/hooks/commit-msg /tmp/test-msg) && echo "[nexus] good" > /tmp/test-msg && .git/hooks/commit-msg /tmp/test-msg && git config --get rerere.enabled | grep -q true && echo "ALL CHECKS PASS" - .git/hooks/commit-msg exists and is executable (`test -x .git/hooks/commit-msg`) - scripts/nexus-commit-msg-hook.sh contains `[nexus]` - scripts/nexus-commit-msg-hook.sh contains `Merge (branch|pull request|remote-tracking)` - Hook rejects "bad message" with exit code 1 - Hook accepts "[nexus] feat: test" with exit code 0 - Hook accepts "Merge branch 'upstream/master'" with exit code 0 - `git config --get rerere.enabled` returns `true` - `git config --get rerere.autoupdate` returns `true` commit-msg hook installed and rejects non-[nexus] commits. Merge commits pass through. git rerere enabled with autoupdate. Hook source tracked in scripts/ for re-installation after clone. 1. `.planning/ZONE-TAXONOMY.md` exists with DISPLAY, CODE, STORED sections 2. `.planning/REBASE-RUNBOOK.md` exists with range-diff workflow 3. `.git/hooks/commit-msg` rejects bad messages, accepts [nexus] prefixed and merge commits 4. `git config --get rerere.enabled` returns `true` - Zone taxonomy classifies all rename targets from the Research inventory into DISPLAY/CODE/STORED zones - commit-msg hook enforces [nexus] prefix on all non-merge commits - git rerere enabled with autoupdate - Rebase runbook documents range-diff verification workflow - Hook source script tracked in `scripts/` for clone re-installation After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md`