Conversation
…ly a running token verify_owner_tx rejects writes once the workflow is terminal or the request inactive, so an orchestrator cannot overwrite a durable cancellation. Admission re-admits the same token only while it is the running owner of an active request; a released token is admitted as a new owner. Release results no longer report ownership changes nobody consumes.
…rity The synchronous path called a separate epoch function under the caller's scope, which required a new funcs.call grant from existing consumers. The orchestrator entry now carries the epoch reader group, merged into whatever scope it runs under, and reads the epoch itself on every path. Admission and state-creation failures give up the canonical name, a same-runtime owner that lost its name is reported as such, and the unreachable ownership-change projection branches are removed.
…ve holders, bound pre-admission restarts - A monitored owner is woken once for every durable generation it has not been woken for, so a request whose COMMIT message was lost, or a deadline promoted before an overseer restart, still reaches the live owner. - An inactive activation stops nobody: a released owner exits by itself and any other name holder is refused admission or admitted by a newer request, so a stale observation can no longer cancel an admitted successor. - Spawns for one unchanged ownership state are bounded; an orchestrator that keeps exiting before admission fails the activation instead of respawning. - runtime_failure_test kills the orchestrator only after its admission; the overseer is also exercised against real ownership rows. - Remove the unused wake_repo, the pid_for helper and duplicated literals.
… due A due wake that could not be promoted made the loop arm time.after(0), which returns no channel, and crashed the overseer on every restart. The loop now promotes a due wake immediately and arms a timer only for a future one. Due promotion discards the wakes of a dataflow that no longer exists, which SQLite leaves behind because it does not enforce the cascading foreign key; tests remove their dependent rows explicitly for the same reason.
…greSQL The PostgreSQL driver renders TIMESTAMPTZ without fractional seconds, so the overseer saw a wake as due up to a second before the database did and armed no timer for it; exact deadlines then waited for the safety scan. The deadline is now formatted in SQL at the stored precision.
… wake - Spawns for one unchanged ownership state wait 1s, 2s, 4s and 8s between attempts, so a transient outage recovers; after five the activation fails with orchestrator_start_failed. The exhausted budget is kept until that failure is durable and the observed state changes, so a failed write never reopens it. - The service loop promotes due wakes and then arms a timer for the nearest wake that is not yet due, so a due wake that cannot be promoted never hides a later one and the loop does not spin on it. - DELETE_WORKFLOW removes the activation row explicitly, as it already did for wakes, since SQLite does not enforce the cascading foreign keys; due promotion no longer discards wakes of a missing dataflow. - Document the epoch_reader group for callers with explicit env.get denies.
Each iteration settles everything that is overdue, due wakes and deferred start retries alike, repeating while it makes progress, and then arms one timer for the earliest deadline still ahead. Deadlines are read from pending rows rather than bounded by a freshly sampled now, so a wake or retry that falls due during the pass is processed before the loop blocks. A due item that makes no progress is skipped until the next event or safety pass instead of hiding later deadlines. Start budgets are retired when the observed ownership changes, including admission, and after a durable start failure; a retry deadline exists only while a spawn is deferred.
…; prove upgrades from an older release - Migration 11 deletes activation and wake rows without a workflow, which releases before 10_add_activation_ownership left on SQLite. - restart-proof.sh takes DATAFLOW_RESTART_FROM: the first runtime runs that older release, the second upgrades its database in place. On SQLite the proof seeds rows of a deleted workflow and checks the upgrade removes them; it also checks the recovered owner record. Duplicates are counted against the workflows present before the restart, since the first runtime's probe can race its migrations. - make test-upgrade-sqlite / test-upgrade-postgres (UPGRADE_FROM, default v0.7.19) run it outside the default test target.
…pass on an absolute schedule - When settle exhausts its pass budget while still making progress, the next deadline is now, so draining continues on the next iteration after pending events instead of waiting for the safety pass. - The safety deadline is absolute and advances only when the safety pass runs; it is part of the single deadline timer, so deadline events cannot postpone it. The safety pass clears the excluded items. - A pending wake whose deadline cannot be read counts as progress, so a page of such rows cannot hide later valid wakes. register_yield_wake_tx rejects a deadline that is not an RFC 3339 time, since SQLite stores it as text.
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.
Fixes the overseer/orchestrator race: a released or dead orchestrator's name, EXIT and wake signals racing a new spawn.
Ownership model
owner_token,owner_pid,owner_phaseandowner_epoch(the runtime epoch);load_state. It refuses terminal or inactive activations, stale requests, and a running owner from the same runtime.commit.execute. Terminal workflows and inactive requests are rejected inside the locked check. Passivate and complete are fenced by token, phase and generation.Overseer
Loop and restart handling
orchestrator_start_failed.Security
epoch_readergroup, which is merged into the caller's scope.Data cleanup and fixes
DELETE_WORKFLOWdeletes the activation row explicitly; SQLite does not enforce the FK cascade.Tests
M.runloop tests with an injected clock.restricted_caller_testwith a realistic consumer scope.runtime_failure_testnow waits for durable admission.make test-upgrade-{sqlite,postgres}(UPGRADE_FROM=v0.7.19).Verification
Reviewed over five rounds by Codex Astra and Fable; both approve.