Skip to content

Releases: EduDanielV/sett-framework

v0.14.0 - Durable evidence, deterministic authorization, and a separate execution boundary

Choose a tag to compare

@EduDanielV EduDanielV released this 08 Sep 20:28

Opt-in durable evidence and versioned state, pure recovery with explicit audit closure, copy-on-write migrations, deterministic authorization, and a separate execution boundary. SETT restores what durable evidence can support and never resumes interrupted work automatically.

✨ Added

  • sett.persistence: EvidenceStream and StateRecordStore keep append-only evidence separate from random-access state, bound by PersistenceBackend
  • Versioned binary formats for trace preimages, stream positions, stage-state envelopes, private-memory mutations, and migration manifests
  • Durable trace evidence preserves the exact preimage used for each entry hash; recovery never reproduces a historical hash by reserialization
  • IntegrityPolicy, Sha256IntegrityPolicy and NoDigestPolicy; SHA-256 is documented as change detection, not authentication
  • In-memory reference implementations and a SQLite backend with transactional compare-and-append and idempotent state writes
  • SQLite durability declarations come from effective pragma readback rather than requested settings
  • TraceRecorder.restore() for pure recovery and TraceRecorder.resume() for explicit continuation
  • RecoveryReport separates chain integrity, trace completeness, reconstructed outcome, unresolved boundaries, stage descriptors, and the last durable position
  • Durable stage-output persistence for run_pipeline_controlled(), with materialization as a separate explicit operation
  • Opt-in PrivateMemory persistence through a stable memory_id; ordinary ephemeral memory is unchanged
  • AuditClosure as an axis independent from ExecutionStatus, with AuditGapPolicy and SETTAuditClosureError
  • Append-only boundary dispositions with typed evidentiary bases
  • sett.authorization_ruler: closed GRANT / REQUIRE_APPROVAL / DENY vocabulary, detached requests with explicit field provenance, and store-backed receipts
  • ReceiptUse declared per policy decision; replay requires unanimous policy consent plus a controlled request with an idempotency key
  • Versioned strict JSON authorization fingerprint with NFC text, signed-zero and integral-float normalization, and exact IEEE-754 hexadecimal for other floats
  • AuthorizationRequestResolver and optional paired executor configuration; once enabled, authorization is mandatory for every handler
  • sett.execution_ruler owns the effect boundary that verifies authorization receipts
  • docs/foreign_callers.md: the stable contract for governing an external tool loop with no dependency in either direction
  • examples/foreign_tool_loop.py and examples/governance_card.py, plus reusable adapter and phrasing-expert templates

🔄 Changed

  • SETTOrchestrator accepts an optional backend and explicit persistence policy; durable execution is limited to run_pipeline_controlled()
  • SETTAgent accepts an optional private_memory_id; omitting it preserves ephemeral behavior
  • ExecutionResult carries audit_closure, defaulting to NOT_REQUESTED
  • Trace event vocabulary and frame size are bounded before a lifecycle boundary can open, and only when persistence is enabled
  • The documented concurrency roster now contains ten narrow guarantees

🐛 Fixed

  • A durable terminal whose metadata is rejected records a framework-owned contingency terminal, so invalid terminal metadata cannot leave an already opened boundary unverifiable
  • Distribution metadata now uses the PEP 639 SPDX form, declares LICENSE through license-files, and no longer uses the deprecated license table or license classifier
  • The release builder now rejects unsafe destinations and option-like artifacts, handles command-line help safely, and fixes cross-platform ZIP entry metadata
  • Corrected Convention #21 to record that v0.13.2 was subsequently published, without changing the rationale for its Pocket TTS exception
  • Corrected stale Convention #9: human_at_risk is an urgency and audit signal that can conservatively promote ALLOW to WARN; it does not override the harm score
  • Completed the source-installation correction begun in v0.13.2 across adapter docs, runtime dependency errors, API examples, and test documentation
  • Corrected result_digest() documentation that described an unkeyed digest as unable to reveal its input
  • Corrected the public ethics description: numeric harm scoring comes from ContextAnalyzer, not from HarmCategory weights or the rules list
  • SQLitePersistenceBackend.open() now returns an object accepted directly by SETTOrchestrator
  • verify() now documents that an interrupted run also returns False, and points to RecoveryReport to distinguish interruption from corruption

🛡️ Audit remediation

  • M-01: SQLite infrastructure errors are normalized without flattening the domain failures they must not hide
  • M-02: world-readable SQLite files are documented rather than silently assumed safe
  • M-03: an automated matrix now covers every declared Python version
  • L-01: SETTAdapterError.__str__() no longer carries provider-supplied text
  • L-02: template distribution corrected

