Skip to content

feat(elos): morning coach from the learner snapshot, scheduled by Hermes - #23

Merged
eulogep merged 1 commit into
mainfrom
feat/morning-coach
Oct 23, 2026
Merged

eulogep merged 1 commit into
mainfrom
feat/morning-coach

Conversation

@eulogep

@eulogep eulogep commented Oct 23, 2026

Copy link
Copy Markdown
Owner

Summary

Deterministic morning message (no model, no network) from the learner snapshot: streak, workload, retrieval question on the top difficulty, English word of the day, roleplay line, exam countdown. scripts/morning-coach.ts writes coach-du-jour.md and can notify on macOS; Hermes schedules it with cron create --script --no-agent (docs in docs/integrations/HERMES.md).

Test plan

  • 3 unit tests (content, stale/missing snapshot, determinism and rotation); npm test 645/645, typecheck, eslint .
  • Run on a real snapshot

🤖 Generated with Claude Code

Deterministic message (no model, no network): streak, cards and words
due, a retrieval question on the top difficulty, English word of the day
with example, a roleplay line with its task, exam countdown with advice.
scripts/morning-coach.ts writes it to coach-du-jour.md next to the
snapshot and can show a macOS notification; Hermes runs it with
`cron create --script --no-agent`. Stale or missing snapshots are stated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
daily-english-mission Ready Ready Preview Oct 23, 2026 5:29am UTC

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ecbe0a98-7628-499e-b9a0-510a5e79e5df
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T05:32:55.846827Z c71d292 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@eulogep
eulogep merged commit 1bf28af into main Oct 23, 2026
5 checks passed
@eulogep
eulogep deleted the feat/morning-coach branch October 23, 2026 05:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c71d2928b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +25 to +27
const today = snapshot.today;
const index = dayIndex(today);
if (now.getTime() - Date.parse(snapshot.generatedAt) > STALE_MS) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject prior-day snapshots before reporting today's plan

When ELOS was last opened the previous evening, the snapshot can be less than 24 hours old and therefore trigger no warning, but snapshot.today, dueToday, dueWords, and daysLeft still describe yesterday. The 08:00 job then labels yesterday's workload as today's, repeats the previous word, and reports a stale exam countdown beneath a header generated from the current date. Compare snapshot.today with the current local calendar day and require a refresh or avoid presenting its date-dependent fields as current.

Useful? React with 👍 / 👎.

Comment on lines +80 to +81
Avec une messagerie configurée dans Hermes (`hermes gateway setup`), remplace `--deliver local` par `telegram`,
`signal`… Le contenu (vocabulaire, jeux de rôle, intitulés de notions) est générique ; aucun passage de cours n’y figure.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Warn before forwarding snapshot-derived labels

For learners with imported personal course documents, the message is not entirely generic: it includes studio.difficulties[].term, which is derived from those documents, and the exam course name. Hermes' --no-agent mode delivers script stdout verbatim, so replacing local with Telegram or Signal forwards these labels to an external service despite the assurance here. Disclose the exact fields and obtain informed authorization, or redact snapshot-derived labels for external delivery.

AGENTS.md reference: AGENTS.md:L14-L14

Useful? React with 👍 / 👎.

Comment thread scripts/morning-coach.ts
const file = process.env.ELOS_STATE_FILE ?? path.join(process.env.HOME ?? "", "ELOS-Hermes", "elos-state.json");
let snapshot: LearnerSnapshot | null = null;
try { snapshot = parseLearnerSnapshot(readFileSync(file, "utf8")); } catch { snapshot = null; }
const message = buildMorningMessage(snapshot, new Date());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle nested snapshot corruption in the fallback

The surrounding try handles only reading and parsing, while parseLearnerSnapshot accepts structurally incomplete same-version values such as dailyEnglish: {} and studio: {}. Passing that value here makes the builder throw on fields such as cards.length, so the scheduled job exits without writing or delivering the intended missing-snapshot fallback. Include message construction in the recovery path or validate the complete nested schema before returning it.

AGENTS.md reference: AGENTS.md:L30-L31

Useful? React with 👍 / 👎.

This branch was successfully deployed

1 active deployment
Preview — c71d2928 Deployed Oct 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant