v0.12.0 - Execution lifecycle, idempotency, and the first public release
Cooperative cancellation, deadlines, structured outcomes and idempotency
for executions already in flight, together with the hardening this
release's own auditing turned up along the way - several of those
fixes correct behavior that had been wrong since well before v0.12.0.
This is also the first public release of SETT: everything here was
already built and versioned internally (0.1.0 through 0.12.0), and this
is the first version anyone outside the project can install or link to.
✨ Added
- Immutable lifecycle primitives in
sett/core_ruler/lifecycle.py:
ExecutionControl,ExecutionControlRegistry,CancellationToken,
CancellationSource,CancellationSnapshot,Deadline. A control
carries its ownExecutionContext; subtree cancellation walks the
parent_idchain that context tree already maintains, so no second
hierarchy is introduced. - Cooperative cancellation with LIFO cleanup hooks, monotonic deadlines
a nested unit can shorten but never extend,lifecycle_scope()
propagation viacontextvars, andLifecyclePolicyfor per-level
timeout defaults - run, stage, agent, adapter, handler. ExecutionStatus,ExecutionState,ExecutionResult: six terminal
statuses that keep an ethical rejection, a cancellation, a deadline and
a technical failure apart.unwrap()re-raises the original exception
instance, preserving its concrete type.SETTOrchestrator.process_controlled()/run_pipeline_controlled()/
cancel(run_id), added alongside the existing entry points the same way
process_traced()was in v0.11.0.- Idempotency in
sett/core_ruler/idempotency.py:action_fingerprint(),
theIdempotencyStoreprotocol,InMemoryIdempotencyStore, and the
record/reservation/attempt types behind it. RetryPolicy,ErrorClass,classify_error(). Retries are opt-in
per error type; a set of framework errors is never retried regardless
of policy.SETTExecutor.submit_controlled(),register_controlled_handler(),
andHandlerContext, carrying the idempotency key and the run's real
remaining time into a handler.SETTCancelledError,SETTTimeoutError,SETTDependencyError,
SETTIdempotencyConflictError, all underSETTError.- Eleven new test modules.
🔒 Security
- Per-instance Google Cloud credentials: TTS, STT and sentiment adapters
no longer setGOOGLE_APPLICATION_CREDENTIALSprocess-wide, where two
differently configured instances used to interfere with each other and
with every other Google client in the process. - Sensitive metadata and trace keys were matched by plain substring, so
apiKey,x-api-key,api.keyandprivate/keyall passed. Keys are
now normalized to letters and digits before comparison. RiskProfilevalues could reachUniversalMemorythrough an
uncooperative agent despite the documented boundary. The check is now
structural, at the one place every publication passes through.
🐛 Fixed
- A non-finite
risk_scorefrom aContextAnalyzerreachedALLOW-
nancomparisons are alwaysFalsein Python, so a fail-open slipped
through the layer meant to fail closed. SETTExecutor.submit()andUniversalMemory.update()each read a
caller-held object twice; a concurrent mutation between reads could let
policy approve one payload while the handler performed another.PrivateMemory.get_history()returned live internal entries instead
of copies.ElevenLabsTTSAdapteraccepted a whitespace-only API key.- Provider SDK exceptions escaped adapter constructors untranslated
(OpenAI, Anthropic, Gemini, and Google client construction). Every
construction failure now leaves as a SETT error, with the original
preserved as__cause__. - Adapter timeouts skipped the
NaN/infinity validator this release
otherwise applies everywhere. - An invisible character (zero-width space, fullwidth spelling) was
enough to dodge aContextAnalyzerkeyword match; text is canonicalized
first now. OllamaAdapterlet a malformedbase_urlescape as a bare
ValueErrorinstead of aSETTLLMAdapterError.HandlerContext.attempt_numberreset to 1 on every resubmission of
the sameidempotency_keyinstead of climbing with it, the way
IdempotencyRecord.attempt_countalready did.
⚠️ Breaking changes
EnvironmentalContext.auto_notify_emergencyis now
should_notify_emergency(attribute andto_dict()key).register_expert()/register_handler()/
register_controlled_handler()/register_analyzer()now refuse a
duplicate instead of silently replacing it.register_agent()still
replaces - that is how aStubDomainAgentgives way to the real
implementation - but now warns when what it replaced was not a stub.
🔄 Changed
PrivateMemory.write()stores a deep copy;clear()now records an
audit entry too.- Timeouts and durations reject
NaNand infinity everywhere, through
onevalidate_duration_seconds(). - An
Actioncarrying anidempotency_keymust have a
JSON-serializable payload. docs/api_reference.mdnow covers every name insett.__all__, with
attribute tables for the four new exceptions; the concurrency section
namesExecutionControlRegistryandInMemoryIdempotencyStore. Every
public definition carries a docstring. Three new guard tests keep all of
this from drifting again.docs/SETT_Conventions_v2.mdis nowdocs/SETT_Conventions.md- no
version of SETT has been public before now, so no external reader ever
had a reason to link the old name.
🗑️ Removed
- The per-version
MIGRATION_v*.mdmechanism. No version has shipped
externally before now, so there is no adopter for a migration guide to
serve;CHANGELOG.mdis the record of what changed and why. - The per-release
AUDIT_vX.Y.Z.mdfile. OnlyAUDIT_v0.11.0.mdwas
ever produced under that name; no version before it had one, and this
release does not restart the pattern - a single instance was never a
convention to begin with.CHANGELOG.mdis the record of what was
verified for a given release and why.
✅ Compatibility
process(),run_pipeline()andsubmit()were deliberately not
rewired to their controlled counterparts in this release.- The 340 tests of v0.11.0 pass unmodified.
💖 Sponsors
- Sponsors: eight tiers from a symbolic $1 up to logo
placement on 4humanityAI.com, with an explicit note on what sponsorship
does and does not buy.
Known limitations
- SETT cannot cancel an arbitrary non-cooperative Python handler; three
levels of guarantee are documented (cooperative code, a provider given
the remaining time, untrusted code that belongs in an isolated process). - Exactly-once is not offered against an external system; an in-memory
idempotency store says nothing about anything before the current
process started. - Canonicalization does not defeat homoglyphs (Cyrillic
аvs Latin
a) - a hand-maintained confusables table would produce confidence
rather than safety. What guards a critical action isSETTExecutor
resolving handlers by exactaction_typeand failing closed, together
with a domain-specific analyzer. - The public namespace of the submodules (names without a leading
underscore that live outsidesett.__all__) has no formal policy yet;
that decision belongs to the v1.0 freeze. Full list inCHANGELOG.md.
Status
- 893 tests passing (828 immediately before this release's hardening
pass, 340 at v0.11.0). - Reference-consumer compatibility: the private companion-assistant
application's suite (1146 tests) passes against this source release
without any application code changes, with exactly one expected failure
(an intentional version-pin guard, unrelated to this release). - Zero mandatory dependencies in the core framework - every provider
integration (OpenAI, Anthropic, Gemini, Ollama, Google Cloud,
ElevenLabs) is an optional extra.
See CHANGELOG.md for the complete, itemized history of this and every prior internal version.