Planning artifacts (milestones v1.0-v1.2.1, v1.3 queue, PROJECT.md, STATE.md, config) now live alongside the code they describe. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
377 lines
16 KiB
Markdown
377 lines
16 KiB
Markdown
---
|
|
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"
|
|
---
|
|
|
|
<objective>
|
|
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.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
@.planning/phases/01-foundation/01-RESEARCH.md
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Create zone taxonomy document and rebase runbook</name>
|
|
<files>
|
|
.planning/ZONE-TAXONOMY.md,
|
|
.planning/REBASE-RUNBOOK.md
|
|
</files>
|
|
<read_first>
|
|
/Volumes/UsbNvme/agent/.planning/phases/01-foundation/01-RESEARCH.md
|
|
</read_first>
|
|
<action>
|
|
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."
|
|
```
|
|
</action>
|
|
<verify>
|
|
<automated>test -f /Volumes/UsbNvme/repos/nexus/.planning/ZONE-TAXONOMY.md && test -f /Volumes/UsbNvme/repos/nexus/.planning/REBASE-RUNBOOK.md && echo "OK"</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- .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"
|
|
</acceptance_criteria>
|
|
<done>
|
|
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.
|
|
</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Install commit-msg hook and enable git rerere</name>
|
|
<files>
|
|
.git/hooks/commit-msg,
|
|
scripts/nexus-commit-msg-hook.sh
|
|
</files>
|
|
<read_first>
|
|
/Volumes/UsbNvme/repos/nexus/.git/hooks/commit-msg.sample
|
|
</read_first>
|
|
<action>
|
|
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
|
|
```
|
|
</action>
|
|
<verify>
|
|
<automated>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"</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- .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`
|
|
</acceptance_criteria>
|
|
<done>
|
|
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.
|
|
</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
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`
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- 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
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/01-foundation/01-02-SUMMARY.md`
|
|
</output>
|