Repository navigation
feat(mental-models): scheduled full refresh for delta models - #5674
Merged
Merged
Conversation
A delta mental model can now be rewritten from scratch without leaving delta mode:
- POST /mental-models/{id}/refresh takes an optional {"mode": "full"} for a one-off
full refresh. The stored trigger is untouched, and a failed full refresh keeps the
previous content (unlike clear + refresh). A full submit that folds into a queued
plain refresh upgrades it.
- trigger.full_refresh_cron: an independent schedule, combinable with
refresh_after_consolidation or refresh_cron. It runs in the existing cron scan,
comes due against a new mental_models.last_full_refreshed_at, and is skipped when no
refresh ran since the last full one. Min interval and failure pause apply as usual.
- Migration d4f7a2c9e1b5: the column, a partial index, and mental_models_with_cron()
returning the full-refresh schedule (owned-routine safe).
- Control plane: scheduled full refresh row in the trigger form, 'Full refresh now'
with a token-cost confirm, 'Last full refresh' in the detail view, 10 locales.
- CLI (refresh --full, --trigger-full-refresh-cron), Python/TS wrappers (mode),
MCP trigger field, regenerated OpenAPI + SDKs, docs with tested examples.
- Tests: api-slim (scheduler, fold upgrade, engine, HTTP), system story 39,
control-plane form, CLI, wrapper mapping on both sides.
… automatic triggers are listed - http.py: min_refresh_interval_seconds, last_refresh_failed_at and the page trigger descriptions now list full_refresh_cron alongside the other automatic triggers. - memory_engine: _REFRESH_AUTOMATIC_KEY comment no longer claims to be the only payload key a fold reconciles. - docs: rate-limit, failure-pause and keep_trace paragraphs name full_refresh_cron. - test: say why _queued_payload reads async_operations directly. - regenerated OpenAPI, TS types and docs skill.
- migration d4f7a2c9e1b5 now follows b2429c65cc20 (main gained a migration; one head). - regenerate bank-template-schema.json for trigger.full_refresh_cron (verify-generated-files). - test_refresh_outcome_metadata: the refresh stub accepts the new mode kwarg the worker handler now passes.
nicoloboschi
force-pushed
the
feat/scheduled-full-refresh
branch
from
October 16, 2026 15:42
245a685 to
67c0e36
Compare
This was referenced Oct 20, 2026
Merged
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.
Closes #4340.
A delta mental model can now be rewritten from scratch — once on demand, or on its own schedule — without stopping being a delta model. Delta keeps unchanged sections byte-for-byte; over months of small edits a document drifts from what a fresh write would say. This gives users the "edit incrementally, rewrite weekly" pattern the issue asks for.
What changes
One-off full refresh —
POST /mental-models/{id}/refreshtakes an optional body{"mode": "full"}.trigger.modeis untouched; the next plain refresh is a delta again._upgrade_queued_refresh_to_full), so "full" is never silently dropped by dedupe.Scheduled full refresh — new
trigger.full_refresh_cron(UTC, 5-field).refresh_after_consolidationandrefresh_cron— combine with either.MaintenanceLoop._run_scheduled_mm_refresh): same croniter due check, tenant routing,skip_if_in_flight,automatic=True(so the min-interval floor and the failure pause apply).mental_models.last_full_refreshed_at, notlast_refreshed_at(every delta moves that one, so a weekly full refresh would never fire on a model that deltas daily).Migration
d4f7a2c9e1b5— the column (PG + Oracle), a partial index on the new predicate, andmental_models_with_cron()recreated to also return full-refresh-only models (guarded byexecute_unless_owned; the loop reads the new columns optionally so an operator-owned routine keeps working).Surfaces
mental-model refresh --full,--trigger-full-refresh-cron.mode="full"/{ mode: "full" }. MCP trigger field. OpenAPI + all SDKs regenerated.Tests
test_39_full_refresh.py: a delta model's full refresh through the client — a dropped override would hit the unscripted delta-merge step and fail.