Repository navigation
Releases
Releases · ylecoyote/uns
v0.6.1 — MPDD 2026-11-03 Audit Remediations (F01-F15) & Variant 4a Brand System
[0.6.1] - 2026-11-03
Added
- UNS Brand System (Variant
4a) & Complete Console Screenshot Gallery:- Added clean SVG brand marks (
docs/assets/logo/uns-mark.svg,uns-mark-on-dark.svg,uns-mark-mono.svg,uns-lockup.svg,uns-lockup-dark.svg,apps/ui/public/favicon.svg) and GitHub social preview card (docs/assets/logo/uns-social-preview.png). - Integrated
UnsLogoMark(apps/ui/src/components/UnsLogoMark.tsx) into the UNS Console top navigation bar and sign-in header, configured MkDocs theme logo/favicon (mkdocs.yml), and expanded the documentation screenshot gallery to 8 high-DPI views includingconsole-policy-inspector.pngandconsole-docs.png.
- Added clean SVG brand marks (
Fixed
- MPDD v2.5 Security & Functionality Audit Remediations (
F01–F15):F01(Scoped Read & MCP Tenant Isolation): Enforced fail-closed record-level and collection-levelallowed_sources+allowed_namespacesbounds across/api/v1/runtime/notifications/{id},/api/v1/runtime/dead-letters,/api/v1/notifications/{id}/delivery,/api/v1/notifications/{id}/audit,/api/v1/dlq*,/ui/deliveries*,/ui/audit, and all registereduns-mcpread/list tools before pagination and counts.F02&F09(Governance Approval Identity & Durable Settlement Callbacks): Includedtenant_id,resource_type, andresource_idin_deterministic_decision_id(), enforced bound-content fingerprint matching (ApprovalConflictError) inGovernanceApprovalBridge.request_approval(), and decoupled terminal approval status fromon_settledcallback completion so failed resume callbacks retry across subsequent resolution and runtime sync calls.F03,F07,F08,F10(Policy Evolution Atomicity, Exact Draft Binding & Shared-DB Cache): Bound exactdraft_policy_idandcandidate_hashtoAPPROVE_DRAFTevidence and verified/materialized the exact approved candidate inactivate_draft(); madepromote_to_shadow(),approve_to_draft(), andactivate_draft()rollback-safe across policy and learning stores; removed the process-local negative candidate cache so warm workers immediately evaluate peer-createdSHADOW/PREVIEWcandidates; preserved explicitdedup_window_seconds=0inconfig_dict_to_policy().F04(PagerDuty Provider Incident Key Isolation): Scoped PagerDutydedup_keygeneration and webhook target resolution to the obligation's isolated runtimededup_key(uns_obligation_dedup_key) and persistedCHANNEL_ATTEMPT_RESULTmessage_id, rejecting ambiguous raw producer keys across isolated tenants.F05(Bounded Unmatched Route Metric Cardinality): Mapped unmatched HTTP 404 paths to"__unmatched__"and normalized HTTP methods insrc/notification/metrics.pyandsrc/uns/api/observability.py.F06(Admin Gate onpromote_to_shadowProposal Creation): Requiredadminscope whenpromote_to_shadow: trueis passed toPOST /api/v1/policies/proposals.F11,F12,F13,F14,F15(SLO Stalled-Backlog Gate, Shared Channel Health,/readyzHTTP 503, Lifespan Reload Worker & Docs Contracts): Addedzero_stalled_pending_backloggate tocompute_slo_report(), wiredRuntime._channel_result()into the sharedChannelHealthTrackeracross HTTP and MCP, returned HTTP503on/readyzfailure, started a background policy reload worker inapp.py:lifespan, and resolved all 39 MkDocs link diagnostics (validation.links.not_found: warn).
v0.6.0 — Pre-Execution Governance Engine, SLO Certification CLI & Hardening
What's New in v0.6.0
Added
- In-Tree Pre-Execution Governance Engine & Approval Obligation Bridge (
uns.governance, #49):- Completed
src/uns/governance/context_schema.py(ContextSchema,parse_field_path(),validate_policy_against_schema(),validate_context_capsule(),resolve_field_path(), and canonical JSON SHA-256compute_context_hash()). - Completed
src/uns/governance/decision_engine.pywith pure, deterministicdecide()(DENY > REQUIRE_APPROVAL > ALLOWprecedence, full rule evaluation without short-circuiting, and default-DENYfallback) and impureDecisionEnginesupporting hot-reload last-known-good quarantine, bounded audit ledger (max_audit_entries), and per-intent fail-mode semantics (SAFETY/GOVERNANCE/OPERATIONALfail-closedDENY;INFORMATIONALfail-openALLOWwith operational alert emission). - Added
src/uns/governance/approval_workflow.py(GovernanceApprovalBridge,ApprovalRequestRecord,ApprovalStatus,sign_approval_callback(),verify_approval_callback()) wiringREQUIRE_APPROVALdecisions to durableuns.Runtimenotification obligations (idempotency_key="gov-approval:{decision_id}"), stateless cross-restart recovery (_recover_from_runtime()), and HMAC-SHA256 signed resume callbacks (X-UNS-Signature,X-UNS-Timestampwith±300sreplay guard).
- Completed
- SLO Telemetry & Certification CLI Harness (
uns-slo-certify/src/uns/slo.py, #48):- Added
compute_slo_report(),format_slo_markdown(), and theuns-slo-certifyconsole script entry point to compute SHA-256 hash-verifiable operational SLO receipts (receipt_sha256/receipt_hash), human response latency percentiles (p50,p95,max), persistent external provider error rates,recording_onlyvs. live external provider classification (observed_live_span_days), and 6-gatev1.0certification checks.
- Added
Fixed
- MPDD v2.5 Post-Milestone 4 Hardening:
- Enforced upfront
Content-Lengthcheck and streamingMAX_WEBHOOK_BODY_BYTES(262,144) cap insrc/uns/api/routes_webhooks.py:_read_bounded_body(). - Added
SQLAlchemyPolicyStore.retire_candidate_revisions()and wiredShadowPolicyEvaluator.reject_delta()to retirePREVIEW/DRAFTrevisions on rejection so rejected proposals cannot resurrect on subsequent intakes. - Replaced deprecated
HTTP_422_UNPROCESSABLE_ENTITYstatus constant withHTTP_422_UNPROCESSABLE_CONTENTinsrc/notification/routes.py.
- Enforced upfront
v0.5.0 — Governed Policy Evolution & Shadow Evaluation Workspace
Highlights (v0.5.0)
- Automated
PREVIEWShadow Evaluation Runner (uns.shadow_evaluator.ShadowPolicyEvaluator, #46):- Asynchronous in-process shadow evaluation of
SHADOWpolicy deltas andPREVIEWpolicy revisions against live notification intake without external channel side effects or live obligation mutation. - Deterministic candidate vs. baseline routing comparison (
policy_to_envelope,envelope_to_policy), allow-listed policy field-path validation (ALLOWED_POLICY_FIELD_PATHS), O(1)_write_seqfast-path skipping when noPREVIEW/SHADOWcandidates exist, and automaticShadowEvaluationResult+ShadowEvaluationAggregatepersistence inSQLAlchemyPolicyLearningStore(UNS_SHADOW_EVALUATION_ENABLED,UNS_SHADOW_MIN_SAMPLES,UNS_SHADOW_ACCURACY_THRESHOLD).
- Asynchronous in-process shadow evaluation of
- Console
/policyPromotion Workflow & Governed Policy Delta API (#47):- Added read endpoints (
GET /ui/policies/proposals,GET /ui/policies/proposals/{delta_id},GET /api/v1/policies/proposals,GET /api/v1/policies/proposals/{delta_id}) and operator-authenticated promotion endpoints (POST /api/v1/policies/proposals,POST /api/v1/policies/proposals/{delta_id}/shadow,/approve,/activate,/reject, andPOST /api/v1/policies/revisions/{policy_id}/activate). - Enforced
BOUNDS,CONFLICT, andINVARIANTSguards, baseline hash drift checks (409 policy_baseline_drift), and shadow sample/accuracy threshold gates before promotingSHADOWdeltas intoDRAFTrevisions and explicitly activatingDRAFT -> ACTIVE. - Updated
/policy(PolicyInspectorPage.tsx) with the Proposals & Shadow Evidence workspace, interactive proposal builder, sample/accuracy/guard/baseline badges, one-clickPromote to SHADOW/Approve to DRAFT/Activate DRAFT -> ACTIVEactions, and the Shadow Evidence & Guard Ledger drawer.
- Added read endpoints (
- Documentation & Console Gallery:
- Added high-DPI screenshots of the 6-surface Modernist UNS Console under
docs/assets/screenshots/acrossREADME.md,docs/README.md, anddocs/user-guides/OPERATOR-CONSOLE-GUIDE.md.
- Added high-DPI screenshots of the 6-surface Modernist UNS Console under
v0.4.0 — Multi-Node Operations, PostgreSQL Maintenance & Scoped RBAC
Highlights in v0.4.0
1. PostgreSQL Retention & Archive-Before-Prune (uns-maintain, #43)
- Extended
uns-maintain(src/uns/maintenance.py) to supportpostgresql+psycopg://databases alongside SQLite. - Added PostgreSQL native UUID casting in
_eligible()(sa_cast(work.c.id, Uuid)),SET LOCAL lock_timeout = '30s', transactional advisory locking (SELECT pg_advisory_xact_lock(758392014)), andFOR UPDATEcandidate row locking before exporting mode-0600SHA-256 verified JSON archives and pruning settled notification groups.
2. Cross-Process Policy Reload Broadcast (LISTEN/NOTIFY & Redis Pub/Sub, #44)
- Added
PolicyReloadEnvelope,RedisPolicyReloadBroadcaster,RedisPolicyReloadSubscriber(uns:policies:reload/UNS_POLICY_REDIS_CHANNEL), andPostgresPolicyReloadListener(LISTEN uns_policy_reload) insrc/uns/policy_runtime.pyandsrc/db/policy_store.py. - Added parsed
NotificationPolicycaching onPolicySnapshotand warm snapshot caching + activation listeners onSQLAlchemyPolicyStoreandPolicyRuntimesosave_policy(),bootstrap_policies(), andPOST /api/v1/policies/reloadbroadcast revision changes immediately across multi-worker deployments.
3. Source- & Namespace-Scoped Credentials Across HTTP, WebSocket, & uns-mcp (#45)
- Extended
WritePrincipal(src/uns/api/auth.py) withallowed_sourcesandallowed_namespaceswildcard/prefix patterns (*,ci-*,deploy.*), configured viaUNS_PRODUCER_ALLOWED_SOURCES,UNS_PRODUCER_ALLOWED_NAMESPACES,UNS_RESPONDER_ALLOWED_SOURCES,UNS_RESPONDER_ALLOWED_NAMESPACES,UNS_OBSERVER_ALLOWED_SOURCES,UNS_OBSERVER_ALLOWED_NAMESPACES, and multi-team JSON credentials (UNS_SCOPED_API_KEYS). - Enforced source and namespace scopes (
403 namespace_or_source_forbidden) across HTTP REST,/ui/*, WebSocket/ws/agents/{agent_id}live push + replay + ack frames, anduns-mcp(UNS_MCP_ALLOWED_SOURCES,UNS_MCP_ALLOWED_NAMESPACES).
v0.3.0 — Bi-Directional Webhooks & Registry Publishing
Highlights in v0.3.0
- Inbound Signed Slack Interactivity Webhook (
POST /api/v1/webhooks/slack, #40):- Verifies
X-Slack-Signature(v0=<hex>) andX-Slack-Request-Timestamp(±300sreplay window) withUNS_SLACK_SIGNING_SECRET(constant-timehmac.compare_digest, 256 KB body limit, fail-closed503when unset). - Settles the canonical
obligation_owner_iddirectly from Slack Block KitAcknowledge(ack_<id>) andDismiss(dismiss_<id>) buttons as actorslack:<team_id>:<user_id>and returns an in-place Block Kit message update (replace_original: true).
- Verifies
- Inbound Signed PagerDuty v3 Webhook & Bi-Directional Sync (
POST /api/v1/webhooks/pagerduty, #41):- Verifies
X-PagerDuty-Signature(v1=<hex>, supporting comma-separated rotation signatures) withUNS_PAGERDUTY_WEBHOOK_SECRET(fail-closed503when unset). - Settles
uns-<dedup_key>/uns-<notification_id>obligations onincident.acknowledged/incident.resolvedaspagerduty:<agent_id>, and propagates HTTP/SlackACKandDISMISSoutbound viaRuntime.sync_pagerduty_incident()(PAGERDUTY_OUTBOUND_SYNC).
- Verifies
- Automated PyPI & Multi-Arch GHCR Release Publishing (
.github/workflows/release.yml, #42):- Builds, smoke-tests, and attaches Python wheels/sdists to GitHub Releases, publishes multi-arch (
linux/amd64,linux/arm64) images toghcr.io/ylecoyote/unswith build provenance attestations, and publishes to PyPI via OIDC Trusted Publishing orPYPI_API_TOKEN.
- Builds, smoke-tests, and attaches Python wheels/sdists to GitHub Releases, publishes multi-arch (
Full Changelog: v0.2.0...v0.3.0
v0.2.0
[0.2.0] - 2026-11-02
Added
- Durable Transactional Outbox Runtime (
uns.Runtime&uns.Client):- Atomic SQLite/SQLAlchemy intake (
uns_notifications,uns_events,uns_dedup) combining policy provenance resolution, idempotency verification (principal + source + idempotency_key), and deduplication window claiming (LEADER/FOLLOWERgenerations). - Fenced 60-second delivery leases (
lease_token,lease_until) with pre-channel fencing (CHANNEL_ATTEMPT_STARTED), append-only per-channel attempt observations (CHANNEL_ATTEMPT_RESULT),LEASE_LOSTrecording, exponential retry backoff, and automatic follower settlement (DEDUP_SATISFIEDon leader delivery;OBLIGATION_HANDED_OFF,DEDUP_OWNER_PROMOTED, andDEDUP_RELINKEDon leader exhaustion). - Durable successor lineage (
dedup_successor_id) and guarded replay (replay_blocked_by,replay_block_reason) preventing duplicate delivery when a successor obligation is pending or already satisfied (F-01,F-02). - Deadline/cancellation-aware SMTP admission and
UNKNOWNprovider outcome recording for timed-out in-flight sends (F-04a,F-04b). - Durable acknowledgment deadline sweeps (
TIMED_OUT) and due-time ordered (callback_until, at, id) at-least-once terminal callback delivery (deliver_callbacks,F-06). - Operator dead-letter inspection (
GET /api/v1/runtime/dead-letters), attributable cycle replay (POST /api/v1/runtime/notifications/{id}/replay), and non-replay failure resolution (DELETE /api/v1/dlq/{id}).
- Atomic SQLite/SQLAlchemy intake (
- Revision-Locked Policy Authority (
uns.policy_runtime.PolicyRuntime):- Immutable
ACTIVEpolicy snapshots (notification_policy_revisions,notification_policy_snapshots) locked at intake and read in a single lock-freeSELECTduring warm simulation/inspection (F-05). - Strict enforcement blocking producer overrides from weakening
ACTIVEpolicies and blocking reserved adapter-steering metadata keys (slack_channel,email_to,pagerduty_severity,websocket_user_id).
- Immutable
- Unified HTTP, Console Read-Model, & WebSocket Service (
uns/uns.app:create_app):- Consolidated FastAPI service mounting
/api/v1/notifications/*,/api/v1/runtime/*,/api/v1/policies/reload,/ui/*,/ws/agents/{agent_id}, public/healthz, and authenticated/readyzand/metrics. - Pre-accept WebSocket authentication supporting native
Authorization: Bearerheaders and browseruns.v1+bearer.<base64url>subprotocols with closed-listOriginvalidation.
- Consolidated FastAPI service mounting
- Trusted-Local MCP Server (
uns-mcp):- Read-only default mode (
stdio-local) and explicit--enable-writesmode (stdio-persistent) requiringUNS_DATABASE_URL,UNS_API_PRINCIPAL, andUNS_MCP_DELIVERY_CONFIRMATION_TOKENwith an owned lifespan recovery worker and runtime-bound read helpers (F-07).
- Read-only default mode (
- Explicit Database Maintenance & Archival CLI (
uns-maintain&uns-migrate):uns-migratefor idempotent additive schema bootstrap, successor-lineage reconstruction, and callback due-time normalization.uns-maintainfor bounded operational pruning, cursor continuation (--after-id), andO_EXCLmode-0600SHA-256 verified JSON group archival (--archive).
- Responder & Operator Console (
apps/ui) & Local Recording Stack:- React 19 + TypeScript 5.9 + ESLint 9 flat config + Vite SPA styled in the Modernist Swiss-grid design system (
Archivo800/600/400, warm paper#f3f2f2/ stone#eae9e9/ charcoal#201e1d/ signal vermilion#ec3013,0pxcorners, filled-delivery vs. outlined-response badge grammar) across six primary surfaces:/deliveries(with/deliveries/:iddetail),/policy,/operations,/invariants,/audit, and/docs. - Server-verified session capability introspection (
GET /ui/session), non-lossy capability pills (OPERATOR,RESPONDER,PRODUCER,READ-ONLY), tab-memory credential isolation, and multi-tabBroadcastChannel('uns_console_session')synchronization (UNS_SESSION_REQUEST,UNS_SESSION_GRANT,UNS_SESSION_SYNC,UNS_SESSION_EXPIRE,UNS_SESSION_CLEAR). - Responder obligation workflows (inline
Acknowledge/Dismisswith responder notes, canonical owner vs. deduplicated follower lineage, automatic409 Conflictrecovery), operator dead-letter recovery (/operationsfull outer join of/api/v1/dlq+/api/v1/runtime/dead-letters, inlineReplay/Resolve), Policy Workspace (GET /ui/policies/active,GET /ui/policies/revisionsacrossACTIVE/PREVIEW/DRAFT/RETIRED, dry-run simulator, tagged[TEST]live dispatch, atomic policy reload), dual-mode Audit Timeline (1e"By notification" lifecycle correlation withTIME TO RESPONDvs.1d"All events" stream), and in-portal Documentation & Runbooks (/docs). - Persistent localhost recording deployment (
deploy/local/,docs/LOCAL_DEPLOYMENT.md,docs/DEPLOYMENT_SMOKE.md) plus runnable first-party producer integration demo (examples/mip_producer_demo.py) and opt-in external channel smoke verifier (scripts/opt_in_channel_smoke.py).
- React 19 + TypeScript 5.9 + ESLint 9 flat config + Vite SPA styled in the Modernist Swiss-grid design system (
- Live PostgreSQL 16 Operational Acceptance & Sustained Load Validation (
tests/uns/test_postgres_and_load.py):- Out-of-the-box PostgreSQL driver support (
psycopg[binary]>=3.2.0inuns[sql]/uns[full]) verified in CI againstpostgres:16-alpineacross schema migrations (uns-migrate), policy snapshot revision locking, deduplication leader/follower promotion, lease-fenced delivery, ACK/timeout callbacks, andSQLAlchemyReadModelAdapterqueries. - Sustained concurrency and load suite validating 100-request burst intake and deduplication storm coalescing, 4-worker racing
Runtime.dispatch(limit=...)lease contention with zero duplicate external sends, and concurrent policy reload interleaved with active intake. - Optional
delivery_serviceanddlq_servicedispatch integration onuns.signaling.send_signal().
- Out-of-the-box PostgreSQL driver support (
- Comprehensive Documentation Suite (
docs/):- Production Deployment reference (
docs/DEPLOYMENT.md), complete API reference (docs/API.md), Support State Machine & Schema guide (docs/support/STATE-MACHINE-AND-SCHEMA.md), Troubleshooting Guides (docs/tsg/TSG-01throughTSG-06), User/Integrator Manuals (docs/user-guides/), and MkDocs Material GitHub Pages configuration (mkdocs.yml,.github/workflows/docs.yml).
- Production Deployment reference (
Fixed & Hardened
- Same-Window Dedup Replacement & Callback Retention (
uns.Runtime,uns.maintenance):- Linked
dedup_successor_idand emittedOBLIGATION_HANDED_OFFwhen a new request replaces a failed solo leader within the same deduplication window, and preserveduns_dedupgeneration state while any retained notification sharesdedup_key. - Refreshed per-callback lease timestamps (
self.clock()) insidedeliver_callbacks()and clearedcallback_pendingon 3rd-attempt exhaustion so exhausted callbacks do not blockuns-maintainretention pruning.
- Linked
- Email, Rate-Limiter, Policy Reload, & Audit Query Hardening:
- Escaped HTML entities (
html.escape) inEmailAdapter._build_html_body()and sanitized CR/LF characters from MIME header fields. - Keyed HTTP rate-limiter buckets by SHA-256 digests of verified API keys only, falling back to client IP for unauthenticated or invalid headers.
- Constrained
POST /api/v1/policies/reloadto reject path traversal (..), enforceUNS_POLICY_DIRroot boundaries when configured, and reject empty policy directories (loaded_count == 0). - Pushed
event_typefiltering andtotal_countcomputation into SQLWHERE/COUNT(*)clauses inSQLAlchemyReadModelAdapter.get_audit_events(). - Bounded
MetricsCollectorsample storage with ring buffers (deque(maxlen=10_000)), validatedX-Request-IDheaders, capped serialized requestmetadataat 64 KiB, isolatedRedisWebSocketSubscriberonto a dedicated thread pool, and hardened.github/workflows/python-tests.ymlwith strictmypyverification.
- Escaped HTML entities (