Repository navigation
feat: add proactive Astra item engine - #725
Conversation
There was a problem hiding this comment.
Caution
Three high-priority issues need fixes before merging: bad-habit abstinence produces return-to-habit guidance, completed flexible quotas still produce reminders, and the migration breaks old-instance account resets during deploy overlap.
Reviewed changes Reviewed the persistent proactive engine, all six triggers, delivery and lifecycle handling, migration, API contracts, and tests.
- Persistent lifecycle: Adds proactive items, calendar read claims, outcome timestamps, rest periods, goal cooldowns, and daily push uniqueness.
- Hourly evaluation: Replaces the old scheduler with local-time trigger evaluation, batched facts, calendar checks, and analytics.
- Client operations: Adds authenticated current/opened/acted endpoints and corresponding agent catalog capabilities.
- Messages and settings: Adds grounded localized generation and fallback actions, nullable stored preferences, and additive export fields while retaining public boolean settings.
- Verification: Focused proactive suites passed: 70 infrastructure, six application, and seven domain tests. Separate SQLite probes reproduced the bad-habit and completed-flexible failures; the full solution suite was not rerun.
gpt-6.1-sol | 𝕏
Keep the legacy check-in ledger during deploy overlap, exclude slips and bad habits from restart and action prompts, and honor flexible habit quotas during creation and current-item revalidation.
|
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed 62e3bf4e, the commit added since the prior Pullfrog review, and confirmed that the three resolved findings are addressed.
- Retained rollout compatibility: Preserved
SentProactiveCheckinsin the migration and EF models so previous instances can continue using the ledger during deployment overlap. - Separated habit semantics: Excluded bad habits from positive-action guidance and excluded slips from successful restart activity while preserving weekly slip reporting.
- Applied flexible quotas: Reused the quota-aware scheduling helper with the owner's week start for item creation and current-item revalidation.
- Verified regressions: Passed all 57 focused engine, migration and account-reset tests, then all 114 tests in the broader proactive, account-cleanup and catalog selection. The full solution suite was not rerun in this review.
gpt-6.1-sol | 𝕏




