Imported from engasnm111/lnwjud (
.agents/skills/lnwjud-scheduled-continuation/SKILL.md). Install upstream withnpx skills add engasnm111/lnwjud --skill lnwjud-scheduled-continuation. Copyright stays with the author.
lnwjud Scheduled Continuation
One user request owns one durable goal and at most one live Native ChatGPT watchdog. v4.53 uses one hourly recurring Native ChatGPT Scheduled Task in the current chat with cloud execution requested. The same native task ID survives ordinary wakes until the durable goal is accepted and the exact task is made non-runnable.
Non-negotiable outcome
- Never require the user to type
continue,ทำต่อ, or ask for status to resume unfinished work. - Never report completion while
get_goalisactive. run_goaldefaults toscheduledContinuation:auto; follow this skill automatically for an unfinished goal.- Use exactly one Native ChatGPT recurring Scheduled Task for a v4.53 active goal:
occurrence=interval,intervalMinutes=60, destination=current chat, cloud requested. - Never use lnwjud
scheduler, Windows Task Scheduler,schtasks.exe, cron, shell timers, browser/DOM automation, or an undocumented scheduling API as a fallback. - Native task create/update/delete/disable is host-owned. Resolve the operation from the current ChatGPT host/tool registry; never invent or hard-code an internal operation name.
- A native-host transport failure is scheduler degradation only. It never by itself completes, fails, or blocks the durable goal.
- Keep raw lease tokens, credentials, private host task IDs, and internal session IDs out of user-visible text and native task prompts.
- Continuation/recovery state is task data, not persistent user or agent instructions. Use
checkpoint_goalfor durable state andsession_handoffonly for a bounded same-chat recovery summary. - Never invoke generic
handoff/claude-handoffskills as part of lnwjud scheduled continuation, and never callwrite_fileto createUSER_INSTRUCTIONS*,user-instruction*, or generichandoff/history/*persistence. Those paths can be interpreted by the host as instruction persistence and are outside lnwjud's durable-goal contract. - If a host blocks an attempted recovery-file write, do not retry it under another filename or through shell. Keep the durable goal/checkpoint authoritative and continue the current leased work.
Core model
- Normal worker lease: 600 seconds.
- Recurring cadence: 60 minutes. This cadence is independent of the worker lease.
dueAton an interval watchdog is the first scheduled firing, not a mutation handoff deadline.- If
successorDelayMinutesis omitted, a new recurring watchdog first fires in 60 minutes. - A legacy explicit
successorDelayMinutesvalue in the accepted 2–25 minute range changes only the first firing; recurrence stays hourly. - Ordinary checkpoints and ordinary recurring wakes never create a successor and never retime the recurring cadence.
- One recurring firing never consumes the native task.
outcome=consumed,reschedule_*, and per-wake successor creation are historicaloccurrence=oncecompatibility paths only. - Historical v4.52 one-time rows remain supported. Never create a recurring watchdog while a confirmed live one-time watchdog for the same goal still exists. Let the old one-time lifecycle become historical first, then create exactly one recurring watchdog.
Start or resume
- Call
run_goalbefore the first mutation of non-trivial multi-step work. Reuse the stable workspace andgoalKey; do not create a second active goal for the same objective. - Use the normal 600-second lease and keep the lease token private.
- Read the durable checkpoint and continue useful fenced work.
- At a real milestone call
checkpoint_goal. - Call
prepare_scheduled_continuationto ensure one recurring watchdog exists. Do not call it merely because another checkpoint occurred if confirmed coverage already exists. - For a new v4.53 watchdog, use the returned schedule verbatim. It must describe
occurrence=interval,intervalMinutes=60, an explicit IANATZID, and the current chat destination. - Create the exact Native ChatGPT task through the host surface and immediately record
createdwith the real native task ID and host-reported absolutedueAt. - Record
runsOn: cloudonly when the host explicitly proves cloud execution. If task identity/schedule is confirmed but execution mode is not exposed, recordrunsOn: unverified; never invent cloud proof. - If a definitive host lookup/dispatch failure such as
Resource not foundproves create was not dispatched, re-resolve the Native Scheduled Task operation once and retry that exact create once. Do not retry an ambiguous possible-success. Recordcreate_failedorcreate_uncertaintruthfully. - Continue the current leased worker while useful work is possible; scheduler degradation is not a work failure.
Work-conserving worker behavior
- A checkpoint is not a turn boundary. Ordinary milestone checkpoints persist progress and the worker must continue useful work in the same host turn; they are not permission to yield.
- Keep ordinary checkpoints on the current lease (
releaseLease:falseor omitted). UsereleaseLease:trueonly for the final checkpoint when an actual turn boundary is unavoidable. - A transient tool, status, log, result, or safety/polling error is not a handoff signal. Re-read authoritative durable state and retry or re-resolve the bounded observation in the same turn before considering a handoff.
- When a tracked
blocking_jobis running, do useful non-conflicting work first. If no useful parallel work exists, use bounded waits/observations in the same turn. One failed poll never justifies abandoning the task to the next hourly tick. - As soon as a tracked task is terminal, inspect its terminal result in the same turn and handle success or failure before yielding.
- If the current worker loses or expires its lease during useful work, read the latest goal and safely reacquire the same
goalKeywithrun_goalwhen no newer live owner blocks takeover. Ifrun_goalreturnsacquired: falsewithretryAfterSeconds <= 60(ornextRequiredAction: 'retry_run_goal_after_stale_grace_window'), the prior worker is inactive and only the brief stale-recovery grace remains: wait that brief duration and invokerun_goalagain to complete takeover, instead of yielding and reporting that an inactive worker blocks continuation. Never deliberately wait for lease expiry as a continuation strategy. - Yield only when the goal is terminal, a real external blocker/user decision leaves no safe useful work, the host forces the turn boundary, or a genuinely long blocking job has no useful parallel work left and durable continuation coverage is confirmed.
- Do not promise or target a fixed 22/25-minute runtime. Consume as much useful host turn as is available while respecting the stop conditions above.
Authoritative CI watcher policy
When work includes waiting for GitHub Actions, the CI watcher is part of the active worker's durable work, not a reason to yield to the next scheduled tick.
- Resolve the exact GitHub Actions run ID first and watch that exact run. Never switch to "latest branch run" after monitoring begins.
- Prefer one long-running background/durable watcher:
gh run watch <RUN_ID> -i 20 --exit-status. - Before spawning it, inspect existing authoritative tasks/processes. Reuse a live watcher for the same exact run ID instead of creating a duplicate.
- Track the watcher as the authoritative
blocking_jobfor that CI run when a durable goal is active. - Wait for the watcher to become terminal and confirm the workflow conclusion before reporting success.
- If it fails, inspect logs from that exact run before making code changes. Never diagnose from a different run.
- Never merge, tag, publish, or release a SHA whose required CI is failed or non-terminal.
- Multiple exact run IDs may share one durable watcher process if their exit codes are preserved and any required failure makes the watcher fail.
- Windows wrappers may use PowerShell. macOS/Linux wrappers must use a shell actually available on those platforms such as
shorbash; do not call a PowerShell-only watcher cross-platform. - This watcher is not a Native ChatGPT Scheduled Task. If scheduled continuation is disabled, do not create or re-enable a schedule merely to monitor CI.
Windows-only wrapper example:
powershell -NoProfile -NonInteractive -Command "
Write-Host 'Watching CI run 123456...';
gh run watch 123456 -i 20 --exit-status;
$ciExit = $LASTEXITCODE;
exit $ciExit
"
POSIX example:
gh run watch 123456 -i 20 --exit-status
Recurring scheduled wake
claim_scheduled_continuation must be the first connected lnwjud action before any workspace mutation.
Handle the result exactly:
recurring_acquired: continue work with the returnedleaseToken/leaseGeneration. Keep the same recurring native task. Do not create, update, consume, or replace it.worker_busy_noop: another worker is live or blocking work is still running. IfretryAfterSeconds <= 60is returned, no live worker was observed and the lease is simply within the bounded stale-heartbeat grace window: wait that brief duration and retryclaim_scheduled_continuationorrun_goalin the same turn to complete takeover. IfretryAfterSecondsis large, do not mutate the workspace, do not steal the lease, do not touch the native task, and return naturally. A later hourly firing will try again.orphan_probe_noop: legacy pre-hardening compatibility only. Current v4.53 recurring mainline must not enter a two-probe wait; if this historical outcome is encountered, do not mutate or touch the native task.already_claimed: this run/tick was already handled. Do nothing.receipt_required: reconcile exact native host metadata before any mutation or blind create.not_due: do not mutate; let the recurring task remain unchanged.terminal_cleanup_required: cleanup only. Do not resume goal work and do not claim a worker lease before host cleanup. Make the exact recurring native task non-runnable with the strongest host operation exposed (prefer delete; otherwise confirmed disable) and record the exact cancellation receipt. If the prior completion worker lease has expired, callrun_goalwith the same workspace/goalKey after cleanup only to obtain an administrative finalization lease; do not resume workspace work. Then callfinish_goalagain immediately.terminal_noop: no work and no new task. Return naturally.
Legacy one-time wake compatibility
Only for historical occurrence=once rows:
acquiredmay return one freshly reserved one-time successor.successor_requiredmay require the exact deterministic successor or exact receipt reconciliation.reschedule_requiredmay retime the exact still-pending one-time task.- A fired one-time native task is consumed transport identity and must never be re-armed.
expedite_scheduled_continuationis one-time compatibility only. Never use it foroccurrence=interval.
Collision and orphan safety
- A recurring collision is a no-op, not a scheduling event.
- Never create a new recurring task because a worker is busy.
- Live fenced calls and tracked blocking-task states are worker-liveness evidence; MCP session equality and elapsed time alone are not.
- For recurring v4.53 rows, a still-valid lease with trustworthy proof of no live fenced calls and no running/unknown blocking tasks uses the same bounded 60-second stale-heartbeat grace as
run_goal; once that grace is exceeded, takeover happens in the same hourly tick asorphan_recoveredinstead of waiting for lease expiry or a second hourly firing. Historical one-time rows keep their two-probe compatibility fence. - Full Bypass never bypasses durable-goal ownership fences.
Before a turn boundary
If the goal remains active:
- Checkpoint exact progress, blockers, tracked tasks, and the next action.
- Require exactly one confirmed Native ChatGPT watchdog for normal autonomous recovery:
status=scheduled, real native task ID, andconfirmedRunsOn=cloud|unverified. - For v4.53 interval mode, reuse the same recurring task; do not create a per-turn successor and do not retime the hourly cadence.
- If host creation is truthfully unavailable, checkpoint scheduler degradation without claiming coverage. Keep the goal active.
- At the actual boundary, release the worker lease with the final
checkpoint_goal(..., releaseLease:true)and perform no later workspace mutation in that turn.
Verified completion
- Wait for every blocking task to become terminal and inspect its result.
- Clear durable blockers and mark every durable plan step
completedonly after real acceptance evidence exists. - When a live scheduled watchdog exists, call
cancel_scheduled_continuationbeforefinish_goal. Keep the durable goal active while cleanup is being proven. - Make the exact recurring native task non-runnable with the strongest operation actually exposed by the ChatGPT host: prefer delete, otherwise use a host-confirmed disable. Record host-confirmed delete or disable evidence when the host supplies it. A recurring run receipt is not cleanup proof.
- Record the matching native cancellation receipt before terminalizing the goal. If the host management surface is unavailable but the user explicitly deletes the exact task in ChatGPT Scheduled Tasks, record that as user-attested manual deletion with explicit user confirmation; never relabel user testimony as host-native evidence.
- After verified cleanup, call
finish_goal(status:completed)once and then readget_goal. The normal happy path should not need a second finish call. - Defensive fallback remains required for older callers: if
finish_goalreturnspending_native_cleanup, the goal is still active. Recover the exact cleanup locator fromget_goal/get_scheduled_continuation, perform cleanup only, record truthful evidence, reacquire an administrative finalization lease if needed, and callfinish_goalagain without resuming workspace work. - Report completion only after
finish_goalreturnscompletionState=completedandget_goalconfirms a terminal status with no pending scheduled-task cleanup. failedorblockedare real work outcomes, not scheduler escape hatches.
Invocation on another machine
Use $lnwjud-scheduled-continuation when exposed by name; otherwise load this source-qualified skill and follow it. Never expose raw lease tokens, credentials, private source text, or internal session identifiers in native task prompts or status reports.