@thebassclef/lite 0.1.0 → 0.1.3
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.
- package/dist/cli.cjs +40 -6
- package/dist/cli.js +40 -6
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/substrate/.bassclef/lite-manifest.json +999 -92
- package/substrate/.claude/hooks/longrun-prep-compounding-axis-check.sh +492 -0
- package/substrate/.claude/hooks/longrun-prep-compounding-sequence-check.sh +492 -0
- package/substrate/.claude/hooks/pre-commit-gate.sh +1 -2
- package/substrate/.claude/hooks/turn-prose-kiss-check.sh +30 -1
- package/substrate/.claude/luminaries/glenford-myers.md +230 -0
- package/substrate/.claude/luminaries/hunt-thomas.md +115 -0
- package/substrate/.claude/luminaries/hyrum-wright.md +94 -0
- package/substrate/.claude/luminaries/michael-feathers.md +2 -2
- package/substrate/.claude/luminaries/tony-hoare.md +170 -0
- package/substrate/.claude/luminaries/vaughn-vernon.md +50 -0
- package/substrate/.claude/luminaries/w-edwards-deming.md +158 -0
- package/substrate/.claude/rules/accessor-library-discipline.md +138 -0
- package/substrate/.claude/rules/adr-discipline.md +120 -0
- package/substrate/.claude/rules/api-conventions.md +125 -0
- package/substrate/.claude/rules/bootstrap-pair-discipline.md +141 -0
- package/substrate/.claude/rules/cold-adopter-harness-discipline.md +129 -0
- package/substrate/.claude/rules/compounding-axis-fresh-analysis.md +188 -0
- package/substrate/.claude/rules/compounding-sequence-fresh-analysis.md +188 -0
- package/substrate/.claude/rules/defensive-bash.md +68 -0
- package/substrate/.claude/rules/deferred-actions.md +233 -0
- package/substrate/.claude/rules/github-issue-flash-tweet.md +156 -0
- package/substrate/.claude/rules/hook-wire-on-author.md +103 -0
- package/substrate/.claude/rules/iteration-bet-brief-completeness.md +54 -0
- package/substrate/.claude/rules/lite-manifest-schema-change-discipline.md +3 -3
- package/substrate/.claude/rules/longrun-prep-plan-doc-compression.md +89 -0
- package/substrate/.claude/rules/loop-discipline.md +81 -0
- package/substrate/.claude/rules/manual-prod-approval.md +100 -0
- package/substrate/.claude/rules/marker-enrichment-discipline.md +99 -0
- package/substrate/.claude/rules/mobile-ephemeral-session.md +109 -0
- package/substrate/.claude/rules/new-dependency-check.md +51 -0
- package/substrate/.claude/rules/option-label-discipline.md +108 -0
- package/substrate/.claude/rules/pattern-annotation.md +100 -0
- package/substrate/.claude/rules/plain-english-discipline.md +11 -9
- package/substrate/.claude/rules/plan-enumeration-needs-value-props.md +211 -0
- package/substrate/.claude/rules/pr-title-shape.md +161 -0
- package/substrate/.claude/rules/prototype-workflow.md +65 -0
- package/substrate/.claude/rules/reserved-skill-names.md +123 -0
- package/substrate/.claude/rules/schema-management.md +49 -0
- package/substrate/.claude/rules/security.md +37 -0
- package/substrate/.claude/rules/skill-composition-declarations.md +124 -0
- package/substrate/.claude/rules/skill-description-clarity.md +247 -0
- package/substrate/.claude/rules/skill-procedure-step-list.md +137 -0
- package/substrate/.claude/rules/stuck-signal-diagnostic.md +140 -0
- package/substrate/.claude/rules/substrate-config-schema.md +98 -0
- package/substrate/.claude/rules/test-list-discipline.md +175 -0
- package/substrate/.claude/rules/test-sufficiency.md +210 -0
- package/substrate/.claude/rules/testing-tier-config.md +145 -0
- package/substrate/.claude/rules/testing.md +38 -0
- package/substrate/.claude/rules/turn-estimate-grounding.md +134 -0
- package/substrate/.claude/rules/visual-hierarchy.md +437 -0
- package/substrate/.claude/rules/we-dont-break-adopters.md +126 -0
- package/substrate/.claude/rules/wu-sequencing-compounds.md +145 -0
- package/substrate/.claude/skills/build/SKILL.md +1 -1
- package/substrate/.claude/skills/chronicle/SKILL.md +55 -0
- package/substrate/.claude/skills/clean-artifacts/SKILL.md +249 -0
- package/substrate/.claude/skills/decompose/SKILL.md +1 -1
- package/substrate/.claude/skills/diagnose/SKILL.md +1 -1
- package/substrate/.claude/skills/feynman/SKILL.md +90 -0
- package/substrate/.claude/skills/howdoi/SKILL.md +1 -1
- package/substrate/.claude/skills/ia-model/SKILL.md +1 -1
- package/substrate/.claude/skills/interaction-design/SKILL.md +1 -1
- package/substrate/.claude/skills/interpret-input/SKILL.md +8 -8
- package/substrate/.claude/skills/journal/SKILL.md +209 -0
- package/substrate/.claude/skills/kiss/SKILL.md +1 -1
- package/substrate/.claude/skills/launch/SKILL.md +14 -23
- package/substrate/.claude/skills/lean-canvas/SKILL.md +1 -1
- package/substrate/.claude/skills/longrun/SKILL.md +45 -8
- package/substrate/.claude/skills/luminary/SKILL.md +1 -1
- package/substrate/.claude/skills/ogilvy-writing-audit/SKILL.md +1 -1
- package/substrate/.claude/skills/onboard-repo/SKILL.md +143 -709
- package/substrate/.claude/skills/pattern-review/SKILL.md +1 -1
- package/substrate/.claude/skills/personas/SKILL.md +5 -5
- package/substrate/.claude/skills/promote/SKILL.md +1 -1
- package/substrate/.claude/skills/requirement/SKILL.md +1 -1
- package/substrate/.claude/skills/retro/SKILL.md +1 -1
- package/substrate/.claude/skills/riff/SKILL.md +1 -1
- package/substrate/.claude/skills/roadmap-reconcile/SKILL.md +1 -1
- package/substrate/.claude/skills/session-end/SKILL.md +1 -1
- package/substrate/.claude/skills/session-log/SKILL.md +3 -3
- package/substrate/.claude/skills/skills/SKILL.md +1 -1
- package/substrate/.claude/skills/spec/SKILL.md +1 -1
- package/substrate/.claude/skills/sprint/SKILL.md +1 -1
- package/substrate/.claude/skills/stage/SKILL.md +1 -1
- package/substrate/.claude/skills/state-a-problem/SKILL.md +1 -1
- package/substrate/.claude/skills/temperance/SKILL.md +1 -1
- package/substrate/.claude/skills/use-case/SKILL.md +1 -1
- package/substrate/.claude/skills/user-stories/SKILL.md +1 -1
- package/substrate/.claude/skills/value-prop/SKILL.md +1 -1
- package/substrate/.claude/skills/verify/SKILL.md +1 -1
- package/substrate/.claude/skills/visual-review/SKILL.md +503 -0
- package/substrate/.claude/skills/whats-the-plan/SKILL.md +202 -0
- package/substrate/.claude/skills/whereami/SKILL.md +2 -2
- package/substrate/CONTRIBUTING.md +1 -1
- package/substrate/README.md +5 -5
- package/substrate/lib/prose-scan-boundary.sh +171 -0
- package/substrate/lib/tier-check.sh +50 -1
- package/substrate/lib/tier-dependency-audit.sh +159 -4
- package/substrate/presence/install/bassclef-sync.template.sh +1 -1
- package/substrate/scripts/generate-lite-manifest.sh +21 -5
- package/substrate/standards/adr-template.md +86 -0
- package/substrate/standards/api-conventions/nextjs.md +84 -0
- package/substrate/standards/artifact-composition.md +209 -0
- package/substrate/standards/bash-hook-safety.md +246 -0
- package/substrate/standards/branch-stacking.md +408 -0
- package/substrate/standards/code-safety-principles.md +176 -0
- package/substrate/standards/composer-prerequisites.md +155 -0
- package/substrate/standards/dependency-discipline/cargo.md +39 -0
- package/substrate/standards/dependency-discipline/gem.md +43 -0
- package/substrate/standards/dependency-discipline/go-mod.md +41 -0
- package/substrate/standards/dependency-discipline/npm.md +42 -0
- package/substrate/standards/dependency-discipline/pip.md +42 -0
- package/substrate/standards/deployment-topology/ec2-tailscale.md +225 -0
- package/substrate/standards/deployment-topology.md +69 -0
- package/substrate/standards/docs-sync-allowlist.md +4 -4
- package/substrate/standards/domain-and-dns.md +145 -0
- package/substrate/standards/frontend-stack.md +67 -0
- package/substrate/standards/frontmatter-schema.md +154 -0
- package/substrate/standards/hook-injection-discipline.md +202 -0
- package/substrate/standards/hook-install-class.md +215 -0
- package/substrate/standards/input-handler-interface.md +152 -0
- package/substrate/standards/lite-manifest-schema-changes.md +60 -0
- package/substrate/standards/luminary-matching.md +105 -0
- package/substrate/standards/migration-discipline/active-record.md +50 -0
- package/substrate/standards/migration-discipline/alembic.md +43 -0
- package/substrate/standards/migration-discipline/gorm.md +50 -0
- package/substrate/standards/migration-discipline/prisma.md +53 -0
- package/substrate/standards/migration-discipline/sqlalchemy.md +51 -0
- package/substrate/standards/mobile-ephemeral-session.md +167 -0
- package/substrate/standards/model-routing-discipline.md +160 -0
- package/substrate/standards/persona-schema.md +229 -0
- package/substrate/standards/pluggable-luminaries.md +323 -0
- package/substrate/standards/pr-body-discipline.md +115 -0
- package/substrate/standards/preview-state-schema.md +189 -0
- package/substrate/standards/reserved-skill-names.md +120 -0
- package/substrate/standards/scannable-multi-option-output.md +261 -0
- package/substrate/standards/sdlc-gates/typescript.md +57 -0
- package/substrate/standards/session-board.md +256 -0
- package/substrate/standards/state-spine-contract.md +255 -0
- package/substrate/standards/steering-hints/kiss-words.md +11 -0
- package/substrate/standards/substrate-config-schema.md +267 -0
- package/substrate/standards/tier-dependency-analysis.md +1 -1
- package/substrate/standards/tier-tag-schema.md +1 -1
- package/substrate/standards/two-layer-config.md +99 -0
- package/substrate/standards/use-case-format.md +292 -0
- package/substrate/standards/user-story-invest.md +268 -0
- package/substrate/standards/velocity-and-appetite.md +229 -0
- package/substrate/standards/voice-input-pattern.md +119 -0
- package/substrate/standards/worktree-management.md +211 -0
- package/substrate/templates/chronicle-template.md +75 -0
- package/substrate/templates/memory-proposal-template.md +77 -0
- package/substrate/templates/persona-template.md +200 -0
- package/substrate/templates/pr-faq.md +45 -0
- package/substrate/templates/secret-rotation-template.md +162 -0
- package/substrate/templates/spec-template.md +131 -0
- package/substrate/templates/use-case-template.md +194 -0
- package/substrate/templates/user-story-template.md +107 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: How work is estimated, measured, and calibrated in agent-driven SDLC.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Velocity and Time Budget Standard
|
|
7
|
+
|
|
8
|
+
How work is estimated, measured, and calibrated in agent-driven SDLC.
|
|
9
|
+
|
|
10
|
+
(Formerly `Velocity and Appetite` per ADR-040 D1 rename 2026-07-17.
|
|
11
|
+
The filename stays `velocity-and-appetite.md` for backward compat via
|
|
12
|
+
`standards/vocabulary-migration.json`. Shape Up's original term is
|
|
13
|
+
`appetite`; bassclef calls it "time budget" in operator-facing prose.)
|
|
14
|
+
|
|
15
|
+
Based on Ryan Singer's Shape Up (Basecamp). Core insight: don't estimate
|
|
16
|
+
how long things will take — set how much time you're willing to spend,
|
|
17
|
+
then scope to fit. Fixed budget, variable scope.
|
|
18
|
+
|
|
19
|
+
This matters more for agents than for humans. A human developer gets
|
|
20
|
+
tired, checks the clock, pushes back on scope. An agent will happily
|
|
21
|
+
expand forever. The time budget is the constraint that prevents infinite work.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Feynman Explanation
|
|
26
|
+
|
|
27
|
+
Imagine you're renovating a bathroom. The traditional approach: get an
|
|
28
|
+
estimate ("it'll take 3 weeks"), then discover it takes 6. The Shape Up
|
|
29
|
+
approach: "I'm willing to spend 2 weeks on this bathroom. What can I get
|
|
30
|
+
done in 2 weeks?" Maybe you skip the heated floors. Maybe you use
|
|
31
|
+
off-the-shelf tile instead of custom. The *scope flexes to fit the budget.*
|
|
32
|
+
|
|
33
|
+
Now imagine the contractor is a robot that never gets tired and thinks
|
|
34
|
+
every detail is equally important. Without a ceiling, it'll spend 3 weeks
|
|
35
|
+
on grout patterns. That's an agent without a time budget. The time budget says: "you
|
|
36
|
+
have 40 turns. Ship something real. Cut what doesn't fit."
|
|
37
|
+
|
|
38
|
+
The magic is in the closeout. After the work, you write down: "I budgeted
|
|
39
|
+
40 turns, it took 15." Next time something similar comes up, you budget 20.
|
|
40
|
+
The system learns. After a few iterations, your estimates converge on
|
|
41
|
+
reality — not because you got better at estimating, but because you have
|
|
42
|
+
data.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Key Terms
|
|
47
|
+
|
|
48
|
+
### Round-trip (aka "turn")
|
|
49
|
+
|
|
50
|
+
One round-trip: you send a message, the agent responds. That's one.
|
|
51
|
+
This is the atomic unit of work in agent-driven development.
|
|
52
|
+
|
|
53
|
+
A round-trip can be trivial ("read this file") or substantial ("implement
|
|
54
|
+
the entire scoring module"). Not all round-trips are equal, but over
|
|
55
|
+
enough iterations, round-trips-per-issue averages out into a useful signal.
|
|
56
|
+
|
|
57
|
+
**Why round-trips, not hours?** Hours measure clock time, which is
|
|
58
|
+
meaningless for agents. An agent that takes 3 minutes of wall time but
|
|
59
|
+
50 round-trips of back-and-forth consumed more resources than one that
|
|
60
|
+
took 10 minutes but 8 round-trips. Round-trips are the actual unit of
|
|
61
|
+
consumption.
|
|
62
|
+
|
|
63
|
+
**Notation**: The frontmatter field is `turns:` (Claude Code's internal
|
|
64
|
+
term). Exact when known (`turns: 15`), approximate with tilde when
|
|
65
|
+
estimated (`turns: ~40`). In prose and metrics output, use "round-trips"
|
|
66
|
+
for clarity.
|
|
67
|
+
|
|
68
|
+
### Time Budget
|
|
69
|
+
|
|
70
|
+
(Bassclef's name for Shape Up's `appetite` concept per Ryan Singer + Basecamp.
|
|
71
|
+
Renamed per ADR-040 D1 2026-07-17.)
|
|
72
|
+
|
|
73
|
+
How many turns you're willing to spend on an iteration. The budget
|
|
74
|
+
ceiling. Set *before* work begins in the iteration goal.
|
|
75
|
+
|
|
76
|
+
The time budget is **not an estimate**. An estimate says "I think this will
|
|
77
|
+
take 40 turns." The time budget says "I'm willing to spend 40 turns on this.
|
|
78
|
+
If it can't fit in 40, descope or split."
|
|
79
|
+
|
|
80
|
+
**How the time budget is set:**
|
|
81
|
+
|
|
82
|
+
1. **By phase** — different phases consume turns at different rates:
|
|
83
|
+
|
|
84
|
+
| Phase | Typical time budget | Why |
|
|
85
|
+
|-------|-----------------|-----|
|
|
86
|
+
| Inception | 30–50 turns | Thinking artifacts (canvas, shaping) — more back-and-forth |
|
|
87
|
+
| Elaboration | 30–40 turns | Design + architecture — moderate depth |
|
|
88
|
+
| Construction | 20–30 turns per branch | Code + tests — focused, less ambiguity |
|
|
89
|
+
| Transition | 15–20 turns | Deploy + verify — mechanical |
|
|
90
|
+
|
|
91
|
+
2. **By calibration** — closeout data from previous iterations:
|
|
92
|
+
- First iteration: use the phase defaults above. You're guessing.
|
|
93
|
+
- Second iteration: adjust based on the first closeout's delta.
|
|
94
|
+
- Third+ iteration: your estimates converge. Trust the data.
|
|
95
|
+
|
|
96
|
+
3. **By scope complexity** — more files touched, more integration points,
|
|
97
|
+
more unknowns = higher time budget. But prefer splitting into multiple
|
|
98
|
+
smaller iterations over inflating a single time budget.
|
|
99
|
+
|
|
100
|
+
4. **By confidence** — "I've done this exact thing before" = lower time budget.
|
|
101
|
+
"This is novel and uncertain" = higher time budget or spike first.
|
|
102
|
+
|
|
103
|
+
**The rule**: when the time budget is exhausted, descope. Don't extend. If the
|
|
104
|
+
work can't fit, the scope was wrong — split it, defer the tail, ship what
|
|
105
|
+
fits. This is how fixed budget / variable scope works.
|
|
106
|
+
|
|
107
|
+
### Actuals
|
|
108
|
+
|
|
109
|
+
How many turns the work actually consumed. Measured at closeout from
|
|
110
|
+
chronicle timing data (`turns` field in frontmatter).
|
|
111
|
+
|
|
112
|
+
Actuals are always approximate — counting exact conversation turns is
|
|
113
|
+
fragile. The value is in the *trend*, not the precision. A closeout
|
|
114
|
+
that says "time budget 40, actual ~15" tells you the time budget was 2.5x
|
|
115
|
+
too generous. That's useful even if the actual was really 18.
|
|
116
|
+
|
|
117
|
+
### Delta
|
|
118
|
+
|
|
119
|
+
The difference between the time budget and actuals, expressed as a percentage.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Delta = (Actuals - Time Budget) / Time Budget × 100
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
- **Negative delta** (e.g., -62%): under budget. Time budget was generous.
|
|
126
|
+
Next similar iteration: lower the time budget.
|
|
127
|
+
- **Zero delta**: perfect calibration. Unlikely but ideal.
|
|
128
|
+
- **Positive delta** (e.g., +30%): over budget. Scope was underestimated
|
|
129
|
+
or complexity was higher than expected. Check: was the scope too big,
|
|
130
|
+
or was there unexpected rework?
|
|
131
|
+
|
|
132
|
+
### Iteration Goal
|
|
133
|
+
|
|
134
|
+
(Bassclef's name for Shape Up's `iteration bet` per ADR-040 D1 rename 2026-07-17.
|
|
135
|
+
The goal doc filename stays under `docs/iteration-bets/` for backward compat.)
|
|
136
|
+
|
|
137
|
+
A scoped piece of work with a thesis, acceptance criteria, and time budget.
|
|
138
|
+
The unit of planning. Lives at `docs/iteration-bets/YYYY-MM-DD-slug.md`.
|
|
139
|
+
|
|
140
|
+
An iteration goal declares:
|
|
141
|
+
- **What** we're building (scope)
|
|
142
|
+
- **Why** it matters (risk retired, value proved)
|
|
143
|
+
- **How much** we're willing to spend (time budget in turns + cost ceiling)
|
|
144
|
+
- **How we'll know** it worked (acceptance criteria, lovability/viability signals)
|
|
145
|
+
|
|
146
|
+
The goal metaphor comes from Shape Up's `bet` framing (Ryan Singer, Basecamp):
|
|
147
|
+
you're wagering that this scope, at this time budget, will produce value.
|
|
148
|
+
Sometimes you lose — the scope was wrong, the approach was wrong, or the
|
|
149
|
+
time budget was too tight. That's information, not failure.
|
|
150
|
+
|
|
151
|
+
### Closeout
|
|
152
|
+
|
|
153
|
+
The section appended to an iteration goal when the work completes (or is
|
|
154
|
+
explicitly abandoned). Records what actually happened vs what was planned.
|
|
155
|
+
|
|
156
|
+
A closeout contains:
|
|
157
|
+
- **Actuals vs time budget table**: turns, duration, issues closed — with deltas
|
|
158
|
+
- **Gate compliance summary**: which gates fired, which were skipped, why
|
|
159
|
+
- **Calibration notes**: what was over/underscoped, guidance for next time
|
|
160
|
+
|
|
161
|
+
The closeout is the feedback loop. Without it, the time budget is just a guess
|
|
162
|
+
that never improves. With it, each iteration makes the next estimate
|
|
163
|
+
better.
|
|
164
|
+
|
|
165
|
+
**When to write**: when all acceptance criteria are met (or explicitly
|
|
166
|
+
deferred). Before the final chronicle. See `standards/sdlc-compliance.md`
|
|
167
|
+
for the closeout format.
|
|
168
|
+
|
|
169
|
+
### Velocity
|
|
170
|
+
|
|
171
|
+
Issues closed per turns consumed, measured across iterations. Not a target
|
|
172
|
+
to maximize — a diagnostic to understand.
|
|
173
|
+
|
|
174
|
+
High velocity + low quality (many fix: branches after feat: branches) =
|
|
175
|
+
shipping too fast, cutting corners. Low velocity + high quality (no
|
|
176
|
+
rework) = possibly over-engineering, or just hard problems. The metrics
|
|
177
|
+
script shows both together so you can read the signal.
|
|
178
|
+
|
|
179
|
+
### Calibration
|
|
180
|
+
|
|
181
|
+
The process of using closeout data to improve future time budget estimates.
|
|
182
|
+
Not a manual exercise — it happens naturally when you read previous
|
|
183
|
+
closeouts before setting the next time budget.
|
|
184
|
+
|
|
185
|
+
**Calibration pattern**:
|
|
186
|
+
1. First iteration: time budget 40 (guess from phase defaults)
|
|
187
|
+
2. Closeout: actual 15, delta -62%. Note: "spec already existed"
|
|
188
|
+
3. Second iteration (similar scope): time budget 20
|
|
189
|
+
4. Closeout: actual 18, delta -10%. Converging.
|
|
190
|
+
5. Third iteration: time budget 20 is now a validated default for this type
|
|
191
|
+
|
|
192
|
+
The calibration notes in the closeout capture *why* the delta happened,
|
|
193
|
+
not just the number. "Spec already existed" vs "unexpected schema migration"
|
|
194
|
+
are both -62% but mean completely different things for future estimates.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Relationship to Metrics
|
|
199
|
+
|
|
200
|
+
The `scripts/metrics.sh --iteration` view aggregates closeout data across
|
|
201
|
+
all iteration goals. The `--overall` view rolls up velocity, throughput,
|
|
202
|
+
quality, and DORA into a single dashboard. Both read from artifacts that
|
|
203
|
+
already exist — no separate tracking system.
|
|
204
|
+
|
|
205
|
+
| Term | Where it lives | Who writes it |
|
|
206
|
+
|------|---------------|---------------|
|
|
207
|
+
| Time budget | Iteration goal (set at start) | Operator + agent during `/autonomous start` |
|
|
208
|
+
| Turns | Chronicle frontmatter (`turns:` field) | Agent at session-end (Must tier) |
|
|
209
|
+
| Actuals | Iteration goal closeout | Agent when iteration completes |
|
|
210
|
+
| Delta | Iteration goal closeout (computed) | Agent when writing closeout |
|
|
211
|
+
| Velocity | `scripts/metrics.sh --iteration` (computed) | Script, on demand |
|
|
212
|
+
| Calibration | Closeout "calibration notes" section | Agent, informed by previous closeouts |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## What This Is Not
|
|
217
|
+
|
|
218
|
+
- **Not story points.** Story points estimate relative complexity. The time budget
|
|
219
|
+
sets absolute budget. Points ask "how hard is this?" The time budget asks "how
|
|
220
|
+
much am I willing to spend?" Different question, different answer.
|
|
221
|
+
|
|
222
|
+
- **Not time tracking.** Duration (minutes) is captured in chronicles for
|
|
223
|
+
context, but turns are the primary unit. An agent that finishes in 5
|
|
224
|
+
minutes but takes 50 turns consumed more than one that takes 30 minutes
|
|
225
|
+
but 10 turns.
|
|
226
|
+
|
|
227
|
+
- **Not a productivity target.** "Increase velocity" is not a goal. The
|
|
228
|
+
goal is calibration — estimates that match reality. If velocity drops
|
|
229
|
+
because the work got harder, that's information, not a problem.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: How bassclef handles voice as input to skill dispatches.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Voice Input Pattern
|
|
7
|
+
|
|
8
|
+
How bassclef handles voice as input to skill dispatches. Phase V Hey-Alexa MVD uses macOS native dictation (Fn-Fn keyboard shortcut) into a Claude Code prompt. Hands-free voice listener is V2 (deferred).
|
|
9
|
+
|
|
10
|
+
## When this fires
|
|
11
|
+
|
|
12
|
+
Operator dictates intent into a Claude Code session instead of typing it. Skills downstream (especially `/preview-build`) treat the resulting text as voice-originated + apply tolerant intent extraction.
|
|
13
|
+
|
|
14
|
+
## The pattern (V1 — MVD)
|
|
15
|
+
|
|
16
|
+
### 1. Operator-side: macOS dictation
|
|
17
|
+
|
|
18
|
+
Operator presses **Fn-Fn** on a Mac with dictation enabled (System Settings → Keyboard → Dictation → On). macOS captures audio + transcribes to the active text field.
|
|
19
|
+
|
|
20
|
+
Operator speaks the intent. Operator releases Fn-Fn (dictation stops). Transcribed text appears in the Claude Code prompt input.
|
|
21
|
+
|
|
22
|
+
Operator submits the prompt. The transcribed text flows to bassclef's skills like any text input.
|
|
23
|
+
|
|
24
|
+
### 2. bassclef-side: voice-input mode
|
|
25
|
+
|
|
26
|
+
`/launch` (and chained skills) accept the input. The transcribed text is treated as the operator's intent paragraph — conversational shape (fragments, restarts, filler) is preserved verbatim and flows through `/interpret-input` like any keyboard-typed text.
|
|
27
|
+
|
|
28
|
+
The mode is signaled via:
|
|
29
|
+
- Explicit flag: `/launch --voice-input` (operator dispatch convenience)
|
|
30
|
+
- Auto-detection heuristics (optional V2): text shape suggests spoken vs typed origin
|
|
31
|
+
|
|
32
|
+
V1 ships explicit flag only. Auto-detection is a polish-shelf concern.
|
|
33
|
+
|
|
34
|
+
### 3. Downstream chain
|
|
35
|
+
|
|
36
|
+
After the text lands, the rest of the pipeline is unchanged:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
voice → text (macOS dictation)
|
|
40
|
+
↓
|
|
41
|
+
text → InputArtifact (/interpret-input — text mode)
|
|
42
|
+
↓
|
|
43
|
+
InputArtifact → variants (existing /launch Phase 4 — deterministic luminary round-robin)
|
|
44
|
+
↓
|
|
45
|
+
variant → repo (existing /build)
|
|
46
|
+
↓
|
|
47
|
+
repo → live URL (existing /launch-preview + Amplify)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The chain composes existing bassclef skills. Voice is a thin front-end on top.
|
|
51
|
+
|
|
52
|
+
## The pattern (V2 — hands-free, future)
|
|
53
|
+
|
|
54
|
+
Phase V's roadmap entry says "voice → Bandleader → polished output → live URL." V2 adds:
|
|
55
|
+
|
|
56
|
+
- **Standalone voice listener** — daemon captures audio without Claude Code prompt step
|
|
57
|
+
- **Whisper API or similar** — offline + accuracy beyond macOS dictation
|
|
58
|
+
- **Bandleader orchestration** — voice → intent → multi-agent dispatch (Phase IV)
|
|
59
|
+
- **Hands-free flow** — operator never touches keyboard during demo
|
|
60
|
+
|
|
61
|
+
V1 (this standard) ships the MVD. V2 unblocks the full Phase V vision when Phase IV Bandleader lands.
|
|
62
|
+
|
|
63
|
+
## Why macOS dictation for V1
|
|
64
|
+
|
|
65
|
+
- **Already on operator's machine** — no new substrate primitive needed
|
|
66
|
+
- **Works offline** (macOS local processing) — no API dependency
|
|
67
|
+
- **Latency low** — real-time transcription
|
|
68
|
+
- **Cross-app** — works in any text field including Claude Code's
|
|
69
|
+
- **Operator already knows it** — Fn-Fn muscle memory
|
|
70
|
+
|
|
71
|
+
The tradeoff: requires operator to press Fn-Fn (not hands-free). MVD accepts this trade.
|
|
72
|
+
|
|
73
|
+
## Operator setup checklist (V1)
|
|
74
|
+
|
|
75
|
+
Before the demo:
|
|
76
|
+
|
|
77
|
+
- [ ] System Settings → Keyboard → Dictation → ON
|
|
78
|
+
- [ ] Dictation language matches operator's spoken English
|
|
79
|
+
- [ ] Test: press Fn-Fn in any text field; speak a short phrase; verify transcription
|
|
80
|
+
- [ ] Claude Code session active in target directory
|
|
81
|
+
- [ ] bassclef-sync has run (bassclef's substrate up-to-date in target repo)
|
|
82
|
+
|
|
83
|
+
## Why bassclef core preserves the text as-is
|
|
84
|
+
|
|
85
|
+
Bassclef core does not run intent extraction against an embedding model + LLM judge. The voice-transcribed text is treated as the operator's intent paragraph and passed through `/interpret-input` unchanged. Downstream phases use it the same way they use keyboard-typed text.
|
|
86
|
+
|
|
87
|
+
Bassclef-private adopters who want intent-grounded matching can layer their own `/extract-intent` skill via `additionalDirectories` injection. That skill consumes the voice-originated text the same way it consumes typed text; tolerance for conversational shape (fragments, restarts) is the adapter's concern, not bassclef's.
|
|
88
|
+
|
|
89
|
+
## What this does NOT cover
|
|
90
|
+
|
|
91
|
+
- Voice in audio-only contexts (telephony, smart speakers) — V3+ scope
|
|
92
|
+
- Multi-speaker scenarios (transcription disambiguation) — V3+
|
|
93
|
+
- Languages other than operator's spoken language — V2+
|
|
94
|
+
- Real-time streaming intent extraction — V2+ (today's pattern is batch: speak → submit → process)
|
|
95
|
+
|
|
96
|
+
## Distinct from
|
|
97
|
+
|
|
98
|
+
- `standards/bassclef-test-repos.md` — test ground for substrate validation; foobar exists for bassclef's tests, NOT as the demo target
|
|
99
|
+
- `.claude/skills/launch/SKILL.md` — composes the input → variants chain; voice-input mode is an addition to existing surface
|
|
100
|
+
|
|
101
|
+
## When this retires
|
|
102
|
+
|
|
103
|
+
This standard retires if:
|
|
104
|
+
- Hands-free voice listener (V2) replaces the Fn-Fn pattern as the primary mode
|
|
105
|
+
- Phase IV Bandleader supersedes the operator-driven dispatch model
|
|
106
|
+
- Bassclef evolves to a different voice-input convention
|
|
107
|
+
|
|
108
|
+
Until V2 ships, this is SENTINEL_the_bassclef_V1_pattern for "speak out loud → app lands in cloud."
|
|
109
|
+
|
|
110
|
+
## Sources read
|
|
111
|
+
|
|
112
|
+
- `docs/iteration-bets/2026-05-12-phase-v-hey-alexa-mvd.md` — parent bet
|
|
113
|
+
- `docs/roadmaps/2026-05-07-7-phase-staircase.md` Phase V entry (voice → app on live URL)
|
|
114
|
+
- `.claude/skills/launch/SKILL.md` — downstream consumer of voice-originated text
|
|
115
|
+
- bassclef#944 — Voyage matcher excision from bassclef core
|
|
116
|
+
|
|
117
|
+
## Closes
|
|
118
|
+
|
|
119
|
+
WU-1 of Phase V Hey-Alexa MVD bet. bassclef#944 cleared the embed+LLM coupling so voice-input mode now flows through bassclef core's deterministic luminary path.
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
description: Defines the lifecycle for git worktrees in autonomous agent sessions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Worktree Management Standard
|
|
7
|
+
|
|
8
|
+
Defines the lifecycle for git worktrees in autonomous agent sessions.
|
|
9
|
+
Worktrees enable parallel branch work but create operational hazards when
|
|
10
|
+
agents crash, hit rate limits, or exhaust context without cleanup.
|
|
11
|
+
|
|
12
|
+
This standard applies whenever agents use `git worktree add` — whether
|
|
13
|
+
in parallel autonomous mode or manual multi-branch work.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Worktree Lifecycle
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
CREATE → WORK → COMMIT → PR → CLEANUP
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Every worktree must complete this lifecycle. A worktree that skips CLEANUP
|
|
24
|
+
leaves a branch lock, consumes disk, and confuses the next session.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Pre-Session Audit (MUST — session start)
|
|
29
|
+
|
|
30
|
+
Before creating any new worktrees, audit existing ones:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git worktree list
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For each worktree that is not the main working tree:
|
|
37
|
+
|
|
38
|
+
1. **Check if prunable**: `git worktree list` shows `prunable` for worktrees
|
|
39
|
+
whose directory no longer exists
|
|
40
|
+
2. **Check age**: if the worktree is from a previous session (different date
|
|
41
|
+
or session ID), it is stale
|
|
42
|
+
3. **Check for uncommitted work**: `git -C <worktree-path> status` — if dirty,
|
|
43
|
+
the previous agent died mid-work
|
|
44
|
+
|
|
45
|
+
### Stale worktree resolution
|
|
46
|
+
|
|
47
|
+
| State | Action |
|
|
48
|
+
|-------|--------|
|
|
49
|
+
| Prunable (directory gone) | `git worktree prune` — safe, just cleans metadata |
|
|
50
|
+
| Clean (no uncommitted changes) | `git worktree remove <path>` — safe to remove |
|
|
51
|
+
| Dirty (uncommitted changes) | Commit as `chore: wip — recovered from stale worktree`, then remove |
|
|
52
|
+
| Branch has open PR | Remove worktree, leave PR open for review |
|
|
53
|
+
| Branch has no PR and no useful commits | Remove worktree, delete branch |
|
|
54
|
+
|
|
55
|
+
Present stale worktrees to the operator at session start. In orchestrator-gated
|
|
56
|
+
mode, auto-clean prunable and clean worktrees; prompt for dirty ones.
|
|
57
|
+
|
|
58
|
+
The session-start hook should surface stale worktrees. If it doesn't, the
|
|
59
|
+
agent checks manually.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Creating Worktrees
|
|
64
|
+
|
|
65
|
+
### Naming convention
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
.claude/worktrees/<slug>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Where `<slug>` matches the branch's short description. Example:
|
|
72
|
+
`feature/100-stack-1-worktree-mgmt` → `.claude/worktrees/worktree-mgmt`
|
|
73
|
+
|
|
74
|
+
### Creation checklist
|
|
75
|
+
|
|
76
|
+
1. Verify the branch doesn't already exist: `git branch --list <name>`
|
|
77
|
+
2. Create from main (not from another worktree's branch):
|
|
78
|
+
```bash
|
|
79
|
+
git worktree add .claude/worktrees/<slug> -b <branch-name>
|
|
80
|
+
```
|
|
81
|
+
3. Record the worktree in the stack manifest if one exists
|
|
82
|
+
4. Never `cd` into the worktree — use `git -C <path>` for all operations
|
|
83
|
+
|
|
84
|
+
### Why never `cd` into a worktree
|
|
85
|
+
|
|
86
|
+
If the agent's working directory is inside a worktree and the worktree is
|
|
87
|
+
removed (by cleanup, crash recovery, or another agent), the shell's cwd
|
|
88
|
+
becomes invalid. All subsequent commands fail with "Unable to read current
|
|
89
|
+
working directory." This was observed in POA parallel run 2026-04-07.
|
|
90
|
+
|
|
91
|
+
Instead:
|
|
92
|
+
```bash
|
|
93
|
+
# Good — run from main working tree
|
|
94
|
+
git -C .claude/worktrees/my-feature add .
|
|
95
|
+
git -C .claude/worktrees/my-feature commit -m "feat: description"
|
|
96
|
+
|
|
97
|
+
# Bad — changes cwd, creates cleanup hazard
|
|
98
|
+
cd .claude/worktrees/my-feature
|
|
99
|
+
git add .
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## File Watcher Conflicts
|
|
105
|
+
|
|
106
|
+
### Problem
|
|
107
|
+
|
|
108
|
+
Dev servers (Next.js, Vite), linters (ESLint watch mode), formatters
|
|
109
|
+
(Prettier watch), and IDE file sync tools monitor the filesystem. When a
|
|
110
|
+
worktree agent writes a file, watchers may:
|
|
111
|
+
|
|
112
|
+
- Revert the file to their cached state
|
|
113
|
+
- Trigger a rebuild that overwrites agent output
|
|
114
|
+
- Lock files that the agent needs to write
|
|
115
|
+
|
|
116
|
+
### Mitigation
|
|
117
|
+
|
|
118
|
+
Before creating worktrees for parallel work:
|
|
119
|
+
|
|
120
|
+
1. **Stop all file watchers**: dev server, lint --watch, test --watch
|
|
121
|
+
2. **Check for processes holding files**:
|
|
122
|
+
```bash
|
|
123
|
+
lsof +D <worktree-path> 2>/dev/null
|
|
124
|
+
```
|
|
125
|
+
3. **If watchers can't be stopped** (e.g., IDE integration), document in
|
|
126
|
+
the stack manifest that this branch is not parallel-safe
|
|
127
|
+
|
|
128
|
+
The `/autonomous start` boot sequence should check for running dev servers
|
|
129
|
+
and warn before spawning parallel agents.
|
|
130
|
+
|
|
131
|
+
### IDE-specific notes
|
|
132
|
+
|
|
133
|
+
- **VS Code**: File watcher is aggressive. If the worktree is inside the
|
|
134
|
+
project directory (which `.claude/worktrees/` is), VS Code will watch it.
|
|
135
|
+
Consider creating worktrees outside the project directory for parallel runs.
|
|
136
|
+
- **Cursor/JetBrains**: Similar behavior. Same mitigation.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Cleanup Protocol (MUST — before session end)
|
|
141
|
+
|
|
142
|
+
Every agent that creates a worktree MUST clean it up before exiting.
|
|
143
|
+
This is part of the graceful exit protocol (see `standards/graceful-exit.md`).
|
|
144
|
+
|
|
145
|
+
### Normal cleanup (work complete, PR open)
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
git worktree remove .claude/worktrees/<slug>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
If the branch was merged, also delete the branch:
|
|
152
|
+
```bash
|
|
153
|
+
git branch -d <branch-name>
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Abnormal cleanup (agent dying, context exhaustion)
|
|
157
|
+
|
|
158
|
+
If the agent knows it's about to die (context pressure, rate limit, budget):
|
|
159
|
+
|
|
160
|
+
1. Commit any in-progress work: `git -C <worktree-path> commit -am "chore: wip"`
|
|
161
|
+
2. Push the branch: `git -C <worktree-path> push -u origin <branch>`
|
|
162
|
+
3. Remove the worktree: `git worktree remove <path>`
|
|
163
|
+
4. Note in checkpoint: "worktree cleaned, branch pushed, PR not yet open"
|
|
164
|
+
|
|
165
|
+
If the agent dies without cleanup (crash, kill, timeout), the next session's
|
|
166
|
+
pre-session audit handles recovery.
|
|
167
|
+
|
|
168
|
+
### Cleanup order
|
|
169
|
+
|
|
170
|
+
When multiple worktrees exist:
|
|
171
|
+
|
|
172
|
+
1. Remove worktrees with merged PRs first (safest)
|
|
173
|
+
2. Remove worktrees with open PRs next (work is preserved in the PR)
|
|
174
|
+
3. Remove worktrees with unpushed work last (commit and push first)
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Rate Limit Awareness
|
|
179
|
+
|
|
180
|
+
Parallel worktree agents multiply API request rate against the same account
|
|
181
|
+
quota. This was observed in POA 2026-04-07: 3 agents = 3x RPM pressure,
|
|
182
|
+
causing 429 errors.
|
|
183
|
+
|
|
184
|
+
### Mitigations
|
|
185
|
+
|
|
186
|
+
| Strategy | When to use |
|
|
187
|
+
|----------|------------|
|
|
188
|
+
| Sequential mode | Default. Zero rate limit risk. Recommended for most work. |
|
|
189
|
+
| Staggered starts | If parallel: delay 30s between agent spawns |
|
|
190
|
+
| Reduced context | Send only relevant files to each agent, not full repo |
|
|
191
|
+
| Fewer parallel agents | Max 2 concurrent for most account tiers |
|
|
192
|
+
|
|
193
|
+
### Rate limit detection
|
|
194
|
+
|
|
195
|
+
If an agent receives a 429 or rate limit error:
|
|
196
|
+
|
|
197
|
+
1. Do NOT retry immediately — this makes it worse
|
|
198
|
+
2. Wait the duration specified in the Retry-After header (or 60s default)
|
|
199
|
+
3. If rate limits persist after 3 retries: save state, report to operator,
|
|
200
|
+
recommend switching to sequential mode
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## Relationship to Other Standards
|
|
205
|
+
|
|
206
|
+
| Standard | Relationship |
|
|
207
|
+
|----------|-------------|
|
|
208
|
+
| `standards/graceful-exit.md` | Worktree cleanup is a MUST gate in exit protocol |
|
|
209
|
+
| `standards/branch-stacking.md` | Stack manifest tracks worktree branches |
|
|
210
|
+
| `.claude/rules/cost-governance.md` | Rate limit cost of parallel worktrees |
|
|
211
|
+
| `strategy/agent-choreography.md` | Orchestrator manages worktree lifecycle in parallel mode |
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
tier: lite
|
|
3
|
+
session_id: {YYYY-MM-DD}-{HHMM}
|
|
4
|
+
project: {active project}
|
|
5
|
+
agent: personal
|
|
6
|
+
status: completed
|
|
7
|
+
tags: [relevant, tags]
|
|
8
|
+
started_at: {ISO 8601 — from session-end hook or /tmp/claude-session-timing-*}
|
|
9
|
+
ended_at: {ISO 8601 — from session-end hook or current time}
|
|
10
|
+
duration_minutes: {exact from hooks, or approximate as fallback}
|
|
11
|
+
turns: {approximate, e.g., ~40}
|
|
12
|
+
closes: [{list of issues closed, e.g., "#37", "#42"}]
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# Session: {Title}
|
|
16
|
+
|
|
17
|
+
## Entry State
|
|
18
|
+
- State before this session
|
|
19
|
+
|
|
20
|
+
## Work Done
|
|
21
|
+
- Bullet points of accomplishments
|
|
22
|
+
- Reference commits + PRs by SHA / number
|
|
23
|
+
|
|
24
|
+
## Decisions Made
|
|
25
|
+
- Key decisions with rationale
|
|
26
|
+
|
|
27
|
+
## Open Threads
|
|
28
|
+
- What's unfinished or needs follow-up
|
|
29
|
+
- (most important section — what the next session reads first)
|
|
30
|
+
|
|
31
|
+
## Key Files Changed
|
|
32
|
+
- List of files created or modified
|
|
33
|
+
|
|
34
|
+
## Gate Evidence
|
|
35
|
+
|
|
36
|
+
**MUST be populated.** This section is the authoritative input for the
|
|
37
|
+
5-session gate-compliance counter. An empty/missing section reads as
|
|
38
|
+
"no data" and silences the compliance signal.
|
|
39
|
+
|
|
40
|
+
Auto-populate from gate markers (run before writing the chronicle):
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
BRANCH_SLUG=$(git branch --show-current | tr '/' '-')
|
|
44
|
+
[ -f "state/markers/temperance/${BRANCH_SLUG}.marker" ] && echo "temperance: yes"
|
|
45
|
+
[ -f "state/markers/diagnose/${BRANCH_SLUG}.marker" ] && echo "diagnose: yes"
|
|
46
|
+
[ -f "state/markers/verify/${BRANCH_SLUG}.marker" ] && echo "verify: yes"
|
|
47
|
+
# For multi-branch sessions, iterate over each branch worked.
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| Gate | Fired | Evidence | Outcome |
|
|
51
|
+
|------|-------|----------|---------|
|
|
52
|
+
| Temperance | {yes/no/n/a} | {marker path or "session-level (longrun)" or n/a reason} | {PASS / N/A — reason} |
|
|
53
|
+
| Diagnosis | {yes/no/n/a} | {marker path; "n/a — not a fix/ branch"; or "trivial — [cause]"} | {root cause / n/a} |
|
|
54
|
+
| Tests | {yes/no/n/a} | {N unit, M integration; or "n/a — docs only"} | {pass count / n/a} |
|
|
55
|
+
| Verify | {yes/no/n/a} | {marker path; or "n/a — docs only"} | {PASS / N/A — reason} |
|
|
56
|
+
|
|
57
|
+
### Gate skip justifications
|
|
58
|
+
|
|
59
|
+
If any gate shows `no` without a valid `n/a` reason, that's a compliance
|
|
60
|
+
failure (per `standards/sdlc-compliance.md`). Valid skip reasons:
|
|
61
|
+
|
|
62
|
+
- **n/a** — gate doesn't apply (e.g., diagnosis on a feature branch)
|
|
63
|
+
- **Degraded mode** — infrastructure unavailable; note workaround
|
|
64
|
+
- **Assessed as trivial** (diagnosis only) — cause was immediately obvious; state it
|
|
65
|
+
|
|
66
|
+
Invalid reasons: "ran out of time", "will do later", bare "no" with no rationale.
|
|
67
|
+
|
|
68
|
+
## Promotable Patterns
|
|
69
|
+
|
|
70
|
+
Did this session produce a novel diagnostic, workaround, or workflow
|
|
71
|
+
improvement worth shipping to other repos? If yes:
|
|
72
|
+
|
|
73
|
+
- {Pattern name}: {one-sentence description} → /promote candidate
|
|
74
|
+
|
|
75
|
+
Then run /promote before session-end.
|