Implements thomasluizon/orbit-tickets#1477 with persistent proactive Astra items, six hourly local-time triggers, push limits and recorded outcomes.
Change and approach
ProactiveItem,ProactiveCalendarDayandProactiveRuleshold the lifecycle, persisted calendar-read claim and named trigger thresholds.OrbitDbContextand the replacement migration removeSentProactiveCheckins, add cascade deletion and enforce one item per trigger per local day plus one pushed item per local day. The migration also removes the historical database default of false while preserving stored choices.ProactiveEngineServicebatches eligible users and facts, evaluates the six triggers, enforces priority, push limits and rest periods, and records outcomes and PostHog events. A scoped engine serves the hourly scheduler and current-item revalidation. Both background-job registrations replace the old scheduler while retaining its recurring-job identity.ProactiveAstraControllerdispatches the current, opened and acted operations through Application handlers and validators. Owner checks return 404, and first timestamps are idempotent.AiProactiveCheckinMessageServiceserves all triggers with English and pt-BR templates, a temperature of 0.3 and conservative output validation. Tests stub the repository-owned completion port instead of inventing provider response payloads.AgentContracts.csandAgentCatalogService.Capabilities.csdeclares dedicated proactive read and outcome capabilities for the three controller actions, using notification scopes and no agent tools. Restart facts explicitly store the scheduled-yesterday, positive-logs-yesterday and recent-activity predicates inProactiveFacts.csandProactiveEngineService.cs.openapi.jsonis regenerated.Assumptions
Retained the ledger through an EF model-only mapping rather than restoring its retired domain entity or scheduler. The later contract migration belongs to #1491.
Test evidence
dotnet test tests/Orbit.Infrastructure.Tests --no-build --no-restoreexited 0 with 3,308 passed and none failed.dotnet test tests/Orbit.Application.Tests --no-build --no-restoreexited 0 with 5,460 passed and none failed.dotnet build Orbit.slnxexited 0 with zero errors and 18 existing warnings.dotnet test tests/Orbit.Domain.Tests --no-build --no-restoreexited 0 with 668 passed and none failed.dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter 'FullyQualifiedName~AgentCatalogServiceTests|FullyQualifiedName~Proactive'exited 0 with 91 passed, including the controller coverage check and the strengthened restart case.dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter 'FullyQualifiedName~Proactive|FullyQualifiedName~AccountDeletionServiceDbTests|FullyQualifiedName~NotificationVoiceTests': 202 passed.dotnet test tests/Orbit.Infrastructure.Tests --no-build --filter FullyQualifiedName~BusyCalendar_DurationThresholdAndAllDayExclusionpassed unchanged with the defect present. The strengthened commanddotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter 'FullyQualifiedName~BusyCalendar_DurationCountsElapsedHoursAcrossDst|FullyQualifiedName~WeeklyReview_IncludesWeeksWithOnlyBadOrChildHabits'failed three cases: three elapsed hours instead of four, and missing weekly items. After correcting the child fixture to use a scheduled parent with a future due date,dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter FullyQualifiedName~WeeklyReview_IncludesWeeksWithOnlyBadOrChildHabitsstill failed the child case before removing the parent-only filter. All these cases pass in the 202-test focused run after the fixes.dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter FullyQualifiedName~Migration_OnlyRelaxesStoredSettingAndReplacesTheLedgerthen failed because the old default was null instead of false. It passes after correcting the migration metadata.dotnet ef migrations script 20261001074038_AddHabitSkipUndo 20261017083409_ReplaceProactiveCheckinsWithItems --project src/Orbit.Infrastructure --startup-project src/Orbit.Api --no-buildinitially emitted onlyDROP NOT NULLfor the setting; after the fix it also emitsDROP DEFAULT.dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter 'FullyQualifiedName~EachTrigger_RequiresItsConditionAndWindow|FullyQualifiedName~EveryControllerAction_IsMappedToTheCatalog'exited 1 before changes: the six unchanged trigger cases passed with the missing facts, while the catalog test failed for Current, Opened and Acted.dotnet test tests/Orbit.Infrastructure.Tests --no-restore --filter FullyQualifiedName~EachTrigger_RequiresItsConditionAndWindowexited 1 with five passes and the restart case failing at the missingHadScheduledHabitsYesterdayproperty. Restart green: the same command exited 0 with all six cases passing after persisting the three supporting predicates.Focused command:
Unchanged tests passed with defects present: 45 passed. Repeated with
--no-restoreafter strengthening tests: 12 failed, 45 passed before fixes; 57 passed afterward.Regression evidence:
Migration_OnlyRelaxesStoredSettingAndExpandsTheLedger,Migration_DownLeavesTheRetainedLedgerUntouched,Models_RetainTheLegacyLedgerUntilTheContractMigrationBadHabitOnly_WithRecentSlipAndAbstinenceYesterday_NeverPromptsStartingOrResuming,RestartAfterMiss_OnlyCountsSuccessfulActivity, correctedWeeklyReview_IncludesWeeksWithOnlyBadOrChildHabitsFlexibleQuota_UsesTheOwnersWeekStartBeforePrompting,Current_ResolvesFlexibleItemWhenQuotaIsMetOnAnotherDayAdditional verification:
dotnet build Orbit.slnx --verbosity minimal: 0 errors.dotnet test Orbit.slnx --no-build --no-restore --verbosity minimal: 9,480 passed.npm_config_yes=false npx turbo run type-check --force: unavailable because Turbo is absent; no package installed.External interface evidence
No new provider response fields are read. The engine consumes the repository-owned calendar, token and AI completion interfaces. PostgreSQL migration behavior was checked through the actual EF-generated SQL, including the missing and then present default removal. No new external response fixture was authored.
Eval scenarios for #26
Run each scenario in English and pt-BR, requiring one sentence of at most 140 characters, only supported facts, no sales language, and feminine agreement when Astra refers to herself in pt-BR:
behindorat_riskstatus; do not invent progress, velocity or a different goal.Deploy the completed API before thomasluizon/orbit-tickets#1481. The operational kill-switch key is
astra_proactive_engine_disabled.Existing
System.Security.Cryptography.Pkcsadvisories are tracked separately in thomasluizon/orbit-tickets#1488.Manual steps
None. The existing startup migration path applies the expand migration.