🧹 Maintenance

  • CONTRIBUTING.md fixes the lint gate to the Ruff version pinned in pyproject.toml
  • Convention #23 enumerates all eight structural pillars and records when the Ruler suffix may name a class
  • Release archives use fixed cross-platform entry metadata and are byte-reproducible for identical source bytes under a matching Python/zlib toolchain

✅ Compatibility

  • Persistence and authorization are opt-in and add no mandatory dependency; SQLite uses the standard library
  • No v0.13.2 public symbol was removed or renamed
  • sett.SETTExecutor and sett.core_ruler.executor continue to resolve after the executor moved to sett.execution_ruler
  • Supported Python versions are 3.11, 3.12, 3.13 and 3.14; requires-python is now >=3.11, correcting a v0.13.2 claim that never worked
  • SETTAdapterError.__str__() drops provider text; structured attributes, safe_view(), reason codes and __cause__ are unchanged. Code that asserted on provider wording inside a message must read __cause__
  • 1,255 tests pass, comprising the 1,038-test v0.13.2 baseline plus 217 new tests
  • Automatic pipeline resumption, retention, compaction, cross-namespace migration, import, and production secret storage remain outside this release

⚠️ Architectural decision

Two structural pillars enter the framework. Authorization is promoted first and execution derives from it, so the dependency direction points away from the kernel. sett.core_ruler keeps its kernel contracts; its historical executor module is a compatibility reexport, and those kernel contracts have no runtime dependency on Authorization.

💖 Sponsors

Sponsors:
Eight tiers from a symbolic $1 up to logo placement on 4humanityAI.com
With explicit limits on what sponsorship does and does not buy.

See the complete itemized history in CHANGELOG.md.

v0.13.2 - Voice language consistency, audited boundaries, and optional Pocket TTS

Choose a tag to compare

@EduDanielV EduDanielV released this 21 Aug 22:43

Provider-neutral voice language consistency, audited error boundaries,
and optional Kyutai Pocket TTS support.

🐛 Fixed

  • LocalSTTAdapter.transcribe() now accepts language_code, matching
    GoogleSTTAdapter and AssemblyAISTTAdapter, and reduces a BCP-47 tag
    to the bare language identifier faster-whisper expects (es-AR becomes
    es). The historical language name remains a compatibility alias.
    When both names are present, equivalent primary subtags are accepted
    and a real conflict raises a structured configuration error instead of
    silently allowing one spelling to overwrite the other.
  • AzureTTSAdapter and AzureSTTAdapter now accept language_code at
    construction and per call. A call such as transcribe(..., language_code="es-AR") reaches Azure as language=es-AR instead of
    being silently discarded in favor of the configured default.
  • The canonical spelling covers every official STT adapter that offers
    language selection. Deepgram accepts language_code at construction
    and per call; Gladia and hosted Whisper accept it per call. Whisper
    reduces BCP-47 tags to the primary language identifier its provider
    expects.
  • The historical language spelling remains a compatibility alias
    where it already existed. Equivalent effective tags are accepted;
    conflicts raise a structured SETTServiceAdapterError with
    adapter.language_arguments_conflict before provider work.
  • CartesiaTTSAdapter joins Azure, Google, and LocalTTS in accepting
    per-call language_code, with the same compatibility and conflict
    behavior.
  • LocalTTSAdapter now normalizes failures raised while creating the
    engine, reading voice metadata, or applying voice properties. These
    paths no longer leak provider exceptions outside SETT's error
    hierarchy.
  • pyttsx3 language matching now understands the control-byte prefix
    emitted by older eSpeak metadata and underscore-separated locale tags.
    The local-tts extra now requires pyttsx3 2.99 because pyttsx3 2.90
    does not expose SAPI5 language metadata on Windows, making honest
    language selection impossible there.
  • Local TTS and STT paths preserve cancellation and deadline exceptions
    after provider work instead of translating them into service-adapter
    failures.
  • ContextAnalyzer.EMOTIONAL_RISK_MODIFIERS is now an immutable
    mapping. One analyzer instance can no longer change the risk score
    produced by every other instance through shared class state.

✨ Added

  • LocalTTSAdapter.synthesize() now accepts an optional
    language_code keyword argument, matching GoogleTTSAdapter. Without
    an explicit voice_id, it looks for an installed host voice whose own
    metadata names the requested language and leaves the current voice
    untouched when none does. It deliberately does not guess from
    free-form voice identifiers.
  • PocketTTSAdapter adds optional Kyutai Pocket TTS 2.1 support
    through the existing TTSBase contract. It lazily loads a
    caller-selected language and voice, accepts the conditioning forms
    supported by Pocket TTS, and returns mono PCM16 WAV bytes. The adapter
    declares six language families and voice cloning.
  • Pocket TTS generation is exposed honestly as non-streaming because
    TTSBase.synthesize() returns one complete byte payload. The
    underlying model's streaming API does not change SETT's current
    contract.
  • One adapter instance serializes model loading, voice conditioning,
    and generation because Pocket TTS documents its generation methods as
    not thread-safe. The package and model remain optional; first use can
    download model weights or catalog voices, while cached assets can
    synthesize without a remote service.

