th pearls: schedulable pearls that speak up in the prime hook when due#176
Merged
Conversation
Pearls gain an optional scheduled_at so a work item can be set aside now and resurface itself later, instead of being lost in the backlog until someone re-reads it. - `th pearls schedule <id> <when>` sets it; omit <when> to clear. <when> is relative (+2h / 30m / 2d / 1w / tomorrow / now, leading `-` allowed for past) or absolute (2026-07-10, 2026-07-10 09:00, RFC3339), parsed as UTC. - `th pearls due` lists pearls whose time has arrived (scheduled_at <= now, not closed, soonest-first). - The prime hook (SessionStart/PreCompact) now prints a "⏰ Scheduled & due" section above "Ready to work" — a scheduled pearl automatically speaks up at the next session start once it comes due. `show`/`ready`/`list` render a ⏰ marker. Storage mirrors closed_at (nullable DATETIME, idempotent ADD COLUMN IF NOT EXISTS migration). Due comparison uses a Rust Utc::now() literal, NOT Dolt NOW() — Dolt NOW() returns server-local time while scheduled_at is stored UTC, so `<= NOW()` would be off by the local offset. Regression test guards it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: ff431e8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A pearl you want to revisit later (after a deploy, next week, in 2h) has no way to resurface on its own — it just sits in the backlog until someone re-reads the whole list. Brent asked for pearls to "start speaking up in hooks when a scheduled pearl is up."
Solution
Add an optional
scheduled_atto pearls and surface due ones through the existing session-priming hook.th pearls schedule <id> <when>— set it; omit<when>to clear.<when>is relative (+2h,30m,2d,1w,tomorrow,now; leading-= past) or absolute (2026-07-10,2026-07-10 09:00, RFC3339), parsed as UTC.th pearls due— pearls whose time has arrived (scheduled_at <= now, not closed, soonest-first).th primenow prints a⏰ Scheduled & duesection aboveReady to work, so a scheduled pearl automatically speaks up at the next session start / compaction once it comes due.show/ready/listrender a⏰marker.Storage mirrors
closed_atexactly (nullableDATETIME, idempotentADD COLUMN IF NOT EXISTSmigration for existing Dolt stores).The one non-obvious bit
Due comparison uses a Rust
Utc::now()literal, not DoltNOW(). Dolt'sNOW()returns the server's local time whilescheduled_atis stored as UTC, soscheduled_at <= NOW()was off by the local UTC offset (a pearl 1h in the past read as not-yet-due on an EDT box). Caught in end-to-end smoke; a store-level regression test (test_due_scheduled_uses_utc_not_dolt_local_now) guards it with a ±1h window that would flip under the bug.Verification
cargo test -p smooai-smooth-cli -p smooai-smooth-pearls -p smooai-smooth-diver→ 469 passed. New tests:schedule_tests::{relative_offsets,keywords,absolute_forms,garbage_is_rejected}(parser) +test_due_scheduled_uses_utc_not_dolt_local_now(TZ-correct query).cargo fmt --checkclean,cargo clippyclean on touched crates.-1hpast → due + surfaced in prime;+90mfuture → not due; clear → gone; absolute past date → due.docs/Engineering/Using-th-CLI.md).🤖 Generated with Claude Code