feat(events): a failed step may say when to retry (MODULE_API 1.15.0)
A module's perform() may answer { ok: false, retry: true, retryAfterMs }
and the runner waits that long instead of the flat EVENT_STEP_RETRY_MS
(Rust PLAN_REDESIGNS §14.3.13, D371). Dangerous Treasures' warm-up is the
first user.
- dispatch.classify reads it on the retry shape only, clamped to 60 000 to
1 800 000 ms; a value that is not a number is dropped and logged, and the
step retries on the flat delay.
- It is one attempt of EVENT_STEP_MAX_ATTEMPTS and degrades the run like any
retry. A run paused or cancelled in the wait is not picked up.
- Every step.retry log line now carries retryAt (and retryAfterMs when
hinted); the run console reads "retrying at 20:10".
- MODULE_API 1.15.0, additions only; the engagement manifest is regenerated.
Module-uo (^1.10.0) answers none of it and is unaffected.
- Test harness: resourcesDb.finishedRunsWithNothingLeft was never stubbed in
eventRunner.test.js, so a tick that reached the cleanup sweep with a
terminal run waited on the dead pool.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
This commit is contained in:
@@ -966,6 +966,15 @@ function detailValue(value) {
|
||||
|
||||
export const logKindWord = (kind) => KIND_WORDS[kind] || kind
|
||||
|
||||
// "20:10", in the viewer's own clock. Time only: the log line it sits in carries
|
||||
// its own timestamp, and a retry is at most thirty minutes after it.
|
||||
function clockTime(value) {
|
||||
if (!value) return ''
|
||||
const t = new Date(value)
|
||||
if (Number.isNaN(t.getTime())) return ''
|
||||
return `${String(t.getHours()).padStart(2, '0')}:${String(t.getMinutes()).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* One log line as a sentence.
|
||||
*
|
||||
@@ -992,8 +1001,12 @@ export function describeLogLine(line) {
|
||||
return `${line.phase} finished`
|
||||
case 'step.parked':
|
||||
return `${d.action} is waiting on a human`
|
||||
case 'step.retry':
|
||||
return `${d.action} failed, attempt ${d.attempt} of ${d.of}${d.error ? `: ${d.error}` : ''}`
|
||||
case 'step.retry': {
|
||||
// `retryAt` is on every retry line since MODULE_API 1.15.0; a line written
|
||||
// before it says what it always said.
|
||||
const at = clockTime(d.retryAt)
|
||||
return `${d.action} failed, attempt ${d.attempt} of ${d.of}${at ? `, retrying at ${at}` : ''}${d.error ? `: ${d.error}` : ''}`
|
||||
}
|
||||
case 'step.status':
|
||||
return d.control
|
||||
? `${d.action} → ${d.to}${by} — ${d.control}${d.note || d.reason ? `: ${d.note || d.reason}` : ''}`
|
||||
|
||||
Reference in New Issue
Block a user