🧹 Maintenance

  • SETT now owns an explicit Ruff 0.16.0 policy in pyproject.toml.
    Repository validation no longer depends on whichever default rule set
    an installed Ruff version happens to provide. The full tree passes
    with zero findings.
  • Imports, annotations, unused test values, broad exception
    assertions, intentional Unicode fixtures, and context-manager
    structure were cleaned across the repository. Deliberate
    audit-boundary catches remain in place with narrow inline
    explanations.
  • Thirteen test modules now use stable, version-independent filenames.
    Their names describe the contract under test, so future releases
    update the same files instead of creating parallel version-labelled
    suites.
  • LocalSTT now delegates language aliases, conflicts, primary-subtag
    handling, and lowercase normalization to the shared _language.py
    resolver instead of maintaining a second copy of the same rule.

📄 Documentation

  • README.md and docs/getting_started.md now document source
    installation instead of presenting SETT as available from PyPI, where
    it is not published.
  • Removed the unpublished draft Convention #24, which proposed a
    repository checksums.txt practice that was never present in the
    released v0.13.1 archive. This entry records the governance edit
    without presenting the draft as a released guarantee.

✅ Compatibility

  • No public symbol was removed or renamed. Existing callers using
    language continue to work where that spelling already existed;
    language_code is the canonical spelling for provider-neutral call
    sites.
  • The 1,003 tests of v0.13.1 pass unmodified.
  • The complete v0.13.2 suite passes with 1,038 tests, 0 skipped.
  • The private companion-assistant application's suite (1,162 tests)
    passes against this source release with zero application code
    changes.
  • SETT keeps zero mandatory dependencies. pocket-tts is available as
    an opt-in extra, included only in the all extra.

⚠️ Versioning decision

PocketTTSAdapter is additive public API, which would ordinarily place
it in a minor release under this project's own versioning convention.
This is an explicit, one-time exception: Pocket TTS became known only
days before this release closed and addressed an immediate need for a
local CPU TTS option. Keeping the completed work in the same patch
avoided manufacturing two releases for one review cycle. This does not
redefine the stable API boundary and does not relax the default rule
for future additive public APIs.

💖 Sponsors

Sponsors:
eight tiers from a symbolic $1 up to logo placement on 4humanityAI.com,
with explicit limits on what sponsorship does and does not buy.

See the complete itemized history in
CHANGELOG.md.

v0.13.1 - Fail-closed routing preflight and benchmark-driven overhead fix

Choose a tag to compare

@EduDanielV EduDanielV released this 19 Aug 22:59

A frozen comparative benchmark exposed avoidable steady-state action
latency in SETT's governed execution path. Follow-up scenario-level
profiling and repeated ablation isolated two confirmed contributors:
synchronous logging.lastResort writes when the host application had
not configured logging, and governance work performed before handler
availability was known.

This patch fixes both causes while preserving fail-closed execution,
boundary integrity, sanitized trace completeness, and compatibility
with v0.13.0.

🔄 Changed

  • Importing sett now installs a package-level
    logging.NullHandler without configuring the root logger.
    Applications that never configured logging no longer fall through to
    Python's synchronous stderr lastResort handler. Handlers installed
    by the application continue receiving propagated records normally.

  • SETTExecutor.submit() resolves the exact handler before copying
    payloads, reading environmental context, or invoking the
    EthicalFilter. An unroutable action emits action.blocked with
    verdict block and reason handler.not_registered, then raises a
    structured SETTConfigurationError. It does not manufacture an
    ethical verdict or handler failure for something that never had a
    route.

  • SETTExecutor.submit_controlled() performs the same readiness and
    route preflight before payload snapshots, fingerprints, idempotency
    reservations, or handler-attempt events. An impossible action cannot
    consume an idempotency key or fabricate an attempt that never reached
    a handler.

🐛 Fixed

  • The concurrency reference now counts and names its five narrow
    thread-safe exceptions consistently, including UniversalMemory in
    the practical deployment guidance.

  • CartesiaTTSAdapter now reports a blank voice_id as a structured
    SETTServiceAdapterError with configuration metadata instead of
    leaking a native ValueError.

  • The v0.13.0 changelog entry now includes release-audit changes that
    were present in the published v0.13.0 source and release notes but
    were mistakenly carried into the draft v0.13.1 entry. This corrects
    the historical record and does not attribute those changes to this
    patch.

  • README.md's Install section documented pip install sett-framework
    as though the package were available on PyPI. It is not, and there is
    no near-term plan to publish it. The section, and
    docs/getting_started.md, now document installing from source.

Performance interpretation

