Files
JamBuddy/CONTRIBUTING.md
vadimwit 8a7f932170 docs: CONTRIBUTING.md + issue templates — the musician contribution path (task H-02)
'Add a style without deep coding' centerpiece: KB data contract, mirror gospel pack,
register, run validator; explains why the validator exists; /kb-expand assisted path;
PR checklist. add-style/bug_report/feature_request templates + config.yml. License flagged
unsettled, not decided. Critic PASS (all links/commands verified, schema-faithful).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-15 08:34:21 +01:00

164 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Contributing to JamBuddy
JamBuddy is two things at once: a live **jam companion** that hears your key and chords and shows you how to play over them, and an open **learning platform** for the style knowledge behind those changes. The full vision is in [`GOAL.md`](GOAL.md).
The best part: **the style packs are data, not code.** If you're a gigging musician who knows how a style is voiced and played, you can teach JamBuddy a new genre by filling in a structured file — no audio or detection internals required. This guide is about that path.
---
## Quick start (setup)
You'll need [Node.js](https://nodejs.org/) (18+) and, for the live app, a microphone.
```bash
git clone https://github.com/whattheflat/whattheflat.git
cd whattheflat
npm install
# Desktop app — Vite dev server + Electron window, hot reload, mic access
npm run electron:dev
# Or browser-only (no Electron shell) — then open http://localhost:5173
npm run dev
```
You do **not** need the app running to add a style — adding a style is editing data files and running one validator command. But it's nice to see your pack light up live once it's in.
---
## Add a music style without deep coding
This is the heart of contributing. A "style" is a genre pack: the standard progressions of that style, plus idiomatic ways to play each one. One pack renders in **all 12 keys** automatically, because everything is stored key-agnostically (scale degrees, not chord names).
The data contract you're filling is [`src/data/kb/SCHEMA.md`](src/data/kb/SCHEMA.md) — read it; it's the source of truth. The steps below are the workflow around it.
### Step 1 — Copy an existing pack as your template
A style lives in `src/data/kb/<style>/` and has (at least) three files:
```
src/data/kb/<style>/
meta.js — the style's identity (label, feel, tempo, one-line character)
progressions.js — the style's standard progressions (instrument-independent)
guitar.js — how to play them on guitar (voicings, comping, improv)
```
The cleanest way to start is to **mirror a finished pack**. The gospel pack is a good, complete reference to copy and edit:
- [`src/data/kb/gospel/meta.js`](src/data/kb/gospel/meta.js)
- [`src/data/kb/gospel/progressions.js`](src/data/kb/gospel/progressions.js)
- [`src/data/kb/gospel/guitar.js`](src/data/kb/gospel/guitar.js)
(`SCHEMA.md` names the `jazz/` pack as its canonical exemplar — gospel mirrors the same shape and is a good second model. Pick whichever style is closest to yours.)
Make a new folder named after your style (e.g. `src/data/kb/neosoul/`), copy those three files in, and rewrite the content.
### Step 2 — Fill in the fields (in plain musician language)
**`meta.js`** — the style's identity. `id` (must equal the folder name), `label` (display name), `feel` (`swing` / `straight` / `shuffle` / `16th` / `bossa`…), `tempoRange` (`[low, high]` BPM), and a one-sentence `character` of what makes the style sound like itself.
**`progressions.js`** — your style's signature progressions, 48 of them. Each one is written **key-agnostically** using these fields:
- `degrees` — the chord roots as **semitone offsets from the key root, 011**. So in any major key: I = `0`, ii = `2`, IV = `5`, V = `7`, vi = `9`. A iiVI is `[2, 7, 0]`. You write the *intervals*, JamBuddy fills in the actual chords once it knows the key.
- `qualities` — the chord **quality** for each degree, e.g. `min7`, `dom7`, `maj7`, `maj`, `add9`, `sus4`, `dim7`. These must be one of the names JamBuddy knows: `maj`, `min`, `dom7`, `maj7`, `min7`, `dim`, `dim7`, `half_dim`, `aug`, `sus4`, `sus2`, `maj6`, `min6`, `add9`. (That list lives in `CHORD_TYPES` in `src/lib/theory.js`.)
- `rn` — the Roman numerals you'd *write on a chart* (`['ii7', 'V7', 'Imaj7']`) — purely for display.
- `bars` — how many bars each chord lasts.
- `mode``major`, `minor`, `dorian`, `phrygian`, `lydian`, or `mixolydian`.
- `songs` — real songs that use the progression. **Be honest here** (see the PR checklist).
- `tip` — one transferable idea a player can take away.
- `id` — a globally unique slug, prefixed with your style name (`neosoul-251`, `neosoul-vamp`…).
`degrees`, `qualities`, `rn`, and `bars` must all be the **same length** (one entry per chord in the loop).
**`guitar.js`** — the ways to play each progression. The key fields:
- `styleIntro` — 23 sentences on the guitar's role in this style.
- `comping` — at least one named rhythm with a description.
- `plays` — for each progression id, **at least two genuinely different ways to play it** (different register, density, or technique — not the same voicing moved up the neck).
- `improv` — scales to solo over each chord, target notes, optional licks.
Each chord in a play carries a guitar **shape**, written in one of two formats:
- **Movable shape** (the common case) — fret offsets *relative to the root fret*, so the same grip works in every key:
```js
shape: {
rootStr: 6, // which string carries the root (6 = low E)
offsets: [0, 'x', 0, 1, 'x', 'x'], // always 6 entries, low-E string first; 'x' = muted
fingers: [1, 0, 2, 3, 0, 0],
}
```
- **Open shape** (open-string chords that only work in certain keys) — uses absolute `frets` plus `onlyRoot` (the pitch class, 011, the shape is built for) instead of `offsets`.
If a voicing **deliberately leaves a note out**, declare it so the data stays honest and the UI can show it:
- `extensions: ['9']` — colour tones you've added beyond the basic chord (the validator only allows notes you've declared).
- `rootless: true` — the shape omits the root (e.g. guide-tone grips where the bass covers the root).
- `omit3: true` — the shape omits the 3rd (e.g. power chords that work over major or minor).
### Step 3 — Register the style
Open [`src/data/kb/index.js`](src/data/kb/index.js) and add your pack the same way the others are wired: import its `meta`, `progressions`, and `guitar`, then add an entry to the exported registry. Mirror an existing block exactly — the UI reads only this registry.
### Step 4 — Run the validator until it's green
```bash
node scripts/validate-kb.mjs
```
A passing run looks like:
```
✓ KB valid — 9 style(s), 45 progressions, 90 plays
```
If it fails, it prints a specific line for each problem (which file, which chord, what's wrong). Fix the data and run again. **Never weaken the validator to make content pass** — if you think a rule is wrong, open an issue instead.
#### Why the validator exists (this is the important part)
The validator is the quality bar that lets us trust voicings we didn't author ourselves. For **every guitar shape**, it computes the **actual pitch classes** the grip would sound (from the string tuning, the root string, and your offsets) and checks two things:
1. **Every note you sound actually belongs to the chord** — the chord's own tones plus any `extensions` you declared. A misspelled grip (a wrong fret, a stray open string) sounds a note that isn't in the chord, and the validator rejects it.
2. **The chord's defining tones are present** — unless you've honestly declared them omitted via `rootless` / `omit3`.
In plain terms: you can't accidentally ship an "Amaj7" that's secretly an A7, and you can't claim a voicing has a note it doesn't. That mechanical check is what makes a contributed pack trustworthy without a maintainer re-fingering every chord by hand.
---
## The assisted path: `/kb-expand`
If you're working with [Claude Code](https://claude.com/claude-code), the `/kb-expand` skill is an assisted authoring route. It does exactly **one style × instrument cell end to end** — researches the style's standard progressions and idiomatic voicings (with sources), drafts the files per `SCHEMA.md`, registers the style, and **self-validates** by running `node scripts/validate-kb.mjs` until green before stopping. It's the fastest way to go from "I know this genre" to a scaffolded, validated pack you can refine. You still own the musical judgment — check its voicings and attributions.
---
## Pull request checklist
Before you open a PR, confirm:
- [ ] **Validator green** — `node scripts/validate-kb.mjs` prints `✓ KB valid …`.
- [ ] **Build green** — `npm run build` succeeds (your new file imports cleanly).
- [ ] **Honest attributions** — every song listed actually uses the progression. Do **not** claim a specific recording uses an exact voicing unless you genuinely know it does; "standard in the tradition" or a hedged reference is better than a fabricated one. Licks and sources are real.
- [ ] **Plays genuinely differ** — the 2+ ways to play each progression contrast in register, density, or technique (not transpositions of one another).
- [ ] **One style per PR** — keeps review focused and easy to merge.
That's it. Open the PR, and a maintainer (the Critic in our [ensemble](docs/agents/ROSTER.md)) will run the same checks before merging.
---
## Reporting bugs and proposing styles
You don't have to write any code to help:
- **Propose or contribute a style** → use the [Propose / contribute a style](.github/ISSUE_TEMPLATE/add-style.md) issue template. Tell us the genre, its signature progressions, and whether you'll author the voicings or want help.
- **Found a bug?** → [Bug report](.github/ISSUE_TEMPLATE/bug_report.md).
- **Have an idea?** → [Feature request](.github/ISSUE_TEMPLATE/feature_request.md).
---
## Scope and ground rules
- Adding/editing **style data** under `src/data/kb/` and using the issue templates needs no special permission — that's exactly the contribution path this guide is for.
- Changes to **app code, the audio pipeline, the schema, or the validator** are bigger — open an issue to discuss first so it fits the roadmap in [`GOAL.md`](GOAL.md).
- **License:** the project doesn't have a license file yet, so reuse terms aren't settled. If that matters for your contribution, raise it in an issue before investing heavily.
Thanks for helping musicians hear, play, and *learn* the jam.