MEMORY.md

Hard gate for athlete-facing sessions: if the candidate reply is not the final athlete-useful body, send nothing. Do not allow any progress-update, scratchpad, or draft text to enter the athlete reply path.

User preferences

  • When the user provides setup, identity, preference, or other details that are clearly meant to persist, save them promptly to the appropriate workspace files rather than leaving them only in chat context.
  • After saving important information, explicitly confirm that it has been persisted.
  • Use Canadian English for Sidney-facing and TrainingPeaks workout content, including Fuelling, unless the operator explicitly requests another style. Do not use American spelling for those athlete-facing workout descriptions.
  • Do not use em dashes anywhere in messaging, reporting, logging, or any other text communication. Use commas, colons, semicolons, or spaced hyphens instead.
  • When the user asks a question, interpret the actual question carefully and verify against the real source of truth when needed rather than answering from a narrower assumption or only the currently loaded context.
  • Do not tell the user they are right unless the statement has been fully verified. If a claim merely seems plausible, consistent with the evidence, or directionally sensible, say that instead of claiming correctness.
  • Use formal professional coaching and technical terminology with elite athletes and in coaching documents; avoid banned shorthand and generalized phrasing, and prefer precise language such as sessions, blocks, frequency, intensity, volume, density, threshold, and other standard high-performance coaching terms. Hard rule: never use the banned shorthand term in this coaching context.
  • Before revising any document, read a fresh copy first because files may have been changed manually or by other processes; do not edit from stale context.
  • Do not commit files to git unless the user has given explicit approval for that commit.
  • When recommending storage locations or creating file structures, keep all files inside the workspace root unless the user explicitly asks for an external path. Recommendations should be stated as workspace-rooted paths, not ambiguous top-level locations.
  • Sidney's canonical delivery record is athlete/delivery-config.md. Use that as the source of truth for channel target, timezone, send windows, and current delivery behavior.
  • For nutrition daily review logging, do not save the athlete-facing nutrition message under ## Nutrition -> ### Athlete message draft. Save it under ## Messages -> ### Nutrition review, using the same canonical outbound-message pattern as Morning plan and Evening summary, and place it after ### Evening summary when both exist. Add a ## System event for the nutrition-review save, and if the review is sent, add a separate ## System event with the send time and available delivery details.
  • Durable daily-log timing rule, added 2026-04-17: when a workflow analyzes previous-day or other historical evidence, separate the review target date from the log date. Any newly generated analysis, saved athlete-facing message, and ## System event must be written to the athlete-local day when that workflow actually ran, not backdated into the evidence day.
  • Durable delivery rule, added 2026-04-17: if an athlete-facing workflow resolves to Telegram direct and the runtime lacks a first-class messaging tool, do not treat that alone as a delivery blocker. Use the OpenClaw CLI send path, validate it with openclaw message send --dry-run, then send for real if validation succeeds. Only log delivery as blocked if the dry-run or real send actually fails.
  • Sidney's canonical raw TrainingPeaks archive location is athlete/data/trainingpeaks/raw/. Treat that as the source archive path for future ingest, processing, and Markdown conversion work unless the user changes it.
  • Sidney's canonical race planning file is athlete/context/race-calendar.md; treat the older race-schedule.md path as retired unless the user explicitly restores it.
  • For Sidney nutrition logging, preserve the system logging timestamp as Received, add the athlete-local equivalent as Local, use athlete-local time for nutrition item headings, and use athlete-local time for any time presented to the athlete unless the athlete explicitly requests another timezone.
  • Nutrition detail block ordering rule, updated 2026-04-28: all ### HH:MM detail blocks under ## Nutrition must be in ascending chronological order, same as the ### Summary table. When writing a new detail block, always determine the correct insertion position relative to existing ### HH:MM blocks - not relative to named subsections like ### Watch or ### Carry-forward. If the new item is later than all existing blocks, insert it after the last existing ### HH:MM block. If earlier, insert before the first. Common failure mode: inserting after the last named subsection heading when ### HH:MM blocks already follow it, causing the new block to land before those existing blocks. After any write that revises ## Nutrition, verify the section is still in time order before the write is considered complete. Full insertion algorithm is in skills/nutrition-intake/references/workflow.md.
  • Use and output metric values only in generated content and saved nutrition-analysis fields. Do not save or emit oz, ounces, lb, lbs, pounds, inches, cups, tbsp, or tsp in generated nutrition notes, assumptions, portion summaries, uncertainty notes, or athlete-facing nutrition estimates; convert such values to g, kg, mL, cm, or other metric units first.
  • For nutrition multi-service comparison output and canonical nutrition log entries, round calories to the nearest whole kcal, including per-service calorie values and aggregate calories. Protein, carbohydrate, and fat may keep one decimal place when needed.
  • If writing a markdown code block, use plain ~~~ fenced blocks and no code type specifier is required, such as ``~~~text`, unless explicitly instructed otherwise.
  • For estimate markers in athlete-facing message bodies saved inside plain ~~~ fenced blocks, do not escape ~; use plain ~. Escape the tilde only when it is rendered directly in Markdown tables or other non-code raw Markdown where the renderer would misinterpret it.
  • When a nutrition log item includes athlete text, store the original athlete message text directly in a code block, one separate block per related message; if the event has only image or other media and no text, omit the athlete-message block.
  • In daily logs and related planning records, prefer Readiness check as the section label. Use ## System for internal workflow and delivery metadata sections in canonical daily logs.
  • In operator-facing status notes and heartbeat summaries, use plain wording such as check-in or athlete check-in, and avoid clunky phrases such as saved same-day athlete-facing follow-up.
  • Never use phrasing such as same-morning in athlete-facing communication. Use plain alternatives such as morning check-in, no morning check-in, no check-in today, or simply check-in, depending on context.
  • Hard coordinator rule, added 2026-04-26: any text that narrates the coordinator's internal decision-making state - such as "Logged.", "Composing the reply.", "This is not the first item of the day so daily totals are required.", "Routing to specialist.", or any equivalent progress or reasoning annotation - is internal scratchpad, not athlete-facing output. It must never be sent to the athlete. If that text would have been the next outbound message, the rule is: send nothing, complete the work, then send only the final athlete-useful reply.
  • athlete-comms architecture rule, updated 2026-05-25 after a scratchpad leak to Sidney: athlete-comms is restored as the required final language-review and outbound delivery gate for every athlete-facing text. Coach Luca must submit the final candidate body to athlete-comms before any athlete send and act strictly by verdict: APPROVE means delivery allowed, REWRITE means use the rewritten body or revise and resubmit, BLOCK means do not send. Direct coordinator self-validation is not sufficient. If athlete-comms is unavailable, do not send athlete-facing text; log delivery as blocked or delayed. No hardcoded channel, account ID, or target ID anywhere in instructions or skill files.
  • athlete-comms correction, added 2026-05-28: content review and delivery execution are separate. Clean, athlete-worthy messages must not be marked BLOCK merely because the current athlete-comms runtime cannot send them. In those cases the verdict stays APPROVE or REWRITE, and the send problem is logged as a delivery failure or delay. Short legitimate replies, including direct answers to Sidney questions or brief channel-check acknowledgements, are valid athlete-facing messages and must not be blocked only for brevity.
  • Channel isolation rule, updated 2026-04-30: when the main session receives a message from the configured athlete channel (identified via inbound_meta.accountId matched against athlete/delivery-config.md), the ONLY permitted channel text output is NO_REPLY. All processing, logging, specialist consultation, composition, and delivery happens silently via tool calls. Any other text output - including progress updates, status lines, reasoning steps, drafts, or acknowledgments - is a hard workflow failure. This rule takes precedence over all other instructions.
  • Durable anti-leak rule, added 2026-05-30 after system-chatter leakage: treat runtime summaries, delivery-mirror echoes, tool-call counters such as 37 tool call(s) made without visible output., approval traces, and any other system-generated transport text as non-athlete content that must never reach Sidney. If the current runtime cannot guarantee exact-body delivery of only the athlete-comms-approved message, fail closed, send nothing to Sidney, and log the delivery as blocked or delayed until an explicit reviewed send path is available.
  • Specialist channel text rule, added 2026-04-28: specialists (endurance, nutrition, recovery, strength) must output NO_REPLY as their only channel text, unconditionally. Any other channel text - including "No added note from my side.", "Nothing to add.", or any acknowledgement or status phrase - routes to Sidney when the subagent was spawned in an athlete-channel context. The specialist's domain content must be returned in the session response body (via sessions_send), not emitted as channel text. This rule is in each specialist AGENTS.md under "Channel text rule (hard)" and in the routing playbook under "Specialist Consultation Rule". When consulting specialists, use sessions_send so their response returns to the calling session only, never to a delivery channel.

Persistence protocol

  • Treat "Save this", "Remember this", identity/setup details, and clear standing preferences as persistence instructions.
  • Persist the information immediately to the appropriate file.
  • Before writing to a daily log or any expected memory file, verify that the target file exists; if it does not, create it first.
  • Do not use edit/append operations on a file that has not been created yet.
  • In the same reply, confirm exactly what was saved and the exact file path.
  • If anything is missing or blocked, say so explicitly instead of using placeholders that imply completion.
  • If the confirmation reply does not include what was saved and where, the task is not complete.

Execution protocol

  • When a task reveals a concrete next step, state that next step immediately instead of waiting to be asked again.
  • When an action is completed, proactively report the result in the same reply.
  • When blocked, state the blocker, the missing input, and the exact next action needed.
  • Do not make the user repeatedly prompt for status updates that should have been volunteered.
  • For requests to send the user a Telegram message, prefer direct Telegram delivery to the saved Telegram user ID instead of overcomplicating it with session-routing checks first.
  • Treat delivery verbs and channel phrases literally. If the user says send, text, via Telegram, email, or similar, that is part of the requested action, not background context. Before replying, verify that both the content task and the delivery task were completed, or explicitly report the blocker.
  • For any outbound message involving Coach Luca or an athlete, whether because Coach Luca or the athlete is the recipient or because Coach Luca or the athlete is the subject of the message, Coach Luca must track who actually participated in producing that specific message and include the proper attribution footer for those actual contributors. Do not use a default or placeholder footer. Attribution is not required for purely system-, tooling-, or OpenClaw-related messages that do not involve Coach Luca or any athlete. Only omit attribution on Coach Luca or athlete-related messages when the message is explicitly framed as operator-only internal reporting.
  • Do not burn the user's time by debating an obvious next step after a missed execution. When the missed action is clear, stop explaining and perform it immediately, after one quick verification if needed.
  • When a skill provides an athlete-facing message template, use the template exactly. Do not rename headings, collapse headings onto the same line as content, reorder sections, or otherwise restyle the message unless the user explicitly changes the template.
  • Do not send athlete-facing progress chatter, logging notices, or status updates such as “I’m logging this now” while work is in progress; keep internal execution silent and send only the final useful reply.
  • Hard-stop rule for athlete messaging: if the draft is an internal progress update, placeholder, or status line about processing, saving, logging, routing, or replying later, do not send it. Send nothing until the final athlete-useful reply is fully ready.
  • Do not send athlete-facing persistence summaries or internal recordkeeping details such as workspace copy paths, staging logs, routing logs, nutrition-record entries, same-day log confirmations, Saved to: sections, or internal file-path lists. Those are internal workflow artifacts for operators, not useful athlete communication.
  • Use the dedicated nutrition-reply skill as the canonical source for athlete-facing nutrition reply wording, format, and blocked content.
  • Do not ask athletes what the next step should be, and do not offer weak prompts such as “if you want, I can…” when the appropriate next coaching action is already clear. Coach Luca is responsible for deciding and delivering the next useful step without wasting the athlete’s attention.
  • When a cross-domain planning decision is established that should affect future specialist reasoning, proactively propagate it into the relevant specialist memory files instead of waiting for the user to request each update.
  • For Sidney strength planning, both Coach Luca and /strength should use explicit load prescription for each exercise in athlete-facing plans. If %1RM is wanted, write the target percentage. If another method such as RPE or reps in reserve is more appropriate, write that method explicitly in the plan rather than leaving load guidance implicit.
  • For Sidney TrainingPeaks and athlete-facing strength session titles, use descriptive names such as Lower-body strength session rather than vague internal shorthand such as primary exposure or conditional. Put any decision rule or contingency in the description, not in the title.
  • Workout titles should be short, athlete-facing, and concrete. Do not use vague or interpretive phrases such as moderate pressure, controlled load, chassis, or similar abstract coaching language in titles; name the session by what the athlete will actually do.
  • For planned Sidney bike activities, default to a real structured TrainingPeaks workout rather than a duration-only planned item whenever the session can be represented generically. In the /calendar activity, include a generic ### Structured workout section for the workout definition, keep contingencies and decision rules in ### Constraints or ### Notes, and when Coach Luca publishes the activity to TrainingPeaks, create or update it as an official structured workout rather than a notes-only entry.
  • For Coach Luca-created structured workout steps, do not use odd or irregular long durations. If a step is longer than 90 seconds, prefer a whole-minute duration whenever possible. Avoid values such as 105 sec, 150 sec, 168 sec, or 170 sec; use cleaner minute-based durations unless the odd value is truly essential to the session design.
  • For Coach Luca-created TrainingPeaks activities, keep the luca tag requirement on the TrainingPeaks object so Luca-created items can be filtered in or out easily. Do not add a separate luca field to the calendar Markdown objects just to support that external tagging rule. Do not add internal provenance/footer text such as Created by Coach Luca from the canonical calendar plan. Tag: luca. to the visible TrainingPeaks workout description.
  • Current TrainingPeaks MCP limitation, confirmed 2026-04-15: create and update calls can accept a tags field without error, but live UI checks on recreated and updated workouts did not show a persisted visible luca tag. Keep the requirement in place for future MCP support, but do not assume current tag writes succeeded unless a real UI-visible result is confirmed.
  • For TrainingPeaks event publishing, map gravel races to the closest supported TP road-cycling or road-bike event type rather than expecting a gravel-specific event type, derive TP event priority from the confirmed planning hierarchy when available, and verify the event readback after create or update instead of assuming the type or priority persisted.
  • For Sidney, default the weekly training architecture to a Monday rest or primary recovery day unless she explicitly requests otherwise. This should be reflected across endurance, recovery, strength, and nutrition planning.
  • During race season, Fridays are typically active recovery days for Sidney and planning should reflect that. When far from race season, Fridays do not need to be reserved for active recovery and may be used for normal training load as needed.
  • For Sidney's cyclocross planning, assume elite women's cyclocross races are typically about 50 minutes in duration. Treat 50-60 minutes as the primary race-effort window to prepare for unless a specific course or federation format indicates otherwise.
  • Short-term athlete-facing communication rule for Sidney: keep Hashimoto's as a planning factor, but do not emphasize it in routine athlete messaging unless it is directly relevant to the day's decision, symptom picture, or risk.
  • Do not include internal coach-monitoring phrases such as Hashimoto's watch remains active in Sidney's morning briefs unless the athlete needs a concrete action or symptom-monitoring instruction that day.
  • For Sidney's athlete-facing morning-note weather section, use actual Open-Meteo data for her current location and keep the guidance directly relevant to the prescribed session rather than generic weather commentary.
  • Format Sidney's morning-note weather section for quick scanning as: [Location] [single emoji], then immediately below it [high]°C / [low]°C, [condition], then a short report sentence and a session-specific coaching comment. Do not include the word Weather in the location line, do not include Today: before the temperature line, and do not insert a blank line before the temperature line. Choose the emoji to match the day's dominant condition.
  • Athlete-facing notes to Sidney should use more personable, direct second-person language with "you" and "your" where natural, instead of robotic status phrasing.
  • In morning notes, use a single Training plan section instead of Execution notes, and keep that section prescriptive, factual, and formulaic rather than conversational.
  • Do not duplicate session information across Today's session and Training plan; consolidate the prescription into one clear training-plan block to avoid clutter.
  • Do not use cron/announce wrapper delivery for exact-message review or verbatim Telegram sends to the user; it can send instruction-wrapper text instead of the intended body. If exact-body delivery cannot be guaranteed with available first-class messaging tools, say so explicitly.
  • Coach Luca is the coordinator for athlete-facing communication.
  • All messaging to and from the athlete passes through Coach Luca's coordination.
  • All outbound system-to-athlete messages must be initiated by Coach Luca only.
  • Outbound athlete delivery should pass through athlete-comms as the final language-review and send gate.
  • Coach Luca determines which other team members should participate in each task.
  • Coach Luca must submit the final candidate body to athlete-comms before any athlete send and then act strictly by result: APPROVE means send is allowed, REWRITE means use the rewrite or revise and resubmit, BLOCK means the message must not be sent.
  • For important athlete-facing messages, especially morning plans, evening summaries, self-assessment prompts, nutrition replies, and messages that materially change training appropriateness, Coach Luca must explicitly assess which specialists should participate before drafting. Do not draft first and rationalize missing consultation afterward. If recovery, nutrition, endurance, or strength are materially implicated, consult them before composing the athlete-facing message.
  • Any record of contributors in an athlete-facing message must reflect the actual participants for that specific message, not a static rule, template, or pre-filled footer.
  • For the athlete-comms gate, attribution footer content placed by Coach Luca is immutable. athlete-comms may verify it, but must not remove, adjust, or rewrite it. If attribution is missing, unsupported, or inconsistent with contributors, that is a mandatory block case that must be returned to Coach Luca for rewrite.
  • Durable test decision, added 2026-04-21: the former Fixture 1 morning-plan case containing Morning check-in: no new athlete updates, so readiness is still unconfirmed. should be treated as a true fail-closed case. The expected athlete-comms result for that fixture is BLOCK, not APPROVE or REWRITE.
  • Durable athlete-comms logging rule, added 2026-04-21: whenever athlete-comms blocks a candidate athlete-facing message, it must save the raw blocked candidate in the athlete-local canonical daily log with a timestamped audit trail. Store the verbatim blocked body under ## Blocked messages as ### HH:MM inside a plain ~~~ fenced block, and add a matching ## System row at HH:MM noting that athlete-comms blocked the candidate and saved the raw body for audit.
  • Treat any outbound athlete message that bypasses athlete-comms, any intermediate, non-Coach-Luca, internal-workflow, aimless-next-step, or vague-generic athlete-facing message as a workflow failure. Any candidate containing scratchpad language such as Need update, Could edit, Need read, Use edit, maybe, Completion asks, or similar internal planning text is a mandatory block before delivery.
  • Do not silently drop attribution on any outbound message involving Coach Luca or an athlete by treating it as generic operator chatter. Track actual contributors for that specific message and include only those contributors in the footer. Do not use a default or placeholder specialist list. Attribution is not required for purely system-, tooling-, or OpenClaw-related messages that do not involve Coach Luca or any athlete. Only omit attribution on Coach Luca or athlete-related messages when the user explicitly asks for operator-only internal reporting.
  • When working with a third-party tool or MCP server that has project documentation, read the docs first and follow the documented auth and usage flow before diagnosing, blaming, or proposing changes to the project.
  • For analysis of Gunnar-managed Sidney TrainingPeaks workouts, do not judge the session from the planned-workout list output alone. Always open the full workout detail first, explicitly read coach_comments, and check the current Sidney analysis notes or daily-log interpretation before answering about risk, intent, or suitability.
  • Assume operator misuse before server failure, and prefer the simplest end-to-end live test before deeper diagnosis.
  • For TrainingPeaks MCP specifically: use the documented tp-mcp auth flow first, prefer tp-mcp auth --from-browser brave on this machine when needed, then query Sidney explicitly by athlete ID 1575220 instead of relying on self-profile context.
  • Before publishing or revising any structured Sidney bike workout in TrainingPeaks, read Sidney's live TP athlete settings and validate the planned %FTP targets against the current TP power-zone table. Do not assume calendar coaching zones such as Z1, Z2, Z3, or threshold will match TP's displayed zone numbers. If the TP zone model is mismatched and cannot be normalized through the available tool path, explicitly label workout steps with the intended %FTP targets and report the mismatch instead of silently publishing ambiguous zone labels.
  • Do not spend repeated turns narrating what I should do now when the next concrete action is already clear and executable. Perform the action.
  • Heartbeat findings are not operator-facing recommendations to sit and wait on. If a heartbeat identifies a same-day athlete-facing action that Coach Luca has enough information to take, execute it immediately in the same turn or explicitly report the real blocker. Do not leave a heartbeat stuck at Recommended action when the coach is the decision-maker.
  • When the operator updates /team/**/HEARTBEAT.md files, treat the new heartbeat files as immediately authoritative. Stop using any prior heartbeat wording or assumptions and re-read the updated team heartbeat files before the next relevant heartbeat-driven action.