Under the frozen SGBS-01 benchmark protocol, the repeated Stage 13
ablation measured, against the Stage 12 official run (three independent
repetitions each, run-to-run spread under 0.5%):

  • Mean latency: 14.2% lower
  • p95 latency: 23.8% lower
  • p99 latency: 25.5% lower
  • Throughput: 18.8% higher

These are observations under that protocol, not universal performance
guarantees.

The logging change affects emitted WARNING and ERROR records. The
routing change affects unroutable and unready actions. Neither removes
work from a registered ALLOW path.

The same ablation observed an approximately 7% improvement on registered
ALLOW-shaped paths. Those paths should not invoke either corrected
behavior, so that result remains unexplained and is excluded from the
patch's claimed effects pending isolated investigation.

The complete protocol, comparisons, and measurements will be published
separately as a citable benchmark report (SGBS-01).

✅ Compatibility

  • Zero breaking changes. No public symbol was renamed, removed, or had
    its contract narrowed.
  • All 995 tests inherited from v0.13.0 pass unmodified.
  • The complete v0.13.1 suite passes with 1,003 tests.
  • The private companion-assistant application's suite of 1,175 tests
    passes with zero application code changes.
  • Zero mandatory dependencies were added.

💖 Sponsors

Sponsors:
eight tiers from a symbolic $1 up to logo placement on 4humanityAI.com,
with explicit limits on what sponsorship does and does not buy.

See the complete itemized history in
CHANGELOG.md.

v0.13.0 - Adapter capability contracts and opt-in resilience

Choose a tag to compare

@EduDanielV EduDanielV released this 17 Aug 04:18

Provider-neutral adapter contracts, honest capability selection, passive
health, structured failures, opt-in resilience, and an expanded voice
roster. Every adapter still ships present and importable, never
framework-selected: an application always names the one it wants.

✨ Added

  • Immutable adapter contracts in sett/core_ruler/adapter.py:
    AdapterCapabilities, AdapterRequirements, AdapterHealth,
    AdapterErrorView, AdapterHandle, AdapterSelection. Every
    capability field is tri-state (yes / no / never declared), never a
    plain boolean, and views are detached, JSON-safe copies.
  • select_adapter(): pure filtering with a stable, explained rejection
    reason per excluded candidate, passive health/circuit-state checks, and
    caller-owned tie-breaking through SelectionPolicy /
    PrioritySelectionPolicy. SETT ships no provider default or
    recommendation - selection policy belongs to the application.
  • SETTAdapterError as the structured common parent of the existing
    SETTLLMAdapterError and SETTServiceAdapterError. Official adapters
    now normalize authentication, quota, timeout, unavailable,
    invalid-response, unsupported-capability and configuration failures,
    always preserving the original provider exception as __cause__.
  • CircuitBreaker, CircuitBreakerPolicy, CircuitState and
    execute_with_resilience() in the new sett.core_ruler.resilience.
    Retry and circuit breaking are both off by default; retry additionally
    refuses to run without an explicit idempotency statement.
  • Sanitized adapter trace events: call, health, retry, circuit and
    fallback-selection. Prompts, audio, responses, credentials and raw
    provider messages never appear in them.
  • Remote voice adapters: Deepgram STT, Azure Speech TTS/STT, AssemblyAI
    STT, Gladia STT, OpenAI-hosted Whisper STT, Cartesia TTS.
  • Local voice adapters: pyttsx3 TTS, faster-whisper STT, Kokoro TTS,
    Piper TTS. Model loading is deferred until first use where applicable,
    so importing the module never pays a load cost the application doesn't
    ask for.
  • EdgeTTSAdapter, explicitly labeled community/unofficial in its own
    docstring: it calls Microsoft Edge's reader-mode API rather than the
    supported Azure Speech API, and callers should read that distinction
    before using it commercially.
  • sett.testing.adapter_contract: a dependency-free contract kit any
    third-party adapter author can run without copying SETT's own test
    suite, covering capability immutability, lifecycle honoring,
    cancellation-before-contact, error normalization, __cause__
    preservation, secret-free views, and honest UNKNOWN health.
  • docs/adapters.md and examples/adapter_selection.py.

🐛 Fixed

  • The internal execution-context conformance helper _is_uuid() raised
    NameError when called directly instead of importing UUID first.

