Skip to content

Harden consistency and reliability (single-instance) - #2

Merged
FrancescoCoding merged 1 commit into
masterfrom
claude/oak-consistency-hardening
Jun 30, 2026
Merged

FrancescoCoding merged 1 commit into
masterfrom
claude/oak-consistency-hardening

Conversation

@FrancescoCoding

Copy link
Copy Markdown
Owner

Summary

Makes the agent way more consistent and closer to public-ready, keeping the single-user / single-instance design (no distributed store). The theme: move consistency-critical behaviour from prompt-only into code, and remove silent-failure / data-loss paths. Planned and scoped with the maintainer; this is the recommended first batch.

Behavioural guardrails (consistency now code-enforced)

  • sync-dashboard (scripts/notion.mjs): re-derives the This Week, Goals, and Body Stats tiles directly from the databases. Counts and values come from queries, never the model, so the Dashboard can't drift or carry fabricated numbers. The coach runs one deterministic command after any data change instead of hand-building three tiles. --now <YYYY-MM-DD> takes the chat-header date so "this week" is timezone-correct.
  • Write validation: select/multi_select/status values are checked against the live schema and RPE is range-checked (1–10), failing locally with the valid options instead of writing a miscategorised or impossible row. Adds log --dry-run to read a parsed row back before committing.
  • Deterministic session-context line: runner.ts injects Notion/workspace status and whether PERSONAL.md is filled in, into every prompt — so onboarding facts are present even on resumed sessions rather than depending on the model to fetch them.
  • Fast tier is opt-in (FAST_TIER_ENABLED, default off): every message uses CLAUDE_MODEL by default for consistent behaviour; enable it to route trivial logs to the cheap model.

Runtime reliability (no silent failure, no data loss)

  • Atomic writes everywhere: a shared writeJsonAtomic() (temp + rename) for sessions, the schedule, and the Notion id caches, so a crash mid-write can't truncate state into a silent reset (which previously reseeded defaults or re-created databases).
  • Transient retry: runner.ts retries the agent query with backoff on transient startup errors — only before a session is established, to avoid duplicate Notion writes — and broadens subscription-cap detection.
  • Append-then-delete tile refresh: a failed refresh leaves the old tile intact rather than wiping it empty.
  • Fail-fast config: webhook mode now refuses to start without PUBLIC_BASE_URL and CRON_SECRET, so /cron/run is never left unauthenticated.
  • Scheduler warns on duplicate task ids instead of silently overwriting.

Tests + CI

  • Extended scripts/notion.test.mjs to 26 tests covering value validation and the pure dashboard-tile renderers.
  • Added .github/workflows/ci.yml running npm ci, npm run build (strict tsc), and npm test on push/PR.

Docs

CLAUDE.md, the notion-formatting skill, docs/configuration.md, and .env.example updated for sync-dashboard, FAST_TIER_ENABLED, and the webhook requirements.

Verification

  • npm run build (strict tsc) — green.
  • npm test — 26/26 pass.
  • Both Notion scripts pass node --check; sync-dashboard is wired into the command table.

Out of scope (by decision)

Multi-user / multi-instance and a shared session/schedule store. The single-instance constraint stays; fail-fast config makes it explicit and safe rather than silent. Follow-up tier (ffmpeg timeout, attachment feedback, hard message-split, SECURITY.md, package metadata, wider redaction) can land in a second PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XvGkxgFtZB4DfNAVkFwx54


Generated by Claude Code

Moves consistency-critical behaviour from prompt-only into code, and removes
silent-failure / data-loss paths, keeping the single-user design.

Behavioural guardrails:
- notion.mjs `sync-dashboard`: re-derives the This Week, Goals, and Body Stats
  tiles directly from the databases (counts/values come from queries, never the
  model), so the Dashboard cannot drift or carry fabricated numbers. The coach
  now runs one deterministic command after any data change. `--now` takes the
  chat-header date so "this week" is timezone-correct.
- notion.mjs writes now validate select/multi_select/status values against the
  live schema and range-check RPE (1-10), failing locally with the valid options
  instead of writing a miscategorised or impossible row. Adds `log --dry-run`.
- runner.ts injects a deterministic context line (Notion/workspace status,
  PERSONAL.md filled-in state) into every prompt, so onboarding facts are present
  even on resumed sessions instead of relying on the model to fetch them.
- Fast model tier is now opt-in (`FAST_TIER_ENABLED`, default off), so default
  behaviour is consistent; every message uses CLAUDE_MODEL unless enabled.

Runtime reliability:
- Shared writeJsonAtomic() (temp + rename) for sessions, schedule, and the Notion
  id caches, so a crash mid-write can't truncate state into a silent reset.
- runner.ts retries the agent query with backoff on transient startup errors
  (only before a session is established, to avoid duplicate writes) and broadens
  subscription-cap detection.
- Dashboard tile refresh is now append-then-delete, so a failed refresh leaves the
  old tile intact rather than empty.
- Startup fails fast in webhook mode when PUBLIC_BASE_URL or CRON_SECRET is unset,
  so the service never runs with an unauthenticated /cron/run.
- Scheduler warns on duplicate task ids instead of silently overwriting.

Tests + CI:
- Extends scripts/notion.test.mjs (26 tests) covering value validation and the
  pure dashboard-tile renderers.
- Adds .github/workflows/ci.yml running build + test on push/PR.

Docs: CLAUDE.md, notion-formatting skill, configuration.md, and .env.example
updated for sync-dashboard, FAST_TIER_ENABLED, and the webhook requirements.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XvGkxgFtZB4DfNAVkFwx54
@FrancescoCoding
FrancescoCoding merged commit 9372ef1 into master Jun 30, 2026
1 check passed
FrancescoCoding added a commit that referenced this pull request Jul 19, 2026
…dening

Harden consistency and reliability (single-instance)
@FrancescoCoding
FrancescoCoding deleted the claude/oak-consistency-hardening branch July 19, 2026 19:46
FrancescoCoding added a commit that referenced this pull request Jul 19, 2026
…dening

Harden consistency and reliability (single-instance)
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.

2 participants