Releases: anulum/director-ai
Release list
v3.20.0
Added
-
Deployment latency SLO qualification.
director-ai latency-slonow drives
the live/v1/reviewendpoint at a declared request count and concurrency,
records p95 latency and error rate in a secret-safe integrity packet, and
exits non-zero when the deployment misses its declared operating point. The
gate is explicitly deployment- and workload-specific; it does not turn one
passing host into a universal latency claim. -
Fail-closed EU AI Act Annex IV template. The compliance surface can emit
a structured technical-documentation template whose mandatory evidence
fields block completion until populated, including system purpose, risk
controls, evaluation, monitoring, cybersecurity, and change history. -
Reusable remote benchmark dependencies. The remote benchmark launcher
accepts validated PEP 508 requirements through repeatable--remote-deps
options and safely quotes them for installation. The implementation is now
the neutralrun_remote_benchmark_gpu.py; the historical audit-specific path
remains only as a deprecated, provenance-preserving reproduction shim. -
RFC 3161 external timestamp anchoring for the compliance audit chain
(KIMI3-anchoring). The tamper-evident audit hash chain
(compliance/audit_log.py) proves nobody altered a row without the HMAC
secret, but not existence-at-time — the keyholder could rebuild it with
back-dated timestamps. The newcompliance/timestamp_anchor.pycloses that
gap: it obtains an RFC 3161 timestamp token from a Timestamp Authority over the
current chain head (which, through theprev_hashlinkage, commits to the whole
prior history), verifies the token (message-imprint binding, thecontent-type
andmessage-digestsigned attributes, and the CMS signature over the signed
attributes against the embedded certificate — RSA or ECDSA), and stores it in an
audit_anchortable. Verification has two tiers: by default internal-consistency
only (TSA-token-anchored); when trusted TSA roots are configured
(audit_anchor_tsa_roots,director-ai compliance verify-anchors --tsa-roots)
the signing certificate must also chain to a pinned root — validated at
genTime, with a sole critical time-stamping EKU on the leaf and RFC 5280 CA
constraints (basicConstraints CA=True, keyCertSign, pathLen) enforced on every
attacker-supplied intermediate — which is trusted-TSA-attested and completes
back-dating resistance.AuditLog.current_head()exposes the head; the
director-ai compliance anchor/verify-anchorscommands drive it. Opt-in
(audit_anchor_enabled, default off;audit_anchor_tsa_url,
audit_anchor_timeout_s) and offline-graceful — a down or unreachable TSA
yields a logged warning, never breaking the audit path. Needs thecrypto
extra (addsasn1crypto); the import is lazy so the free/core surface never
pulls it. Publishing to a public transparency log (Rekor) is deliberately out
of scope. BUSL-1.1 (paid compliance tier).
Changed
- Public pricing and package documentation now follows the canonical annual
plans: Pro at CHF or USD 490/year, Full at CHF or USD 980/year, and
Director-Class AI under a separately scoped commercial order. The two active
Polar checkout links were verified live before being recorded. - EU compliance references now cite the final Digital Omnibus instrument rather
than proposal-stage material. - Release dependency hygiene replaces yanked
build1.5.1 with stable 1.5.0
and advances the independent hash-pinned SAST stack to Semgrep 1.171.0.
Fixed
- Tag-driven releases now dispatch the Core, Lite, and paid publish workflows
whenRELEASE_PATis absent, preserving each workflow's own trusted-publisher
identity and preventing duplicate dispatch when the PAT-driven event chain is
available. Missing or mismatched release tags fail closed with a clear error. - Trusted RFC 3161 verification now selects the CMS signer by signer identifier
and enforces RFC 5280 CA constraints, key-cert-sign usage, path length, and a
sole critical time-stamping EKU across the supplied chain. docs/internal/is guarded as forever-private repository state so internal
planning and review material cannot enter public release history.
v3.19.0
Added
-
First-class
abstainedverdict + selective-prediction metrics.
CoherenceScore.abstainedmarks a verdict where a ground-truth store was
configured but retrieval found no usable context, so the factual signal fell
back to the neutral mid-score — a genuine "don't know" now distinguishable
from a borderline verdict. The newcore.scoring.selective_predictionturns a
batch of(CoherenceScore, is_hallucinated)verdicts into the standard
risk-coverage pair (coverage, selective accuracy), counting abstentions as
misses in overall accuracy so a guard cannot inflate its score by abstaining
on the hard cases. No scoring decision changed — the field is additive. -
Probability calibration for the coherence score. Isotonic (PAV) and Platt
calibration with ECE / Brier / reliability-bin reporting and a--max-eceCI
gate threshold. Measured on 20k grounded QA pairs: ECE 0.0345 raw improves to
0.0 (isotonic) / 0.0199 (Platt). -
Committed FEVER dev fact-verification benchmark result. Accuracy 78.4 %,
macro-F1 0.773, on the held-out FEVER dev split scored by a 3-class
DeBERTa-v3-large hallucination model (n=18209 scored, per-sample rows + git
provenance). A fail-loud guard rejects a 2-class model on the 3-class task and
a NaN-logit probe rejects a broken checkpoint, so the number cannot be
silently fabricated. -
Streaming contradiction-halt corpus at n>=500/class + isolated refresh.
The shared halt corpus grew from 135/30 to 612/507 matched fact pairs (values
drawn from authoritative reference tables, correct by construction). On an
isolated A30 GPU (load average 2.2, not the earlier contended 33), the
contradiction-halt gate catches semantic contradictions at 0.9309 recall —
the headline capability, consistent with the prior measurement — and
numeric-value contradictions at only 0.5586, a documented gap where
NLI-based detection reasons weakly over bare numbers (aggregate recall 0.7179,
false-halt 0.0065). The per-mode split is recorded inhalt_recall_by_kind;
numeric-contradiction detection is a roadmap item, not a shipped capability. -
The adversarial robustness suite now covers NLI-evasion classes. The
built-in patterns targeted the prompt boundary (encoding tricks, role-play,
zero-width/homoglyph); the classes the 2026-07-16 red-team reproduction
measured — synonym-reworded falsehoods, authority/recency framing
("As of 2025, researchers confirmed…"), and explicit negations of true
facts — target the detector itself and are now first-class pattern
categories (paraphrase,temporal,negation) in
testing.adversarial_suite. -
AnthropicProvider streams real tokens; no provider degrades silently.
AnthropicProvider.stream_generate()now streams Messages API server-sent
events (content_block_delta/text_delta) instead of silently falling
back to a single non-streamed completion, and gains abase_urlparameter
(Anthropic-compatible gateways, parity withOpenAIProvider). The base
LLMProvidersingle-shot fallback — still used by providers without a
streaming endpoint guarantee (e.g.HuggingFaceProvideron the classic
Inference API) — now logs a warning naming the degradation instead of
yielding one giant chunk with no indication that streaming never happened. -
CoherenceScore.degraded_mode— the verdict says when it came from
heuristic scoring. Without the[nli]extra the scorer falls back to a
weak word-overlap heuristic that false-blocks true claims, and the only
signal was a log line. The verdict now carries a first-class
degraded_mode: bool(true when no model-backed contradiction path was
available), and the fallback log line states the consequence plainly
("install director-ai[nli] or expect false blocks"). No scoring behaviour
or defaults changed. -
audit_strict_mode— the compliance audit trail fails closed. With
strict mode on, constructing the audit log raises unless a PII redactor is
configured (or raw storage is explicitly acknowledged with
allow_raw=True), and raises when no durable HMAC secret is available
(hmac_secret=orDIRECTOR_AUDIT_HMAC_SECRET) — a per-process random
key would make the tamper-evident seal unverifiable across restarts, and
previously both conditions only warned. The production profile enables it,
the production scaffold declaresDIRECTOR_AUDIT_HMAC_SECRETin its
.env, anddirector-ai production-checkrequires it. The non-strict
default keeps the previous warn-only behaviour. -
stream_disclosure="buffered"proxy mode — a halted stream discloses
nothing unreviewed. In the defaultimmediatemode a mid-stream halt
stops future tokens only, so content emitted before the halt has already
reached the client (early termination with partial disclosure — now named
explicitly in the README caveats). The new opt-inbufferedmode withholds
streamed chunks until the accumulated content passes a review, discards the
unreleased window on a halt, gates the final release on the terminal
[DONE]review, and fails closed if the upstream drops without[DONE]—
at a latency cost of up toSTREAM_CHECK_INTERVAL(8) chunks. Available as
create_proxy_app(stream_disclosure=...)and
director proxy --stream-disclosure buffered. The default is unchanged.
Fixed
- Zero-width and confusable characters no longer false-halt a true claim.
The NLI inference layer now scrubs its text inputs (NFKC normalisation +
removal of control/format characters, e.g. a U+200B zero-width space) before
tokenisation, at the single_tokenizechokepoint. An invisible character
inside an otherwise-true claim previously split a word for the tokenizer and
inflated the divergence, blocking a correct output (measured: one zero-width
space pushed support from 0.87 to 0.44). Confusable letters are left
unfolded, so legitimate non-Latin scripts are unaffected; plain-ASCII text
skips the scan entirely. - Grounded true answers to questions are no longer false-halted. When a
grounding store is configured, the logical-coherence signal (h_logical)
now scores against the retrieved context instead of the raw prompt. A bare
interrogative prompt is a degenerate NLI premise — a true declarative answer
does not entail the question that prompted it, so the old premise=prompt
scoring inflatedh_logicalfor every true answer and blocked correct
outputs (reproduced on GPU against the KIMI red-team, 2026-07-16). Scoring
the logical signal against the context keeps false claims caught (the
context contradicts them) while letting true claims through, on both the
singlereview()and coalescedreview_batch()paths. Ungrounded reviews
(no store) are unchanged. No change to the score weights or threshold.
v3.18.1
Fixed
- Live temporal-refresh moves from the free wheel to the paid tiers —
correcting a licence-boundary leak.core/scoring/temporal_refresh.py
carries a BUSL-1.1 header (it is the paid live web-search refresher), but
the 3.18.0 open-core re-slice omitted it from the paid manifest, so the
3.17.0 and 3.18.0 free wheels shipped it by accident — a BUSL module
physically inside the Apache-2.0 artefact. It now ships only in
director-ai-pro/director-ai-full. If you relied on
guard.temporal_refresher(live web-search staleness checking) on a free
install, it was never licensed for the free tier; it is now a Pro feature
and a core-only install raises a clear "requires the advanced tier" error
(the sibling Apache-2.0temporal_freshnessstaleness flagger stays
free). Thetemporal_consistencyproperty gained the same friendly
guard. A parity test now fails the build if any BUSL-headered file falls
outside the paid boundary, so this cannot recur. REUSE.tomlno longer contradicts the per-file BUSL headers: an explicit
BUSL-1.1 annotation block was added for the advanced/labs source so a
reader ofREUSE.tomlsees the same split the file headers declare
(reuse lintwas already compliant — headers are authoritative).
v3.18.0
Changed
- The public PyPI wheel is now core-only (open-core re-slice per the
2026-07-16 packaging decisions). The production server surface
(REST/gRPC server, proxy, routers, middleware), the advanced-accuracy
set (verified_scorer,sharded_nli, cross-model consensus,
forecasting, calibration), evaluation, training/fine-tuning and the
enterprise packages now ship only in the commercial
director-ai-pro/director-ai-fullwheels (BUSL-1.1), installed
from the private index atpypi.remanentia.com. Public names remain
importable in a core-only install and raise a friendly
"requires the advanced tier" error when used; the free streaming
halt, 5-tier scorer, RAG grounding, CLI verification surface and
integrations are unchanged. - The sdist mirrors the same boundary and carries the build shims, so a
wheel built from the sdist applies identical slicing. - Docker images (CPU + GPU) now compose the free core wheel with the
director-ai-prooverlay, matching their pre-slice content — the
server image has always carried the BUSL production surface. - Paid wheels declare
director-ai>=3.18.0,<4: the slimmed core is a
file-level prerequisite for overlaying the pro/full modules.
Added
scripts/check_free_wheel.py— CI contents check plus an
unpacked-wheel import simulation proving the free wheel imports
standalone with friendly tier boundaries; the public publish lane
refuses paid-tier artefacts (dependency-confusion gate) and the paid
lane uploads to the private index.packages/paid_tier_manifest.json+packages/tier_build_hooks.py—
the shared record of paid single modules consumed by the build hooks,
wheel checks and the packaging parity test suite.
v3.17.0
Changed
- Dialogue reviews now gate raw weakest-link claim support at a
matched-FPR operating point instead of squeezing bidirectional NLI
through the 0.80 baseline (WCS-2a). The WCS-1 end-to-end proof
(BENCHMARK_REPORT §16, tracked artefact
e2e_nli_only_200_wcs1_wired.json) showed the squeeze absorbs
evidence improvements — decisions were identical at catch 4.5 % —
while the raw operating point measures catch 27 % at the same 4.5 %
false-positive rate on HaluEval-dialogue. Each response claim is
scored independently against the conversation context and the
weakest claim decides; coherence for the dialogue route is that raw
support. New config:nli_dialogue_scoring
("raw_support"default,"baseline_squeeze"restores the previous
behaviour) andnli_dialogue_support_threshold(seeded 0.0091 from
the FactCG sweep; recalibrate per deployment — see the calibration
tool below). - Cache hits now resolve the review gate exactly like fresh scoring
(task detection + adaptive per-task threshold + meta-classifier +
raw-support operating point). Previously a cache hit re-gated the
cached score on the global threshold, so a decision could differ
between a cache miss and a cache hit of the same input. - Summarisation claim-coverage layers (MiniCheck and FactCG) now score
against the whole source document instead of a 3 000-character
prefix; each backend applies its own long-input chunking. The
2026-07-15 evidence sweep (BENCHMARK_REPORT §16) showed the prefix
truncation is dominated on both HaluEval and RAGTruth — catch at the
matched false-positive rate rose from 0.049 to 0.289 on RAGTruth
Summary with whole-document scoring. The previous behaviour is
restorable viaDirectorConfig.nli_summarization_premise_chars = 3000
(DIRECTOR_NLI_SUMMARIZATION_PREMISE_CHARS).
Security
- Defence-in-depth hardening from the validated 2026-07-15 external
review intake: SQL DDL identifiers and column clauses are strictly
validated before f-string composition (audit log chain migration,
feedback-store column migration — internal constants today, now
guarded against future callers); gRPC server reflection is an
explicit opt-in (grpc_reflection_enabled, default off — the full
service schema is a reconnaissance aid); the regulated-domain
profiles (medical,finance,legal) enableprivacy_modeso
PII is redacted from logs and review queues by default. - Streaming trend statistics (
core/runtime/streaming.py) now state
their contract honestly: they are MANDATORY Rust accelerators
(enforced 2026-05-22) — the unreachable pure-Python fallback bodies,
the misleading_RUST_TRENDdispatch flag, and the stale
"falls back to Python" tests (inverted by a conftest hook) are
gone; kernel-absent installs raise the actionable[rust]-extra
error, and the tests assert that propagation directly. - Operator-supplied regexes (policy YAML patterns, sanitiser
extra_patterns/allowlist) are validated before compilation:
the classic catastrophic-backtracking shape — an unbounded repeat
nested inside another unbounded repeat, e.g.(a+)+— is rejected
with an actionable error, as are patterns over 4 096 chars
(core/safety/_regex_guard.py). Bounded repetitions pass. - WebSocket streaming sessions cap each prompt at 100 000 chars
(mirrors the SSE cap; the per-connection char budget still applies). - Prompt/query hashes in logs are now keyed (HMAC-SHA256 with a
per-process ephemeral key) instead of bare SHA-256, so exfiltrated
log lines cannot be brute-forced offline against short prompts;
in-run correlation is unchanged (the meta-guard decision log is
in-memory, retrieval query hashes are log-line correlators).
Fixed
- PII redaction was quadratic in the number of findings: the
non-overlapping span selection rescanned every accepted span per
candidate, so a 2 MB input of dense PII took 13 minutes to redact —
a denial-of-service vector whereverprivacy_modeis enabled. The
selection is now linear (2.4 s on the same input, 324× faster),
with the old implementation kept as a behavioural oracle in tests.
Added
-
Weakest-link summarisation aggregation
(nli_summarization_aggregation="weakest_link"+
nli_summarization_support_threshold): scores every summary claim
against the whole source and gates the least-supported claim at a
matched-FPR support operating point — the only WCS-1 configuration
that improved on both HaluEval (catch 0.120 → 0.125) and RAGTruth
(0.049 → 0.289). Default stays the coverage/Layer-A blend. -
Matched-FPR operating-point calibration
(director_ai.core.calibration.operating_pointsand
director-ai operating-points <labeled.jsonl>): collects raw
weakest-link supports through the production scorer
(CoherenceScorer.raw_task_support), picks the largest support
threshold whose false-positive rate on labelled good responses stays
within a per-task target, and emits a ready-to-use config/env
overlay. Shipped thresholds are sweep seeds — deployments should
calibrate on their own traffic. -
Rubric-scored, optionally ensembled LLM judge
(DirectorConfig.llm_judge_rubric/llm_judge_ensemble): the
escalation judge can score grounding / fabrication-risk /
contradiction-risk dimensions (G-Eval-style, composite decides the
verdict) instead of a bare YES/NO, and can aggregate 1–5
independent calls — majority vote with confidence damped by the
agreement fraction, so a split panel weakens the judge's influence
on the blended score. Defaults unchanged (single-shot verdict);
invalid or empty panels fall back to the NLI score exactly as
before. -
Self-consistency / semantic-entropy uncertainty signal
(director_ai.core.scoring.self_consistency):SelfConsistencyScorer
clusters caller-supplied alternative generations by bidirectional
entailment (shipped NLI backend, lexical fallback labelled in the
result) and scores normalised semantic entropy plus the primary
response's consensus agreement. Opt-in fusion on the review
pipeline:enable_self_consistency(weight=…)+
review_with_samples(prompt, action, samples)— the fused score can
revoke an approval but never approves a rejected review;
CoherenceScoregainsself_consistency_score,semantic_entropy
andself_consistency_backendfields. -
Hardened per-tenant isolation for shared vector indexes:
TenantScopedBackend
(director_ai.core.retrieval.vector_store.tenant_guard) binds any
VectorBackendto one tenant — adds stamp the bound tenant into
metadata (conflicting labels raiseTenantIsolationError), an
empty caller tenant can no longer widen a query to the whole
index, and every returned row is verified against the bound tenant
(foreign or unlabelled rows are dropped and counted in the
tenant_isolation_violationsmetric, or raise with
strict=True).VectorGroundTruthStore.grounded()gains
enforce_tenant_isolation=Trueto wrap the whole retrieval stack;
FAISSBackendtenant-filtered queries now expand the over-fetch
window geometrically until enough tenant documents are found or
the whole index is searched, instead of silently starving tenants
whose documents sit beyond the previous fixed 3× window. -
Hybrid retrieval fusion strategies beyond RRF
(director_ai.core.retrieval.vector_store.fusion):convex
(min-max normalised convex combination, CombSUM family),combmnz
(CombSUM × cross-run agreement) andzscore(standardised-score
sum) join the default weightedrrf. Selectable via
HybridBackend(fusion_method=...),
VectorGroundTruthStore.grounded(fusion_method=...)and the new
DirectorConfig.hybrid_fusion_method/
hybrid_sparse_weight/hybrid_dense_weightfields;
HybridBackend.with_fusion()derives query views that share one
BM25 + dense index so strategies can be compared without
re-indexing. The BM25 run now carries native scores into the
fusion layer, and the RRF docstring cites the actual source
(Cormack, Clarke & Büttcher, SIGIR 2009). -
NeMo Guardrails rails-as-config loader
(director_ai.integrations.rails_config.load_rails_config): maps the
honest subset of a NeMo config directory (config.yml+ Colang.co
files) onto Director's nativePolicy— Colang v1 topical refusal
rails become forbidden phrases, recognised self-check/content-safety
rails enable the dependency-free moderation detectors — and reports
every unmapped construct inRailsLoadResult.unsupportedinstead of
silently dropping it. RAIL XML deliberately raises with a pointer to
the native Guardrails AI validator integration. New docs page
docs-site/integrations/nemo-rails.md. -
Computed AI-governance controls (
director_ai.compliance. governance_controls, BUSL tier):compute_governance_controls()
derives NIST AI RMF 1.0 / ISO/IEC 42001:2023 / EU AI Act crosswalk
controls from observable deployment state — DirectorConfig guard and
data-governance knobs, a liveverify_chain()pass over the
tamper-evident audit log, and documentation evidence artefacts under
an operator-supplied evidence root. Six controls cover Articles 9
(risk management), 10 (data governance), 11 (technical
documentation), 12 (record-keeping), plus the Article 15 accuracy
bridge and Article 14 human-oversight readiness; every status is
derived from namedControlSignalobservations, so missing inputs
degrade honestly instead of aborting. New endpoint
GET /v1/compliance/governance-controls(never 503s — an
unconfigured audit log is itself the reported finding) and CLI
subcommanddirector-ai compliance governance. Previously only
Article 15 reporting was computed; SOC 2/ISO 27001/HIPAA remain the
static readiness catalogue. -
POST /v1/stream/sse— REST Server-Sent Events streaming endpoint
(routers/streaming_sse.py). Serves the same two session shapes as
the `...
v3.16.0
Director-AI v3.16.0 Standalone director-ai-lite distribution (dependency-free streaming-halt guard) alongside the director-ai open-core. Pinned prompt-injection model revision; pypdf floor bump; Rust span-reduction path. Authored by Anulum Fortis & Arcane Sapience (protoscience@anulum.li)
Director-AI v3.15.3
What changed
- Release metadata and documentation alignment to 3.15.3 across package and public docs.
- Changelog entry for 3.15.3 with evidence-gate guidance.
- Legacy API and CLI references updated to current release.
- Legacy cookbook release references normalized for current release line.
v3.15.2
Changes
- Refreshes product overview, evaluation onboarding, quickstart, tutorial, notebook-gallery, and API entry points for clearer buyer, evaluator, and developer understanding.
- Bumps package, citation, and lockfile metadata to 3.15.2 and refreshes capability inventory.
- Keeps release and container packaging version-independent where practical, including the Docker wheel install path.
- Aligns optional Qdrant backend testing with CI's locked install policy.
Verification
- GitHub CI green on 2a44c21: https://github.com/anulum/director-ai/actions/runs/26781046725
- Pre-commit, CodeQL, and OpenSSF Scorecard green on the same commit.
- Local push gates green: ruff-format, ruff-check, version-sync, bandit, and spdx-guard.