🔄 Changed

  • LLMBase, TTSBase, STTBase and SentimentBase now provide
    concrete capabilities, health and non-billable check_health()
    members. Existing v0.12 third-party subclasses need no changes to gain
    them.
  • All eight existing official adapters declare only the behavior their
    current synchronous implementation actually has, and feed the same
    passive health/tracing machinery as the new ones.
  • Retry moved from sett.core_ruler.retry to sett.core_ruler.resilience,
    alongside the new circuit breaker so both share one failure
    classification. The old module path remains as a compatibility
    re-export.
  • CircuitBreaker is now covered by the documented concurrency
    guarantees and an 8-thread, 2,000-failure stress test. A late failure
    from a call already in flight no longer moves an OPEN circuit's
    timestamp or postpones recovery; a failed HALF_OPEN probe still
    starts a new recovery timeout.
  • The living adapter and execution-context design documents moved to
    stable canonical paths (docs/adapter_contract.md,
    docs/execution_context.md) instead of versioned filenames, so future
    revisions update in place instead of creating parallel contracts.
  • Prose across the project now favors commas, semicolons, colons,
    parentheses or a sentence break over a dash-shaped pause. Arithmetic
    operators, list markers, changelog dates, ranges and tool directives
    keep their functional symbols unchanged.
  • OpenAI, Anthropic and Gemini client construction now preserves
    SETT-owned adapter, cancellation and timeout exceptions unchanged,
    matching their real call paths, while genuine provider construction
    failures still arrive normalized.

✅ Compatibility

  • Zero breaking changes in this release.
  • Every existing third-party adapter written against v0.12's LLMBase /
    TTSBase / STTBase / SentimentBase keeps instantiating unmodified.
  • The 893 tests of v0.12.0 pass unmodified.
  • Reference-consumer compatibility: the private companion-assistant
    application's suite (1,175 tests) passes against this source release
    with no application code changes beyond its own declared sett-framework
    version pin. The only local failures came from an audio-hardware gap in
    the verification environment, unrelated to this release.

💖 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

  • No Capability Broker, credential/secret store, or billing/quota
    handling ships in SETT. Provider selection by cost, plan or commercial
    preference is deliberately left to the consuming application.
  • Health and circuit-breaker state live in process memory only; neither
    persists across a restart.
  • EdgeTTSAdapter depends on an interface Microsoft documents for its
    reader feature, not a supported API contract - stable in practice for
    years, but outside the same guarantee the other adapters carry, and
    flagged as such in its own docstring.
  • Declaring a capability as supported describes what an adapter's
    current implementation does, not what a specific provider account,
    plan or region will actually grant at call time.
  • The public namespace of the submodules (names without a leading
    underscore that live outside sett.__all__) still has no formal
    policy; that decision remains deferred to the v1.0 freeze.

Status

  • 995 tests passing (893 immediately before this release).
  • Reference-consumer compatibility: the private companion-assistant
    application's full suite (1,175 tests) passes against this source
    release with zero application code changes beyond its own version pin.
  • Zero mandatory dependencies in the core framework. Every provider
    integration, old and new (OpenAI, Anthropic, Gemini, Ollama, Google
    Cloud, ElevenLabs, Deepgram, Azure Speech, AssemblyAI, Gladia, Cartesia,
    pyttsx3, faster-whisper, Kokoro, Piper, edge-tts), is an optional extra.

See CHANGELOG.md for the complete, itemized history of this and every prior version.

v0.12.0 - Execution lifecycle, idempotency, and the first public release

Choose a tag to compare

@EduDanielV EduDanielV released this 11 Aug 03:54

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 own ExecutionContext; subtree cancellation walks the
    parent_id chain 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 via contextvars, and LifecyclePolicy for 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(),
    the IdempotencyStore protocol, 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(),
    and HandlerContext, carrying the idempotency key and the run's real
    remaining time into a handler.
  • SETTCancelledError, SETTTimeoutError, SETTDependencyError,
    SETTIdempotencyConflictError, all under SETTError.
  • Eleven new test modules.

🔒 Security

  • Per-instance Google Cloud credentials: TTS, STT and sentiment adapters
    no longer set GOOGLE_APPLICATION_CREDENTIALS process-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.key and private/key all passed. Keys are
    now normalized to letters and digits before comparison.
  • RiskProfile values could reach UniversalMemory through 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_score from a ContextAnalyzer reached ALLOW -
    nan comparisons are always False in Python, so a fail-open slipped
    through the layer meant to fail closed.
  • SETTExecutor.submit() and UniversalMemory.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.
  • ElevenLabsTTSAdapter accepted 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 a ContextAnalyzer keyword match; text is canonicalized
    first now.
  • OllamaAdapter let a malformed base_url escape as a bare
    ValueError instead of a SETTLLMAdapterError.
  • HandlerContext.attempt_number reset to 1 on every resubmission of
    the same idempotency_key instead of climbing with it, the way
    IdempotencyRecord.attempt_count already did.

