gabriel / musehub public
.windsurfrules
225 lines 7.8 KB
Raw
sha256:009b5a222314f47640a58d75ce5a1f428f1624cf0b51384dfcdfbdfab3cc42a4 feat: migration idempotency, file attribution DAG walk, mpa… Sonnet 4.6 minor ⚠ breaking 51 days ago
1 # Workspace — Shared Agent Configuration
2
3 This file contains shared rules for all repositories in this workspace.
4 Each member repository may have its own ``.muse/agent.md`` with repo-specific
5 additions.
6
7 Managed by `muse agent-config` — regenerate adapters with `muse agent-config sync`.
8
9 ---
10
11 ## Workspace Members
12
13 | Repo | Path | Branch |
14 |------|------|--------|
15 | **muse** | `muse` | `dev` |
16 | **musehub** | `musehub` | `dev` |
17 | **agentception** | `agentception` | `dev` |
18 | **contracts** | `contracts` | `dev` |
19 | **Stori** | `Stori` | `dev` |
20 | **maestro** | `maestro` | `dev` |
21 | **muse-zsh** | `muse-zsh` | `dev` |
22
23 ---
24
25 ## Version Control
26
27 This workspace uses **Muse** for version control — not git, not GitHub.
28
29 - Never run `git`, `gh`, or any git subcommand.
30 - Never reference GitHub, GitHub Actions, or GitHub URLs.
31 - Use `muse -C ~/path/to/repo <command>` when CWD differs from the target repo.
32
33 If you find a `git` or `gh` call anywhere — delete it in the same commit.
34
35 ---
36
37 ## Commit Convention — Agent-First
38
39 This workspace is **agent-first**: agents do the work, humans provision agents.
40 Every commit made by an agent must carry full provenance. Human commits (direct
41 manual changes without an agent) are the exception, not the norm.
42
43 ### Agent commit — always use this
44
45 ```bash
46 muse commit -m "feat: ..." \
47 --agent-id claude-code \
48 --model-id claude-sonnet-4-6 \
49 --sign
50 ```
51
52 - `--agent-id` — identifies the agent type (`claude-code`, `codex`, `agentception/worker`, …)
53 - `--model-id` — the specific model that produced the change (`claude-sonnet-4-6`, …)
54 - `--sign` — embeds Ed25519 public key + signature; traces back to gabriel's root mnemonic in `~/.muse/identity.toml`
55
56 Use the model you are actually running. For Claude Code the current model is `claude-sonnet-4-6`.
57
58 ### Human commit — manual actions only
59
60 ```bash
61 muse commit -m "chore: manual config change"
62 ```
63
64 No provenance flags. Their absence is itself a signal that a human acted directly.
65
66 ### Provenance chain
67
68 ```
69 ~/.muse/identity.toml ← root mnemonic (HD wallet seed, gabriel's root identity)
70 ↓ HD derivation
71 Ed25519 key pair ← signer_public_key embedded in every --sign commit
72 ↓ signs
73 CommitRecord ← agent_id + model_id + signature stored per-commit
74 ↓ content-addressed
75 sha256:<commit_id> ← tamper-evident, auditable forever
76 ```
77
78 Agents spawned by agentception receive a derived key via `MUSE_AGENT_KEY` env var —
79 their commits sign with that key, which itself traces back to gabriel's root identity.
80
81 ---
82
83 ## Branch Flow
84
85 Always work on a feature branch — never commit directly to `main` or `dev`.
86
87 ```bash
88 muse -C ~/path/to/repo checkout dev
89 muse -C ~/path/to/repo checkout -b task/my-thing
90
91 muse rm <file> # delete from disk + stage deletion (mirrors git rm)
92 muse code add . # stage additions + modifications + already-deleted files
93 muse commit -m "feat: ..." --agent-id claude-code --model-id claude-sonnet-4-6 --sign
94
95 muse -C ~/path/to/repo checkout dev
96 muse -C ~/path/to/repo merge task/my-thing
97 muse -C ~/path/to/repo branch -d task/my-thing
98 muse -C ~/path/to/repo push local dev
99 ```
100
101 ---
102
103 ## Code Intelligence
104
105 | Task | Command |
106 |------|---------|
107 | Find symbol declaration | `muse code grep "Name" --json` |
108 | Read one symbol | `muse code cat "file.py::Symbol" --json` |
109 | File structure | `muse code symbols --file file.py --json` |
110 | Blast radius | `muse code impact "file.py::Symbol" --json` |
111 | Dependencies | `muse code deps "file.py" --json` |
112 | Tests for changed code | `muse code test --json` |
113
114 ---
115
116 ## Testing Rules
117
118 **Never run the full test suite.** It is slow and gabriel runs it when he's ready.
119
120 1. **Start with `muse code test --json`** — runs only tests relevant to changed files.
121 2. **Run one file at a time** when fixing a specific failure:
122 ```bash
123 python3 -m pytest tests/test_foo.py -q --tb=short
124 ```
125 3. **Run one test by name** to verify a fix:
126 ```bash
127 python3 -m pytest tests/test_foo.py::test_bar -q --tb=short
128 ```
129
130 ### Forbidden
131
132 - `python3 -m pytest tests/` — runs everything, never do this
133 - `python3 -m pytest` with no path — same as above
134 - `pytest -x tests/` or any whole-suite invocation
135 - Looping retries on the same command after a failure — diagnose first
136
137 # musehub — Agent Configuration
138
139 This repository is a member of a workspace.
140 Shared workspace rules live in the parent ``.muse/agent.md``.
141 This file contains only musehub-specific additions.
142
143 Managed by `muse agent-config` — regenerate adapters with `muse agent-config sync`.
144
145 ---
146
147 ## Proposal Titles
148
149 Proposal titles must be plain English — not branch-name style.
150
151 The branch (`feat/auth-v2`, `task/proposal-models-v2`) already encodes the type prefix.
152 The title is what a human reads in the list; it should describe the change, not echo the branch.
153
154 | Branch | Bad title | Good title |
155 |--------|-----------|------------|
156 | `feat/auth-v2` | `feat: auth v2` | `Ed25519 key rotation and MSign auth v2` |
157 | `task/proposal-models-v2` | `feat: proposal models v2` | `Proposal type badges, 7-state tabs, and ghost object integrity fix` |
158 | `fix/wire-timeout` | `fix: wire timeout` | `Increase push stream timeout to prevent drops on large repos` |
159
160 Rule: if the title could be mistaken for a branch name or a commit message subject line, rewrite it.
161
162 ---
163
164 ## Localhost Container — ALWAYS Restart After Code Changes
165
166 The localhost container (`musehub`) runs uvicorn **without** `--reload`. Code changes to the live-mounted volume are **not picked up until the container restarts**. This is non-negotiable:
167
168 ```bash
169 docker restart musehub && sleep 5 && curl -sk https://localhost:1337/healthz
170 ```
171
172 **Do this immediately after every edit to musehub Python source.** No exceptions. Every cycle spent debugging "why aren't my logs showing up" is wasted because the container is running stale code.
173
174 ---
175
176 ## Repo-Specific Notes
177
178 ### Staging Deploy
179
180 ```bash
181 bash deploy/push.sh staging # build, push to ECR, blue-green deploy
182 bash deploy/push.sh prod # same for prod
183 bash deploy/push.sh staging prod # staging then prod
184 ```
185
186 ### Recovering a Down Staging Instance
187
188 If staging returns 502 or the webserver is down:
189
190 1. **Restart the container** — containers use `--restart unless-stopped` so a reboot brings them back, but a manual `docker stop` does not:
191 ```bash
192 sudo docker start musehub-blue # or musehub-green, whichever is active
193 ```
194
195 2. **Switch the active slot** — the ONLY correct way to change which slot nginx points to:
196 ```bash
197 sudo musehub-set-slot blue # blue = port 1337
198 sudo musehub-set-slot green # green = port 1338
199 ```
200 This script lives at `/usr/local/bin/musehub-set-slot` on the instance. It is the only sanctioned way to write `/etc/nginx/musehub-active-port`. **Never write to that file directly** — it must contain a full nginx upstream directive (`server 127.0.0.1:1337;`), not a bare port number. Writing a bare port breaks nginx config parsing and causes 502s.
201
202 3. **Check current state**:
203 ```bash
204 cat /opt/musehub/.active-slot # which slot is active (blue or green)
205 cat /etc/nginx/musehub-active-port # what nginx is pointing at
206 sudo docker ps --format "{{.Names}} {{.Status}}" # container health
207 ```
208
209 4. **If SSM commands are stuck as Pending** — reboot the instance. Containers with `--restart unless-stopped` come back automatically:
210 ```bash
211 aws ec2 reboot-instances --region us-east-1 --instance-ids i-07547cd20bee2dea5
212 ```
213 Then poll until SSM is back before sending new commands:
214 ```bash
215 aws ssm describe-instance-information --region us-east-1 \
216 --filters "Key=InstanceIds,Values=i-07547cd20bee2dea5" \
217 --query 'InstanceInformationList[0].PingStatus' --output text
218 ```
219
220 ### Instance IDs
221
222 | Environment | Instance ID |
223 |-------------|-------------|
224 | staging | `i-07547cd20bee2dea5` |
225 | prod | `i-0855d6efe7fa1a49d` |
File History 1 commit
sha256:009b5a222314f47640a58d75ce5a1f428f1624cf0b51384dfcdfbdfab3cc42a4 feat: migration idempotency, file attribution DAG walk, mpa… Sonnet 4.6 minor 51 days ago