skillscript-runtime v0.35.0
Upgrade impact: none (additive). Everything here is opt-in: a skill without # Deadline: and a runtime without SKILLSCRIPT_MAX_DEADLINE_SECONDS behave exactly as before (per-op timeouts only). Editing a # Deadline: on an already-approved skill does drop it to Draft (the value is in the signing hash — see below), so a re-approve is needed after such an edit.
Promotes skillscript's leaky per-op timeout into a single propagating wall-clock deadline that bounds a whole run — and everything it composes — with real cancellation, not race-and-abandon. An approver signing a bounded skill now gets both halves they assumed: the run is time-bounded, and in-flight work is actually stopped.
# Deadline: Nfrontmatter. An absolute wall-clock budget (seconds) for the entire run. Set once at the root, propagated by remaining to every composed child (a child inherits the shared instant and can only tighten it, never loosen). Exceeding it terminates the run via an uncatchableRunDeadlineExceeded— op(fallback:)trailers and targetelse:blocks do not catch it, so a fallback-laden skill can't cascade to a looks-complete result past the bound. The run returns a partial result flaggeddeadline_exceededwith whatever completed.- Real cancellation. A
shell(...)op is killed by process-group SIGKILL (the child truly stops). A$ connector.tooldispatch receives anAbortSignalon itsctx.signal— a connector that forwards it to its fetch/RPC genuinely cancels; one that ignores it degrades to today's behavior. Proven end-to-end: a non-responding MCP call +# Deadline: 2returns at ~2s instead of hanging forever. - Bounded cleanup for effects that outlive the call (
onAbort). A connector whose effect keeps running aftercall()returns (a robot motion, a long job) declareseffectBoundary: "outlives-call"+ anonAbort(budgetMs)hook; on an in-flight cut the runtime aborts the call, then givesonAborta bounded reserve slice (min(1000ms, remaining)) to issue a real safety-stop — and the whole run still returns within the deadline. The registry hard-refuses to register an outlives-call connector withoutonAbort(leak-prevention). - Operator deadline ceiling (
SKILLSCRIPT_MAX_DEADLINE_SECONDS). A hard maximum on every run — enforced even when a skill declares no# Deadline:, on both the server/MCP path and theskillfile executeCLI. A skill's own# Deadline:can only make the bound tighter, never exceed it. The guard against an untrusted (agent) author evading the time bound by simply omitting the deadline. Unset = no ceiling. - Uncertain-effect log. An external dispatch cut mid-flight is recorded as
uncertain_effects: [{ ..., reason: "issued, outcome uncertain", retry: false }]— aborting stops the client, but the request may already have reached the backend, so the runtime doesn't claim success or failure. Safe default: everyshelland$ connector.toolrecords; only ops the runtime can provably rule out an external effect for are excluded —data_read,json_parse,execute_skill, and$ llm(a prompt→text completion lands nothing external). A connector tool's name can't downgrade it (get_statusstill records — per-tool read-exclusion is a latereffect_classannotation, not a name guess). Surfaced on theexecute_skillreturn envelope and the durable trace record (deadline_exceeded+uncertain_effects), so an autonomous cron/event fire — which has no live caller — still leaves the "a mutation may have landed" signal in the record. # Deadline:is in the approval signing hash. Unlike# Tags:/# Status:(carved out), editing a# Deadline:changes the canonical form → invalidates the signature → drops the skill to Draft. Deliberate: the deadline is the safety envelope the approver signed off on, so any change to it (even tightening) re-approves. The mirror of the# Tags:carve-out.unbounded-no-deadlinelint (tier-3 advisory). Nudges a skill that dispatches an effectful op ($/shell/notify) but declares no# Deadline:.- Discoverability.
help({topic:"frontmatter"})documents# Deadline:+ the operator ceiling;help({topic:"lint-codes"})coversunbounded-no-deadline; the adopter playbook gains a deadlines & cancellation section; the README listsSKILLSCRIPT_MAX_DEADLINE_SECONDSas an operator control.