arcane-cli 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +253 -253
  3. package/dist/assets/.arcane/agents/agent-policies-template.md +414 -414
  4. package/dist/assets/.arcane/governance/agent-policies.md +414 -414
  5. package/dist/assets/.arcane/governance/agent-work-queue-model.md +61 -61
  6. package/dist/assets/.arcane/governance/cicd-standards.md +227 -227
  7. package/dist/assets/.arcane/governance/development-methodology.md +384 -384
  8. package/dist/assets/.arcane/governance/git-conventions.md +759 -759
  9. package/dist/assets/.arcane/governance/naming-conventions.md +142 -142
  10. package/dist/assets/.arcane/governance/new-business-setup.md +182 -182
  11. package/dist/assets/.arcane/governance/portable-bootstrap.md +101 -101
  12. package/dist/assets/.arcane/governance/product-excellence-standards.md +211 -211
  13. package/dist/assets/.arcane/governance/testing-standards.md +158 -158
  14. package/dist/assets/.arcane/governance/universal-agent-rules.md +108 -108
  15. package/dist/assets/.arcane/image-prompts/adelaide-image-prompt.md +140 -140
  16. package/dist/assets/.arcane/image-prompts/alexander-image-prompt.md +138 -138
  17. package/dist/assets/.arcane/image-prompts/bess-image-prompt.md +139 -139
  18. package/dist/assets/.arcane/image-prompts/circe-image-prompt.md +143 -143
  19. package/dist/assets/.arcane/image-prompts/custodio-image-prompt.md +140 -140
  20. package/dist/assets/.arcane/image-prompts/iris-image-prompt.md +139 -139
  21. package/dist/assets/.arcane/image-prompts/kellar-image-prompt.md +141 -141
  22. package/dist/assets/.arcane/image-prompts/lafayette-image-prompt.md +140 -140
  23. package/dist/assets/.arcane/image-prompts/lince-image-prompt.md +142 -142
  24. package/dist/assets/.arcane/image-prompts/mercurio-image-prompt.md +140 -140
  25. package/dist/assets/.arcane/image-prompts/merlin-image-prompt.md +139 -139
  26. package/dist/assets/.arcane/image-prompts/prospero-image-prompt.md +141 -141
  27. package/dist/assets/.claude/commands/spell-enchant.md +9 -9
  28. package/dist/assets/.github/agents/adelaide.agent.md +44 -44
  29. package/dist/assets/.github/agents/alexander.agent.md +43 -43
  30. package/dist/assets/.github/agents/bess.agent.md +42 -42
  31. package/dist/assets/.github/agents/circe.agent.md +43 -43
  32. package/dist/assets/.github/agents/custodio.agent.md +44 -44
  33. package/dist/assets/.github/agents/iris.agent.md +43 -43
  34. package/dist/assets/.github/agents/kellar.agent.md +43 -43
  35. package/dist/assets/.github/agents/lafayette.agent.md +42 -42
  36. package/dist/assets/.github/agents/lince.agent.md +43 -43
  37. package/dist/assets/.github/agents/mercurio.agent.md +43 -43
  38. package/dist/assets/.github/agents/merlin.agent.md +44 -44
  39. package/dist/assets/.github/agents/prospero.agent.md +43 -43
  40. package/dist/assets/.github/prompts/spell-close-session.prompt.md +17 -5
  41. package/dist/assets/.github/prompts/spell-commit-work.prompt.md +24 -6
  42. package/dist/assets/.github/prompts/spell-create-pull-request.prompt.md +12 -3
  43. package/dist/assets/.github/prompts/spell-enchant.prompt.md +385 -385
  44. package/dist/assets/.github/prompts/spell-feedback.prompt.md +113 -113
  45. package/dist/assets/.github/prompts/spell-full-cycle.prompt.md +202 -201
  46. package/dist/assets/.github/prompts/spell-implement.prompt.md +101 -101
  47. package/dist/assets/.github/prompts/spell-open-session.prompt.md +20 -5
  48. package/dist/assets/.github/prompts/spell-scope.prompt.md +263 -263
  49. package/dist/assets/agents/architecture-lead.yaml +61 -61
  50. package/dist/assets/agents/collaborator.yaml +59 -59
  51. package/dist/assets/agents/devops.yaml +60 -60
  52. package/dist/assets/agents/frontend-dev.yaml +60 -60
  53. package/dist/assets/agents/fullstack-dev.yaml +59 -59
  54. package/dist/assets/agents/marketing-strategist.yaml +60 -60
  55. package/dist/assets/agents/mobile-dev.yaml +59 -59
  56. package/dist/assets/agents/operations-comms.yaml +58 -58
  57. package/dist/assets/agents/orchestrator.yaml +60 -60
  58. package/dist/assets/agents/qa-lead.yaml +60 -60
  59. package/dist/assets/agents/research-analyst.yaml +59 -59
  60. package/dist/assets/agents/security-ops.yaml +61 -61
  61. package/dist/index.js +323 -7
  62. package/dist/index.js.map +1 -1
  63. package/package.json +72 -72
  64. package/dist/assets/.claude/commands/spell-eas-ios-deploy.md +0 -9
  65. package/dist/assets/.github/prompts/spell-eas-ios-deploy.prompt.md +0 -183
