First beta release, targeting 389 DS support engineers triaging live instances and SOS reports. Read-only diagnostics suitable for evaluation and internal troubleshooting; tool schemas, output formats, and configuration fields may still change before 1.0.0.
Added
Support-engineer workflow
- Mode errors now teach the workflow: refusing a live-only tool on an offline/archive server (and archive-only tools on live servers, log tools on remote servers) names the tools that DO work there —
try_insteadin error dicts, alternatives listed inLiveServerRequiredmessages - Admin playbooks:
docs/playbooks/archive-sos.md(summarize an SOS report before opening the case) anddocs/playbooks/install-troubleshooting.md(python-ldap builds, WSL2, uvx, config path resolution) docs/RELEASE.mdrelease checklist (manual pre-tag steps; publishing itself is automated on tag)- 8 release-critical routing cases in the eval dataset (SOS investigation, broken replication, slow directory, privacy/offline/archive mode queries) — gate in CI
- README restructured around the support-engineer path: uvx install from PyPI, four server modes table, "first questions to ask", tool groups, playbook links
Packaging & Distribution
- Proper installable package:
src/ldap_assistant_mcp/distribution package, hatchling build,ldap-assistant-mcpconsole script, tests excluded from the wheel - Tag-triggered release workflow (
release.yml): build → PyPI trusted publishing → MCP Registry publish - CI: fast no-container job (ruff + non-live tests + build + clean-venv wheel smoke test) on a Python 3.11/3.12/3.13 matrix; Dependabot;
livepytest marker - Package version reported to MCP clients; server-level
instructionsshipped by default; stderr logging handler (LDAP_MCP_DEBUGfor debug level)
Privacy
- IPv4/IPv6 address redaction in text sanitization (bare, bracketed, zone-indexed, and port-suffixed forms) with deterministic per-session
[ip-…]tokens - Startup WARNING when privacy mode is disabled (
expose_sensitive_data=true) - Fail-closed sanitization: unrecognized backend-result and finding-metadata keys are now redacted by default instead of passed through raw
- Fail-closed hardening extended to RUV data (including error text), attribute values outside the sensitive sets (identifier-shaped values tokenized, nested entry structures sanitized per-attribute), and finding top-level keys; text sanitization now also covers email addresses and modern TLDs (.xyz, .dev, .ai, country codes, …)
Configuration
LDAP_IS_OFFLINEenvironment variable implemented (was documented but ignored): impliesLDAP_IS_LOCAL=true, requiresLDAP_SERVERIDtls_verifyconfig field +LDAP_TLS_VERIFY/LDAP_CONNECT_TIMEOUTenvironment variables (from 0.4.x hardening)
Changed
Contract honesty
- Unimplemented
auth_methodvalues (sasl_gssapi,sasl_digest_md5,sasl_external) are now rejected with a clear error instead of silently degrading to a simple bind with an empty password; LDAPI/SASL EXTERNAL is selected viause_ldapi - Invalid
LDAP_PORT/LDAP_AUTH_METHODvalues fail startup with clear configuration errors instead of bare tracebacks - A server with
is_offline=truebut missingis_local/serveridnow gets a clear error instead of falling through to a live connection attempt - The OpenLDAP provider (experimental, bypasses the privacy sanitizer) now requires an explicit
LDAP_MCP_EXPERIMENTAL_OPENLDAP=trueopt-in;LDAP_PROVIDER=openldapwithout it errors with guidance
Diagnostics correctness (0.4.x hardening series)
- Fixed silently-wrong results in
find_unindexed_searches, disk/certificate health checks, backend lint discovery, SOS healthcheck parsing, logtime_rangefiltering, and offline replication detection - Archive robustness: decompression-bomb guard, extraction caching, DN-normalized
compare_dse_configs, streamed JSON log parsing, bounded log memory
Fixed
- Config-load failures for an explicitly configured
LDAP_SERVERS_CONFIGnow fail loudly instead of silently booting an env-fallback phantom server - Multiple privacy-mode leak paths closed (monitor connection data, credential hashes, mapping-tree suffixes, resource errors, traceback text)
- lib389 workarounds:
DSEldifcase-sensitive attribute lookup,DSEldiflast-line drop,DirsrvAuditLog.parse_linecrash,parse_timestampprecision loss