⚠️ Breaking changes

  • EnvironmentalContext.auto_notify_emergency is now
    should_notify_emergency (attribute and to_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 a StubDomainAgent gives 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 NaN and infinity everywhere, through
    one validate_duration_seconds().
  • An Action carrying an idempotency_key must have a
    JSON-serializable payload.
  • docs/api_reference.md now covers every name in sett.__all__, with
    attribute tables for the four new exceptions; the concurrency section
    names ExecutionControlRegistry and InMemoryIdempotencyStore. Every
    public definition carries a docstring. Three new guard tests keep all of
    this from drifting again.
  • docs/SETT_Conventions_v2.md is now docs/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*.md mechanism. No version has shipped
    externally before now, so there is no adopter for a migration guide to
    serve; CHANGELOG.md is the record of what changed and why.
  • The per-release AUDIT_vX.Y.Z.md file. Only AUDIT_v0.11.0.md was
    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.md is the record of what was
    verified for a given release and why.

✅ Compatibility

  • process(), run_pipeline() and submit() 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 is SETTExecutor
    resolving handlers by exact action_type and failing closed, together
    with a domain-specific analyzer.
  • The public namespace of the submodules (names without a leading
    underscore that live outside sett.__all__) has no formal policy yet;
    that decision belongs to the v1.0 freeze. Full list in CHANGELOG.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.

v0.11.0 - End-to-end execution traceability

Choose a tag to compare

@EduDanielV EduDanielV released this 03 Aug 01:00
c823e09

End-to-end execution traceability: one trace_id now reconstructs
routing, broadcasts, agents, experts, native pipeline stages,
universal-memory publication, ethical decisions, action proposals,
handlers, results, rejections, and errors. An independent adversarial
review was run against the release candidate before publishing - every
finding reproduced against source and fixed (see AUDIT_v0.11.0.md).

✨ Added

  • Immutable ExecutionContext: generated or caller-supplied
    trace_id/run_id, causal parent_id, UTC creation time, opaque
    application/instance/subject/session/turn identifiers, recursively
    frozen size-bounded metadata, and derive() for child operations.
  • Run-local propagation via contextvars - bound only while a component
    executes, always reset (including after rejection and exceptions).
  • TraceEvent and per-orchestrator TraceRecorder: thread-safe
    structured events, monotonic sequence, SHA-256 hash chain, immediate
    cause_id references, parent-run verification, sanitized export, and
    exporter hooks.
  • End-to-end instrumentation across routing, broadcast, agents, experts,
    pipeline stages, universal-memory publication, ethical decisions,
    action proposals, handlers, results, rejections, and errors.
  • SETTOrchestrator.process_traced() / TracedResult, get_trace(),
    export_trace(), register_trace_exporter(), verify_traces(),
    last_trace_id.
  • Stable generated Action.action_id for causal effect correlation.
  • docs/execution_context_v0.11_design.md and MIGRATION_v0.11.md.

🔒 Security

  • Traces record operational metadata only - input/action payloads,
    handler return values, exception messages/locals, biometric values,
    risk profiles, prompts, model responses, and private-memory values are
    excluded by default.
  • Metadata is bounded (32 top-level keys, depth 8, 16 KiB serialized) and
    rejects sensitive key fragments and non-JSON objects.
  • handler.authorized is the committed pre-effect boundary: an exporter
    failure there records handler.blocked, raises
    SETTConfigurationError, and neither handler.started nor the real
    handler ever runs.
  • Trace exports are defensive copies; hash and causal verification
    detects mutation, removal, reordering, duplicate IDs, cross-trace/
    forward causes, invalid parent runs, and incomplete instrumented
    operations.

🐛 Fixed

  • tests/test_elevenlabs_adapter.py now guards with
    pytest.importorskip("requests") - already fixed as of v0.9.0 (see
    that release), carried forward unchanged.

✅ Compatibility

  • SETTAgent.process(), SETTExpert.resolve(), executor handlers,
    SETTOrchestrator.process(), broadcasts, and pipelines remain
    source-compatible. execution_context is additive and keyword-only.
  • The complete v0.10.1 suite passes unchanged.
  • The private companion-assistant reference application's complete
    baseline suite (842 tests) passes against this source release without
    any application code changes.

Status

  • 340 tests passing (290 before), 50 new (tests/test_execution_context_v011.py).
  • Independent adversarial review: 8/8 findings reproduced and fixed - see AUDIT_v0.11.0.md.

v0.10.1 - Documentation consistency and the Spanish-leak guard

Choose a tag to compare

@EduDanielV EduDanielV released this 03 Aug 00:56
eba1d9a

Four documentation/consistency fixes, all found and fixed the same day,
squashed into one release since none had been published individually
(same reasoning as v0.7.0's own three-pieces-in-one-release precedent).

📝 Fixed

  • docs/security_model.md claimed PrivateMemory "intentionally retains
    normal Python object identity" - true before v0.9.0, false since: that
    release changed read()/get_all() to return deepcopy()s (same
    hardening already applied to UniversalMemory in v0.8.0), but this
    paragraph was never updated to match. Found by an independent
    installation/upgrade validation exercise, cross-checking docs against
    actual behavior rather than symbol inventory. Corrected, with the "why"
    spelled out instead of just flipping the claim. docs/api_reference.md's
    PrivateMemory method table now explicitly says "deep copy (since
    v0.9.0)" for both read() and get_all().
  • sett/services_tts_stt/base.py's module docstring had a Spanish
    paragraph that does not exist in the actual published v0.7.0 source - a
    local-only artifact, never part of any released version. Removed, along
    with five Spanish example strings elsewhere translated to English for
    consistency (SETT is a general-purpose framework; its source should read
    in English throughout).

✨ Added

  • docs/SETT_Conventions_v2.md: the framework's own conventions and
    invariants document, published for the first time. Cited from source
    since v0.7.0 ("Convención #N" / SETT_Convenciones_v2.md), but never
    actually shipped - it only existed as a private working note used to
    draft the project's arXiv paper. Translated in full; every citing site
    across CHANGELOG.md and three source files updated to the new name
    and to English ("Convention #N").
  • tests/test_no_spanish_in_public_tree.py: a new guard test, same spirit
    and structure as test_no_internal_project_names.py. Scans the public
    tree for text that looks like Spanish (accented vowels, n-with-tilde,
    inverted question/exclamation marks) and fails if it finds any that
    isn't on an explicit, documented allowlist (the framework author's real
    name, the project's own "English, Español, 日本語" paper-language list,
    a couple of necessary illustrative example words/names, and a couple of
    historical CHANGELOG/README entries quoting already-fixed past mistakes
    for the record). Deliberately not a grammar-aware classifier - manual
    review before a release remains the backstop for the rare case of
    Spanish written with zero accented characters - but this catches the
    common case automatically going forward.