@@ -1,759 +1,759 @@
1
- ---
2
- title: Git Conventions — Commit Format and Branching Model
3
- audience: both
4
- status: active
5
- distributable: true
6
- last_updated: 2026-07-05
7
- tags: [git, conventional-commits, workflow, standards, attribution]
8
- ---
9
-
10
- # Git Conventions
11
-
12
- How to structure commits, branches, and pull requests for this repository.
13
-
14
- ## Executive Summary
15
-
16
- - This repo uses Conventional Commits format for all commit messages — industry standard, tool-portable, human-readable.
17
- - Trunk-based development with short-lived feature branches keeps history clean and reduces merge conflicts.
18
- - No custom git hooks — conventions work on any machine without setup, no fragile tooling dependencies.
19
- - Use `spell-commit-work` prompt during sessions to automate commit message generation in the correct format.
20
-
21
- ---
22
-
23
- ## Conventional Commits Format
24
-
25
- All commit messages follow the [Conventional Commits](https://www.conventionalcommits.org/) standard.
26
-
27
- ### Basic Structure
28
-
29
- ```
30
- type(scope): short description
31
-
32
- [optional body with details]
33
-
34
- [optional footer with breaking changes or issue references]
35
- ```
36
-
37
- ### Commit Types
38
-
39
- | Type | When to Use | Example |
40
- | ---------- | ----------------------------------------------- | -------------------------------------------------------------- |
41
- | `feat` | New feature or capability | `feat(prompts): add spell-commit-work for checkpointing` |
42
- | `fix` | Bug fix | `fix(auth): restore token validation after refactor` |
43
- | `docs` | Documentation only | `docs(decisions): add table of contents to DECISIONS.md` |
44
- | `refactor` | Code/structure change, no behavior change | `refactor(playbooks): reorganize setup steps` |
45
- | `chore` | Maintenance, deps, tooling, cleanup | `chore(deps): bump <dependency> to <version>` |
46
- | `test` | Adding or fixing tests | `test(security): add token-expiry test` |
47
- | `perf` | Performance improvements | `perf(api): reduce cold-start latency` |
48
- | `ci` | CI/CD pipeline changes | `ci(azure): add DevOps pipeline for repo sync` |
49
- | `style` | Code formatting, whitespace (rare in this repo) | `style(markdown): fix inconsistent heading levels` |
50
- | `revert` | Revert a previous commit | `revert: undo feat(prompts): add spell-commit-work` |
51
-
52
- ### Scopes
53
-
54
- Scope indicates what part of the repo changed. Use singular, lowercase.
55
-
56
- | Scope | Area |
57
- | ---------------- | ------------------------------------------------- |
58
- | `prompts` | `.github/prompts/*.prompt.md` |
59
- | `agents` | `agents/` directory, agent config, policies |
60
- | `security` | `security/` directory, threat model, hardening |
61
- | `infrastructure` | `infrastructure/` directory, hardware, OS setup |
62
- | `decisions` | `DECISIONS.md` updates |
63
- | `journal` | `journal/` entries |
64
- | `governance` | `governance/` directory, process docs |
65
- | `playbooks` | `playbooks/` directory |
66
- | `business` | `ventures/` directory |
67
- | `ai-context` | `ai-context/` directory |
68
- | `repo` | Root-level files (README, TODO, .gitignore, etc.) |
69
- | `naming` | `naming-conventions.md` |
70
-
71
- Multiple scopes? Pick the primary one. If everything changed, use `repo` or omit the scope.
72
-
73
- ### Short Description Rules
74
-
75
- - **Imperative mood:** "add", "fix", "update", "remove" (not "added", "fixes", "updating")
76
- - **Lowercase:** start with lowercase letter
77
- - **No period:** don't end with `.`
78
- - **72 characters max:** keeps `git log --oneline` readable
79
-
80
- **Good examples:**
81
-
82
- - `add spell-commit-work prompt`
83
- - `fix gateway auth regression after onboarding`
84
- - `update table of contents in DECISIONS.md`
85
-
86
- **Bad examples:**
87
-
88
- - `Added spell-commit-work prompt.` (past tense, period)
89
- - `Fix gateway authentication regression that occurred after running the onboarding wizard` (too long, 84 chars)
90
-
91
- ### Optional Body
92
-
93
- Include a body when:
94
-
95
- - The short description doesn't explain _why_
96
- - Multiple related changes need enumeration
97
- - ADR or file references add value
98
- - Future readers need context
99
-
100
- **Format:**
101
-
102
- - Blank line after the short description
103
- - Bullet list or paragraphs
104
- - Wrap at 72 characters per line
105
- - Reference ADRs, files, or issues
106
-
107
- **Example:**
108
-
109
- ```
110
- feat(prompts): add spell-commit-work for session checkpoints
111
-
112
- Enables committing work-in-progress during active sessions without
113
- waiting for spell-close-session. Generates Conventional Commits format
114
- messages with proper type and scope.
115
-
116
- Implements ADR-019 spell- naming convention.
117
-
118
- Changes:
119
- - Created .github/prompts/spell-commit-work.prompt.md
120
- - Created governance/git-conventions.md as reference doc
121
- - Updated TODO.md to mark git conventions doc complete
122
- ```
123
-
124
- ### Optional Footer
125
-
126
- Use for:
127
-
128
- - **Breaking changes:** `BREAKING CHANGE: removed support for plaintext token auth`
129
- - **Issue/ticket references:** `Closes #535` or `Fixes #127`
130
-
131
- Most commits in this repo won't need footers.
132
-
133
- ---
134
-
135
- ## Atomic Commits
136
-
137
- Each commit should be a **single logical change** — one coherent unit that can be understood, reviewed, reverted, or cherry-picked on its own.
138
-
139
- ### The Rule
140
-
141
- > **One commit = one purpose.** If you can't describe the commit in a single short description without "and", it's probably two commits.
142
-
143
- ### When to Split
144
-
145
- | Situation | Action |
146
- | -------------------------------------------------- | --------------------------------------------------------------------------------- |
147
- | New governance doc + updates to 3 referencing docs | One commit — the doc and its cross-references form one logical unit |
148
- | New feature + unrelated typo fix | Two commits — the typo fix is a separate `fix` or `docs` commit |
149
- | Refactor + behavior change | Two commits — refactor first (`refactor`), then behavior change (`feat` or `fix`) |
150
- | Multiple ADRs decided independently | One commit per ADR, each with its related doc updates |
151
- | Config change + documentation of that change | One commit — the config and its docs are one logical unit |
152
-
153
- ### When to Combine
154
-
155
- Not every file change needs its own commit. **Group changes that only make sense together:**
156
-
157
- - A new spell prompt + updates to the methodology doc, CLAUDE.md, copilot-instructions.md, and DECISIONS.md that reference it = **one commit** (the spell and its integration are one feature)
158
- - A playbook + its template files = **one commit**
159
- - A security fix + its threat model update = **one commit**
160
-
161
- The test: if you reverted just one of the commits, would the repo be in an inconsistent state? If yes, they belong together.
162
-
163
- ### Staging Strategy
164
-
165
- Use `git add -p` or selective staging to separate unrelated changes that were edited in the same session:
166
-
167
- ```bash
168
- # Stage only the files related to one logical change
169
- git add governance/new-standard.md DECISIONS.md CLAUDE.md
170
- git commit -m "docs(governance): add new-standard with ADR-053"
171
-
172
- # Then stage the unrelated fix
173
- git add README.md
174
- git commit -m "fix(repo): correct broken link in README"
175
- ```
176
-
177
- ---
178
-
179
- ## Branch Discipline
180
-
181
- **Trunk-based development** with mandatory topic branches for all actors. No one — human or agent — commits directly to main.
182
-
183
- ### The Rule
184
-
185
- > **Main is an integration-only branch.** It receives merges, never direct commits. All work happens on topic branches.
186
-
187
- This applies to:
188
-
189
- - Humans editing on any machine
190
- - Autonomous agents working independently
191
- - Interactive AI tools (Copilot, Claude Code, Codex, or any other client)
192
-
193
- ### Branch Naming
194
-
195
- **Humans:**
196
-
197
- ```
198
- type/short-description
199
- ```
200
-
201
- **Session branches (interactive tools — Copilot, Claude Code, etc.):**
202
-
203
- ```
204
- sessions/YYYY-MM-DD-topic-slug
205
- ```
206
-
207
- Create the session branch as the **first action** of any session, before any file edits or commits. All session commits land on this branch. At close, push and open a PR. After merge, return to `main`.
208
-
209
- **Examples:**
210
-
211
- - `sessions/2025-11-04-widget-app-implementation` (interactive session)
212
- - `sessions/2025-11-12-payment-webhook-fix` (interactive session)
213
-
214
- **Session branch policy (required):**
215
-
216
- - Session branches must be deterministic, human-readable, and derived from the active task title.
217
- - Default format for new interactive sessions: `sessions/YYYY-MM-DD-<topic-slug>`.
218
- - Random adjective-noun branches (for example, `ideal-disco`) are non-compliant and must be renamed.
219
- - If a non-compliant branch was already pushed, migrate it safely:
220
- 1. `git branch -m <old> <new>`
221
- 2. `git push -u origin <new>`
222
- 3. `git push origin --delete <old>` (skip this if an active PR still depends on `<old>`).
223
-
224
- **Agents:**
225
-
226
- ```
227
- {agent-slug}/type/short-description
228
- ```
229
-
230
- The agent slug prefix makes branch ownership obvious in `git branch -r` output and prevents naming collisions between agents.
231
-
232
- **Examples:**
233
-
234
- - `docs/readme-update` (human)
235
- - `feat/spell-commit-work` (human)
236
- - `fix/auth-token-regression` (human)
237
- - `lafayette/feat/api-endpoint` (agent — Lafayette)
238
- - `merlin/docs/architecture-update` (agent — Merlin)
239
- - `lince/fix/test-regression` (agent — Lince)
240
-
241
- ### Human Workflow
242
-
243
- 1. **Start a topic branch** before any work:
244
- ```bash
245
- git fetch origin
246
- git checkout -b docs/my-topic origin/main
247
- ```
248
- 2. **Commit often** using Conventional Commits format.
249
- 3. **Push your branch** (especially important for multi-machine work):
250
- ```bash
251
- git push origin docs/my-topic
252
- ```
253
- 4. **Merge to main via fast-forward** when done:
254
- ```bash
255
- git checkout main
256
- git pull origin main
257
- git merge --ff-only docs/my-topic
258
- git push origin main
259
- git branch -d docs/my-topic
260
- git push origin --delete docs/my-topic
261
- ```
262
- 5. **If ff-only fails** (someone else merged first), rebase and retry:
263
- ```bash
264
- git checkout docs/my-topic
265
- git rebase main
266
- git checkout main
267
- git merge --ff-only docs/my-topic
268
- ```
269
-
270
- ### Agent Workflow
271
-
272
- 1. **Create a prefixed topic branch:**
273
- ```bash
274
- git checkout -b lafayette/feat/api-endpoint origin/main
275
- ```
276
- 2. **Commit with proper attribution** (author identity + required trailers).
277
- 3. **Sync with main before opening a PR** — always rebase on the latest origin/main before pushing
278
- or creating a PR, regardless of whether conflicts are expected. **This is mandatory for every
279
- agent-initiated PR — see the [🛑 Agent-mandatory pre-PR guard](#-agent-mandatory-pre-pr-guard)
280
- callout below. It applies even when using raw `az repos pr create` / `gh pr create` / MCP tools
281
- instead of the `spell-create-pull-request` spell.**
282
- ```bash
283
- git fetch origin
284
- git rebase origin/main
285
- # If conflicts arise: resolve → git add → git rebase --continue
286
- ```
287
- This ensures the PR diff is clean, the CI runs against current main, and reviewers see no
288
- stale divergence. Resolve conflicts locally — never push a branch with known merge conflicts.
289
- 4. **Push the branch to origin** (after rebase).
290
- 5. **Merge or queue for review** based on power level:
291
- - **Magus+ agents:** self-merge via `git merge --ff-only`, then push main
292
- - **Below Magus:** push the branch, report branch name, and queue for human merge
293
- 6. **Delete the branch** after merge.
294
-
295
- ### Multi-Machine Workflow
296
-
297
- When working across machines, topic branches are the coordination mechanism:
298
-
299
- - **Starting work on any machine:** `git fetch && git checkout -b type/topic origin/main`
300
- - **Continuing work started on another machine:** `git fetch && git checkout type/topic && git pull`
301
- - **Push branches frequently** so work is available across machines
302
- - Main stays clean — only receives merges from completed branches
303
-
304
- ### Merge Strategy by Repo Risk
305
-
306
- | Repo Type | Examples | Merge Method | PR Required? |
307
- | -------------- | ------------------------------------------- | ------------ | ------------ |
308
- | **Docs repos** | docs hub, prototypes | PR | Yes |
309
- | **Code repos** | application, API, storefront repos | PR | Yes |
310
-
311
- - **All repos have main branch protection.** Direct pushes to main are rejected. All changes must go through a PR.
312
-
313
- #### Azure DevOps PR Merge Type
314
-
315
- When completing a PR in Azure DevOps, allow only these merge strategies by default:
316
-
317
- - **Merge (no fast forward)**, or
318
- - **Rebase and fast-forward**
319
-
320
- Do **not** use Squash commit.
321
-
322
- | Merge Type | Use? | Why |
323
- | --------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
324
- | **Rebase and fast-forward** | **Yes** | Preserves linear history while keeping individual commits and attribution trailers intact. |
325
- | **Merge (no fast forward)** | **Yes** | Preserves full branch context and review traceability where explicit merge commits are preferred. |
326
- | Squash commit | **No** | Collapses commit history and breaks per-commit attribution/analytics and granular rollback. |
327
- | Semi-linear merge | No | Adds unnecessary merge commits on top of rebased commits; avoid by default. |
328
-
329
- ### Commit Governance
330
-
331
- Commit execution rights depend on the interaction context:
332
-
333
- | Context | Commit Behavior | Rationale |
334
- | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
335
- | **Interactive session** (Copilot, Claude in VS Code, Claude Code) | **Must ask human** before committing. Stage changes, present proposed message, wait for approval. | Human is actively collaborating; commits are a shared decision. |
336
- | **Autonomous agent** at Magus+ power level | May self-commit and self-merge within approved scope (per your power-level policy). Must use proper author/trailers. | Agent is operating independently with delegated authority. |
337
- | **Autonomous agent** below Magus | Must commit to topic branch and queue merge for human review. | Insufficient autonomy level for unsupervised merges to main. |
338
-
339
- **Interactive session rule applies to ALL interactive tools, regardless of agent identity.** Even a high-power-level agent cannot auto-commit when operating through an interactive editor session — the human is present and must approve.
340
-
341
- ### Post-Merge Cleanup
342
-
343
- After every PR merge or local fast-forward merge, **always return to main and prune the branch**. Failing to do this leaves you on a stale branch where new work gets committed to the wrong place or stays unpushed.
344
-
345
- ```bash
346
- # After PR merges on remote:
347
- git checkout main
348
- git pull origin main
349
- git branch -d type/old-topic # delete local branch
350
- git push origin --delete type/old-topic # delete remote branch (safety net; ignore 'does not exist' errors if already auto-deleted)
351
- ```
352
-
353
- This applies to all actors — humans, interactive tools (Copilot, Claude), and autonomous agents. The `spell-commit-work` and `spell-close-session` prompts enforce this check.
354
-
355
- ### ADO PR Lifecycle — Complete Command Reference
356
-
357
- When working in an Azure DevOps repo with branch protection (direct push to `main` rejected), use this exact sequence. Several shortcut tools have known reliability issues on Windows — use the commands below instead.
358
-
359
- ```powershell
360
- # 1. Push your topic branch
361
- git push origin <branch>
362
-
363
- # 2. Create the PR
364
- az repos pr create `
365
- --repository <repo> `
366
- --org https://dev.azure.com/<org> `
367
- --source-branch <branch> `
368
- --target-branch main `
369
- --title "type(scope): description" `
370
- --description "Body..."
371
- # Capture pullRequestId from the JSON output
372
-
373
- # 3. Assign reviewer (default to operator identity; idempotent)
374
- # Resolve reviewer (example: git config user.email), then:
375
- az repos pr reviewer list --id <PR_ID> --org https://dev.azure.com/<org>
376
- # If reviewer is missing, add:
377
- az repos pr reviewer add --id <PR_ID> --org https://dev.azure.com/<org> --reviewer "<email>"
378
-
379
- # 4. Approve via CLI first (self-approve only when policy allows)
380
- az repos pr set-vote --id <PR_ID> --org https://dev.azure.com/<org> --vote approve
381
- # If policy blocks self-approval, record and require second human approval.
382
-
383
- # 5. REST fallback only if CLI vote command fails
384
- $bearer = az account get-access-token --resource "499b84ac-1321-427f-aa17-267ca6975798" --query accessToken -o tsv
385
- $headers = @{ Authorization = "Bearer $bearer"; "Content-Type" = "application/json" }
386
- Invoke-RestMethod -Method PUT `
387
- -Uri "https://dev.azure.com/<org>/<project>/_apis/git/repositories/<repo>/pullRequests/<PR_ID>/reviewers/<AAD-id>?api-version=7.1" `
388
- -Headers $headers -Body '{"vote": 10}'
389
-
390
- # 6. Verify vote registered (expect vote: 10 unless policy blocks self-approval)
391
- az repos pr reviewer list --id <PR_ID> --org https://dev.azure.com/<org>
392
-
393
- # 7. Complete (merge) the PR with source-branch deletion and squash disabled
394
- # Allowed merge strategies: Merge (no fast forward) or Rebase+fast-forward
395
- az repos pr update --id <PR_ID> --org https://dev.azure.com/<org> --status completed --delete-source-branch true --squash false
396
-
397
- # 8. Pull merge commit and clean up (worktree-safe)
398
- git checkout main
399
- git pull origin main
400
- git branch -d <branch> # delete local branch (skip if branch is attached to an active worktree)
401
- git push origin --delete <branch> # delete remote branch (safety net — --delete-source-branch true usually handles this; ignore 'does not exist' errors)
402
- ```
403
-
404
- **Known issues:**
405
-
406
- | Issue | Symptom | Fix |
407
- | --------------------------------------------------------------- | ----------------------------------- | ------------------------------------------ |
408
- | Reviewer already assigned | `reviewer add` returns already exists | Treat as idempotent success and continue |
409
- | `az repos pr set-vote` succeeds but approval still blocked | Policy requires additional approver | Confirm vote state, then request second human approval |
410
- | MCP `vote_pull_request` returns "Success" but vote stays 0 | `reviewer list` shows `vote: 0` | Use `Invoke-RestMethod` step 5 above |
411
- | `az rest --body '{"vote":10}'` fails | Shell parsing error on Windows | Use `Invoke-RestMethod` |
412
- | `az repos pr update --status completed` fails with policy error | "Needs 1 approval" | Verify `vote: 10` first, then retry |
413
- | MCP `create_pull_request` returns no data | No PR ID/URL in response | Fall back to `az repos pr create` |
414
- | `gh pr create` not found | `gh` CLI not installed | Use `az repos pr create` |
415
- | `creatorVoteCounts` is false on branch policy | Vote registers but PR still blocked | A second human must approve via ADO web UI |
416
- | `az repos pr update --status completed` returns `status: active` without error | PR silently not merged | Add `--squash false` to the command; the flag triggers the merge path correctly |
417
- | `git branch -d <branch>` fails after merge | Branch is attached to a worktree | Skip local delete; run remote delete + prune |
418
- | `git push origin --delete <branch>` fails with missing ref | Branch already deleted remotely | Treat as non-fatal and continue |
419
-
420
- ### Branch Lifecycle
421
-
422
- - **Short-lived:** hours to a few days, not weeks
423
- - **Delete after merge:** don't let branches pile up — delete local and remote
424
- - **No long-running feature branches:** they create merge hell
425
- - **Stale branch cleanup:** branches older than 7 days or already merged should be pruned
426
- - **Scheduled hygiene:** any scheduled auto-pull job should also run `git fetch --prune` to remove stale remote-tracking branches. Locally merged branches are pruned on the next session or scheduled cycle.
427
- - **Workspace isolation:** agents must never create, switch, or modify branches in a human's primary workspace. All agent work happens in their own isolated clones.
428
-
429
- ---
430
-
431
- ## Ticket Tagging
432
-
433
- If your tracker links commits to work items by ID (Azure Boards, GitHub Issues, Jira, etc.), tag commits so the linkage happens automatically.
434
-
435
- **Recommended for Spell Loop PRs:**
436
-
437
- - Create or identify a work item **before** starting spell-plan
438
- - Include the work item ID in the PR description and link it before merging
439
- - If your branch policy requires a linked work item, PRs without one will be blocked
440
-
441
- **Commit prefix format:**
442
-
443
- ```
444
- #506 test(api): add xUnit test project
445
- ```
446
-
447
- - Prefix commits with `#WORKITEM` to enable automatic commit → work item linking
448
- - The orchestrating agent should include the work item ID in the initial spell-plan message and carry it through to ship
449
-
450
- **Agent responsibility:** When a Spell Loop run is triggered, the work item ID should be provided upfront. The agent stores it in `stories.json` top-level as `"workItemId"` and includes it in every commit and the PR description.
451
-
452
- ---
453
-
454
- ## PR Standards
455
-
456
- All pull requests — whether created by humans or agents — must meet these requirements.
457
-
458
- ### 🛑 Agent-mandatory pre-PR guard
459
-
460
- > **AGENTS: BEFORE running any PR-creation tool (`az repos pr create`, `gh pr create`, the `create_pull_request` MCP tool, or any equivalent), you MUST run `git fetch origin && git rebase origin/<target-branch>` and resolve any conflicts. This is not optional. Skipping this step is a governance violation.**
461
-
462
- This rule applies **every single time**, regardless of:
463
-
464
- - Which tool or CLI is used to open the PR (spell, raw `az`/`gh`, MCP tool, REST call, web UI-triggered automation).
465
- - Whether the branch was recently created off `main` or has been open for hours.
466
- - Whether the agent "thinks" no conflicts are likely — assumptions do not substitute for a rebase.
467
-
468
- **Correct sequence for every agent-initiated PR:**
469
-
470
- ```bash
471
- git fetch origin
472
- git rebase origin/<target-branch> # resolve conflicts locally, never push a conflicted branch
473
- git push --force-with-lease # only if the branch existed remotely before the rebase
474
- # ...only THEN run the PR-creation tool of your choice
475
- ```
476
-
477
- If a rebase produces conflicts the agent cannot confidently resolve, **STOP** and hand off to the human — do **not** open the PR and hope reviewers will sort it out. Pushing a branch that will produce a merge conflict on the target is a governance violation and wastes reviewer time.
478
-
479
- The `spell-create-pull-request` spell encodes this check in Step 0, but the guard is on **the agent**, not on the spell. Bypassing the spell (by calling `az repos pr create` / `gh pr create` directly) does **not** bypass this rule.
480
-
481
- See also: [Agent Workflow — Sync with main before opening a PR](#agent-workflow) below.
482
-
483
- ### PR Requirements
484
-
485
- | Requirement | Details |
486
- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
487
- | **Work item link** | Optional. Linking is encouraged for traceability but enforce it only if your branch policy requires it. |
488
- | **Title format** | Conventional Commits format: `type(scope): description` |
489
- | **Description** | Must include: summary of changes, rationale, verification steps, and a linked work item ID if applicable |
490
- | **Pre-PR sync** | **Mandatory rebase on latest `origin/<target>` before pushing.** See [🛑 Agent-mandatory pre-PR guard](#-agent-mandatory-pre-pr-guard) above — this applies even when opening PRs via raw `az repos pr create` / `gh pr create` / MCP tools. |
491
- | **Branch cleanup** | After merge, delete the source branch (local and remote). |
492
- | **PR link format** | All PR references in agent output should be clickable markdown links to the PR, not a bare `PR #NNN`. |
493
-
494
- ### Agent PR Workflow
495
-
496
- 1. **Create a work item** (if one doesn't exist) using `spell-suggest-feature` or `spell-bug`.
497
- 2. **Open PR** with proper title, description, and work-item link.
498
- 3. **Notify the human** through your configured channel with: `[PR #{number}] {repo} — {title} (#{workItemId})`.
499
- 4. **Address review feedback** if a reviewer requests changes.
500
- 5. **After merge**, delete the branch (local + remote) and confirm cleanup.
501
-
502
- ### PR Hygiene
503
-
504
- - `spell-open-session` checks for open PRs across all repos and reports them.
505
- - PRs open >3 days are flagged as **stale** — the human is prompted to review or close.
506
- - PRs open >7 days without activity are flagged for **closure** — the human decides.
507
- - Abandoned PRs should be closed with a comment explaining why (e.g., "superseded by #{newPR}", "scope changed").
508
-
509
- ---
510
-
511
- ## Agent Attribution Model
512
-
513
- Every commit must clearly identify **who produced the content** and **who approved/pushed it**.
514
-
515
- ### Author vs. Committer
516
-
517
- | Field | Represents | Examples |
518
- | -------------------------- | -------------------------------- | -------------------------------------------------------------------- |
519
- | **Author** (`--author`) | Entity that produced the content | `{AGENT_NAME} <{AGENT_EMAIL}>`, `{OPERATOR_NAME} <{OPERATOR_EMAIL}>` |
520
- | **Committer** (Git config) | Human who approved and pushed | Always the operator: `{OPERATOR_NAME} <{OPERATOR_EMAIL}>` |
521
-
522
- - If **you** wrote the content: don't override author. Your global Git config is used.
523
- - If an **agent** produced the content: use `--author` to set the agent's identity.
524
- - If an **interactive AI tool** (Copilot, Claude in VS Code) produced the content: use the tool-level identity.
525
-
526
- ### Agent Email Convention
527
-
528
- Give every agent/tool a stable email under a domain you control. Most hosts treat author email as metadata only — authentication uses the push credential (SSH key / PAT), not the author email.
529
-
530
- **Format:** `[Persona Name] <[lowercase-persona]@{OPERATOR_DOMAIN}>`
531
-
532
- Maintain a registry of the identities you use, for example:
533
-
534
- | Identity | Email | Type | Role |
535
- | --------------- | --------------------------- | ------------------------------- | -------------------------- |
536
- | {OPERATOR_NAME} | `{OPERATOR_EMAIL}` | Human (owner) | — |
537
- | {AGENT_NAME} | `{AGENT_EMAIL}` | Autonomous agent | Product Operations Manager |
538
- | Merlin | `merlin@{OPERATOR_DOMAIN}` | Autonomous agent | CTO / Architecture Lead |
539
- | Lafayette | `lafayette@{OPERATOR_DOMAIN}` | Autonomous agent | Full-Stack Developer |
540
- | Copilot | `copilot@{OPERATOR_DOMAIN}` | GitHub Copilot | Tool |
541
- | Claude | `claude@{OPERATOR_DOMAIN}` | Claude Code | Tool |
542
-
543
- New agents are registered during onboarding.
544
-
545
- ### Required Commit Trailers (Agent Commits)
546
-
547
- Agent-authored commits MUST include trailers in the commit message footer. Human commits MAY include them.
548
-
549
- | Trailer | Required | Example |
550
- | -------------- | ----------- | --------------------------------------------- |
551
- | `Agent` | Yes | `kellar`, `copilot`, `claude` |
552
- | `Model` | Yes | `claude-opus-4-20250918`, `gpt-4o` |
553
- | `Provider` | Yes | `anthropic`, `openai` |
554
- | `Role` | Recommended | `product-ops`, `developer`, `cto` |
555
- | `Task-Type` | Optional | `docs`, `code`, `review`, `marketing` |
556
- | `Approval` | Optional | `interactive`, `batch`, `post-review` |
557
- | `Channel` | Optional | `chat`, `cli`, `editor` |
558
- | `Risk-Class` | Optional | `low`, `medium`, `high` |
559
- | `Request-ID` | Optional | `req-001` |
560
- | `Session` | Optional | `session-01` |
561
- | `Rollback-Ref` | Optional | path or commit to the pre-change state |
562
-
563
- ### Complete Examples
564
-
565
- **Agent-authored commit ({AGENT_NAME}):**
566
-
567
- ```bash
568
- git commit --author="{AGENT_NAME} <{AGENT_EMAIL}>" \
569
- --trailer="Agent=kellar" \
570
- --trailer="Model=<model-id>" \
571
- --trailer="Provider=<provider>" \
572
- --trailer="Role=product-ops" \
573
- --trailer="Channel=chat" \
574
- -m "feat(inventory): generate initial product catalog
575
-
576
- Created 47 SKUs from the inventory spreadsheet."
577
- ```
578
-
579
- **Copilot-assisted commit (Copilot in editor):**
580
-
581
- ```bash
582
- git commit --author="Copilot <copilot@{OPERATOR_DOMAIN}>" \
583
- --trailer="Agent=copilot" \
584
- --trailer="Model=<model-id>" \
585
- --trailer="Provider=<provider>" \
586
- --trailer="Channel=editor" \
587
- -m "docs(governance): add attribution model to git conventions"
588
- ```
589
-
590
- **Human-authored commit (no overrides):**
591
-
592
- ```bash
593
- git commit -m "docs(decisions): add ADR-028 agent attribution model"
594
- ```
595
-
596
- ### Querying Attribution
597
-
598
- ```bash
599
- # All commits by {AGENT_NAME}
600
- git log --author="{AGENT_NAME}" --oneline
601
-
602
- # All commits by any agent (non-human)
603
- git log --author="@{OPERATOR_DOMAIN}" --oneline
604
-
605
- # All human-only commits
606
- git log --author="{OPERATOR_EMAIL}" --oneline
607
-
608
- # Extract trailers
609
- git log -10 --format='%H %s%n%(trailers:key=Agent,key=Model,key=Provider)%n'
610
-
611
- # Count commits per agent
612
- git log --all --format='%(trailers:key=Agent,valueonly)' | sort | uniq -c | sort -rn
613
- ```
614
-
615
- ---
616
-
617
- ## Tools to Help
618
-
619
- ### Automated Commit Generation
620
-
621
- Use `spell-commit-work` prompt during sessions:
622
-
623
- 1. Type `@spell-commit-work` in chat
624
- 2. Prompt analyzes `git status` and conversation context
625
- 3. Generates Conventional Commits message
626
- 4. Shows for approval
627
- 5. Executes `git add -A && git commit` if approved
628
-
629
- ### Manual Commit Template
630
-
631
- If committing manually, use this mental checklist:
632
-
633
- ```
634
- [ ] Type correct? (feat, fix, docs, chore, refactor, etc.)
635
- [ ] Scope correct? (prompts, agents, security, etc.)
636
- [ ] Imperative mood? ("add" not "added")
637
- [ ] Lowercase start, no period?
638
- [ ] Under 72 chars?
639
- [ ] Body needed for context?
640
- ```
641
-
642
- ### Validating Format
643
-
644
- Quick regex to check format (optional — not enforced by hooks):
645
-
646
- ```bash
647
- # Valid: type(scope): description
648
- ^(feat|fix|docs|refactor|chore|test|perf|ci|style|revert)(\([a-z-]+\))?:\s.{1,72}$
649
- ```
650
-
651
- ---
652
-
653
- ## Examples from This Repo
654
-
655
- **Feature addition:**
656
-
657
- ```
658
- feat(prompts): add spell-commit-work for checkpointing
659
-
660
- Enables mid-session commits without waiting for spell-close-session.
661
- Generates Conventional Commits messages with approval workflow.
662
- ```
663
-
664
- **Documentation update:**
665
-
666
- ```
667
- docs(decisions): add table of contents to DECISIONS.md
668
- ```
669
-
670
- **Bug fix:**
671
-
672
- ```
673
- fix(auth): restore token SecretRef after onboarding
674
-
675
- Onboarding wizard overwrote auth config with a plaintext token.
676
- Restored the SecretRef and restarted the service.
677
- ```
678
-
679
- **Refactor:**
680
-
681
- ```
682
- refactor(prompts): rename to spell- prefix
683
-
684
- - continue-arcane.prompt.md → spell-open-session.prompt.md
685
- - session-close.prompt.md → spell-close-session.prompt.md
686
- - doc-drift-check.prompt.md → spell-check-drift.prompt.md
687
- - new-business-bootstrap.prompt.md → spell-bootstrap-business.prompt.md
688
-
689
- Implements ADR-019 spell- naming convention.
690
- ```
691
-
692
- **Chore:**
693
-
694
- ```
695
- chore(repo): add root .gitignore
696
-
697
- Excludes .env, *.log, node_modules/, .obsidian/, OS artifacts.
698
- ```
699
-
700
- ---
701
-
702
- ## What NOT to Commit
703
-
704
- Enforced by root `.gitignore`:
705
-
706
- - Secrets (`.env`, `*.pem`, `*.key`)
707
- - Logs (`*.log`)
708
- - Dependencies (`node_modules/`, `vendor/`)
709
- - Build artifacts (`dist/`, `build/`, `*.pyc`)
710
- - OS artifacts (`.DS_Store`, `Thumbs.db`, `desktop.ini`)
711
- - Editor state (`.vscode/settings.json`, `.idea/`)
712
- - Obsidian vault state (`.obsidian/`)
713
-
714
- See [.gitignore](../.gitignore) for full list.
715
-
716
- ---
717
-
718
- ## When to Commit
719
-
720
- **During active work (use `spell-commit-work`):**
721
-
722
- - Completed a discrete task (added ADR, renamed files, fixed bug)
723
- - About to switch context to a different task
724
- - Reached a checkpoint before taking a break
725
-
726
- **At session close (use `spell-close-session`):**
727
-
728
- - Generated journal entry, updated TODO.md
729
- - Finalized session documentation
730
- - Ready to hand off or resume later
731
-
732
- **Commit early, commit often.** Small commits with clear messages are easier to review, revert, and understand than giant "end of day" dumps.
733
-
734
- ---
735
-
736
- ## Troubleshooting Notes
737
-
738
- ### Git command unavailable in interactive PowerShell terminal
739
-
740
- **Symptom:** Running `git` returns "The term 'git' is not recognized" even though recent command output still includes Git diff content.
741
-
742
- **Cause:** Terminal PATH resolution can differ between integrated shell contexts, especially when commands are piped or executed in chained command blocks.
743
-
744
- **Fix:** Use the explicit executable path:
745
-
746
- ```powershell
747
- & "C:\Program Files\Git\cmd\git.exe" <subcommand>
748
- ```
749
-
750
- **Verify:** Run:
751
-
752
- ```powershell
753
- & "C:\Program Files\Git\cmd\git.exe" --version
754
- & "C:\Program Files\Git\cmd\git.exe" status --short
755
- ```
756
-
757
- Both commands should return successfully.
758
-
759
- **Prevention:** Prefer explicit git path in scripted close-session and commit workflows when shell behavior is inconsistent.
1
+ ---
2
+ title: Git Conventions — Commit Format and Branching Model
3
+ audience: both
4
+ status: active
5
+ distributable: true
6
+ last_updated: 2026-07-05
7
+ tags: [git, conventional-commits, workflow, standards, attribution]
8
+ ---
9
+
10
+ # Git Conventions
11
+
12
+ How to structure commits, branches, and pull requests for this repository.
13
+
14
+ ## Executive Summary
15
+
16
+ - This repo uses Conventional Commits format for all commit messages — industry standard, tool-portable, human-readable.
17
+ - Trunk-based development with short-lived feature branches keeps history clean and reduces merge conflicts.
18
+ - No custom git hooks — conventions work on any machine without setup, no fragile tooling dependencies.
19
+ - Use `spell-commit-work` prompt during sessions to automate commit message generation in the correct format.
20
+
21
+ ---
22
+
23
+ ## Conventional Commits Format
24
+
25
+ All commit messages follow the [Conventional Commits](https://www.conventionalcommits.org/) standard.
26
+
27
+ ### Basic Structure
28
+
29
+ ```
30
+ type(scope): short description
31
+
32
+ [optional body with details]
33
+
34
+ [optional footer with breaking changes or issue references]
35
+ ```
36
+
37
+ ### Commit Types
38
+
39
+ | Type | When to Use | Example |
40
+ | ---------- | ----------------------------------------------- | -------------------------------------------------------------- |
41
+ | `feat` | New feature or capability | `feat(prompts): add spell-commit-work for checkpointing` |
42
+ | `fix` | Bug fix | `fix(auth): restore token validation after refactor` |
43
+ | `docs` | Documentation only | `docs(decisions): add table of contents to DECISIONS.md` |
44
+ | `refactor` | Code/structure change, no behavior change | `refactor(playbooks): reorganize setup steps` |
45
+ | `chore` | Maintenance, deps, tooling, cleanup | `chore(deps): bump <dependency> to <version>` |
46
+ | `test` | Adding or fixing tests | `test(security): add token-expiry test` |
47
+ | `perf` | Performance improvements | `perf(api): reduce cold-start latency` |
48
+ | `ci` | CI/CD pipeline changes | `ci(azure): add DevOps pipeline for repo sync` |
49
+ | `style` | Code formatting, whitespace (rare in this repo) | `style(markdown): fix inconsistent heading levels` |
50
+ | `revert` | Revert a previous commit | `revert: undo feat(prompts): add spell-commit-work` |
51
+
52
+ ### Scopes
53
+
54
+ Scope indicates what part of the repo changed. Use singular, lowercase.
55
+
56
+ | Scope | Area |
57
+ | ---------------- | ------------------------------------------------- |
58
+ | `prompts` | `.github/prompts/*.prompt.md` |
59
+ | `agents` | `agents/` directory, agent config, policies |
60
+ | `security` | `security/` directory, threat model, hardening |
61
+ | `infrastructure` | `infrastructure/` directory, hardware, OS setup |
62
+ | `decisions` | `DECISIONS.md` updates |
63
+ | `journal` | `journal/` entries |
64
+ | `governance` | `governance/` directory, process docs |
65
+ | `playbooks` | `playbooks/` directory |
66
+ | `business` | `ventures/` directory |
67
+ | `ai-context` | `ai-context/` directory |
68
+ | `repo` | Root-level files (README, TODO, .gitignore, etc.) |
69
+ | `naming` | `naming-conventions.md` |
70
+
71
+ Multiple scopes? Pick the primary one. If everything changed, use `repo` or omit the scope.
72
+
73
+ ### Short Description Rules
74
+
75
+ - **Imperative mood:** "add", "fix", "update", "remove" (not "added", "fixes", "updating")
76
+ - **Lowercase:** start with lowercase letter
77
+ - **No period:** don't end with `.`
78
+ - **72 characters max:** keeps `git log --oneline` readable
79
+
80
+ **Good examples:**
81
+
82
+ - `add spell-commit-work prompt`
83
+ - `fix gateway auth regression after onboarding`
84
+ - `update table of contents in DECISIONS.md`
85
+
86
+ **Bad examples:**
87
+
88
+ - `Added spell-commit-work prompt.` (past tense, period)
89
+ - `Fix gateway authentication regression that occurred after running the onboarding wizard` (too long, 84 chars)
90
+
91
+ ### Optional Body
92
+
93
+ Include a body when:
94
+
95
+ - The short description doesn't explain _why_
96
+ - Multiple related changes need enumeration
97
+ - ADR or file references add value
98
+ - Future readers need context
99
+
100
+ **Format:**
101
+
102
+ - Blank line after the short description
103
+ - Bullet list or paragraphs
104
+ - Wrap at 72 characters per line
105
+ - Reference ADRs, files, or issues
106
+
107
+ **Example:**
108
+
109
+ ```
110
+ feat(prompts): add spell-commit-work for session checkpoints
111
+
112
+ Enables committing work-in-progress during active sessions without
113
+ waiting for spell-close-session. Generates Conventional Commits format
114
+ messages with proper type and scope.
115
+
116
+ Implements ADR-019 spell- naming convention.
117
+
118
+ Changes:
119
+ - Created .github/prompts/spell-commit-work.prompt.md
120
+ - Created governance/git-conventions.md as reference doc
121
+ - Updated TODO.md to mark git conventions doc complete
122
+ ```
123
+
124
+ ### Optional Footer
125
+
126
+ Use for:
127
+
128
+ - **Breaking changes:** `BREAKING CHANGE: removed support for plaintext token auth`
129
+ - **Issue/ticket references:** `Closes #535` or `Fixes #127`
130
+
131
+ Most commits in this repo won't need footers.
132
+
133
+ ---
134
+
135
+ ## Atomic Commits
136
+
137
+ Each commit should be a **single logical change** — one coherent unit that can be understood, reviewed, reverted, or cherry-picked on its own.
138
+
139
+ ### The Rule
140
+
141
+ > **One commit = one purpose.** If you can't describe the commit in a single short description without "and", it's probably two commits.
142
+
143
+ ### When to Split
144
+
145
+ | Situation | Action |
146
+ | -------------------------------------------------- | --------------------------------------------------------------------------------- |
147
+ | New governance doc + updates to 3 referencing docs | One commit — the doc and its cross-references form one logical unit |
148
+ | New feature + unrelated typo fix | Two commits — the typo fix is a separate `fix` or `docs` commit |
149
+ | Refactor + behavior change | Two commits — refactor first (`refactor`), then behavior change (`feat` or `fix`) |
150
+ | Multiple ADRs decided independently | One commit per ADR, each with its related doc updates |
151
+ | Config change + documentation of that change | One commit — the config and its docs are one logical unit |
152
+
153
+ ### When to Combine
154
+
155
+ Not every file change needs its own commit. **Group changes that only make sense together:**
156
+
157
+ - A new spell prompt + updates to the methodology doc, CLAUDE.md, copilot-instructions.md, and DECISIONS.md that reference it = **one commit** (the spell and its integration are one feature)
158
+ - A playbook + its template files = **one commit**
159
+ - A security fix + its threat model update = **one commit**
160
+
161
+ The test: if you reverted just one of the commits, would the repo be in an inconsistent state? If yes, they belong together.
162
+
163
+ ### Staging Strategy
164
+
165
+ Use `git add -p` or selective staging to separate unrelated changes that were edited in the same session:
166
+
167
+ ```bash
168
+ # Stage only the files related to one logical change
169
+ git add governance/new-standard.md DECISIONS.md CLAUDE.md
170
+ git commit -m "docs(governance): add new-standard with ADR-053"
171
+
172
+ # Then stage the unrelated fix
173
+ git add README.md
174
+ git commit -m "fix(repo): correct broken link in README"
175
+ ```
176
+
177
+ ---
178
+
179
+ ## Branch Discipline
180
+
181
+ **Trunk-based development** with mandatory topic branches for all actors. No one — human or agent — commits directly to main.
182
+
183
+ ### The Rule
184
+
185
+ > **Main is an integration-only branch.** It receives merges, never direct commits. All work happens on topic branches.
186
+
187
+ This applies to:
188
+
189
+ - Humans editing on any machine
190
+ - Autonomous agents working independently
191
+ - Interactive AI tools (Copilot, Claude Code, Codex, or any other client)
192
+
193
+ ### Branch Naming
194
+
195
+ **Humans:**
196
+
197
+ ```
198
+ type/short-description
199
+ ```
200
+
201
+ **Session branches (interactive tools — Copilot, Claude Code, etc.):**
202
+
203
+ ```
204
+ sessions/YYYY-MM-DD-topic-slug
205
+ ```
206
+
207
+ Create the session branch as the **first action** of any session, before any file edits or commits. All session commits land on this branch. At close, push and open a PR. After merge, return to `main`.
208
+
209
+ **Examples:**
210
+
211
+ - `sessions/2025-11-04-widget-app-implementation` (interactive session)
212
+ - `sessions/2025-11-12-payment-webhook-fix` (interactive session)
213
+
214
+ **Session branch policy (required):**
215
+
216
+ - Session branches must be deterministic, human-readable, and derived from the active task title.
217
+ - Default format for new interactive sessions: `sessions/YYYY-MM-DD-<topic-slug>`.
218
+ - Random adjective-noun branches (for example, `ideal-disco`) are non-compliant and must be renamed.
219
+ - If a non-compliant branch was already pushed, migrate it safely:
220
+ 1. `git branch -m <old> <new>`
221
+ 2. `git push -u origin <new>`
222
+ 3. `git push origin --delete <old>` (skip this if an active PR still depends on `<old>`).
223
+
224
+ **Agents:**
225
+
226
+ ```
227
+ {agent-slug}/type/short-description
228
+ ```
229
+
230
+ The agent slug prefix makes branch ownership obvious in `git branch -r` output and prevents naming collisions between agents.
231
+
232
+ **Examples:**
233
+
234
+ - `docs/readme-update` (human)
235
+ - `feat/spell-commit-work` (human)
236
+ - `fix/auth-token-regression` (human)
237
+ - `lafayette/feat/api-endpoint` (agent — Lafayette)
238
+ - `merlin/docs/architecture-update` (agent — Merlin)
239
+ - `lince/fix/test-regression` (agent — Lince)
240
+
241
+ ### Human Workflow
242
+
243
+ 1. **Start a topic branch** before any work:
244
+ ```bash
245
+ git fetch origin
246
+ git checkout -b docs/my-topic origin/main
247
+ ```
248
+ 2. **Commit often** using Conventional Commits format.
249
+ 3. **Push your branch** (especially important for multi-machine work):
250
+ ```bash
251
+ git push origin docs/my-topic
252
+ ```
253
+ 4. **Merge to main via fast-forward** when done:
254
+ ```bash
255
+ git checkout main
256
+ git pull origin main
257
+ git merge --ff-only docs/my-topic
258
+ git push origin main
259
+ git branch -d docs/my-topic
260
+ git push origin --delete docs/my-topic
261
+ ```
262
+ 5. **If ff-only fails** (someone else merged first), rebase and retry:
263
+ ```bash
264
+ git checkout docs/my-topic
265
+ git rebase main
266
+ git checkout main
267
+ git merge --ff-only docs/my-topic
268
+ ```
269
+
270
+ ### Agent Workflow
271
+
272
+ 1. **Create a prefixed topic branch:**
273
+ ```bash
274
+ git checkout -b lafayette/feat/api-endpoint origin/main
275
+ ```
276
+ 2. **Commit with proper attribution** (author identity + required trailers).
277
+ 3. **Sync with main before opening a PR** — always rebase on the latest origin/main before pushing
278
+ or creating a PR, regardless of whether conflicts are expected. **This is mandatory for every
279
+ agent-initiated PR — see the [🛑 Agent-mandatory pre-PR guard](#-agent-mandatory-pre-pr-guard)
280
+ callout below. It applies even when using raw `az repos pr create` / `gh pr create` / MCP tools
281
+ instead of the `spell-create-pull-request` spell.**
282
+ ```bash
283
+ git fetch origin
284
+ git rebase origin/main
285
+ # If conflicts arise: resolve → git add → git rebase --continue
286
+ ```
287
+ This ensures the PR diff is clean, the CI runs against current main, and reviewers see no
288
+ stale divergence. Resolve conflicts locally — never push a branch with known merge conflicts.
289
+ 4. **Push the branch to origin** (after rebase).
290
+ 5. **Merge or queue for review** based on power level:
291
+ - **Magus+ agents:** self-merge via `git merge --ff-only`, then push main
292
+ - **Below Magus:** push the branch, report branch name, and queue for human merge
293
+ 6. **Delete the branch** after merge.
294
+
295
+ ### Multi-Machine Workflow
296
+
297
+ When working across machines, topic branches are the coordination mechanism:
298
+
299
+ - **Starting work on any machine:** `git fetch && git checkout -b type/topic origin/main`
300
+ - **Continuing work started on another machine:** `git fetch && git checkout type/topic && git pull`
301
+ - **Push branches frequently** so work is available across machines
302
+ - Main stays clean — only receives merges from completed branches
303
+
304
+ ### Merge Strategy by Repo Risk
305
+
306
+ | Repo Type | Examples | Merge Method | PR Required? |
307
+ | -------------- | ------------------------------------------- | ------------ | ------------ |
308
+ | **Docs repos** | docs hub, prototypes | PR | Yes |
309
+ | **Code repos** | application, API, storefront repos | PR | Yes |
310
+
311
+ - **All repos have main branch protection.** Direct pushes to main are rejected. All changes must go through a PR.
312
+
313
+ #### Azure DevOps PR Merge Type
314
+
315
+ When completing a PR in Azure DevOps, allow only these merge strategies by default:
316
+
317
+ - **Merge (no fast forward)**, or
318
+ - **Rebase and fast-forward**
319
+
320
+ Do **not** use Squash commit.
321
+
322
+ | Merge Type | Use? | Why |
323
+ | --------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
324
+ | **Rebase and fast-forward** | **Yes** | Preserves linear history while keeping individual commits and attribution trailers intact. |
325
+ | **Merge (no fast forward)** | **Yes** | Preserves full branch context and review traceability where explicit merge commits are preferred. |
326
+ | Squash commit | **No** | Collapses commit history and breaks per-commit attribution/analytics and granular rollback. |
327
+ | Semi-linear merge | No | Adds unnecessary merge commits on top of rebased commits; avoid by default. |
328
+
329
+ ### Commit Governance
330
+
331
+ Commit execution rights depend on the interaction context:
332
+
333
+ | Context | Commit Behavior | Rationale |
334
+ | ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
335
+ | **Interactive session** (Copilot, Claude in VS Code, Claude Code) | **Must ask human** before committing. Stage changes, present proposed message, wait for approval. | Human is actively collaborating; commits are a shared decision. |
336
+ | **Autonomous agent** at Magus+ power level | May self-commit and self-merge within approved scope (per your power-level policy). Must use proper author/trailers. | Agent is operating independently with delegated authority. |
337
+ | **Autonomous agent** below Magus | Must commit to topic branch and queue merge for human review. | Insufficient autonomy level for unsupervised merges to main. |
338
+
339
+ **Interactive session rule applies to ALL interactive tools, regardless of agent identity.** Even a high-power-level agent cannot auto-commit when operating through an interactive editor session — the human is present and must approve.
340
+
341
+ ### Post-Merge Cleanup
342
+
343
+ After every PR merge or local fast-forward merge, **always return to main and prune the branch**. Failing to do this leaves you on a stale branch where new work gets committed to the wrong place or stays unpushed.
344
+
345
+ ```bash
346
+ # After PR merges on remote:
347
+ git checkout main
348
+ git pull origin main
349
+ git branch -d type/old-topic # delete local branch
350
+ git push origin --delete type/old-topic # delete remote branch (safety net; ignore 'does not exist' errors if already auto-deleted)
351
+ ```
352
+
353
+ This applies to all actors — humans, interactive tools (Copilot, Claude), and autonomous agents. The `spell-commit-work` and `spell-close-session` prompts enforce this check.
354
+
355
+ ### ADO PR Lifecycle — Complete Command Reference
356
+
357
+ When working in an Azure DevOps repo with branch protection (direct push to `main` rejected), use this exact sequence. Several shortcut tools have known reliability issues on Windows — use the commands below instead.
358
+
359
+ ```powershell
360
+ # 1. Push your topic branch
361
+ git push origin <branch>
362
+
363
+ # 2. Create the PR
364
+ az repos pr create `
365
+ --repository <repo> `
366
+ --org https://dev.azure.com/<org> `
367
+ --source-branch <branch> `
368
+ --target-branch main `
369
+ --title "type(scope): description" `
370
+ --description "Body..."
371
+ # Capture pullRequestId from the JSON output
372
+
373
+ # 3. Assign reviewer (default to operator identity; idempotent)
374
+ # Resolve reviewer (example: git config user.email), then:
375
+ az repos pr reviewer list --id <PR_ID> --org https://dev.azure.com/<org>
376
+ # If reviewer is missing, add:
377
+ az repos pr reviewer add --id <PR_ID> --org https://dev.azure.com/<org> --reviewer "<email>"
378
+
379
+ # 4. Approve via CLI first (self-approve only when policy allows)
380
+ az repos pr set-vote --id <PR_ID> --org https://dev.azure.com/<org> --vote approve
381
+ # If policy blocks self-approval, record and require second human approval.
382
+
383
+ # 5. REST fallback only if CLI vote command fails
384
+ $bearer = az account get-access-token --resource "499b84ac-1321-427f-aa17-267ca6975798" --query accessToken -o tsv
385
+ $headers = @{ Authorization = "Bearer $bearer"; "Content-Type" = "application/json" }
386
+ Invoke-RestMethod -Method PUT `
387
+ -Uri "https://dev.azure.com/<org>/<project>/_apis/git/repositories/<repo>/pullRequests/<PR_ID>/reviewers/<AAD-id>?api-version=7.1" `
388
+ -Headers $headers -Body '{"vote": 10}'
389
+
390
+ # 6. Verify vote registered (expect vote: 10 unless policy blocks self-approval)
391
+ az repos pr reviewer list --id <PR_ID> --org https://dev.azure.com/<org>
392
+
393
+ # 7. Complete (merge) the PR with source-branch deletion and squash disabled
394
+ # Allowed merge strategies: Merge (no fast forward) or Rebase+fast-forward
395
+ az repos pr update --id <PR_ID> --org https://dev.azure.com/<org> --status completed --delete-source-branch true --squash false
396
+
397
+ # 8. Pull merge commit and clean up (worktree-safe)
398
+ git checkout main
399
+ git pull origin main
400
+ git branch -d <branch> # delete local branch (skip if branch is attached to an active worktree)
401
+ git push origin --delete <branch> # delete remote branch (safety net — --delete-source-branch true usually handles this; ignore 'does not exist' errors)
402
+ ```
403
+
404
+ **Known issues:**
405
+
406
+ | Issue | Symptom | Fix |
407
+ | --------------------------------------------------------------- | ----------------------------------- | ------------------------------------------ |
408
+ | Reviewer already assigned | `reviewer add` returns already exists | Treat as idempotent success and continue |
409
+ | `az repos pr set-vote` succeeds but approval still blocked | Policy requires additional approver | Confirm vote state, then request second human approval |
410
+ | MCP `vote_pull_request` returns "Success" but vote stays 0 | `reviewer list` shows `vote: 0` | Use `Invoke-RestMethod` step 5 above |
411
+ | `az rest --body '{"vote":10}'` fails | Shell parsing error on Windows | Use `Invoke-RestMethod` |
412
+ | `az repos pr update --status completed` fails with policy error | "Needs 1 approval" | Verify `vote: 10` first, then retry |
413
+ | MCP `create_pull_request` returns no data | No PR ID/URL in response | Fall back to `az repos pr create` |
414
+ | `gh pr create` not found | `gh` CLI not installed | Use `az repos pr create` |
415
+ | `creatorVoteCounts` is false on branch policy | Vote registers but PR still blocked | A second human must approve via ADO web UI |
416
+ | `az repos pr update --status completed` returns `status: active` without error | PR silently not merged | Add `--squash false` to the command; the flag triggers the merge path correctly |
417
+ | `git branch -d <branch>` fails after merge | Branch is attached to a worktree | Skip local delete; run remote delete + prune |
418
+ | `git push origin --delete <branch>` fails with missing ref | Branch already deleted remotely | Treat as non-fatal and continue |
419
+
420
+ ### Branch Lifecycle
421
+
422
+ - **Short-lived:** hours to a few days, not weeks
423
+ - **Delete after merge:** don't let branches pile up — delete local and remote
424
+ - **No long-running feature branches:** they create merge hell
425
+ - **Stale branch cleanup:** branches older than 7 days or already merged should be pruned
426
+ - **Scheduled hygiene:** any scheduled auto-pull job should also run `git fetch --prune` to remove stale remote-tracking branches. Locally merged branches are pruned on the next session or scheduled cycle.
427
+ - **Workspace isolation:** agents must never create, switch, or modify branches in a human's primary workspace. All agent work happens in their own isolated clones.
428
+
429
+ ---
430
+
431
+ ## Ticket Tagging
432
+
433
+ If your tracker links commits to work items by ID (Azure Boards, GitHub Issues, Jira, etc.), tag commits so the linkage happens automatically.
434
+
435
+ **Recommended for Spell Loop PRs:**
436
+
437
+ - Create or identify a work item **before** starting spell-plan
438
+ - Include the work item ID in the PR description and link it before merging
439
+ - If your branch policy requires a linked work item, PRs without one will be blocked
440
+
441
+ **Commit prefix format:**
442
+
443
+ ```
444
+ #506 test(api): add xUnit test project
445
+ ```
446
+
447
+ - Prefix commits with `#WORKITEM` to enable automatic commit → work item linking
448
+ - The orchestrating agent should include the work item ID in the initial spell-plan message and carry it through to ship
449
+
450
+ **Agent responsibility:** When a Spell Loop run is triggered, the work item ID should be provided upfront. The agent stores it in `stories.json` top-level as `"workItemId"` and includes it in every commit and the PR description.
451
+
452
+ ---
453
+
454
+ ## PR Standards
455
+
456
+ All pull requests — whether created by humans or agents — must meet these requirements.
457
+
458
+ ### 🛑 Agent-mandatory pre-PR guard
459
+
460
+ > **AGENTS: BEFORE running any PR-creation tool (`az repos pr create`, `gh pr create`, the `create_pull_request` MCP tool, or any equivalent), you MUST run `git fetch origin && git rebase origin/<target-branch>` and resolve any conflicts. This is not optional. Skipping this step is a governance violation.**
461
+
462
+ This rule applies **every single time**, regardless of:
463
+
464
+ - Which tool or CLI is used to open the PR (spell, raw `az`/`gh`, MCP tool, REST call, web UI-triggered automation).
465
+ - Whether the branch was recently created off `main` or has been open for hours.
466
+ - Whether the agent "thinks" no conflicts are likely — assumptions do not substitute for a rebase.
467
+
468
+ **Correct sequence for every agent-initiated PR:**
469
+
470
+ ```bash
471
+ git fetch origin
472
+ git rebase origin/<target-branch> # resolve conflicts locally, never push a conflicted branch
473
+ git push --force-with-lease # only if the branch existed remotely before the rebase
474
+ # ...only THEN run the PR-creation tool of your choice
475
+ ```
476
+
477
+ If a rebase produces conflicts the agent cannot confidently resolve, **STOP** and hand off to the human — do **not** open the PR and hope reviewers will sort it out. Pushing a branch that will produce a merge conflict on the target is a governance violation and wastes reviewer time.
478
+
479
+ The `spell-create-pull-request` spell encodes this check in Step 0, but the guard is on **the agent**, not on the spell. Bypassing the spell (by calling `az repos pr create` / `gh pr create` directly) does **not** bypass this rule.
480
+
481
+ See also: [Agent Workflow — Sync with main before opening a PR](#agent-workflow) below.
482
+
483
+ ### PR Requirements
484
+
485
+ | Requirement | Details |
486
+ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
487
+ | **Work item link** | Optional. Linking is encouraged for traceability but enforce it only if your branch policy requires it. |
488
+ | **Title format** | Conventional Commits format: `type(scope): description` |
489
+ | **Description** | Must include: summary of changes, rationale, verification steps, and a linked work item ID if applicable |
490
+ | **Pre-PR sync** | **Mandatory rebase on latest `origin/<target>` before pushing.** See [🛑 Agent-mandatory pre-PR guard](#-agent-mandatory-pre-pr-guard) above — this applies even when opening PRs via raw `az repos pr create` / `gh pr create` / MCP tools. |
491
+ | **Branch cleanup** | After merge, delete the source branch (local and remote). |
492
+ | **PR link format** | All PR references in agent output should be clickable markdown links to the PR, not a bare `PR #NNN`. |
493
+
494
+ ### Agent PR Workflow
495
+
496
+ 1. **Create a work item** (if one doesn't exist) using `spell-suggest-feature` or `spell-bug`.
497
+ 2. **Open PR** with proper title, description, and work-item link.
498
+ 3. **Notify the human** through your configured channel with: `[PR #{number}] {repo} — {title} (#{workItemId})`.
499
+ 4. **Address review feedback** if a reviewer requests changes.
500
+ 5. **After merge**, delete the branch (local + remote) and confirm cleanup.
501
+
502
+ ### PR Hygiene
503
+
504
+ - `spell-open-session` checks for open PRs across all repos and reports them.
505
+ - PRs open >3 days are flagged as **stale** — the human is prompted to review or close.
506
+ - PRs open >7 days without activity are flagged for **closure** — the human decides.
507
+ - Abandoned PRs should be closed with a comment explaining why (e.g., "superseded by #{newPR}", "scope changed").
508
+
509
+ ---
510
+
511
+ ## Agent Attribution Model
512
+
513
+ Every commit must clearly identify **who produced the content** and **who approved/pushed it**.
514
+
515
+ ### Author vs. Committer
516
+
517
+ | Field | Represents | Examples |
518
+ | -------------------------- | -------------------------------- | -------------------------------------------------------------------- |
519
+ | **Author** (`--author`) | Entity that produced the content | `{AGENT_NAME} <{AGENT_EMAIL}>`, `{OPERATOR_NAME} <{OPERATOR_EMAIL}>` |
520
+ | **Committer** (Git config) | Human who approved and pushed | Always the operator: `{OPERATOR_NAME} <{OPERATOR_EMAIL}>` |
521
+
522
+ - If **you** wrote the content: don't override author. Your global Git config is used.
523
+ - If an **agent** produced the content: use `--author` to set the agent's identity.
524
+ - If an **interactive AI tool** (Copilot, Claude in VS Code) produced the content: use the tool-level identity.
525
+
526
+ ### Agent Email Convention
527
+
528
+ Give every agent/tool a stable email under a domain you control. Most hosts treat author email as metadata only — authentication uses the push credential (SSH key / PAT), not the author email.
529
+
530
+ **Format:** `[Persona Name] <[lowercase-persona]@{OPERATOR_DOMAIN}>`
531
+
532
+ Maintain a registry of the identities you use, for example:
533
+
534
+ | Identity | Email | Type | Role |
535
+ | --------------- | --------------------------- | ------------------------------- | -------------------------- |
536
+ | {OPERATOR_NAME} | `{OPERATOR_EMAIL}` | Human (owner) | — |
537
+ | {AGENT_NAME} | `{AGENT_EMAIL}` | Autonomous agent | Product Operations Manager |
538
+ | Merlin | `merlin@{OPERATOR_DOMAIN}` | Autonomous agent | CTO / Architecture Lead |
539
+ | Lafayette | `lafayette@{OPERATOR_DOMAIN}` | Autonomous agent | Full-Stack Developer |
540
+ | Copilot | `copilot@{OPERATOR_DOMAIN}` | GitHub Copilot | Tool |
541
+ | Claude | `claude@{OPERATOR_DOMAIN}` | Claude Code | Tool |
542
+
543
+ New agents are registered during onboarding.
544
+
545
+ ### Required Commit Trailers (Agent Commits)
546
+
547
+ Agent-authored commits MUST include trailers in the commit message footer. Human commits MAY include them.
548
+
549
+ | Trailer | Required | Example |
550
+ | -------------- | ----------- | --------------------------------------------- |
551
+ | `Agent` | Yes | `kellar`, `copilot`, `claude` |
552
+ | `Model` | Yes | `claude-opus-4-20250918`, `gpt-4o` |
553
+ | `Provider` | Yes | `anthropic`, `openai` |
554
+ | `Role` | Recommended | `product-ops`, `developer`, `cto` |
555
+ | `Task-Type` | Optional | `docs`, `code`, `review`, `marketing` |
556
+ | `Approval` | Optional | `interactive`, `batch`, `post-review` |
557
+ | `Channel` | Optional | `chat`, `cli`, `editor` |
558
+ | `Risk-Class` | Optional | `low`, `medium`, `high` |
559
+ | `Request-ID` | Optional | `req-001` |
560
+ | `Session` | Optional | `session-01` |
561
+ | `Rollback-Ref` | Optional | path or commit to the pre-change state |
562
+
563
+ ### Complete Examples
564
+
565
+ **Agent-authored commit ({AGENT_NAME}):**
566
+
567
+ ```bash
568
+ git commit --author="{AGENT_NAME} <{AGENT_EMAIL}>" \
569
+ --trailer="Agent=kellar" \
570
+ --trailer="Model=<model-id>" \
571
+ --trailer="Provider=<provider>" \
572
+ --trailer="Role=product-ops" \
573
+ --trailer="Channel=chat" \
574
+ -m "feat(inventory): generate initial product catalog
575
+
576
+ Created 47 SKUs from the inventory spreadsheet."
577
+ ```
578
+
579
+ **Copilot-assisted commit (Copilot in editor):**
580
+
581
+ ```bash
582
+ git commit --author="Copilot <copilot@{OPERATOR_DOMAIN}>" \
583
+ --trailer="Agent=copilot" \
584
+ --trailer="Model=<model-id>" \
585
+ --trailer="Provider=<provider>" \
586
+ --trailer="Channel=editor" \
587
+ -m "docs(governance): add attribution model to git conventions"
588
+ ```
589
+
590
+ **Human-authored commit (no overrides):**
591
+
592
+ ```bash
593
+ git commit -m "docs(decisions): add ADR-028 agent attribution model"
594
+ ```
595
+
596
+ ### Querying Attribution
597
+
598
+ ```bash
599
+ # All commits by {AGENT_NAME}
600
+ git log --author="{AGENT_NAME}" --oneline
601
+
602
+ # All commits by any agent (non-human)
603
+ git log --author="@{OPERATOR_DOMAIN}" --oneline
604
+
605
+ # All human-only commits
606
+ git log --author="{OPERATOR_EMAIL}" --oneline
607
+
608
+ # Extract trailers
609
+ git log -10 --format='%H %s%n%(trailers:key=Agent,key=Model,key=Provider)%n'
610
+
611
+ # Count commits per agent
612
+ git log --all --format='%(trailers:key=Agent,valueonly)' | sort | uniq -c | sort -rn
613
+ ```
614
+
615
+ ---
616
+
617
+ ## Tools to Help
618
+
619
+ ### Automated Commit Generation
620
+
621
+ Use `spell-commit-work` prompt during sessions:
622
+
623
+ 1. Type `@spell-commit-work` in chat
624
+ 2. Prompt analyzes `git status` and conversation context
625
+ 3. Generates Conventional Commits message
626
+ 4. Shows for approval
627
+ 5. Executes `git add -A && git commit` if approved
628
+
629
+ ### Manual Commit Template
630
+
631
+ If committing manually, use this mental checklist:
632
+
633
+ ```
634
+ [ ] Type correct? (feat, fix, docs, chore, refactor, etc.)
635
+ [ ] Scope correct? (prompts, agents, security, etc.)
636
+ [ ] Imperative mood? ("add" not "added")
637
+ [ ] Lowercase start, no period?
638
+ [ ] Under 72 chars?
639
+ [ ] Body needed for context?
640
+ ```
641
+
642
+ ### Validating Format
643
+
644
+ Quick regex to check format (optional — not enforced by hooks):
645
+
646
+ ```bash
647
+ # Valid: type(scope): description
648
+ ^(feat|fix|docs|refactor|chore|test|perf|ci|style|revert)(\([a-z-]+\))?:\s.{1,72}$
649
+ ```
650
+
651
+ ---
652
+
653
+ ## Examples from This Repo
654
+
655
+ **Feature addition:**
656
+
657
+ ```
658
+ feat(prompts): add spell-commit-work for checkpointing
659
+
660
+ Enables mid-session commits without waiting for spell-close-session.
661
+ Generates Conventional Commits messages with approval workflow.
662
+ ```
663
+
664
+ **Documentation update:**
665
+
666
+ ```
667
+ docs(decisions): add table of contents to DECISIONS.md
668
+ ```
669
+
670
+ **Bug fix:**
671
+
672
+ ```
673
+ fix(auth): restore token SecretRef after onboarding
674
+
675
+ Onboarding wizard overwrote auth config with a plaintext token.
676
+ Restored the SecretRef and restarted the service.
677
+ ```
678
+
679
+ **Refactor:**
680
+
681
+ ```
682
+ refactor(prompts): rename to spell- prefix
683
+
684
+ - continue-arcane.prompt.md → spell-open-session.prompt.md
685
+ - session-close.prompt.md → spell-close-session.prompt.md
686
+ - doc-drift-check.prompt.md → spell-check-drift.prompt.md
687
+ - new-business-bootstrap.prompt.md → spell-bootstrap-business.prompt.md
688
+
689
+ Implements ADR-019 spell- naming convention.
690
+ ```
691
+
692
+ **Chore:**
693
+
694
+ ```
695
+ chore(repo): add root .gitignore
696
+
697
+ Excludes .env, *.log, node_modules/, .obsidian/, OS artifacts.
698
+ ```
699
+
700
+ ---
701
+
702
+ ## What NOT to Commit
703
+
704
+ Enforced by root `.gitignore`:
705
+
706
+ - Secrets (`.env`, `*.pem`, `*.key`)
707
+ - Logs (`*.log`)
708
+ - Dependencies (`node_modules/`, `vendor/`)
709
+ - Build artifacts (`dist/`, `build/`, `*.pyc`)
710
+ - OS artifacts (`.DS_Store`, `Thumbs.db`, `desktop.ini`)
711
+ - Editor state (`.vscode/settings.json`, `.idea/`)
712
+ - Obsidian vault state (`.obsidian/`)
713
+
714
+ See [.gitignore](../.gitignore) for full list.
715
+
716
+ ---
717
+
718
+ ## When to Commit
719
+
720
+ **During active work (use `spell-commit-work`):**
721
+
722
+ - Completed a discrete task (added ADR, renamed files, fixed bug)
723
+ - About to switch context to a different task
724
+ - Reached a checkpoint before taking a break
725
+
726
+ **At session close (use `spell-close-session`):**
727
+
728
+ - Generated journal entry, updated TODO.md
729
+ - Finalized session documentation
730
+ - Ready to hand off or resume later
731
+
732
+ **Commit early, commit often.** Small commits with clear messages are easier to review, revert, and understand than giant "end of day" dumps.
733
+
734
+ ---
735
+
736
+ ## Troubleshooting Notes
737
+
738
+ ### Git command unavailable in interactive PowerShell terminal
739
+
740
+ **Symptom:** Running `git` returns "The term 'git' is not recognized" even though recent command output still includes Git diff content.
741
+
742
+ **Cause:** Terminal PATH resolution can differ between integrated shell contexts, especially when commands are piped or executed in chained command blocks.
743
+
744
+ **Fix:** Use the explicit executable path:
745
+
746
+ ```powershell
747
+ & "C:\Program Files\Git\cmd\git.exe" <subcommand>
748
+ ```
749
+
750
+ **Verify:** Run:
751
+
752
+ ```powershell
753
+ & "C:\Program Files\Git\cmd\git.exe" --version
754
+ & "C:\Program Files\Git\cmd\git.exe" status --short
755
+ ```
756
+
757
+ Both commands should return successfully.
758
+
759
+ **Prevention:** Prefer explicit git path in scripted close-session and commit workflows when shell behavior is inconsistent.