Automated release: version and notes generated from pull requests merged since 2.10.11.
Added
- Refusals say why in fields, not only in prose. A refusal's
errornow carriesreason, a stable code (output_exists,output_is_input,output_is_directory,output_dir_missing,output_dir_not_writable,output_locked, andrender.py'splan_inputs_changed,plan_version_unsupported,plan_unknown_tool,plan_cwd_missing,plan_argv_invalid), anddetails, the facts the message is written from.contract --jsonlists the codes underjson_output.error_reasons.render.pyforwards a stage's or a plan's tool'sreasonanddetailsin its ownerror. Additive:kind,message,codeandhintare unchanged. diagnostics: what a run decided on its own. Success and failure documents carrydiagnostics: {warnings, fallbacks, skipped}(each entry{code, message, ...facts}) when the run recorded any, beside the stderr line it always printed.render.pycarries its stages' entries, tagged withstage.- A refused plan is explained and logged.
render.py PLANrefusing a plan whose inputs changed lists every input as{path, status, expected: {size, sha256_head_tail}, actual}(actual: "missing"for a file that is gone) withplan_sha256andchecked_atinerror.details, and appends one JSON line to<plan>.audit.jsonlnext to the plan, or to the newrender.py --audit-log FILE. A log that cannot be written is adiagnostics.warningsentry, never the failure; a--dry-runwrites none. - Plans name the inputs they could not bind.
--planwritesunbound_inputs, the inputs that did not exist yet (an earlier step's output) and so carry no fingerprint; executing the plan reports them asunbound_inputsand aplan_unbound_inputswarning.plan_versionstays 1.
Changed
- A live run keeps its output lock until its own time limit has passed. A lock older than an hour was taken over even while its pid was running, so an encode longer than an hour could lose its lock to a second writer. The writer now dates its lock to its deadline (4x
--timeout+ 60 s; never with--timeout 0), and a live holder's lock is taken over only after that; a dead pid's lock is still taken over at once. A lock written by an earlier version is read as before (an hour). A takeover is recorded (diagnostics.fallbacks,stale_lock_taken_over, and alock_takeoverline in the hidden.<output>.ffskill-audit.jsonlor--audit-log), and so is running without a lock where none can be created (output_unlocked). A lock refusal names the holder's pid and the lock file inerror.details. - feat: structured refusals, diagnostics and an audit log (silent paths, part 1 of 3) (#349)
What's Changed
- feat: structured refusals, diagnostics and an audit log (silent paths, part 1 of 3) by @kajisho5 in #349
Full Changelog: v2.10.11...v2.11.0