✅ Compatibility

Documentation and test-suite only. No code logic changed, no public API changed. 290 tests (up from 280 - 10 new, all in test_no_spanish_in_public_tree.py).

v0.10.0 - PhrasingExpert fact verification hook

Choose a tag to compare

@EduDanielV EduDanielV released this 03 Aug 00:53
eda2b26

✨ Added

  • PhrasingExpert.verify_facts(phrased, facts, context) -> str: an
    optional fourth hook, called after phrased already exists (from the
    LLM if configured and successful, from fallback_text() otherwise),
    letting a subclass validate the ACTUAL text against facts already known
    and swap it out if it contradicts them. Default implementation is a
    pass-through (return phrased), so every existing subclass keeps
    behaving exactly as before with zero changes required. resolve() now
    calls it as part of its template:
    determine_facts -> _phrase -> verify_facts.

    Motivated by a second-hand finding during an external audit: two
    independent subclasses in a downstream project each needed this same
    post-hoc check (a greeting that must never contradict the real time of
    day; a reply that must never assert the wrong name for the user) and,
    with no sanctioned hook for it, each had fully overridden resolve()
    just to insert one verification step - triggering the v0.9.0 override
    warning in the process. Same origin story as PhrasingExpert itself
    (see its class docstring): an unplanned repetition across independent
    call sites is the signal that something belongs in the framework, not
    copy-pasted per project.

  • SETTOrchestrator.register_executor(self, executor: SETTExecutor):
    added the missing type hint on executor (residual item from the
    v0.8.0 audit, never part of the 8 accepted fixes at the time). Zero
    behavior change.

✅ Compatibility

Fully backward compatible: verify_facts() is optional with a no-op
default, and does not change PhrasingExpert's existing abstract contract
(determine_facts/build_prompt/fallback_text are still the only
required overrides).

Status

  • 280 tests passing (up from 275).

v0.9.0 - Public API audit and hardening

Choose a tag to compare

@EduDanielV EduDanielV released this 03 Aug 00:50
20d1e7e

Eight findings from a full public-API audit of v0.8.0 - a symbol-by-symbol
inventory, then a phased pass over naming, signatures, exceptions,
mutability, subclassing contracts, documentation, concurrency posture, and
import surface. All eight accepted, none rejected. Same methodology as
always: nothing taken from a summary, every finding reproduced against the
actual source before deciding on a fix.

🔒 Added

  • SETTOrchestrator.verify_ethical_audit_log(): delegates to
    EthicalFilter.verify_audit_log(), reachable from the orchestrator
    itself instead of requiring access to the private _ethical_filter
    attribute. Closes a real gap: v0.8.0's tamper-evidence guarantee was
    invisible to anyone using only the documented entry point.
  • SETTValidationError(SETTError, ValueError): deliberate multiple
    inheritance, the same pattern the standard library's own
    json.JSONDecodeError uses. RiskProfile.__post_init__ now raises this
    instead of a plain ValueError; both except SETTError and
    except ValueError still catch it.
  • A non-blocking warning (logged, not raised) when a PhrasingExpert
    subclass overrides resolve() against its own documented "template
    method, do not override" contract. Fires at instantiation, does not
    prevent the override from working.

