EDDI 6.3.0 turns group conversations from a debate feature into a collaboration platform, and introduces the Platform Operator, a meta-agent that reads and operates the deployment with every write behind a human approval gate, superseding the Agent Father.
Groups gain the machinery a real team needs: explicit voting with quorum and weights, shared artifacts, bid-based task assignment, standing teams with backlogs and cron cadences, a facilitator with bounded moves, humans as first-class members, a NEGOTIATION style, and retro phases that harvest team-owned memory. Five preset templates ship so none of it has to be hand-wired.
EDDI also gains an OpenAI-compatible /v1 API, presenting deployed agents as OpenAI models to Open WebUI, the openai SDK, LangChain and LiteLLM. Alongside that: most tool-enabled turns now stream token-by-token, the tool orchestrator is decomposed behind a ToolSourceProvider SPI, and vault allowedAgents moves from advisory to enforced. Four security fixes apply to code that shipped in 6.2.0, so existing deployments are affected regardless of whether they adopt anything new in this release.
🚀 What's New
🧙 Platform Operator, and the end of the Agent Father
The Platform Operator (/manage/operator) is a meta-agent that reads and operates the deployment through EDDI's own API, including creating other agents, with every write behind a human approval gate. The form-based agent wizard (/manage/agents/wizard) covers the same ground without a conversation. Both call AgentSetupService.
- 🔍 Deterministic gate verification.
POST /administration/operator/gate-dry-runanswers "would this tool call be gated?" without executing anything, so a policy can be proven before it is trusted. - 🔁 Caller-set tool-iteration budget on the setup API, so a long provisioning conversation is not cut off mid-way by a fixed round limit.
- 🧾 Operator metrics and audit surfaces, so operator activity is observable and reconstructable after the fact.
The Agent Father is retired, along with POST /backup/import/initialAgents and the bundled starter ZIP. See Breaking Changes.
👥 Group Collaboration: Deliberation and Work Products
The largest body of work in this release. Groups move from "agents take turns talking" to a team that can decide, produce, and persist.
| Capability | What it does |
|---|---|
| 🗳️ Voting | VOTE phases collect explicit ballots (majority or approval, weighted, quorum-gated) and record a DecisionRecord with the full tally, raw ballots, and the losing side's dissents |
| 📄 Shared artifacts | Content-addressed blackboard with declarative validators; members read and revise a shared work product instead of restating it |
| 🏷️ Bid-based assignment | CNP-lite: members bid for tasks rather than being assigned round-robin |
| 🏭 Standing teams | Persistent teams with a backlog, cron cadences, and metrics |
| 🧠 Retro phases | RETRO harvests team-owned group memory that survives the discussion |
| 🎛️ Facilitator | Bounded moves (CONTINUE, END_PHASE, EXTEND_PHASE, CALL_VOTE, ESCALATE_HUMAN) with a checkpoint cadence |
| 🙋 Humans as members | A HUMAN roster member takes a real turn in the discussion, not just an approval |
| 🤝 NEGOTIATION style | The trade form: offers, concessions, and an arbiter |
| 🧰 Preset templates | Five packaged, validated configs: research pod, editorial team, ops task force, decision board, negotiation table |
Plus: convergence detection with early exit, structured verdicts and deterministic synthesis, abstention and minority reports, runtime recruitment and delegation, an agent-writable shared task list, group cost ceilings with per-child attribution, transcript windowing for rendered member context, a LiveDiscussionRegistry, speaker-level resume points, and graceful-shutdown integration.
🤖 OpenAI-Compatible API: Open WebUI, the openai SDK, LangChain, LiteLLM
A new /v1 surface presents deployed agents as OpenAI "models", so any OpenAI-protocol client can drive EDDI conversations. New integrations/openai/ package, parallel to integrations/slack/. Disabled by default; enable with eddi.openai-compat.enabled=true. Full guide: docs/open-webui-integration.md.
- 🔀 Sync and streaming dispatch on the request body's
streamfield, not onAccept.openai-pythonhardcodesAccept: application/jsonregardless ofstream, and Open WebUI sends noAcceptheader at all, so content negotiation would have routed every streaming request to the JSON path. This matches the OpenAI spec and what vLLM, llama.cpp, LiteLLM and Ollama do. - 🧵 Per-chat conversation isolation keyed on
X-OpenWebUI-Chat-Id, so each chat in the client maps to its own EDDI conversation. - 🎨 Structured outputs survive the protocol. An EDDI turn carries eight output types; the OpenAI protocol carries one string.
OpenAiOutputRenderertakes the extractor's text verbatim, because a reply's wording must not depend on the channel it left through, then appends a Markdown rendering of the rest: quick replies as backticked values, images as, application links as links, buttons as their label, input fields as a described prompt. Without this, an agent whose turn is a question plus five quick replies arrived as a question with no visible answers. - 📊 Token usage reporting, including for streamed responses via
stream_options. - 🔑 Its own auth surface: API-key filter, configurable HTTP policy, optional anonymous access, and a startup guard, all separate from the main REST auth.
- 🧯 HITL-aware, multimodal-aware, with an exception mapper that returns OpenAI-shaped errors.
🪪 Caller Identity: An Agent Can Call an API As the Signed-In User
An HTTP call header may now reference the authenticated caller, so the agent calls the API with that user's credentials rather than a static one:
| Reference | Resolves to |
|---|---|
${caller:token} |
The caller's raw bearer token |
${caller:userId} |
The caller's principal name (not a secret) |
This matters most when an agent calls EDDI's own API, where a static credential expires within the hour, cannot be least-privilege, and attributes every action to one synthetic principal.
Resolution is deliberately narrow and fails loudly rather than degrading quietly. It is same origin only, released to the exact scheme://host:port the caller addressed, read from the inbound request rather than config, so a config naming a third-party host cannot exfiltrate the token. It is headers only for ${caller:token}, which is rejected in a query parameter, body or path. It works on authenticated turns only, so scheduled jobs and triggers cannot satisfy it. And it fails closed, erroring rather than sending an empty Bearer. The token is never persisted, since authorization headers are scrubbed before the request is written to conversation memory. An MCP server's apiKey may also carry it, sending the tool call as the chatting user. Disable with eddi.caller-identity.enabled=false.
🔑 Vault Keys Are Shared, Not Minted Per Agent
Provisioning several agents against one provider key previously left one vault entry per agent (setup.<agent>.<timestamp>.apiKey), so rotating that provider key meant hunting down N unguessably named entries. Agent setup now offers three ways to share one key, including a new REST-only vaultKeyName field that names the entry directly. With vaultKeyName and no apiKey, the entry must already exist, so a second agent needs no plaintext at all.
Pasting an existing ${vault:...} reference into the wizard's API-key field also works reliably now. The reference check was a full-string regex that never trimmed its input, so a reference copied from a UI list carried trailing whitespace, failed the match, and was vaulted as a secret whose value is a reference: a new, useless key on every setup.
🌊 Streaming: Live Output Through Tool Turns
- ⚡ Most tool-enabled turns stream token-by-token (
eddi.llm.tool-loop.streaming.enabled). These turns previously ran on the synchronousChatModel, so output arrived only once the whole tool loop had finished.ToolLoopStreamingChatModeladapts the streaming transport to the synchronous contract, andToolLoopRunneris untouched, so retries, iteration budget, approval gate and pause/resume all keep working. A single-chunk fallback still applies where live streaming is not possible: the kill-switch off, no event sink, output-suppressed tasks, providers with no streaming builder, JSON-formatted final rounds, and the cascade-agent path. When it applies, astreamingDowngradedflag is recorded in the response metadata so the downgrade is observable rather than silent. - 🔧 Live
tool_callSSE event, emitted immediately before each tool executes, so clients can show "Using {tool}…" while the turn is still running. Only the tool name travels; arguments stay in the redacted end-of-turn trace. - 🆔
doneevents carry the pause identity (hitlPausedAt), so a client can tell which pause it is looking at. - 🚦 Known client conditions are typed error events, giving clients something actionable instead of a generic 500.
- 🩹 Leading whitespace is preserved in SSE data lines, correcting spacing in streamed replies.
🔌 MCP Server: 84 Tools
Up from 77. New group-collaboration and HITL discovery tools, plus a documentation bridge so agents can read EDDI's own docs, exposed both as MCP resources and over REST at GET /administration/docs. OpenAPI-generated tools can now read response headers.
Two further REST surfaces arrive with the group work: /groupstore/templates for listing templates and POST /{templateId}/instantiate to create a group from one, and /groupstore/groups/{groupId}/workspace for shared artifacts, the group task list, and a standing team's /backlog and /cadences.
🧩 Orchestrator: Decomposed Behind an SPI
AgentOrchestrator is refactored behind a ToolSourceProvider SPI with one provider per tool source (http, mcp, a2a, dynamic, contextual, builtin), plus extracted ToolLoopRunner, ToolLoopResumer, ToolApprovalGateSupport and ToolContextBudget. ConversationStepRunner and ConversationHitlService are likewise extracted from the conversation path. Behaviour-preserving, but it is what made the streaming and HITL work above tractable.
⚠️ Breaking Changes & Upgrade Notes
| Change | Impact |
|---|---|
| 🗑️ The Agent Father is retired | The bundled starter-agent ZIP, POST /backup/import/initialAgents, and the import machinery that only it used are all removed. A fresh install now starts with no agents deployed. Create the first one via the Platform Operator at /manage/operator or the wizard at /manage/agents/wizard, both of which supersede it. Existing deployments are unaffected: an already-imported Agent Father remains a normal stored agent. |
🔐 eddi.vault.grant-enforcement now defaults to enforce |
SecretMetadata.allowedAgents was previously advisory, because the access model assumed a human authored every agent configuration. Now that configurations can also be authored programmatically via create_sub_agent, scoping a secret to specific agents needs enforcement at runtime. Enforcement runs at deployment, not resolution (the resolver sees only a string, and ChatModelRegistry caches on unresolved parameters). An agent referencing a secret it is not granted will now fail to deploy. Set eddi.vault.grant-enforcement=warn to restore the previous behaviour while grants are widened. |
✋ eddi.hitl.tool.task-approvals.mode now defaults to strict |
A task-level toolApprovals block can now only strengthen the agent-level gate: patterns are united, task-level exempt entries are ignored, task-level AUTO_APPROVE is demoted unless the agent policy grants it, and maxAutoApprovalsPerTurn takes the minimum. The pre-6.3.0 behaviour was a full replace. Set the mode to replace where a design deliberately loosens one task. |
| ☕ Quarkus 3.38 | Redundant @Blocking annotations are now rejected at build time; they were removed rather than suppressed. Relevant only if you build against this tree. |
🏷️ Release tags carry no v prefix |
Documentation-only, but worth stating: ci.yml triggers on tags: ["[0-9]*"], so a tag must start with a digit. The release guide previously showed v-prefixed examples; a v-prefixed tag matches no workflow and starts no build. Tag 6.3.0, never v6.3.0. |
🛡️ Security
The four issues below affect code that shipped in 6.2.0. Upgrading is recommended independently of the features in this release.
🚨 Path traversal through httpcall tool arguments
LLM tool arguments are merged into template data as top-level entries and substituted into path templates such as /agentstore/agents/{id} without encoding. An argument of ../../secretstore/secrets/default/masterkey could therefore redirect the request to a different endpoint, and ? or # could append a query string or truncate the URL.
This also affects HITL classification: the approval gate classifies on the configured endpoint recorded at discovery, so a call presented for approval as a read could reach a write path. Path segments are now encoded and traversal sequences rejected. Present since tool-calling httpcalls shipped.
🚨 An agent could post into its own conversation
An agent granted the runtime conversation endpoints could list conversations (a GET, exempt from approval), locate its own, and POST to it, writing a USER turn indistinguishable from one typed by the person into the channel the safety preamble designates as trusted. That provides a route from content the agent read to content it treats as instruction, and it is not something an approver can reasonably catch, since the request shows only an opaque conversation id. Such calls are now refused.
🚨 Approval gate could become inert after a failed policy read
populateToolApprovalsConfig did not distinguish "this agent has no approval policy" from "the policy could not be read". Both produced a null carrier, and a null carrier leaves ToolApprovalGate inactive, allowing tool calls, including writes, to execute without approval. A transient store error while resuming a gated conversation could therefore open an unapproved-write window. The path now fails closed. Present since tool-call gating shipped in 6.2.0.
🚨 Redaction produced invalid JSON, and every reader parses it
SecretRedactionFilter's generic rule matched the key's closing quote, the colon and the value's opening quote, then replaced all three along with the value. A redacted body came back malformed:
{"modelName":"x","apiKey":"sk-ant-…"} → {"modelName":"x","apiKey=<REDACTED>"}
That is a bare string where a key/value pair belongs. The rule runs last, so it also re-mangled what the sk-… and Bearer … rules had already redacted correctly.
Every reader of a redacted body parses it, and two of the Manager's failed silently as a result. The approval diff for a gated whole-document PUT fell back to raw text comparison and rendered the entire stored config as deleted. More seriously, detectEscalationFlags runs every capability-grant check behind a JSON.parse, so a request that embedded a credential and granted dynamicAgents.allowCreation warned about the credential alone. An approver reads "no second warning" as "no capability grant", which is exactly the false negative that check exists to prevent. Redaction now replaces only the value, decides a value's end by its escaping depth, keeps the vault exemption whole-value, and never redacts whitespace. A generated invariant suite plus fuzzing now pins the behaviour, and fixed a stack overflow found along the way.
Other security fixes
- 👁️ Secret redaction extended to underscored keys and escaped-JSON fields. The
sk-pattern's character class stopped at the first_, so an approval card could render an API key in clear text rather than as<REDACTED>. Bothsk-patterns now include_, and escaped-JSON fields are covered. - 🛡️ Defense-in-depth for HITL surfaces: serve-time re-redaction plus a raw-carrier strip, so a missed redaction upstream does not reach an approver.
- 🧾 The audit ledger no longer produces a false tamper result, alongside four smaller defects found in a full-repo review.
- 🔏 Audit signing can be made mandatory (
eddi.compliance.audit-signing-required), and the audit queue depth is now bounded and tunable (eddi.audit.max-queue-size). - 🚧 The Manager's update check is no longer blocked by EDDI's Content-Security-Policy in production deployments.
- 🔒
allowedAgentsis enforced. See Breaking Changes. - 📌 Four OSV advisories cleared.
jackson-core/jackson-databind,bcprov-lts8onandjson-schema-validatorare pinned as dependency-management overrides, returning Scorecard's Vulnerabilities check to clean. - 📦 UBI9 base digest bumped for CVE-2026-11940 (CPython tarfile extraction-filter bypass,
python3/python3-libs). Red Hat had republished the1.24tag with the fix, so the digest pin moved rather than adding amicrodnfstopgap or a.trivyignoreentry.
📦 Dependency Updates
| Dependency | 6.2.0 | 6.3.0 |
|---|---|---|
| ☕ Quarkus Platform | 3.37.4 | 3.38.3 |
| 🧠 langchain4j | 1.18.0 | 1.19.0 |
| 🧠 langchain4j-libs | 1.18.0 | 1.19.0 |
| 🧪 langchain4j-beta | 1.18.0-beta28 | 1.19.0-beta29 |
| 🌐 langchain4j-community | 1.18.0-beta28 | 1.19.0-beta29 |
| 🥣 jsoup | 1.22.2 | 1.23.1 |
| 🔎 classgraph | 4.8.184 | 4.8.192 |
| 🌿 jinjava | 2.8.3 | 2.8.4 |
| 📡 jnats | 2.26.0 | 2.26.2 |
| 📘 swagger-annotations | 2.2.52 | 2.2.54 |
| 📘 swagger-parser | 2.1.45 | 2.1.47 |
| 📗 jackson-core / jackson-databind | not pinned | 2.22.2 (pinned override) |
| 🔐 bcprov-lts8on | not pinned | 2.73.12.1 (pinned override) |
| 📏 json-schema-validator | not pinned | 1.5.4 (pinned override) |
| ✅ quarkus-hibernate-validator | not present | added (platform-managed), backing the declarative attachment-size constraints in engine/memory/model/validation |
Red Hat UBI9 OpenJDK 25 runtime moved to the digest carrying the CVE-2026-11940 fix, and the demo image's eclipse-temurin base was refreshed. Both remain digest-pinned.
Deliberately not taken in this release, to keep it a stable state: major jumps in jsonschema-generator (5.0.0), json-path (3.0.0), json-schema-validator (3.0.6), bson4jackson (3.2.0), testcontainers (2.0.5), wiremock (4.0.0-beta) and quarkus-mcp-server (2.0.0.CR2), plus the Quarkus 3.39.0.CR1 candidate.
🐛 Other Bug Fixes
- 💬 A tool pause now retains the model's own explanation of what it is about to do, rather than dropping the interim text.
- 🔁 Repeated pauses on the same tool render distinguishable text, so successive approval requests can be told apart.
- 📝 Pending-approval messages are specific to the pause rather than a single generic sentence.
- 🚫 Tool calls with a non-JSON body are rejected before dispatch, with an actionable error, instead of failing at the provider API.
- 🤐 A failed httpcall tool now returns an error the model can act on, rather than an empty object that read as success.
- 💥 Prompts that reference a
${vault:…}placeholder as literal text now render correctly, instead of failing templating for that turn. - 🖼️ Earlier-turn images are re-inlined for vision models, so a follow-up question can still see them.
- 🕰️ The idle-conversation sweep measures age from the correct timestamp.
- 🧬
create_sub_agentnow completes successfully, and a failed setup no longer leaves orphaned resources behind. - 🔗 Deployment-wait machinery is available to all callers, not only the ZIP importer.
- 💰 Ordinary model calls now carry pricing, so the audit ledger records real cost for the common case.
- 🔀 MCP tool names are resolved per server, so a collision cannot route a call to a different server's tool.
- 🔤 575 inline fully-qualified names replaced with imports across the codebase.
🧪 Testing
14,600+ tests across 907 test files, gated at >90% instruction / >80% branch coverage.
🖥️ EDDI Manager 6.3.0 (Admin Dashboard)
The Manager UI ships bundled with EDDI 6.3.0, with 5,200+ tests across 351 test files, translated across 11 locales.
🧙 Platform Operator, the release's largest UI arc
The operator began this cycle as a read-only pilot and ends it able to author the deployment, with a gate in front of every write.
- ✍️ Authoring, not just deploying. Create and modify agents and groups, with editable LLM configs behind a gate guard, and a completed authoring cascade so a provisioning conversation runs end to end.
- 🧪 The write canary. Before write scope is granted, the operator proves a real write actually pauses: a dry-run first, then a self-targeting probe. An unknown outcome no longer deletes anything, and a half-provisioned activation rolls back.
- 🛑 It refuses to aim at itself. Self-targeted writes are rejected, a self-ungating path is closed, and four escalation-flag evasions plus a hole in gate verification itself were fixed.
- 🔑
inlineCredentialescalation flag, which raises the gate when a literal secret appears where a vault reference belongs. - 👀 Approvals resolve inline. Decide a pause inside the operator chat, with the backend's resolved-request preview in the banner and a diff of what a whole-document config write actually changes.
- 💬 A context-aware side-chat drawer in both Manager and Workforce, with the launcher moved from a floating button into both shells' headers.
- 🚗 Test-drive, so an agent or group can be tried by actually talking to it without leaving the operator.
- 🔗 Conversations survive navigation and restart, and a re-pause renders only what is new since the previous pause, so narration is not repeated.
- 🧠 The system prompt is derived from the granted endpoint set, with a config cheatsheet and docs map, so the operator's advice matches what it is actually allowed to do. It uses EDDI's caller-identity resolver rather than conversation context.
👥 Groups & Workforce
- 🧩 The collaboration roadmap reached the UI. Human members, votes, negotiation, artifacts and standing teams are all configurable, and the advanced features are reachable rather than buried.
- 🏷️ Honest collaboration-mode labels and full Manager/Workforce parity, so the same group reads the same way in both shells.
- 📎 Paste and drag-and-drop files into the discussion input.
- 🩹 Fixes: a nested-group seat that invented its own agent, a staging race, a budget rejection that dropped the remaining members, and an unbounded total attachment payload.
💬 Chat, Attachments & Live Status
- 📡 A live status line in the main chat and the drawer, showing the tool actually running. This is the client half of the backend's new
tool_callevent, alongside a flat activity view. - 📥 Attachments everywhere: drag-and-drop onto both chat surfaces, paste-to-attach, and attachments in the operator chat.
- 🖇️ Smart auto-scroll across surfaces, and real Markdown typography at chat scale.
- 🩹 Fixes: the newest tool call spun forever beneath a finished answer; the Markdown bold repair corrupted already-correct emphasis.
✋ HITL Approvals
- 📥 The approvals inbox decides
TOOL_CALLpauses in place, rather than sending you elsewhere. - 🎛️ Per-call Approve / Reject became real controls, having previously read as decoration.
- ⏱️ Pause reason and timeouts are sourced from approval-status, and a failed pause-details read now blocks Approve instead of leaving it enabled.
🌍 Environments, Setup & Updates
- 🗺️ Agents show which environment they run in, and chat opens in that environment, including on resume.
- 🔑 One vault key is reusable across agents in the setup wizard, which now surfaces the backend's vault-grant warning and says up front what
agents/setupwill refuse. - 🆕 Opt-in update check: a dedicated screen that checks GitHub and Docker Hub and shows the release notes. Nothing is sent without consent, pinned as an app-level test, and the third-party dependency was dropped in favour of deriving the Docker tag.
🎨 Design System, i18n & Accessibility
- 🧱 All 29 shared components resynced with real prop contracts (design-sync), and the app chrome brought into the same system.
↔️ No horizontal scrolling anywhere, from a responsive sweep, plus RTL layouts no longer overflow.- 🌐 i18n repairs: the Workforce settings page rendered in English everywhere, Arabic plurals completed, real plural rules, per-page titles, and stale translations fixed.
- 🚧 Error states instead of misleading empty states on every data-loading page, and dead navigation targets repaired and guarded by a route test.
- 🔐 dompurify 3.4.13 (GHSA-55q2-fjhq-7xh7), React Router v7, and production advisories gated in CI.
📋 Full Changelog
6.2.0...6.3.0. See docs/changelog.md for per-change detail, including the reasoning behind each decision.
🐳 Docker Image
This release is distributed as a Docker image:
docker pull labsai/eddi:6.3.0Verify image signature
cosign verify \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
--certificate-identity-regexp '^https://github\.com/labsai/EDDI/\.github/workflows/ci\.yml@refs/(heads/main|tags/.+)$' \
labsai/eddi:6.3.0Note: EDDI is distributed exclusively as a Docker image. There are no binary downloads.
See the Docker Hub page for all available tags.
What's Changed
- chore(docker): bump oss-fuzz-base/base-builder-jvm from
1706e0cto3672cbbin /.clusterfuzzlite by @dependabot[bot] in #612 - feat(keycloak): EDDI-branded login theme by @ginccc in #615
- fix: apply external code-review findings (124 items, wave 1 of 4) by @ginccc in #616
- fix(security): access control, A2A ownership, GDPR & audit ledger (wave 2a) by @ginccc in #617
- feat(security): forward the caller's identity to apicall headers by @ginccc in #613
- fix(llm): LLM core, persistent memory, migration, import/export (wave 2b) by @ginccc in #618
- Fix/release 6.2 polish by @ginccc in #611
- feat(openai): OpenAI-compatible API adapter for Open WebUI and SDK clients by @ginccc in #614
- fix(llm): a malformed workflow version must not abort tool discovery by @ginccc in #621
- fix(runtime): concurrency, lifecycle, cancellation, graceful shutdown, Dream wiring (wave 3) by @ginccc in #619
- feat(operator): foundation for an agent that can safely write by @ginccc in #622
- docs: add Javadoc to datastore core interfaces by @Kayvan-Zahiri in #623
- fix(configs): write-time config validation (E6) + request-body validation (A11) (wave 4a) by @ginccc in #620
- feat(operator): per-endpoint approval friction, gate provisioning, and agent-readable docs by @ginccc in #625
- chore(docker): bump oss-fuzz-base/base-builder-jvm from
3672cbbtocc3c3dain /.clusterfuzzlite by @dependabot[bot] in #632 - fix(docker): bump UBI base digest to pick up the OpenJDK 25.0.4 rebuild by @ginccc in #633
- fix(ci): run the gitleaks CLI so secret scanning works on fork PRs by @Kayvan-Zahiri in #624
- feat(hitl): approval binds to the resolved request, not the tool name by @ginccc in #627
- refactor: Wave R — decompose GroupConversationService, AgentOrchestrator and ConversationService by @ginccc in #626
- feat(groups): org/team preset templates (I10) — on the all-features integration branch by @ginccc in #645
- fix(groups): pre-feature defects N1-N3 - plain-call pricing, schema sentinel, transcript windowing by @ginccc in #636
- feat(groups): shared artifacts - typed co-edited documents with CAS and validators (I17) by @ginccc in #637
- feat(groups): voting with structural ballot independence (I14) by @ginccc in #638
- feat(groups): I8 — retro phases harvest team-owned group memory by @ginccc in #639
- feat(groups): I6 — humans as group members (AWAITING_HUMAN_INPUT turns) by @ginccc in #640
- feat(groups): I11 — NEGOTIATION style, the trade form by @ginccc in #641
- feat(groups): I18 — bid-based task assignment (CNP-lite) by @ginccc in #642
- feat(groups): facilitator with bounded moves (I12) by @ginccc in #643
- feat(groups): standing teams — workspace, backlog, cadences (I13) by @ginccc in #644
- fix(agents): null-version undeploy no-op, deploy under a CHM bin lock, EXECUTE wave deadline, protocol defaults by @ginccc in #648
- fix(agents): dynamic-agent guardrails — permissive fallback on resume, per-member caps, duplicate recruits, V7 by @ginccc in #649
- fix(groups): a paused cadence discussion no longer wedges a standing team forever by @ginccc in #650
- chore(groups): retarget the TASK_FORCE characterization tests at the engine that owns them by @ginccc in #653
- docs(groups): attachments, protocol defaults, context scopes, and a "not yet supported" section by @ginccc in #652
- fix(agents): wire the deployment-wait machinery that only the ZIP importer ever used by @ginccc in #651
- chore(deps): bump the quarkus group across 1 directory with 2 updates by @dependabot[bot] in #628
- chore(deps): bump the langchain4j group across 1 directory with 21 updates by @dependabot[bot] in #630
- feat(vault): enforce allowedAgents at deploy time instead of documenting it by @ginccc in #662
- fix(ci): bump scorecard-action to v2.4.4 so Branch-Protection survives protected release branches by @ginccc in #634
- fix(runtime): age idle conversations by the conversation, not by the agent document by @ginccc in #660
- chore(ci): pin demo image digests and stop gating CodeQL on changed paths by @ginccc in #635
- fix(setup): create_sub_agent could never work, and a failed setup left orphans by @ginccc in #661
- fix(deps): clear four OSV advisories flagged by Scorecard by @ginccc in #665
- chore(vault): default grant-enforcement to enforce by @ginccc in #664
- docs(vault): document allowedAgents enforcement, and correct the javadoc that denies it by @ginccc in #667
- feat: docs for agents on every surface, MCP resource bridge, strict task-level toolApprovals by @ginccc in #668
- docs: refresh for the merged group-collaboration set by @ginccc in #647
- fix(csp): allow api.github.com so the Manager's update check can run by @ginccc in #674
- fix: audit ledger self-tamper defect, plus review fixes across CI, docs and hygiene by @ginccc in #677
- chore: replace 575 inline fully-qualified names with imports by @ginccc in #676
- fix(setup): four defects that broke every wizard-created agent by @ginccc in #673
- Secret hardening for HITL surfaces: serve-time re-redaction + raw-carrier strip by @ginccc in #679
- chore(deps): langchain4j 1.18.1 → 1.19.0 by @ginccc in #680
- fix(test): two assertions still pinned the old vault-redaction behaviour by @ginccc in #681
- fix(hitl+streaming): the paused turn's continuation was unreadable, then indistinguishable by @ginccc in #682
- fix(llm): a prompt mentioning ${vault:key-name} crashed templating every turn by @ginccc in #683
- fix(apicalls): a failed httpcall tool returned "{}" — the model could not know it failed by @ginccc in #684
- fix(hitl): a second pause on the same tool rendered byte-identical text by @ginccc in #685
- fix(llm): refuse a tool call whose body is not JSON before sending it by @ginccc in #687
- feat(mcp): let OpenAPI-generated tools read response headers by @ginccc in #688
- fix(hitl): refuse a tool call that targets its own conversation by @ginccc in #689
- fix(review): operator-stack audit — cross-version placeholders, contract leaks, live-path self-guard by @ginccc in #690
- fix(style): hoist inline fully-qualified names out of the operator-audit changes by @ginccc in #691
- fix(streaming): known client conditions are typed error events, not opaque 500s by @ginccc in #692
- fix(streaming): done events carry the pause identity — hitlPausedAt by @ginccc in #693
- fix(hitl): a tool pause keeps the model's own explanation of what it is about to do by @ginccc in #694
- chore: remove the Agent Father, superseded by the Platform Operator by @ginccc in #672
- fix(docker): bump UBI9 base digest for CVE-2026-11940 by @ginccc in #695
- chore(deps): bump the quarkus group with 2 updates by @dependabot[bot] in #696
- chore(docker): bump eclipse-temurin from
f19dbf0toa214efain /src/main/docker by @dependabot[bot] in #698 - fix(setup): reuse vault keys instead of minting one per agent by @ginccc in #699
- fix(secrets): redact only the value, so a redacted JSON body is still JSON by @ginccc in #703
- chore(release): bump EDDI version 6.2.0 -> 6.3.0 by @ginccc in #671
New Contributors
- @Kayvan-Zahiri made their first contribution in #623
Full Changelog: 6.2.0...6.3.0