@isparling/engram-coach 0.1.0 → 0.2.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.
- package/README.md +85 -18
- package/SETUP.md +559 -0
- package/SKILL_PACK.md +75 -0
- package/analyses/catalog.md +257 -0
- package/analysis-tools/hrv-trend.ts +592 -0
- package/analysis-tools/migrate-structured-capture.ts +234 -0
- package/analysis-tools/race-context.ts +96 -0
- package/analysis-tools/stream-analyze.ts +1008 -0
- package/analysis-tools/tsb-predict.ts +117 -0
- package/capture-handler.ts +301 -0
- package/config.json.example +21 -0
- package/engram-coach-ambient-capture.ts +336 -0
- package/engram-coach-capture-types.ts +185 -0
- package/engram-coach-config.ts +268 -0
- package/engram-coach-domain.ts +7 -2
- package/engram-coach-keys.ts +189 -0
- package/engram-coach-materialization.ts +638 -0
- package/engram-coach-migration.ts +1078 -0
- package/engram-coach-pack.ts +17 -12
- package/engram-coach-presentation.ts +10 -1
- package/engram-coach-reconciliation.ts +305 -2
- package/engram-coach-structured-capture.ts +622 -0
- package/package.json +39 -6
- package/personas/aggressive-monitoring.md +121 -0
- package/personas/aggressive.json +85 -0
- package/personas/conservative-monitoring.md +133 -0
- package/personas/conservative.json +93 -0
- package/personas/polarized-monitoring.md +112 -0
- package/personas/polarized.json +72 -0
- package/personas/volume-monitoring.md +85 -0
- package/personas/volume.json +108 -0
- package/shared/retrieval.md +71 -0
- package/shared/setup.md +207 -0
- package/skills/.gitkeep +0 -0
- package/skills/adapt-plan/SKILL.md +263 -0
- package/skills/block-review/SKILL.md +275 -0
- package/skills/consult/SKILL.md +176 -0
- package/skills/intake/SKILL.md +315 -0
- package/skills/lactate-analyze/SKILL.md +230 -0
- package/skills/lessons-rollup/SKILL.md +196 -0
- package/skills/monitoring-rollup/SKILL.md +208 -0
- package/skills/race-analysis/SKILL.md +219 -0
- package/skills/season-retrospective/SKILL.md +200 -0
- package/skills/set-goal/SKILL.md +297 -0
- package/templates/base.md +55 -0
- package/templates/build-1.md +57 -0
- package/templates/build-2.md +62 -0
- package/templates/race-report.md +51 -0
- package/templates/race-specificity.md +62 -0
- package/templates/season-review.md +40 -0
- package/engram-coach-extractor.ts +0 -295
package/SETUP.md
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
# Setup
|
|
2
|
+
|
|
3
|
+
Full prerequisite reference for NanoClaw Training Skill Pack. Follow these steps in order before invoking any skill.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Prerequisites Overview
|
|
8
|
+
|
|
9
|
+
Confirm each item before continuing. Steps 2-5 below cover each in detail.
|
|
10
|
+
|
|
11
|
+
- [ ] NanoClaw installed and running
|
|
12
|
+
- [ ] Intervals.icu account with API key
|
|
13
|
+
- [ ] Athlete ID from Intervals.icu
|
|
14
|
+
- [ ] QMD installed and initialized
|
|
15
|
+
- [ ] engram-coach installed as a Claude Code plugin (see Step 6)
|
|
16
|
+
- [ ] `.engram-coach/config.json` created in your athlete repo (see Step 5)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. Intervals.icu Setup
|
|
21
|
+
|
|
22
|
+
Skills call Intervals.icu via MCP tools. You need two values from your Intervals.icu account.
|
|
23
|
+
|
|
24
|
+
**API Key**
|
|
25
|
+
|
|
26
|
+
1. Log into Intervals.icu
|
|
27
|
+
2. Go to **Settings → Developer Settings**
|
|
28
|
+
3. Copy your API Key
|
|
29
|
+
|
|
30
|
+
**Athlete ID**
|
|
31
|
+
|
|
32
|
+
1. Go to **Settings → Account**
|
|
33
|
+
2. Your Athlete ID appears in the URL as `i{ID}` (e.g., `i12345`)
|
|
34
|
+
|
|
35
|
+
**These values are used in two places.** The MCP server needs them as environment
|
|
36
|
+
variables (step 3) for the tools skills call during reasoning. The TypeScript
|
|
37
|
+
analysis tools read them from the `intervals_icu` block of your
|
|
38
|
+
`.engram-coach/config.json` (step 5) when invoked over the CLI. Set both.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 3. Intervals.icu MCP Server Setup
|
|
43
|
+
|
|
44
|
+
The Intervals.icu MCP server exposes Intervals.icu API endpoints as MCP tools that skills call during execution. It must be configured in NanoClaw before skills can run.
|
|
45
|
+
|
|
46
|
+
**What it does**
|
|
47
|
+
|
|
48
|
+
Skills call MCP tools such as `get_wellness`, `get_athlete`, and `get_events` to retrieve training data. The MCP server handles authentication with Intervals.icu on each call.
|
|
49
|
+
|
|
50
|
+
**How to configure it in NanoClaw**
|
|
51
|
+
|
|
52
|
+
Refer to the [NanoClaw MCP configuration documentation](https://github.com/nanowell/nanoclaw) for the exact steps to add an MCP server. The general process:
|
|
53
|
+
|
|
54
|
+
1. Add a new MCP server entry pointing to the Intervals.icu MCP server image or binary
|
|
55
|
+
2. Set the required environment variables in the MCP server configuration:
|
|
56
|
+
- `INTERVALS_API_KEY` — your API key from step 2
|
|
57
|
+
- `INTERVALS_ATHLETE_ID` — your Athlete ID from step 2 (format: `i12345`)
|
|
58
|
+
3. Configure bind-mounts if the MCP server needs access to files in this repo
|
|
59
|
+
|
|
60
|
+
> **Note on bind-mount syntax:** Bind-mount configuration syntax can vary between NanoClaw versions. Verify the correct syntax against the current NanoClaw documentation before running — do not rely on examples from older tutorials.
|
|
61
|
+
|
|
62
|
+
**Verify**
|
|
63
|
+
|
|
64
|
+
After configuring the MCP server, check NanoClaw's tool discovery to confirm the Intervals.icu tools appear in the available tool list.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 4. QMD Setup
|
|
69
|
+
|
|
70
|
+
QMD is a local knowledge management tool that skills use to retrieve coaching history and reference documents. This section walks through full setup — QMD is not assumed to be pre-installed.
|
|
71
|
+
|
|
72
|
+
**Install**
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
pip install qmd
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Or consult the [QMD installation documentation](https://github.com/tobi/qmd) for alternative installation methods.
|
|
79
|
+
|
|
80
|
+
**Initialize a collection scoped to this repo**
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
cd ./engram-coach
|
|
84
|
+
qmd init
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
This creates a QMD collection in the current directory.
|
|
88
|
+
|
|
89
|
+
**Verify initialization**
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
qmd ls
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Should show the engram-coach collection without error.
|
|
96
|
+
|
|
97
|
+
**Run first index**
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
qmd update
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
This indexes existing documents in `knowledge/`. If `knowledge/` is empty (Phase 10), the command completes without error — this is expected.
|
|
104
|
+
|
|
105
|
+
**Verify indexing**
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
qmd query "test"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Should return results (possibly empty) without error.
|
|
112
|
+
|
|
113
|
+
**Ongoing use**
|
|
114
|
+
|
|
115
|
+
When you add new coaching records to your `coaching_docs_dir`, run `qmd update` to make them retrievable by future skill invocations. Skills query QMD to load coaching history as reasoning context.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 5. Athlete Configuration
|
|
120
|
+
|
|
121
|
+
engram-coach is installed as a Claude Code **plugin** (§6). The plugin ships the
|
|
122
|
+
engine — skills, personas, templates, tools. Your athlete-specific configuration
|
|
123
|
+
lives **outside** the plugin, in the repo where your coaching records live.
|
|
124
|
+
|
|
125
|
+
> **Why not inside the plugin?** Plugins install by cloning into
|
|
126
|
+
> `~/.claude/plugins/cache/…` at a git SHA, and that directory is replaced on
|
|
127
|
+
> every update. Anything you put there is lost. Config also holds an API key,
|
|
128
|
+
> which should never sit in the engine repo.
|
|
129
|
+
|
|
130
|
+
**Config resolution order.** Skills use the first of these that exists:
|
|
131
|
+
|
|
132
|
+
| Order | Path | Use |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| 1 | `$ENGRAM_COACH_CONFIG` | Explicit override |
|
|
135
|
+
| 2 | `./.engram-coach/config.json` | **Default** — project-level, in your athlete repo |
|
|
136
|
+
| 3 | `~/.claude/engram-coach/config.json` | User-level fallback |
|
|
137
|
+
|
|
138
|
+
**Create it** (from your athlete repo — the one holding `docs/coaching/`):
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
mkdir -p .engram-coach
|
|
142
|
+
cp "$(ls -d ~/.claude/plugins/cache/*/engram-coach/*/ | tail -1)config.json.example" .engram-coach/config.json
|
|
143
|
+
printf '\n# engram-coach machine-local config (holds Intervals.icu API key)\n.engram-coach/\n' >> .gitignore
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**`.engram-coach/` MUST be gitignored** — it holds your Intervals.icu API key.
|
|
147
|
+
Verify with `git check-ignore -v .engram-coach/config.json` before committing anything.
|
|
148
|
+
|
|
149
|
+
Or skip all of the above and run `engram-coach:intake`, which writes the file for you.
|
|
150
|
+
|
|
151
|
+
**Migrating from an existing pre-rename local config directory?** Rename it in
|
|
152
|
+
place — the config contents and schema are unchanged, only the directory name moved:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
mv .claw-coach .engram-coach
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
There is no runtime fallback to the old directory name or the old explicit
|
|
159
|
+
configuration-override environment variable — rename before invoking any skill.
|
|
160
|
+
|
|
161
|
+
**Edit the config**
|
|
162
|
+
|
|
163
|
+
Open `.engram-coach/config.json` and replace the placeholder values:
|
|
164
|
+
|
|
165
|
+
```json
|
|
166
|
+
{
|
|
167
|
+
"active_profile": "default",
|
|
168
|
+
"profiles": {
|
|
169
|
+
"default": {
|
|
170
|
+
"active_persona": "conservative",
|
|
171
|
+
"coaching_docs_dir": "~/REPLACE_WITH_YOUR_COACHING_DOCS_PATH",
|
|
172
|
+
"prescriptions_dir": "~/REPLACE_WITH_YOUR_PRESCRIPTIONS_PATH",
|
|
173
|
+
"season": "REPLACE_WITH_SEASON_LABEL"
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"capture": {
|
|
177
|
+
"model": "REPLACE_WITH_PROVIDER/MODEL",
|
|
178
|
+
"timeout_seconds": 60,
|
|
179
|
+
"max_candidates_per_turn": 3
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Fields:**
|
|
185
|
+
|
|
186
|
+
| Field | Value |
|
|
187
|
+
|-------|-------|
|
|
188
|
+
| `active_profile` | Leave as `"default"` unless running multiple configurations |
|
|
189
|
+
| `active_persona` | One of: `conservative`, `aggressive`, `polarized`, `volume` |
|
|
190
|
+
| `coaching_docs_dir` | Absolute path (~ supported) to where coaching records will be written and read. Create the directory if needed: `mkdir -p ~/coaching` |
|
|
191
|
+
| `prescriptions_dir` | Absolute path to your workout prescriptions directory |
|
|
192
|
+
| `capture.model` | **Required.** Explicit `provider/model` string used for ambient conversation capture (e.g. `anthropic/claude-sonnet-4-5`). Never inherited from the interactive session model. |
|
|
193
|
+
| `capture.timeout_seconds` | Headless extraction deadline in seconds. Default and maximum: `60`. |
|
|
194
|
+
| `capture.max_candidates_per_turn` | Candidate records per settled turn. Default and maximum: `3`. |
|
|
195
|
+
|
|
196
|
+
**Capture model precedence:** a nonblank `ENGRAM_COACH_CAPTURE_MODEL`
|
|
197
|
+
environment variable overrides **only** `capture.model`; the timeout and
|
|
198
|
+
candidate limits always come from the `capture` block. If neither source is
|
|
199
|
+
set, ambient capture fails as a configuration error — run `intake` (Phase 3C)
|
|
200
|
+
or edit the config rather than leaving it unset. There is no implicit fallback
|
|
201
|
+
to any session or default model.
|
|
202
|
+
|
|
203
|
+
**Verify config**
|
|
204
|
+
|
|
205
|
+
Run this check from your athlete repo to confirm no placeholder paths remain and
|
|
206
|
+
a capture model is configured (a nonblank `ENGRAM_COACH_CAPTURE_MODEL` also
|
|
207
|
+
satisfies the model check):
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
python3 -c "import json,os; d=json.load(open('.engram-coach/config.json')); assert '~/REPLACE' not in str(d), 'Placeholder paths still present — edit .engram-coach/config.json'; assert str(d.get('capture',{}).get('model','')).strip() or os.environ.get('ENGRAM_COACH_CAPTURE_MODEL','').strip(), 'capture.model missing — run intake Phase 3C or see SETUP.md'; print('config OK')"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Should print `config OK`.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## 6. Install the Plugin
|
|
218
|
+
|
|
219
|
+
engram-coach is a Claude Code plugin. Skills are discovered from their own
|
|
220
|
+
frontmatter in `skills/*/SKILL.md` — there is no wrapper layer to maintain, and
|
|
221
|
+
new skills register themselves.
|
|
222
|
+
|
|
223
|
+
**Add the marketplace and install**
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
/plugin marketplace add isparling/engram-coach
|
|
227
|
+
/plugin install engram-coach@engram-coach
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
For local development against a working checkout, point the marketplace at the
|
|
231
|
+
directory instead:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
/plugin marketplace add ~/code/engram-coach
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Install tool dependencies.** The TypeScript analysis tools (`stream-analyze`,
|
|
238
|
+
`hrv-trend`, `race-context`, `tsb-predict`) depend on npm packages that are not
|
|
239
|
+
committed. Whether you need this step depends on how you installed:
|
|
240
|
+
|
|
241
|
+
| Install source | `npm install` needed? |
|
|
242
|
+
|---|---|
|
|
243
|
+
| GitHub / remote marketplace | **Yes, after every install and update.** Only tracked files are cloned, so `analysis-tools/node_modules` is absent. |
|
|
244
|
+
| Local path marketplace | **Usually no.** A local install copies the working directory as-is, including `analysis-tools/node_modules`. Run it only if the directory is missing or the lockfile changed. |
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
cd "$(ls -d ~/.claude/plugins/cache/*/engram-coach/*/ | tail -1)analysis-tools" && npm install
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Skills degrade gracefully if this is skipped — each affected analysis annotates
|
|
251
|
+
`[<analysis> unavailable — … Proceeding without.]` rather than failing — but you
|
|
252
|
+
lose decoupling, HR-recovery, interval-CV, and HRV-trend analysis until it runs.
|
|
253
|
+
|
|
254
|
+
> **Local installs copy everything, including gitignored files.** A local-path
|
|
255
|
+
> install is a directory copy, not a git clone, so anything sitting in the working
|
|
256
|
+
> tree — untracked scratch files, `node_modules`, and **gitignored secrets** —
|
|
257
|
+
> is copied into the plugin cache. Keep credentials out of this repo entirely;
|
|
258
|
+
> athlete config belongs in the athlete repo (§5), never here.
|
|
259
|
+
>
|
|
260
|
+
> **Local installs are also unversioned.** Remote installs record a
|
|
261
|
+
> `gitCommitSha` in `~/.claude/plugins/installed_plugins.json`, so the running
|
|
262
|
+
> version is identifiable. A local install records no equivalent — the cache is
|
|
263
|
+
> an unlabeled snapshot of your working tree at install time and drifts silently
|
|
264
|
+
> as you edit. Reinstall after changing a skill, and when behavior looks stale,
|
|
265
|
+
> diff the cache against your checkout:
|
|
266
|
+
>
|
|
267
|
+
> ```bash
|
|
268
|
+
> diff -rq "$(ls -d ~/.claude/plugins/cache/*/engram-coach/*/ | tail -1)skills" ./skills
|
|
269
|
+
> ```
|
|
270
|
+
|
|
271
|
+
**Verify**
|
|
272
|
+
|
|
273
|
+
Restart Claude Code. Type `/engram-coach` — all ten skills should appear:
|
|
274
|
+
`adapt-plan`, `block-review`, `consult`, `intake`, `lactate-analyze`,
|
|
275
|
+
`lessons-rollup`, `monitoring-rollup`, `race-analysis`,
|
|
276
|
+
`season-retrospective`, `set-goal`.
|
|
277
|
+
|
|
278
|
+
### Alternative: Direct OMP integration
|
|
279
|
+
|
|
280
|
+
Instead of (or in addition to) the Claude Code plugin, `engram-coach` can be
|
|
281
|
+
loaded directly into OMP as an Engram external pack, without the plugin layer:
|
|
282
|
+
|
|
283
|
+
```sh
|
|
284
|
+
npm install @isparling/engram-coach @isparling/engram-harness @isparling/engram-cli @isparling/engram-omp
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Bind the OMP extension:
|
|
288
|
+
|
|
289
|
+
```yaml
|
|
290
|
+
extensions:
|
|
291
|
+
- ./node_modules/@isparling/engram-omp/omp-extension.ts
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
The adapter does not read coaching plugin state and does not choose a pack:
|
|
295
|
+
the active binding's `installed_packs` declaration does that. A complete Engram
|
|
296
|
+
binding registry with the space already registered is an external
|
|
297
|
+
prerequisite; this package neither creates nor registers one. For each fresh
|
|
298
|
+
OMP session, the extension selects the space declared by the nearest
|
|
299
|
+
`engram.space.json`. Set `ENGRAM_SPACE_ID` only when that durable project
|
|
300
|
+
default needs an explicit runtime override.
|
|
301
|
+
The `installed_packs` declaration syntax itself (the fields below, and how a
|
|
302
|
+
binding declares a pack) is documented in the
|
|
303
|
+
[external pack interface](https://github.com/isparling/engram/blob/main/harness/docs/pack-interface.md).
|
|
304
|
+
This package documents only the pack declaration to add:
|
|
305
|
+
|
|
306
|
+
```json
|
|
307
|
+
{
|
|
308
|
+
"installed_packs": [
|
|
309
|
+
{
|
|
310
|
+
"id": "engram-coach",
|
|
311
|
+
"version": "0.1.0",
|
|
312
|
+
"from": "@isparling/engram-coach",
|
|
313
|
+
"extract": true
|
|
314
|
+
}
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
`version` here is the **pack identity** version exported by the package as
|
|
320
|
+
`engramCoachPackVersion`, not the npm release version of
|
|
321
|
+
`@isparling/engram-coach`. The two are deliberately independent: the core
|
|
322
|
+
matches pack identity by exact equality and refuses any mutation that would
|
|
323
|
+
change the pack provenance of an existing record, so the identity version
|
|
324
|
+
only ever changes together with a record migration. Keep `0.1.0` here even
|
|
325
|
+
when you install a newer npm release, and make your space manifest's
|
|
326
|
+
`required_packs` entry carry that same identity version.
|
|
327
|
+
|
|
328
|
+
**Set `ENGRAM_BINDING_REGISTRY`** to the absolute path of that binding
|
|
329
|
+
registry file before starting OMP. It is required, not optional: without it
|
|
330
|
+
the adapter logs a warning at session start and disables knowledge capture
|
|
331
|
+
entirely for the whole session.
|
|
332
|
+
|
|
333
|
+
```sh
|
|
334
|
+
export ENGRAM_BINDING_REGISTRY=<absolute-path-to-registry.json>
|
|
335
|
+
# Optional runtime override; omit to use the nearest engram.space.json.
|
|
336
|
+
export ENGRAM_SPACE_ID=<space-id>
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**The space binding's `write_roots` must authorize both
|
|
340
|
+
`coaching_docs_dir` and `prescriptions_dir`**, not only the records
|
|
341
|
+
directory. Generated compatibility views are ordinary artifact writes, and
|
|
342
|
+
the core confines every artifact write to an active write root. If those two
|
|
343
|
+
directories are unauthorized, an approved capture still commits its records
|
|
344
|
+
and refreshes the index, but every view lands in the apply result's
|
|
345
|
+
`artifacts.stale` with `root_not_writable`, and the YAML and Markdown on disk
|
|
346
|
+
stay at their previous contents. Re-running `engram_capture_apply` with the
|
|
347
|
+
same committed hash after widening `write_roots` retries only materialization.
|
|
348
|
+
|
|
349
|
+
At each awaited OMP `session_stop`, the extension imports the binding-selected
|
|
350
|
+
pack and calls its optional `captureFromTurn` handler. `engram-coach` turns new
|
|
351
|
+
coaching observations into create-only `status: "candidate"` draft records and
|
|
352
|
+
refreshes the active space's scoped qmd index. Drafts remain excluded from
|
|
353
|
+
recall and all profile renders until explicitly reviewed and promoted to
|
|
354
|
+
`status: "active"`. Extraction is LLM-only through the configured capture
|
|
355
|
+
model — a failed or missing extraction emits a visible warning and creates no
|
|
356
|
+
draft.
|
|
357
|
+
|
|
358
|
+
During a turn, the agent can commit structured changes through two typed
|
|
359
|
+
tools: `engram_capture_preview({ change_set })` returns the exact mutation
|
|
360
|
+
plan bound to an immutable plan hash, and `engram_capture_apply({ plan_hash })`
|
|
361
|
+
commits that exact plan after the athlete approves the hash. `engram_status`
|
|
362
|
+
reports pending plan hashes and index freshness at any time. See §7 for the
|
|
363
|
+
authority model these tools enforce.
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## 7. Knowledge Records, Generated Views, and Migration
|
|
368
|
+
|
|
369
|
+
### Authority model
|
|
370
|
+
|
|
371
|
+
Engram active records are the authoritative store for mutable coaching state
|
|
372
|
+
and chronological events. Every pack record declares a role in
|
|
373
|
+
`details.recordRole`, exactly one of:
|
|
374
|
+
|
|
375
|
+
- `state` — one current value for a canonical entity key; an approved change
|
|
376
|
+
creates a new active record, retires the prior one, and links them via
|
|
377
|
+
`relationships.supersedes`.
|
|
378
|
+
- `event` — append-only history (consultations, monitoring entries); never
|
|
379
|
+
automatically replaced.
|
|
380
|
+
- `report-claim` — a structured conclusion extracted from an approved
|
|
381
|
+
long-form report; it never replaces the report document.
|
|
382
|
+
|
|
383
|
+
Canonical entity keys are derived by the pack, never accepted from a model:
|
|
384
|
+
|
|
385
|
+
```text
|
|
386
|
+
workout:<session-id>
|
|
387
|
+
prescription:<arc-id>:<session-id>
|
|
388
|
+
threshold:<sport>:lt1
|
|
389
|
+
threshold:<sport>:lt2
|
|
390
|
+
persona:<active-profile>
|
|
391
|
+
monitoring:<concern-id>:<signal>
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
Workout identity is the durable `session_id`; `session_date`, titles, week
|
|
395
|
+
position, and workout contents are mutable attributes, not identity. Existing
|
|
396
|
+
prescriptions without stable IDs receive them during migration, and rescheduling
|
|
397
|
+
preserves the ID.
|
|
398
|
+
|
|
399
|
+
**Generated compatibility views** — the prescription YAML files,
|
|
400
|
+
`consultations.md`, monitoring logs, and doctor-prep summaries — are rendered
|
|
401
|
+
deterministically from committed records after every approved apply. Each
|
|
402
|
+
carries a byte-exact warning header (`# GENERATED FROM ENGRAM ACTIVE RECORDS.
|
|
403
|
+
DO NOT EDIT DIRECTLY.` in YAML; `<!-- GENERATED FROM ENGRAM ACTIVE RECORDS.
|
|
404
|
+
DO NOT EDIT DIRECTLY. -->` in Markdown) and is **never edited directly**:
|
|
405
|
+
direct edits are overwritten by the next materialization and break migration
|
|
406
|
+
comparisons. **Canonical approved documents** remain skill-authored long-form
|
|
407
|
+
files: `RACE_REPORT.md`, block `SUMMARY.md`, `SEASON_REVIEW.md`, methodology
|
|
408
|
+
documents, and arc-overview documents.
|
|
409
|
+
|
|
410
|
+
### Approval ordering and retry semantics
|
|
411
|
+
|
|
412
|
+
Skills that change records follow one ordering: preview records → athlete
|
|
413
|
+
approves the exact plan hash → apply → guarded qmd refresh → regenerate
|
|
414
|
+
compatibility views.
|
|
415
|
+
|
|
416
|
+
- A **stale apply** (the underlying records changed since preview) deletes the
|
|
417
|
+
pending plan and requires a fresh preview plus fresh approval. The old hash
|
|
418
|
+
can never be re-applied.
|
|
419
|
+
- An **`index-stale` status** means the qmd refresh failed or is outdated;
|
|
420
|
+
the committed records remain authoritative either way, and only the index
|
|
421
|
+
needs a later refresh.
|
|
422
|
+
- A **stale view** (materialization failed after commit) leaves the commit in
|
|
423
|
+
place. Re-calling `engram_capture_apply` with the same committed hash in the
|
|
424
|
+
same session reruns only view regeneration — never the record mutations.
|
|
425
|
+
|
|
426
|
+
### Dry-run migration sequence
|
|
427
|
+
|
|
428
|
+
Legacy workspaces migrate through four modes of
|
|
429
|
+
`analysis-tools/migrate-structured-capture.ts` (run from the installed plugin's
|
|
430
|
+
`analysis-tools/` directory). Everything is dry-run except `apply-baseline`,
|
|
431
|
+
which writes only planned stable-ID insertions and warning headers:
|
|
432
|
+
|
|
433
|
+
```sh
|
|
434
|
+
# 1. Plan stable session IDs + generated headers for every legacy
|
|
435
|
+
# prescription and compatibility log. Prints plan JSON; mutates nothing.
|
|
436
|
+
npx tsx migrate-structured-capture.ts scan --config .engram-coach/config.json > scan.json
|
|
437
|
+
|
|
438
|
+
# 2. Apply ONLY the planned ID insertions and warning headers. Refuses when
|
|
439
|
+
# the aggregate hash mismatches or any file drifted since the scan.
|
|
440
|
+
npx tsx migrate-structured-capture.ts apply-baseline --plan scan.json --expect <after-hash>
|
|
441
|
+
|
|
442
|
+
# 3. Plan the legacy import (prescription states + consultation events) into
|
|
443
|
+
# a StructuredChangeSet for preview/approval. Mutates nothing.
|
|
444
|
+
npx tsx migrate-structured-capture.ts emit-change-set --config .engram-coach/config.json --output change-set.json
|
|
445
|
+
|
|
446
|
+
# 4. Render the record-derived views into a temporary root and byte-compare
|
|
447
|
+
# them against the current source files. Exit 0 requires byte equality.
|
|
448
|
+
npx tsx migrate-structured-capture.ts compare --config .engram-coach/config.json --render-root /tmp/migration-render
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Migration is idempotent: stable source IDs prevent duplicate imports, and the
|
|
452
|
+
cutover to record authority happens only once step 4 reports byte-equivalent
|
|
453
|
+
generated views.
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## 8. Verification
|
|
458
|
+
|
|
459
|
+
Run these checks to confirm the complete setup is working before invoking a skill.
|
|
460
|
+
|
|
461
|
+
- [ ] **Skills discovered from the plugin cache**
|
|
462
|
+
```
|
|
463
|
+
ls ~/.claude/plugins/cache/*/engram-coach/*/skills/*/SKILL.md
|
|
464
|
+
```
|
|
465
|
+
Should list all ten `SKILL.md` files — exactly one for `adapt-plan`, `block-review`,
|
|
466
|
+
`consult`, `intake`, `lactate-analyze`, `lessons-rollup`, `monitoring-rollup`,
|
|
467
|
+
`race-analysis`, `season-retrospective`, and `set-goal`. Skills are discovered directly
|
|
468
|
+
from each file's frontmatter (§6); there is no separate slash-command registration step
|
|
469
|
+
to verify.
|
|
470
|
+
|
|
471
|
+
- [ ] **QMD collection present**
|
|
472
|
+
```
|
|
473
|
+
qmd ls
|
|
474
|
+
```
|
|
475
|
+
Should show the engram-coach collection.
|
|
476
|
+
|
|
477
|
+
- [ ] **Active persona readable**
|
|
478
|
+
```
|
|
479
|
+
cat .engram-coach/config.json | python3 -c "import json,sys; d=json.load(sys.stdin); print('active_persona:', d['profiles']['default']['active_persona'])"
|
|
480
|
+
```
|
|
481
|
+
Should print your active persona slug.
|
|
482
|
+
|
|
483
|
+
- [ ] **Persona file resolves**
|
|
484
|
+
```
|
|
485
|
+
ls personas/$(python3 -c "import json; print(json.load(open('.engram-coach/config.json'))['profiles']['default']['active_persona'])").json
|
|
486
|
+
```
|
|
487
|
+
Should print the persona filename without error (e.g., `personas/volume.json`).
|
|
488
|
+
|
|
489
|
+
- [ ] **Intervals.icu MCP tools appear in NanoClaw** — Check NanoClaw's tool discovery interface to confirm the Intervals.icu tools are listed.
|
|
490
|
+
|
|
491
|
+
- [ ] **coaching_docs_dir exists**
|
|
492
|
+
```
|
|
493
|
+
ls $(python3 -c "import json,os; print(os.path.expanduser(json.load(open('.engram-coach/config.json'))['profiles']['default']['coaching_docs_dir']))")
|
|
494
|
+
```
|
|
495
|
+
Should list directory contents without error. If the directory does not exist, create it:
|
|
496
|
+
```
|
|
497
|
+
mkdir -p <your-coaching-docs-path>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
All six checks passing means you are ready to invoke a skill.
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
## 9. Persistent Coaching Docs
|
|
505
|
+
|
|
506
|
+
Once you've run a few skills, your `coaching_docs_dir` will accumulate these documents:
|
|
507
|
+
|
|
508
|
+
| Document | Path | Maintained by | Purpose |
|
|
509
|
+
|---|---|---|---|
|
|
510
|
+
| `ATHLETE_PROFILE.md` | `{coaching_docs_dir}/ATHLETE_PROFILE.md` | `lessons-rollup` (curated) | Working summary of durable, athlete-specific patterns. Read by adapt-plan, consult, block-review, race-analysis, season-retrospective as reasoning context. |
|
|
511
|
+
| `lessons-log.md` | `{coaching_docs_dir}/lessons-log.md` | `lessons-rollup` (append-only) | Durable timestamped + source-tagged record of every calibration point captured. The skill never deletes from this file. |
|
|
512
|
+
| `SUMMARY.md` | `{coaching_docs_dir}/{season}/{block}/SUMMARY.md` | `block-review` | Per-block synthesis. Source for cross-block pattern detection. |
|
|
513
|
+
| `RACE_REPORT.md` | `{coaching_docs_dir}/{season}/races/{date-slug}/RACE_REPORT.md` | `race-analysis` | Per-race synthesis with computed metrics + athlete narrative. |
|
|
514
|
+
| `SEASON_REVIEW.md` | `{coaching_docs_dir}/{season}/SEASON_REVIEW.md` | `season-retrospective` | Season-level arc, persona-fit assessment, cross-block patterns. |
|
|
515
|
+
|
|
516
|
+
### Curation discipline
|
|
517
|
+
|
|
518
|
+
`ATHLETE_PROFILE.md` directly influences coaching reasoning. The `lessons-rollup` skill self-curates, but you should review the profile periodically — especially after a season-retrospective. To retire an entry that turned out wrong, edit `lessons-log.md` directly (add a note explaining the retirement) and run `lessons-rollup` standalone to re-curate the profile from the updated log.
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## 10. Troubleshooting
|
|
523
|
+
|
|
524
|
+
**`/engram-coach:intake` not appearing in Claude Code autocomplete**
|
|
525
|
+
Confirm the skill files exist in the installed plugin cache:
|
|
526
|
+
```
|
|
527
|
+
ls ~/.claude/plugins/cache/*/engram-coach/*/skills/
|
|
528
|
+
```
|
|
529
|
+
If the skills are missing, re-run the install in Step 6 and restart Claude Code —
|
|
530
|
+
plugins are loaded at session start. Check `/plugin` to confirm engram-coach is
|
|
531
|
+
listed and enabled.
|
|
532
|
+
|
|
533
|
+
**"config.json not found"**
|
|
534
|
+
You have not created the athlete config. Either run `engram-coach:intake`, or from
|
|
535
|
+
your athlete repo:
|
|
536
|
+
```
|
|
537
|
+
mkdir -p .engram-coach
|
|
538
|
+
cp "$(ls -d ~/.claude/plugins/cache/*/engram-coach/*/ | tail -1)config.json.example" .engram-coach/config.json
|
|
539
|
+
```
|
|
540
|
+
Remember to gitignore `.engram-coach/` — it holds your API key.
|
|
541
|
+
|
|
542
|
+
**"persona file not found" / `ls: personas/undefined.json: No such file or directory`**
|
|
543
|
+
Your `active_persona` value in `.engram-coach/config.json` does not match any file in `personas/`. Valid slugs are: `conservative`, `aggressive`, `polarized`, `volume`. Check for typos.
|
|
544
|
+
|
|
545
|
+
**"coaching_docs_dir does not exist" or similar path error**
|
|
546
|
+
Create the directory:
|
|
547
|
+
```
|
|
548
|
+
mkdir -p <your-coaching-docs-path>
|
|
549
|
+
```
|
|
550
|
+
Then re-run the verification check.
|
|
551
|
+
|
|
552
|
+
**"Placeholder paths still present"**
|
|
553
|
+
Open `.engram-coach/config.json` and replace all `~/REPLACE_WITH_...` values with real paths.
|
|
554
|
+
|
|
555
|
+
**MCP tools not appearing in NanoClaw**
|
|
556
|
+
Verify the Intervals.icu MCP server is correctly configured in NanoClaw. Consult the NanoClaw documentation for MCP server setup and confirm the server is listed as active. Check that `INTERVALS_API_KEY` and `INTERVALS_ATHLETE_ID` are set correctly in the MCP server environment.
|
|
557
|
+
|
|
558
|
+
**"qmd: command not found"**
|
|
559
|
+
QMD is not installed. Run `pip install qmd` or consult the QMD installation docs.
|
package/SKILL_PACK.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# engram-coach Skill Pack
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
engram-coach is a document-driven endurance-coaching plugin. Skills use athlete-approved local records, Intervals.icu data, and explicit coaching policies to reason about training decisions. The repository ships the engine; athlete records and credentials remain in a separate local workspace.
|
|
6
|
+
|
|
7
|
+
## Package contents
|
|
8
|
+
|
|
9
|
+
- `skills/` — Claude Code skill instructions.
|
|
10
|
+
- `personas/` — generic coaching-policy definitions.
|
|
11
|
+
- `templates/` — Markdown templates for planning and review artifacts.
|
|
12
|
+
- `analyses/` — stream-analysis catalog and data requirements.
|
|
13
|
+
- `analysis-tools/` — deterministic TypeScript analysis utilities.
|
|
14
|
+
- `shared/` — common setup and retrieval instructions.
|
|
15
|
+
|
|
16
|
+
## Personas
|
|
17
|
+
|
|
18
|
+
| Persona | Slug | Policy |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Conservative | `conservative` | Recovery-first; an adverse HRV signal vetoes hard training. |
|
|
21
|
+
| Aggressive | `aggressive` | Progressive overload with weighted readiness. |
|
|
22
|
+
| Polarized | `polarized` | High low-intensity volume with clearly separated high-intensity work. |
|
|
23
|
+
| Volume | `volume` | Long-horizon aerobic volume with a 14-day CTL trend. |
|
|
24
|
+
|
|
25
|
+
Built-in policies are generic. Create a custom policy with [`PERSONA_SCHEMA.md`](PERSONA_SCHEMA.md) when an athlete needs different thresholds or decision logic.
|
|
26
|
+
|
|
27
|
+
## Setup
|
|
28
|
+
|
|
29
|
+
1. Install this repository as a Claude Code plugin using your marketplace or local plugin source.
|
|
30
|
+
2. Configure an Intervals.icu MCP server.
|
|
31
|
+
3. Create a local `.engram-coach/config.json` from [`config.json.example`](config.json.example) in the athlete workspace.
|
|
32
|
+
4. Keep `.engram-coach/` gitignored: it contains credentials and local paths.
|
|
33
|
+
5. Run `/engram-coach:intake` to establish goals, policies, and coaching-record locations.
|
|
34
|
+
|
|
35
|
+
See [`SETUP.md`](SETUP.md) for the detailed configuration contract.
|
|
36
|
+
|
|
37
|
+
## Structured capture contract
|
|
38
|
+
|
|
39
|
+
Skills that change coaching records do not write state files directly. They
|
|
40
|
+
call `engram_capture_preview({ change_set })`, present the returned mutation
|
|
41
|
+
plan for approval against its exact plan hash, and commit with
|
|
42
|
+
`engram_capture_apply({ plan_hash })`. Records declare a `details.recordRole`
|
|
43
|
+
of `state` (superseded by approved changes), `event` (append-only), or
|
|
44
|
+
`report-claim` (a conclusion tied to an approved report). Prescription YAML,
|
|
45
|
+
consultation/monitoring logs, and doctor-prep summaries are generated
|
|
46
|
+
compatibility views carrying a `GENERATED FROM ENGRAM ACTIVE RECORDS.
|
|
47
|
+
DO NOT EDIT DIRECTLY.` warning header — never edited directly. Long-form
|
|
48
|
+
reports (`RACE_REPORT.md`, block `SUMMARY.md`, `SEASON_REVIEW.md`, methodology
|
|
49
|
+
and arc-overview documents) remain canonical approved documents authored by
|
|
50
|
+
their skills.
|
|
51
|
+
|
|
52
|
+
Ambient conversation capture uses an explicit provider/model from
|
|
53
|
+
`.engram-coach/config.json` (`capture.model`; `ENGRAM_COACH_CAPTURE_MODEL`
|
|
54
|
+
overrides the model only). See [`SETUP.md`](SETUP.md) §7 for the authority
|
|
55
|
+
model, retry semantics, and the dry-run migration sequence
|
|
56
|
+
(`scan` → `apply-baseline` → `emit-change-set` → `compare`).
|
|
57
|
+
|
|
58
|
+
## Skills
|
|
59
|
+
|
|
60
|
+
| Skill | Invocation | Purpose |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| intake | `/engram-coach:intake` | Set up a new athlete workspace and coaching policy. |
|
|
63
|
+
| set-goal | `/engram-coach:set-goal` | Create a goal arc, methodology documents, and prescriptions. |
|
|
64
|
+
| adapt-plan | `/engram-coach:adapt-plan` | Assess readiness after a key workout and adapt the next session. |
|
|
65
|
+
| lactate-analyze | `/engram-coach:lactate-analyze` | Query lactate tests and threshold estimates. |
|
|
66
|
+
| consult | `/engram-coach:consult` | Provide evidence-based advice within an active plan. |
|
|
67
|
+
| block-review | `/engram-coach:block-review` | Produce an end-of-block summary. |
|
|
68
|
+
| race-analysis | `/engram-coach:race-analysis` | Produce a post-race report from activity data and narrative. |
|
|
69
|
+
| season-retrospective | `/engram-coach:season-retrospective` | Synthesize cross-block and race patterns. |
|
|
70
|
+
| lessons-rollup | `/engram-coach:lessons-rollup` | Curate durable athlete lessons from coaching records. |
|
|
71
|
+
| monitoring-rollup | `/engram-coach:monitoring-rollup` | Maintain declared longitudinal monitoring records. |
|
|
72
|
+
|
|
73
|
+
## Data boundary
|
|
74
|
+
|
|
75
|
+
Do not commit athlete records, local configuration, tokens, generated data, or private narratives. Public examples in this repository are fictional and synthetic.
|