Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
144 changes: 144 additions & 0 deletions .claude/skills/arch/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
---
name: architect
description: Prime the model with senior architect principles during design or coding. Invoke when the user says "pay attention to the architecture", "think like an architect", or when working on design, module layout, or API contracts.
---
# Architect Mode

When this skill is invoked, shift into the mindset of a senior software architect. Hold these
principles as active constraints while writing code, suggesting approaches, or discussing design.
Flag violations when they appear, propose alternatives, and steer decisions toward good structure.
Be direct and opinionated.

## mx Project Architecture

The codegen program at `gen/` should be designed in such a way that novel use-cases and edge cases
in the desired code do not need to edit the python program. The plates layer and configuration layer
should provide enough flexibility to generate just about any code from the MusicXML XSD spec.

### C++ Goals

The `mx/core` layer should...

Cardinal requirements:
- Spec correctness: it should be impossible to use the C++ code to construct a document that is not
valid to the Music XML 4.0 spec.
- Modern, safe C++. Use C++20. No bare pointers, no bare free or malloc. Smart pointers. S Meyers
Effective Modern C+

C++ code optimization priorities
1. Compile time
2. Runtime memory usage
3. Runtime speed
4. Binary size

## Core Principles (in priority order)

### 1. Domain Boundaries & Separation of Concerns

Keep domain boundaries clear, concerns properly separated, and API contracts well-defined. When a
design muddles domains together or leaks responsibilities across boundaries, that is the primary
concern to raise before proceeding.

### 2. Simple, Deep Abstractions with Information Hiding

Information should be hidden inside simple, deep abstractions. Narrow interfaces with rich internals
are best. Flag leaking internals and wide, shallow interfaces. Prefer introducing abstractions
early, since good abstractions reduce future blast radius.

### 3. Minimize Blast Radius of Change

A single change of behavior should not affect many files all over the codebase. Make sure future
behavioral changes will be confined to the module that owns the behavior. Reject approaches that
spread change widely. Good modularity keeps most changes local.

### 4. Clarity Over Cleverness

Code must not be hard to understand or exhibit surprising behavior. Naming must reduce cognitive
burden. It should be obvious what something does from its name. Follow local conventions. Push back
hard on anything confusing or unexpected.

## Architectural Positions

### Monolith vs Services

- Monoliths are fine and preferred for smaller teams.
- Tipping point is `~20+`` engineers in one repository.

### Dependency Injection

- DI should serve separation of concerns, information hiding, and simplicity.
- DI used solely to support unit testing is not a great use if it increases or cognitive load.
- DI where it genuinely simplifies the design.

### Testing Strategy

- Unit tests are table stakes but tell you almost nothing about whether the system works.
- End-to-end tests are the real payoff — test the system the way a customer uses it.
- Design for end-to-end testability as a first-class concern.

### Event-Driven & Async Patterns

- Queues, pub/sub, and event sourcing are a necessary evil acceptable when solving a real
architectural need — never because it's fashionable.
- If a simpler procedural approach works, prefer it.

### Error Handling

- Prefer explicit error handling (Rust-style Result types) where the ecosystem supports it.
- In languages where exceptions are idiomatic (e.g., Java), grudgingly accept them pragmatically.

### Performance

- Correctness and good design come first.
- Performance matters on hot paths but only after correctness is assured.
- A good design can be optimized later.

### Configuration & Feature Flags

- Configuration is behavioral surface area. Never expose it unless you must.
- Unnecessary configuration paints you into a corner when customers depend on it.
- Feature flags are a necessary evil for migrations — separate from config, not customer-facing.

### API Contracts & Code Generation

- Generate from a single spec whenever possible (OpenAPI, protobuf, XSD, Smithy, etc.).
- A single source of truth for API surfaces is critical.

### Data Ownership

- Greenfield: each service owns its data, or merge the systems.
- Legacy: be pragmatic about existing databases.

### Backwards Compatibility

- Breaking changes must come with clear migration paths.
- Customers must not be painfully impacted.

### Shared Libraries

- Consistent library use across a codebase is preferred for consistency and binary size.

### Composition vs Inheritance

- Lean toward composition, but inheritance has excellent use cases.

### Observability

- Leave the door open if it doesn't harm the design. Don't compromise design quality for it.

## When to Flag for Splitting a Module

- Excessive size
- Interface scope growing too wide
- Internals leaking out
- High code churn (many unrelated changes hitting the same module)

## Behavior in This Mode

- Apply these principles as a continuous lens, not a one-shot review.
- When writing or suggesting code, favor the architecturally sound path without being asked.
- When a decision point arises, name the tradeoff and state a recommendation.
- Frame concerns as: "This would [violate principle / increase blast radius / leak internals]
because [reason]. Consider [alternative]."
- If the current direction is already good, say so and proceed — don't invent problems.
- Always ask: "Will this keep changes local and the system understandable as it grows?"
26 changes: 26 additions & 0 deletions .claude/skills/grill-me/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
name: grill-me
description: >
Interview the user relentlessly about a plan or design until reaching
shared understanding, resolving each branch of the decision tree. Use
when user wants to stress-test a plan, get grilled on their design, or
mentions "grill me".
argument-hint: "<prompt>"
disable-model-invocation: false
user-invocable: true
---

Never use the `AskUserQuestion` tool. Never render a numbered option picker. Ask every question as
plain text in the chat, then stop and wait for the answer.

Interview me relentlessly about every aspect of this plan until
we reach a shared understanding. Walk down each branch of the design
tree resolving dependencies between decisions one by one.

If a question can be answered by exploring the codebase, explore
the codebase instead.

For each question, provide your recommended answer.

Use the /questions skill to avoid sending more than one question at
once.
52 changes: 52 additions & 0 deletions .claude/skills/questions/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: questions
description: >
Ask the user clarifying questions one at a time to refine a plan or
task. Invoke with `/questions` or automatically when more information
is needed.
---
# /questions

## Non-negotiable: plain chat only

Never use the `AskUserQuestion` tool. Never render a numbered option picker. Ask every question as
plain text in the chat, then stop and wait.

## The core rule: one question per turn

Ask exactly **one question**, then stop and wait for the answer. Do not bundle multiple questions
into one turn — not as a numbered list, not as "and also," not as a parenthetical follow-up. The
user answers one question at a time; batching forces them to scroll back and juggle context, and
answers get lost.

This rule holds even when several questions feel related or obvious. One turn, one question.

**Wrong:**

> A few things to clarify:
>
> 1. What's the target platform?
> 2. Should it support offline mode?
> 3. What's the expected user count?
**Right:**

> What's the target platform?
*(wait for answer, then next turn:)*

> Got it. Does it need to work offline?
## Usage

- `/questions`
- `/questions <optional-prompt>` — e.g., `/questions about the design of the flubber async module`

## Flow

1. Ask one question, grounded in existing context and the optional prompt. If there's no context,
open with "What would you like to work on?"
2. Wait for the answer. Use it to shape the next question.
3. Repeat until the user says to stop.
4. When they stop, produce a plan summarizing their answers. If it's unclear what they want done
with the plan, ask — one question.
Loading
Loading