@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
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Polarized Coach",
|
|
3
|
+
"slug": "polarized",
|
|
4
|
+
"display_name": "Polarized",
|
|
5
|
+
"description": "Follows polarized intensity distribution: most volume in Z1 (endurance), hard efforts in Z4/VO2, minimal sweet-spot work. Uses weighted scoring. Workout type map reflects polarized intensity options only.",
|
|
6
|
+
"philosophy": "Physiological research consistently shows that elite endurance athletes spend roughly 80% of training time at low intensity and 20% at high intensity, with minimal time in the 'moderate' middle zone. Sweet-spot work accumulates fatigue without the same aerobic stimulus as true Z1 volume or Z4/VO2 efforts. The polarized model maximises aerobic base while preserving neuromuscular quality.",
|
|
7
|
+
"coaching_voice": "Scientific and methodical. References intensity distribution explicitly. Phrases like 'keep this truly easy — stay in Zone 1', 'today calls for real high-end work, not moderate', 'avoid the grey zone'. Will actively discourage sweet-spot or threshold work unless readiness strongly supports it.",
|
|
8
|
+
"edge_cases": [
|
|
9
|
+
"When recommending 'moderate', default to long Z1 endurance work rather than sweet-spot — the polarized model treats 'moderate readiness' as high-volume easy, not medium-intensity",
|
|
10
|
+
"When TSB is in push zone, recommend Z4/VO2 intervals specifically — not threshold or sweet-spot",
|
|
11
|
+
"In peak phase, require higher TSB freshness (5) for push recommendations to preserve quality for race-specific VO2 efforts"
|
|
12
|
+
],
|
|
13
|
+
"tsb_thresholds": {
|
|
14
|
+
"push": 0,
|
|
15
|
+
"moderate": -8,
|
|
16
|
+
"easy": -18
|
|
17
|
+
},
|
|
18
|
+
"factor_weights": {
|
|
19
|
+
"tsb": 1.0,
|
|
20
|
+
"ctl_trend": 0.6,
|
|
21
|
+
"hrv": 0.8,
|
|
22
|
+
"threshold_currency": 0.1
|
|
23
|
+
},
|
|
24
|
+
"conflict_resolution": "weighted_score",
|
|
25
|
+
"hrv_veto_threshold": null,
|
|
26
|
+
"workout_type_map": {
|
|
27
|
+
"push": "a VO2max or anaerobic interval session (Z4-Z5)",
|
|
28
|
+
"moderate": "a long aerobic endurance ride (Z1-Z2)",
|
|
29
|
+
"easy": "an easy Zone 1 endurance ride",
|
|
30
|
+
"rest": "complete rest — no sweetspot or threshold today"
|
|
31
|
+
},
|
|
32
|
+
"threshold_currency_stale_days": 30,
|
|
33
|
+
"ctl_trend_window_days": 7,
|
|
34
|
+
"phase_overrides": {
|
|
35
|
+
"base": {
|
|
36
|
+
"tsb_thresholds": {
|
|
37
|
+
"push": -2,
|
|
38
|
+
"moderate": -10,
|
|
39
|
+
"easy": -20
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"peak": {
|
|
43
|
+
"tsb_thresholds": {
|
|
44
|
+
"push": 5,
|
|
45
|
+
"moderate": 0,
|
|
46
|
+
"easy": -10
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"phase_factor_weights": {},
|
|
51
|
+
"analyses": {
|
|
52
|
+
"time_in_zones": {
|
|
53
|
+
"enabled": true,
|
|
54
|
+
"thresholds": { "z1_minimum_pct": 75, "grey_zone_max_pct": 5 },
|
|
55
|
+
"phases": null,
|
|
56
|
+
"weight": 0.5
|
|
57
|
+
},
|
|
58
|
+
"power_curve_trend": {
|
|
59
|
+
"enabled": true,
|
|
60
|
+
"durations": [30, 60, 300],
|
|
61
|
+
"thresholds": { "improving": 3, "declining": -5 },
|
|
62
|
+
"phases": ["build", "peak"],
|
|
63
|
+
"weight": 0.3
|
|
64
|
+
},
|
|
65
|
+
"hr_recovery_curve": {
|
|
66
|
+
"enabled": true,
|
|
67
|
+
"thresholds": { "good_bpm_per_min": 25, "poor_bpm_per_min": 15 },
|
|
68
|
+
"phases": null,
|
|
69
|
+
"weight": 0.2
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Volume — Monitoring Signals
|
|
2
|
+
|
|
3
|
+
## Signal Philosophy
|
|
4
|
+
|
|
5
|
+
The volume-first policy prioritizes sustainable aerobic development over a
|
|
6
|
+
long training horizon. CTL trend carries the highest weight, assessed over a
|
|
7
|
+
14-day window to avoid reacting to routine day-to-day variance. TSB, HRV,
|
|
8
|
+
resting heart rate, session quality, and athlete narrative remain meaningful
|
|
9
|
+
constraints; no single metric establishes readiness alone.
|
|
10
|
+
|
|
11
|
+
## HRV Interpretation
|
|
12
|
+
|
|
13
|
+
| Signal | Response |
|
|
14
|
+
|--------|----------|
|
|
15
|
+
| One or two lower readings | Record the direction and compare it with TSB, RHR, sleep, and session quality. Do not change a session from a single reading alone. |
|
|
16
|
+
| Suppressed for 3–5 days | Reduce the next session when it agrees with adverse TSB, RHR, or subjective signals. |
|
|
17
|
+
| Suppressed for 7+ days | Treat as a sustained recovery-cost signal. Shift toward moderate or easy work while investigating illness, life stress, and accumulated fatigue. |
|
|
18
|
+
| Stable or improving | Supports the planned load when the broader signal picture agrees. |
|
|
19
|
+
|
|
20
|
+
## TSB Thresholds
|
|
21
|
+
|
|
22
|
+
| TSB range | Recommendation | Rationale |
|
|
23
|
+
|-----------|----------------|-----------|
|
|
24
|
+
| > -10 | Push | A long aerobic ride or a back-to-back volume day is appropriate when session quality and recovery signals agree. |
|
|
25
|
+
| -20 to -10 | Moderate | Continue aerobic work at a manageable duration. |
|
|
26
|
+
| -30 to -20 | Easy | Preserve frequency while reducing duration or intensity. |
|
|
27
|
+
| < -30 | Rest | Resolve deep training debt before resuming a push cycle. |
|
|
28
|
+
|
|
29
|
+
Base-phase thresholds are slightly more permissive; peak and taper thresholds
|
|
30
|
+
tighten to protect event readiness.
|
|
31
|
+
|
|
32
|
+
## Brake Signals
|
|
33
|
+
|
|
34
|
+
Reduce load when one of these conditions is present:
|
|
35
|
+
|
|
36
|
+
1. CTL is flat or declining across 14 days despite consistent training.
|
|
37
|
+
2. TSB remains below -30 without a positive CTL trend.
|
|
38
|
+
3. HRV is suppressed for seven or more days, especially with rising resting HR.
|
|
39
|
+
4. RPE rises materially at work that was recently manageable, or interval execution degrades.
|
|
40
|
+
|
|
41
|
+
## Accelerator Signals
|
|
42
|
+
|
|
43
|
+
Increase or maintain load only when the full signal picture supports it:
|
|
44
|
+
|
|
45
|
+
1. CTL rises across the 14-day window and TSB remains above the push threshold.
|
|
46
|
+
2. HRV and resting HR are stable while aerobic session quality is maintained.
|
|
47
|
+
3. Heart rate at a comparable aerobic power declines across comparable sessions.
|
|
48
|
+
4. Long-ride decoupling and perceived effort remain stable at the prescribed workload.
|
|
49
|
+
|
|
50
|
+
## Conflicting Signal Resolution
|
|
51
|
+
|
|
52
|
+
A favorable CTL trend supports continued volume but does not erase sustained
|
|
53
|
+
recovery cost. When HRV, resting HR, RPE, or session quality oppose the load
|
|
54
|
+
trend for several days, reduce duration or intensity and reassess the
|
|
55
|
+
underlying cause. When CTL is flat and fatigue is deep, reduce load
|
|
56
|
+
strategically rather than adding more volume.
|
|
57
|
+
|
|
58
|
+
## Analysis Interpretation
|
|
59
|
+
|
|
60
|
+
### Aerobic Decoupling
|
|
61
|
+
|
|
62
|
+
| Decoupling | Response |
|
|
63
|
+
|------------|----------|
|
|
64
|
+
| < 3% | Normal for a comparable long aerobic session. |
|
|
65
|
+
| 3–5% | Monitor the trend across sessions and contextualize terrain, heat, fueling, and stops. |
|
|
66
|
+
| 5–8% | Review duration, fueling, and recovery before the next long session. |
|
|
67
|
+
| > 8% | Treat as a strong brake when the measurement is valid; shorten future long sessions until the pattern resolves. |
|
|
68
|
+
|
|
69
|
+
### Heart Rate at Power Trend
|
|
70
|
+
|
|
71
|
+
Compare standardized steady-state work across a 28-day window. A decline of at
|
|
72
|
+
least 2 bpm at the reference power supports aerobic adaptation. Stable values
|
|
73
|
+
are neutral. A rise of at least 2 bpm calls for recovery and measurement-validity review, particularly when CTL is flat.
|
|
74
|
+
|
|
75
|
+
### Power Curve Trend
|
|
76
|
+
|
|
77
|
+
Use relevant target durations to corroborate the training response. A 3% or
|
|
78
|
+
greater improvement supports the current structure; a 3% or greater decline
|
|
79
|
+
alongside adverse recovery signals calls for a prescription review.
|
|
80
|
+
|
|
81
|
+
### Resting Heart Rate Trend
|
|
82
|
+
|
|
83
|
+
Interpret resting HR across the same 14-day horizon as CTL. A sustained rise
|
|
84
|
+
of 3–5 bpm is an amber signal. A rise greater than 5 bpm is a strong brake,
|
|
85
|
+
especially when HRV and session quality also worsen.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Volume Coach",
|
|
3
|
+
"slug": "volume",
|
|
4
|
+
"display_name": "Volume",
|
|
5
|
+
"description": "A high-volume, long-horizon coaching policy. It accepts controlled fatigue while prioritizing sustained aerobic work, a 14-day CTL trend, and weighted readiness decisions.",
|
|
6
|
+
"philosophy": "This policy uses progressive aerobic volume as its primary training stimulus across long development cycles. It evaluates CTL trajectory, TSB, HRV, and session quality together, allowing controlled fatigue when the full signal picture supports it. Recovery is scheduled strategically to preserve long-term consistency and event readiness.",
|
|
7
|
+
"coaching_voice": "Volume-first and long-term focused. References aerobic capacity, CTL trajectory, and sustainable consistency. It acknowledges fatigue as a training cost while using multi-day recovery signals and session quality to determine when to reduce load.",
|
|
8
|
+
"edge_cases": [
|
|
9
|
+
"When CTL is trending strongly upward, recommend push even at TSB as low as -10 — fatigue tolerance is a feature, not a bug",
|
|
10
|
+
"In base phase, apply even more permissive TSB thresholds (-12/-22/-32) and maximise CTL trend weight (1.5 → 2.0 in phase_factor_weights)",
|
|
11
|
+
"Use 14-day CTL trend window (not 7-day) to smooth out day-to-day variation and capture true fitness trajectory",
|
|
12
|
+
"When athlete is in peak/taper, slightly freshen thresholds (-5/-12/-20) — even volume approaches require race readiness"
|
|
13
|
+
],
|
|
14
|
+
"tsb_thresholds": {
|
|
15
|
+
"push": -10,
|
|
16
|
+
"moderate": -20,
|
|
17
|
+
"easy": -30
|
|
18
|
+
},
|
|
19
|
+
"factor_weights": {
|
|
20
|
+
"tsb": 0.8,
|
|
21
|
+
"ctl_trend": 1.5,
|
|
22
|
+
"hrv": 0.5,
|
|
23
|
+
"threshold_currency": 0.1
|
|
24
|
+
},
|
|
25
|
+
"conflict_resolution": "weighted_score",
|
|
26
|
+
"hrv_veto_threshold": null,
|
|
27
|
+
"workout_type_map": {
|
|
28
|
+
"push": "a long aerobic ride or back-to-back volume day",
|
|
29
|
+
"moderate": "a medium-duration aerobic endurance ride",
|
|
30
|
+
"easy": "an easy aerobic spin or lower-volume day",
|
|
31
|
+
"rest": "a true rest day — even volume coaches need these"
|
|
32
|
+
},
|
|
33
|
+
"threshold_currency_stale_days": 60,
|
|
34
|
+
"ctl_trend_window_days": 14,
|
|
35
|
+
"phase_overrides": {
|
|
36
|
+
"base": {
|
|
37
|
+
"tsb_thresholds": {
|
|
38
|
+
"push": -12,
|
|
39
|
+
"moderate": -22,
|
|
40
|
+
"easy": -32
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"peak": {
|
|
44
|
+
"tsb_thresholds": {
|
|
45
|
+
"push": -5,
|
|
46
|
+
"moderate": -12,
|
|
47
|
+
"easy": -20
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"phase_factor_weights": {
|
|
52
|
+
"base": {
|
|
53
|
+
"tsb": 0.7,
|
|
54
|
+
"ctl_trend": 2.0,
|
|
55
|
+
"hrv": 0.4,
|
|
56
|
+
"threshold_currency": 0.1
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"analyses": {
|
|
60
|
+
"aerobic_decoupling": {
|
|
61
|
+
"enabled": true,
|
|
62
|
+
"thresholds": { "amber": 5, "red": 8 },
|
|
63
|
+
"phases": ["base", "build"],
|
|
64
|
+
"weight": 0.3
|
|
65
|
+
},
|
|
66
|
+
"hr_at_power_trend": {
|
|
67
|
+
"enabled": true,
|
|
68
|
+
"thresholds": { "improving": -2, "stagnant": 0, "worsening": 2 },
|
|
69
|
+
"reference_window_days": 28,
|
|
70
|
+
"phases": ["base"],
|
|
71
|
+
"weight": 0.4
|
|
72
|
+
},
|
|
73
|
+
"power_curve_trend": {
|
|
74
|
+
"enabled": true,
|
|
75
|
+
"durations": [1200, 3600],
|
|
76
|
+
"thresholds": { "improving": 3, "declining": -3 },
|
|
77
|
+
"phases": null,
|
|
78
|
+
"weight": 0.2
|
|
79
|
+
},
|
|
80
|
+
"resting_hr_trend": {
|
|
81
|
+
"enabled": true,
|
|
82
|
+
"window_days": 14,
|
|
83
|
+
"thresholds": { "amber_bpm": 3, "red_bpm": 5 },
|
|
84
|
+
"phases": null,
|
|
85
|
+
"weight": 0.15
|
|
86
|
+
},
|
|
87
|
+
"interval_execution_quality": {
|
|
88
|
+
"enabled": false
|
|
89
|
+
},
|
|
90
|
+
"hrv_trend": {
|
|
91
|
+
"enabled": true,
|
|
92
|
+
"metric": "hrv_rmssd",
|
|
93
|
+
"short_window_days": 14,
|
|
94
|
+
"long_window_days": 60,
|
|
95
|
+
"trend_window_days": 7,
|
|
96
|
+
"analog_tolerance": 2,
|
|
97
|
+
"analog_dedup_days": 3,
|
|
98
|
+
"phases": null,
|
|
99
|
+
"weight": 0.5,
|
|
100
|
+
"thresholds": {
|
|
101
|
+
"green": -0.5,
|
|
102
|
+
"green_watch": -1.0,
|
|
103
|
+
"amber": -1.5,
|
|
104
|
+
"red": -2.0
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Shared retrieval policy (qmd)
|
|
2
|
+
|
|
3
|
+
How to search the athlete's coaching corpus. **This is the only copy — do not
|
|
4
|
+
inline it into a skill.**
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## The rule
|
|
9
|
+
|
|
10
|
+
**Query the question you actually need answered. Never query the skill's own
|
|
11
|
+
name or topic.**
|
|
12
|
+
|
|
13
|
+
Topic-word queries retrieve by keyword and match everything and nothing. The
|
|
14
|
+
corpus is entirely about coaching, so "coaching adaptation history" describes
|
|
15
|
+
every document in it and discriminates between none of them.
|
|
16
|
+
|
|
17
|
+
Measured on this corpus:
|
|
18
|
+
|
|
19
|
+
| Query | Result |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `qmd query "coaching adaptation history"` | Returned a *stale copy of the adapt-plan skill file* at 93% — the skill retrieving its own superseded instructions as history |
|
|
22
|
+
| `qmd query "does the athlete overshoot prescribed easy buffer spin duration"` | Returned the exact W3 Tue buffer record that documents the pattern, at 56% |
|
|
23
|
+
|
|
24
|
+
Same corpus, same tool. The difference is that the second is a question.
|
|
25
|
+
|
|
26
|
+
## Constructing queries
|
|
27
|
+
|
|
28
|
+
Derive **2–3 queries from the specific decision in front of you**, not from the
|
|
29
|
+
skill you are running. Include the concrete particulars — session type, the
|
|
30
|
+
numbers observed, the anomaly, the block name, the symptom.
|
|
31
|
+
|
|
32
|
+
Cover two levels:
|
|
33
|
+
|
|
34
|
+
1. **Durable pattern** — "has this athlete shown X before?" Surfaces the claim
|
|
35
|
+
records under `claims/`, `lessons-log.md`, block summaries, race reports.
|
|
36
|
+
2. **Session precedent** — "what happened last time X occurred in Y?" Surfaces
|
|
37
|
+
adaptation records and consultations.
|
|
38
|
+
|
|
39
|
+
Good:
|
|
40
|
+
|
|
41
|
+
- `qmd query "has HR run high for power on warm under-slept indoor mornings"`
|
|
42
|
+
- `qmd query "how did the athlete respond to sweet spot the week after a long ride"`
|
|
43
|
+
- `qmd query "prior cold weather hand numbness on the bike"`
|
|
44
|
+
|
|
45
|
+
Bad — do not write queries like these:
|
|
46
|
+
|
|
47
|
+
- `qmd query "adapt plan build1"` · `qmd query "coaching adaptation history"`
|
|
48
|
+
· `qmd vsearch "coaching"` · `qmd query "{skill name}"`
|
|
49
|
+
|
|
50
|
+
## Choosing the command
|
|
51
|
+
|
|
52
|
+
| Command | Use for |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `qmd query` | **Default.** Hybrid lexical + vector with expansion and reranking. |
|
|
55
|
+
| `qmd search` | Exact terms, numbers, dates, source tags — e.g. `"165W"`, `"i143346"`. |
|
|
56
|
+
| `qmd vsearch` | Only when you can describe the idea but not name its keywords. |
|
|
57
|
+
|
|
58
|
+
Add `-n <num>` for more results; `-c training` to pin the collection.
|
|
59
|
+
|
|
60
|
+
## Reading results
|
|
61
|
+
|
|
62
|
+
- **Cite the source tag** of anything you rely on, so the athlete can trace it.
|
|
63
|
+
- **Respect confidence grading.** A record marked provisional or
|
|
64
|
+
single-observation does not become established by being retrieved.
|
|
65
|
+
- **Nothing above ~45% means nothing relevant was found.** Say so. Do not
|
|
66
|
+
stretch a weak match into a precedent — a wrong precedent is worse than none,
|
|
67
|
+
because it launders a coincidence into a pattern.
|
|
68
|
+
- **Check what a document *is* before trusting it.** Process documents, task
|
|
69
|
+
briefs, and drafts are keyword-dense and can outrank real records. Only
|
|
70
|
+
`docs/` in the athlete repo is indexed knowledge; if a result looks like
|
|
71
|
+
planning or creative output, discount it.
|
package/shared/setup.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Shared setup preamble
|
|
2
|
+
|
|
3
|
+
Canonical configuration resolution for every engram-coach skill. **This is the only
|
|
4
|
+
copy — do not inline it into a skill.** A skill invokes it by naming which
|
|
5
|
+
optional steps apply.
|
|
6
|
+
|
|
7
|
+
Run silently. No user input except where step 6 applies.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Resolve paths _(all skills)_
|
|
12
|
+
|
|
13
|
+
### Plugin root
|
|
14
|
+
|
|
15
|
+
Resolve `{plugin_root}` before reading any bundled asset:
|
|
16
|
+
|
|
17
|
+
1. Claude Code: use the absolute `${CLAUDE_PLUGIN_ROOT}` value.
|
|
18
|
+
2. OMP: take the absolute path of this skill's loaded `SKILL.md` and remove
|
|
19
|
+
`/skills/{skill-name}/SKILL.md`.
|
|
20
|
+
|
|
21
|
+
The result must contain `shared/setup.md`, `personas/`, `templates/`,
|
|
22
|
+
`knowledge/`, `analyses/`, `analysis-tools/`, and `skills/`. Resolve every
|
|
23
|
+
bundled path beneath this absolute root.
|
|
24
|
+
|
|
25
|
+
### Config path
|
|
26
|
+
|
|
27
|
+
Resolve `{config_path}` from the first existing candidate, in this exact order:
|
|
28
|
+
|
|
29
|
+
1. If `ENGRAM_COACH_CONFIG` is non-empty, expand it to an absolute path and use
|
|
30
|
+
that candidate.
|
|
31
|
+
2. Resolve `{cwd}/.engram-coach/config.json`, where `{cwd}` is the absolute OMP
|
|
32
|
+
or Claude project working directory.
|
|
33
|
+
3. Resolve `{home}/.claude/engram-coach/config.json`, where `{home}` is the
|
|
34
|
+
absolute user home directory.
|
|
35
|
+
|
|
36
|
+
For each candidate, issue Read with the **complete absolute path**. The config
|
|
37
|
+
Read path always ends in `.engram-coach/config.json` or is the explicit
|
|
38
|
+
`ENGRAM_COACH_CONFIG` value; `config.json` by itself is not a resolved path.
|
|
39
|
+
|
|
40
|
+
## 2. Read config _(all skills)_
|
|
41
|
+
|
|
42
|
+
Read the resolved absolute `{config_path}`. If no candidate exists, stop and
|
|
43
|
+
output:
|
|
44
|
+
|
|
45
|
+
> "config.json not found. Run the `intake` skill to create it, or copy
|
|
46
|
+
> `{plugin_root}/config.json.example` to `{cwd}/.engram-coach/config.json`
|
|
47
|
+
> and configure your paths. See SETUP.md."
|
|
48
|
+
|
|
49
|
+
Then verify the ambient capture model is configured. If
|
|
50
|
+
`ENGRAM_COACH_CAPTURE_MODEL` is set nonblank, it overrides **only**
|
|
51
|
+
`capture.model`; the timeout and candidate limits still come from the config's
|
|
52
|
+
`capture` block. Otherwise read `capture.model`. It must be an explicit
|
|
53
|
+
`provider/model` string — it is never inherited from the interactive session.
|
|
54
|
+
If both sources are absent, stop and output:
|
|
55
|
+
|
|
56
|
+
> "Ambient capture model not configured. Run the `intake` skill (it collects a
|
|
57
|
+
> provider/model in Phase 3C), or add a `capture.model` value to
|
|
58
|
+
> `{config_path}`. See SETUP.md."
|
|
59
|
+
|
|
60
|
+
## 3. Resolve active profile _(all skills)_
|
|
61
|
+
|
|
62
|
+
`active_profile` → `profiles[active_profile]` → extract:
|
|
63
|
+
|
|
64
|
+
- `active_persona` (string, required)
|
|
65
|
+
- `coaching_docs_dir` (path, required — expand `~`)
|
|
66
|
+
- `prescriptions_dir` (path — required only for skills that declare PRESCRIPTIONS)
|
|
67
|
+
- `season` (string, optional)
|
|
68
|
+
|
|
69
|
+
## 4. Verify `coaching_docs_dir` _(all skills)_
|
|
70
|
+
|
|
71
|
+
If it does not exist, stop and output:
|
|
72
|
+
|
|
73
|
+
> "coaching_docs_dir '{path}' does not exist. Create it: mkdir -p {path}"
|
|
74
|
+
|
|
75
|
+
## 5. Verify `prescriptions_dir` _(only if the skill declares PRESCRIPTIONS)_
|
|
76
|
+
|
|
77
|
+
If it does not exist, stop and output:
|
|
78
|
+
|
|
79
|
+
> "prescriptions_dir '{path}' does not exist. Check config.json."
|
|
80
|
+
|
|
81
|
+
Skills that do **not** declare PRESCRIPTIONS must not fail when this is absent or
|
|
82
|
+
unset — a prescription-free period is a legitimate state, not a misconfiguration.
|
|
83
|
+
|
|
84
|
+
## 6. Resolve season _(only if the skill declares SEASON)_
|
|
85
|
+
|
|
86
|
+
If `season` is absent from the active profile, ask once:
|
|
87
|
+
|
|
88
|
+
> "What season label should I use for this record? (e.g., '2027-example-season') This
|
|
89
|
+
> will be stored in the path under coaching_docs_dir."
|
|
90
|
+
|
|
91
|
+
Store the answer for the duration of the session.
|
|
92
|
+
|
|
93
|
+
## 7. Load the persona _(all skills)_
|
|
94
|
+
|
|
95
|
+
Load `{plugin_root}/personas/{active_persona}.json` and
|
|
96
|
+
`{plugin_root}/personas/{active_persona}-monitoring.md` as reasoning
|
|
97
|
+
context. If either is missing, stop and output:
|
|
98
|
+
|
|
99
|
+
> "Persona '{active_persona}' not found. Expected:
|
|
100
|
+
> {plugin_root}/personas/{active_persona}.json
|
|
101
|
+
> {plugin_root}/personas/{active_persona}-monitoring.md
|
|
102
|
+
> Check config.json active_persona value."
|
|
103
|
+
|
|
104
|
+
## 8. Load the athlete profile _(all skills)_
|
|
105
|
+
|
|
106
|
+
Read `{coaching_docs_dir}/COACH_PROFILE.md` as your reasoning context alongside
|
|
107
|
+
the persona. If absent (first season, no rollups yet), continue silently.
|
|
108
|
+
|
|
109
|
+
That file holds every active engram-coach claim record, medical ones included —
|
|
110
|
+
medications, airway, and load conditions materially change what should be
|
|
111
|
+
prescribed, and reasoning without them is reasoning from a knowingly
|
|
112
|
+
incomplete model.
|
|
113
|
+
|
|
114
|
+
`ATHLETE_PROFILE.md` is the athlete-facing render of the same records under a
|
|
115
|
+
different title. The presentation pack authorizes the `athlete`, `coach`, and
|
|
116
|
+
`self-coach` audiences identically — every active, eligible engram-coach
|
|
117
|
+
record, unfiltered — so there is no visibility, privacy, or persona-fit split
|
|
118
|
+
between the two files: neither withholds a claim the other carries. Read
|
|
119
|
+
whichever one matches the reasoning context you are in.
|
|
120
|
+
|
|
121
|
+
Neither file is hand-maintained. Both are regenerated by `lessons-rollup`
|
|
122
|
+
through the harness; never write to them directly.
|
|
123
|
+
|
|
124
|
+
**Durable patterns in the profile override generic persona thresholds when they
|
|
125
|
+
conflict.** Cite the source tag (e.g. `[race:example-endurance-event]`)
|
|
126
|
+
whenever reasoning leans on a specific calibration point.
|
|
127
|
+
|
|
128
|
+
Respect the confidence grading the profile carries. An entry marked
|
|
129
|
+
*provisional*, *single observation*, or *mechanism not established* constrains
|
|
130
|
+
how far you may generalize from it — report it at the strength it is written,
|
|
131
|
+
never stronger.
|
|
132
|
+
|
|
133
|
+
## 9. MCP availability check _(only if the skill declares MCP)_
|
|
134
|
+
|
|
135
|
+
Attempt `get_athlete` via the Intervals.icu MCP tools. On a connection or
|
|
136
|
+
availability error, stop and output:
|
|
137
|
+
|
|
138
|
+
> "Intervals.icu MCP server is unavailable. This skill requires Intervals.icu
|
|
139
|
+
> MCP tools to retrieve fitness data. See SETUP.md (Section 3: MCP Server
|
|
140
|
+
> Setup), then restart Claude Code and retry."
|
|
141
|
+
|
|
142
|
+
## 10. Monitoring concerns _(only if the skill declares MONITORING)_
|
|
143
|
+
|
|
144
|
+
Read `{coaching_docs_dir}/tracking/concerns.yaml` if it exists. For each concern
|
|
145
|
+
with `active: true`, find the most recent entry date in its log and compute days
|
|
146
|
+
since. Surface any whose gap ≥ its `cadence_days`:
|
|
147
|
+
|
|
148
|
+
> "[Monitoring: {name} last logged {date} ({N}d ago) — due for capture.]"
|
|
149
|
+
|
|
150
|
+
Awareness only — capture happens via the monitoring-rollup auto-tail at write
|
|
151
|
+
time. If the file is absent or has no active concerns, skip silently.
|
|
152
|
+
|
|
153
|
+
## 11. Record authority and generated views _(all skills)_
|
|
154
|
+
|
|
155
|
+
Engram active records are the authoritative store for mutable coaching state
|
|
156
|
+
and chronological events. Every pack record declares a role in
|
|
157
|
+
`details.recordRole`, exactly one of:
|
|
158
|
+
|
|
159
|
+
- `state` — one current value for a canonical entity key; an approved change
|
|
160
|
+
creates a new active record, retires the prior one, and links them with
|
|
161
|
+
`relationships.supersedes`.
|
|
162
|
+
- `event` — append-only history (consultations, monitoring entries); never
|
|
163
|
+
automatically replaced.
|
|
164
|
+
- `report-claim` — a structured conclusion extracted from an approved
|
|
165
|
+
long-form report; it never replaces the report document.
|
|
166
|
+
|
|
167
|
+
Canonical entity keys are derived by this pack, never accepted from a model:
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
workout:<session-id>
|
|
171
|
+
prescription:<arc-id>:<session-id>
|
|
172
|
+
threshold:<sport>:lt1
|
|
173
|
+
threshold:<sport>:lt2
|
|
174
|
+
persona:<active-profile>
|
|
175
|
+
monitoring:<concern-id>:<signal>
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Workout identity is the durable `session_id`; dates, titles, week position,
|
|
179
|
+
and workout contents are mutable attributes, not identity.
|
|
180
|
+
|
|
181
|
+
**Generated compatibility views.** The prescription YAML files,
|
|
182
|
+
`consultations.md`, monitoring logs, and doctor-prep summaries are rendered
|
|
183
|
+
from committed records after each approved apply. Each carries a byte-exact
|
|
184
|
+
warning header (`# GENERATED FROM ENGRAM ACTIVE RECORDS. DO NOT EDIT DIRECTLY.`
|
|
185
|
+
in YAML, `<!-- GENERATED FROM ENGRAM ACTIVE RECORDS. DO NOT EDIT DIRECTLY. -->`
|
|
186
|
+
in Markdown) and is **never edited directly** — direct edits are overwritten by
|
|
187
|
+
the next materialization and break migration comparisons.
|
|
188
|
+
|
|
189
|
+
**Canonical approved documents.** These remain skill-authored long-form
|
|
190
|
+
documents, not generated views: `RACE_REPORT.md`, block `SUMMARY.md`,
|
|
191
|
+
`SEASON_REVIEW.md`, methodology documents, and arc-overview documents.
|
|
192
|
+
|
|
193
|
+
**Approval and retry semantics.** Skills that change records follow one
|
|
194
|
+
ordering: preview records → athlete approves the exact plan hash → apply →
|
|
195
|
+
guarded qmd refresh → regenerate compatibility views.
|
|
196
|
+
|
|
197
|
+
- A stale apply (records changed since preview) deletes the pending plan and
|
|
198
|
+
requires a fresh preview plus fresh approval — never a re-apply of the old
|
|
199
|
+
hash.
|
|
200
|
+
- If the qmd index reports `index-stale`, the committed records remain
|
|
201
|
+
authoritative and the index is simply retried later.
|
|
202
|
+
- If materialization fails, the commit stands and reports stale views;
|
|
203
|
+
re-calling apply with the same committed hash in the same session reruns
|
|
204
|
+
only view regeneration, never the record mutations.
|
|
205
|
+
|
|
206
|
+
Legacy workspaces migrate through the dry-run sequence documented in
|
|
207
|
+
SETUP.md §7: `scan` → `apply-baseline` → `emit-change-set` → `compare`.
|
package/skills/.gitkeep
ADDED
|
File without changes
|