🐛 Fixed

  • PrivateMemory.read() and get_all() returned mutable references into
    internal state: a caller mutating a nested value could corrupt stored
    data without ever calling write(), with no trace in get_history().
    Both now return deepcopy()s, the same treatment UniversalMemory
    already received in v0.8.0.
  • tests/test_elevenlabs_adapter.py now guards with
    pytest.importorskip("requests"). Previously, a bare install (pip install -e ., without the [elevenlabs] extra) made these 12 tests
    FAIL instead of skip, contradicting the project's own documented
    install instructions. Present unchanged since v0.8.0 as published.

🗑️ Removed

  • sett/services_gen_ai/: an empty scaffold module (a one-line docstring,
    no classes, no functions, not referenced anywhere) since v0.1.0. Will be
    recreated with real content if a concrete use case appears.

📝 Docs

  • api_reference.md: documented SafetyAssessment, ContextAnalysis,
    TTSBase, STTBase, SentimentBase, SentimentResult, and
    SentenceSentiment - all public, exported, used in real tests,
    previously undocumented. Added a field table for EthicalRule.
    Documented EthicalFilter.verify_audit_log() /
    SETTOrchestrator.verify_ethical_audit_log(), and added sequence,
    previous_hash, and entry_hash to the audit log field lists. Added an
    explicit Concurrency section: no thread-safety guarantee for the
    framework as a whole beyond UniversalMemory's internal lock.

✅ Compatibility

Low risk, but not zero: import sett.services_gen_ai now raises
ModuleNotFoundError instead of importing an empty module. RiskProfile
now raises SETTValidationError instead of a plain ValueError; existing
except ValueError handlers keep working unchanged, since
SETTValidationError is one. No other public signature changed.

Status

  • 275 tests passing (264 before this round), 11 new.
  • Full audit methodology and findings: see CHANGELOG.md.

v0.8.0 - Fail-closed by default

Choose a tag to compare

@EduDanielV EduDanielV released this 27 Jul 04:07

🔒 Security and governance hardening

  • SETTExecutor.submit() now raises SETTConfigurationError if the
    Executor is not attached to a SETTOrchestrator, or if the attached
    memory has no EthicalFilter. Previously an unattached Executor would
    run the real handler with no governance at all.
  • SETTAgent._publish_to_universal() and propose_action() now raise
    SETTConfigurationError instead of silently returning when the agent
    is not wired. A misconfigured agent no longer looks like it worked.
  • UniversalMemory, the ethical audit log, the execution log, and
    history now return defensive deep copies. External code can no longer
    mutate internal state through a returned reference.
  • Memory history and both audit logs (ethical decisions and executed
    actions) are now a sequenced SHA-256 hash chain, with a verify_chain()
    helper. Tamper-evident within the running process, not an external
    signature.

🧠 Safety semantics

  • Added SafetyAssessment, separating situation_urgency,
    action_harm_risk, omission_risk, and protective_action.
  • human_at_risk no longer inflates an action's harm score. The old
    behavior pushed the score to reject_threshold - 0.01 any time a human
    was flagged at risk, which meant a genuinely protective action (like
    calling for help) could get rejected precisely because the situation
    was severe. Domain analyzers now decide harm; urgency stays a separate
    signal.
  • New conservative fallback: if human_at_risk is true, the action was
    not classified as protective, and the base verdict is ALLOW, the
    filter promotes it to WARN. The score is untouched, protective actions
    are never affected, and existing REJECT/WARN verdicts are never
    downgraded or relabeled. The audit entry records
    human_at_risk_without_protective_classification under
    decision_reason_codes.

🔧 Fixed

  • examples/with_ethics.py Scenario 2 now actually produces WARN,
    matching its own comment. It previously printed "expected: WARN" and
    returned ALLOW.
  • get_audit_log() / get_ethical_audit_log() no longer expose
    internal dict references that could be mutated after the fact.

✅ Compatibility

  • This release intentionally turns previously silent behavior into
    explicit errors. If your code builds a SETTExecutor or SETTAgent
    outside a fully wired SETTOrchestrator, wire it explicitly or expect
    SETTConfigurationError. No other public signatures changed.

📝 Docs

  • MIGRATION_v0.8.md walks through every behavior change with
    before/after examples.
  • docs/security_model.md documents the hash chain, defensive copies,
    and the exact human_at_risk promotion rule.
  • docs/api_reference.md updated for the new audit log fields
    (situation_urgency, action_harm_risk, omission_risk,
    protective_action, decision_reason_codes).

Status

  • 264 tests passing (up from 244 in v0.7.0).
  • Wheel built and installed in a clean environment; validated against a
    private reference application (709/709) built on top of this release.
  • Python 3.13 declared supported after validation.