Capability Status Matrix
This page tracks the real shipping state of every major capability in Wayland Core. It is the authoritative reference when any other page describes a feature as working; if the status here says partial or not-wired, that qualification takes precedence.
Current engine: v0.13.11. Rows below were audited in full against v0.13.0 and are spot-checked against each release since. Where a row names a specific version, that version is the one the finding was verified at. A capability that changed after its stated version will be corrected here before it is claimed anywhere else — this page leads the marketing, not the other way round.
Legend:
- Shipped: present, wired to production call sites, tested.
- Partial: the code exists and runs in the described scope; the stated gap is real and not a minor edge case.
- Offline-only: runs, but only outside the live agent session (separate process, separate binary, or compile-time gate).
- Not-wired: the code exists (often well-structured) but is not yet connected to the production path it is meant to gate or enforce.
- By design: deliberately not done, with the reason stated. Not a backlog item.
- Platform limit: the constraint belongs to the OS, compositor or upstream dependency, not to Wayland.
Source: code audit of wcore-* crates at v0.12.17, updated per-release against tagged release notes through v0.13.0, and the research artifacts at .planning/core-research/CORE-TRUTH.md + .planning/readme/CAPABILITY-MATRIX.md.
Providers and model routing
Section titled “Providers and model routing”| Capability | Status | Notes |
|---|---|---|
~20 providers via LlmProvider trait | Shipped | 20 ProviderType factory arms in wcore-providers/src/lib.rs. 5 native wire implementations (Anthropic, OpenAI, Bedrock, Vertex, Gemini) + ~15 OpenAI-compatible newtypes + catch-all. |
ProviderCompat declarative quirks | Shipped | wcore-config/src/compat.rs. All provider differences (field names, schema sanitization, streaming shape) are config data, not conditionals. |
| Resilience stack: retry, key-rotation, circuit breaker, failover chain | Shipped | failover.rs, retry.rs, key_rotation.rs, resilient.rs, cooldown.rs, chain.rs in wcore-providers. |
| Smart routing: Cheap / Premium tiers | Partial | RequestShape routing is wired and the vision, large-context, tool-heavy and simple decisions are all genuine. The code_heavy signal that would activate the Balanced tier is left at a conservative 0.0 and never fires, so code-aware routing must not be described as active. Re-verified at v0.13.11: crates/wcore-providers/src/routing.rs:14. |
| Provider count via routers | Shipped (with framing) | ~20 direct integrations. Several are routers (OpenRouter, Flux Router, Together, Fireworks) that front hundreds of additional models. As of v0.12.6, MiniMax connects through an Anthropic-compatible endpoint, appears in the model pickers, and is in the cost catalog (MiniMax-M2). |
| Sakana AI (Fugu) provider | Shipped | As of v0.12.7, Sakana AI is a first-class provider in the engine. Fugu models connect through the OpenAI-compatible path and appear in the model pickers. |
| Keyless self-hosted endpoints | Shipped | As of v0.12.15, a local self-hosted OpenAI-compatible endpoint (Ollama, llama.cpp) needs no provider key at all. The engine recognizes a local base URL as keyless instead of demanding an OpenAI key, so local models run fully private with zero keys. |
| Flux Router image, fetch, and web search | Shipped | As of v0.12.6, Flux Router drives image generation, web fetch, and web search from the engine via a dedicated FluxImageClient and a new wcore image subcommand, with typed entitlement messaging when a capability needs an upgraded plan. |
| Bedrock / Vertex per-model pricing | Partial | Affects Wayland’s own cost estimate only. AWS and Google do the billing; nothing here changes what you are charged. Only claude-opus-4-7 has a full Bedrock/Vertex entry in the bundled catalog, so other models fall back to Opus rates and the displayed estimate can read high. PriceStatus.priced marks a figure as a real rate or an unknown, so an unreliable estimate says so rather than pretending. |
| Crucible Mixture-of-Providers council | Shipped | wayland-core crucible "<task>" runs N proposers, each pinned to a different provider, in parallel, then a fenced read-only aggregator fuses their answers. Three modes (--auto, --advisor, --terminal), per-tier proposer/aggregator temperatures, provenance-fenced injection containment, per-proposer and global soft deadlines with quorum, and a [crucible] budget and daily-cap guard. Cost accounting is provider-aware (bring-your-own pricing catalogs, accurate Gemini pricing, broader Opus support). 151 dedicated tests. See Crucible. |
Clean outbound tool_calls on long sessions | Shipped | As of v0.12.17, internal routing metadata is stripped from outbound tool calls before they leave the engine, so strict providers no longer reject long-context replay with a 400. Long sessions stay clean across providers. (Core #120) |
Per-model output sizing when --max-tokens is omitted | Shipped | As of v0.12.20, known models get their real output ceiling, unknown models on omit-safe providers (Gemini, OpenRouter, Flux) let the provider’s natural ceiling apply, and strict endpoints keep a safe sized floor. Explicit caps always win. |
| Token-efficiency pass: prompt caching + tool-catalog fold | Shipped | As of v0.12.24, requests stamp prompt_cache_key, usage is reported per-run as a delta, tool ordering is deterministic, cold tools defer into a catalog fold (up to 86% smaller tool payloads), and Anthropic requests use a 4-breakpoint cache_control layout with a permanent anchor. (Core #184, #186, #187) |
| Universal MCP tool-name codec across providers | Shipped | As of v0.12.19, a single shared codec (sentinel + hex-escape, 64-char clamp + hash for overlong names) sanitizes MCP tool names uniformly across OpenAI, Anthropic, Gemini, Cohere, and direct DeepSeek, pinned by round-trip and anti-collision tests. (Core #130, #131) |
| Capability | Status | Notes |
|---|---|---|
| ~60+ tools in the registry | Shipped | ~75 .rs files under wcore-tools/src/, registered in bootstrap.rs:426-711. |
| ~50 always-on tools | Shipped | File, shell, search, git, and core utility tools present unconditionally when the binary runs. |
| ~15 availability-gated tools | Shipped | Cloud, media, scheduling, and integration tools are absent from the tool list when their required credentials or system dependencies are not present (NO-STUBS contract). |
| Tool timeouts (per-category) | Shipped | Exec 600s, MCP 120s, Info/Edit 30s. Configured in the agent engine. |
| Capability-first tools gate | Shipped | Tool-incapable models (some Ollama, llama.cpp, and Bedrock models that cannot do native tool calls) degrade gracefully rather than erroring, and the choice is remembered per model so the engine does not re-probe a model it already knows. |
| Provider-aware media tools | Shipped | Image generation and text-to-speech follow the active provider, with graceful fallbacks when the active provider does not offer a given media capability. |
doc_extract office-document extraction | Shipped | As of v0.12.23, a dedicated doc_extract tool reads office documents so the agent can pull content out of document files directly. (Core #172) |
Local image files in vision_analyze | Shipped | As of v0.12.23, vision_analyze accepts local image files, not just URLs, and a shared ContentBlock::Image type encodes images consistently across all providers. (Core #170, #171) |
| Consecutive tool-failure retry cap | Shipped | As of v0.12.22, a per-run failure cap stops a stuck tool loop cleanly instead of burning the turn, tunable via WAYLAND_MAX_CONSECUTIVE_TOOL_FAILURES (the shell tool is exempt). Counted globally across tools as of v0.12.23. Hitting the per-turn cap emits a distinct max_turns finish reason so hosts can offer Continue. |
| Honest MCP tool-error signals | Shipped | As of v0.12.22, MCP tool-level failures propagate the isError flag end to end instead of reading as success, while the error text still reaches the model so it can recover. |
Sandbox
Section titled “Sandbox”| Capability | Status | Notes |
|---|---|---|
Linux bubblewrap (bwrap) | Shipped | Namespace isolation (PID, IPC, UTS, cgroup, user, network), --die-with-parent, --clearenv, minimal fs skeleton. Requires bwrap in PATH. |
| Linux Landlock LSM | By design | wcore-sandbox/src/bwrap_landlock.rs exists, but shipped Linux builds do not compile it in and this is deliberate. wcore-tools/Cargo.toml at v0.13.11 requests features = ["seccomp"] only, with the reason in the file: a Landlock ruleset applied around the bwrap backend confines bwrap’s own privileged setup (uid_map) and breaks it. Containment on Linux is bubblewrap’s namespace and bind-mount view, plus the seccomp filter below. |
| Linux seccomp-bpf | Shipped | wcore-sandbox/src/bwrap_seccomp.rs. Compiled into every shipped Linux build, not opt-in: wcore-tools/Cargo.toml at v0.13.11 requests features = ["seccomp"] under cfg(target_os = "linux"), so SyscallPolicy::Strict is enforced rather than a silent no-op. Pulls libseccomp at link time, which is why it is Linux-only. (This row previously read “opt-in build / not compiled into the default binary” and was stale.) |
Linux AllowHosts DNS gate in bwrap | Platform limit | bwrap has no per-hostname network filter. The bwrap backend can deny the network namespace entirely (NetworkPolicy::Deny) but cannot allow a named-host allowlist. |
| macOS sandbox-exec | Shipped | Deny-default SBPL profile. Tahoe (macOS 26.x) zsh init fix baked in. |
macOS mach-lookup filtering | Not-wired | mach-lookup is intentionally unfiltered in the SBPL profile because the minimum set of Mach services needed for a functional shell is not yet enumerated. |
| Windows AppContainer | Shipped | AppContainerBackend activates when the real-spawn probe passes. Per-path filesystem ACL grants ARE wired (R61): fs_read_allow / fs_write_allow are translated to DACL ACEs for the per-process AppContainer SID before spawn and revoked by a RAII guard on completion. Residual: NetworkPolicy::AllowHosts DNS gating (a WFP filter) is still queued separately. |
| Windows AppContainer shell tools on non-developer machines | Shipped | The AppContainer shell path now works end to end on machines without a developer toolchain: it spawns real subprocesses, the allowlist skips absent dev caches instead of failing, and a job-tree reap returns commands promptly rather than leaving them hanging. |
| Sandboxed bash cmd fallback under AppContainer | Shipped | As of v0.12.16, when PowerShell is selected but cannot run inside the Windows AppContainer sandbox, the sandboxed bash tool falls back to cmd so the command still runs rather than failing outright. |
| Docker backend | Shipped (opt-in) | DockerBackend, cargo feature live-docker. Activated via WAYLAND_SANDBOX=docker when the Docker socket is reachable. |
| Fail-closed default | Shipped | If no real backend is available and WAYLAND_ALLOW_NO_SANDBOX=1 is not set, the engine refuses to execute the command rather than degrading silently. |
WAYLAND_ALLOW_NO_SANDBOX double-key opt-out | Shipped | WAYLAND_SANDBOX=none alone is not sufficient; WAYLAND_ALLOW_NO_SANDBOX=1 must also be set. |
| OS-level secret-read deny | Shipped | As of v0.12.6, the unified WorkspacePolicy adds an OS-level deny on reads of known secret paths, so the sandboxed Bash tool cannot read credential stores even within the workspace jail. |
Egress gate
Section titled “Egress gate”| Capability | Status | Notes |
|---|---|---|
| Egress gate on by default | Shipped | SecurityConfig::default().enabled = true. install_egress_policy runs at CLI startup and at workflow entry. Re-verified at v0.13.11: wcore-config/src/config.rs:404, wcore-cli/src/main.rs:2206 (and :2130 on the onboarding path). |
| 4-tier classifier (Allow / Ask / Exfil / Deny) | Shipped | wcore-agent/src/egress/classify.rs. |
| 38+ shared-platform exfil class (cannot be apex-allowlisted) | Shipped | Hardcoded in the classifier; these hosts can never be promoted to Allow regardless of user config. |
| Clippy-enforced reqwest ban | Shipped | clippy.toml disallowed-methods list. Raw reqwest::Client::new/builder fails CI workspace-wide. |
| Default provider host allowlists | Shipped | As of v0.12.6, NVIDIA NIM, Cerebras, MiniMax failover, Qwen, and Flux Router hosts are recognized by the default egress policy, and operator egress entries allow the exact host you type, so these providers connect on the first request. Native Gemini also reaches its host out of the box under the default policy. |
Permissions layer
Section titled “Permissions layer”| Capability | Status | Notes |
|---|---|---|
wcore-permissions ACL, bearer tokens, learned approval policy | Partial | The ACL PolicyGate is wired into the production tool-dispatch path (wcore-agent/src/orchestration/node_executor.rs), enforcing (Actor, Resource, Action) decisions, but it is opt-in (Option<&PolicyGate>): a session that does not install a gate via set_policy_gate runs every tool with no ACL enforcement. The LearnedPolicy sub-agent pre-filter is still not wired (no production sub-agent spawn path yet). Other layers active in every session by default: egress gate, sandbox, tool-approval protocol, budget caps. |
| Sandbox-to-permissions integration | Not-wired | The sandbox and permissions layers are not yet integrated with each other. |
| Tool approval protocol (ToolApprove / ToolDeny / ApprovalResume) | Shipped | wcore-protocol/src/commands.rs. ToolApprovalManager with TTL reaper (300s), tool-name-scoped Always, prefix-scoped AlwaysPrefix. |
| Action-bound approval secrets | Shipped | As of v0.12.19, approvals carry a server-generated secret (apr-<uuid>) bound to the exact tool call. Resolving an approval over the wire requires that secret, not the model-visible id, so a yes to one action cannot be replayed onto another. Carried end to end on the ACP transport as of v0.12.21. |
| Launch-time opt-in for auto-approving wire modes | Shipped | As of v0.12.19, switching the engine into Force or AutoEdit over the wire requires an explicit local-operator opt-in taken at boot (--force or WAYLAND_ALLOW_WIRE_FORCE=1). With the gate closed (the default) a wire mode change is refused outright, and the model itself can never emit one. |
| Clamp-only project config + default-deny project hooks | Shipped | As of v0.12.19, project-scoped configuration can tighten the security posture but directives that would loosen it are ignored, and project-config hooks are default-deny until explicitly trusted. As of v0.12.25, untrusted project @includes are confined to the repo root and an untrusted project system_prompt is neutralized. |
| Capability | Status | Notes |
|---|---|---|
| MCP client: stdio / SSE / streamable-HTTP | Shipped | wcore-mcp/src/manager.rs. Full initialize + tools/list handshake, deferred loading default, per-turn top-K curation (default 15), cancellation-aware calls. |
| MCP smart tool-curation (provider-aware cap + BM25) | Shipped | A provider-aware tool-count cap keeps large MCP servers (such as Google Workspace) within the active model’s tool limit. Curation uses real MCP server provenance and BM25 relevance ranking to pick the tools surfaced each turn. |
MCP server: wayland-core mcp-serve | Shipped | The server starts and accepts connections over --transport stdio or --transport sse, advertises tool names, and now executes tools/call against the engine’s own tool catalog (ServerToolExecutor::call delegates to tool.execute). Calling clients get working tool execution, not just discovery. |
| MCP-bridge plugins | Shipped | Any conformant MCP binary can be wrapped as a plugin via a manifest; no adapter code required. |
| Runtime MCP injection over host protocol | Shipped | AddMcpServer command / McpReady event in wcore-protocol. |
skill:// resource auto-discovery | Shipped | Skills are auto-discovered at boot via skill:// URIs as MCP resources. |
| Per-assistant scoping for config MCP servers | Shipped | As of v0.12.23, a config MCP server can be scoped to specific assistants, so each assistant sees exactly the servers it should. (Core #161) |
MCP tool discovery through ToolSearch | Shipped | As of v0.13.0, a deferred MCP tool’s name and schema reach the model intact. Structured output no longer passes through the line-fold heuristic, the fold’s similarity measure normalises by the longer line, and ToolSearch results are not truncated mid-object. Under compaction = "full" with a large server, a five-tool catalogue previously folded 27 lines to 5 with zero of five names surviving, and hydrated nothing. |
compact_json escapes object keys | Shipped | As of v0.13.0. A tool whose schema contains a property such as say "hi" no longer produces output that fails to parse. MCP servers choose their own property names. |
MCP tools/list_changed honoured mid-session | Shipped | As of v0.13.0, a server that changes its tool surface is seen without a restart. |
Runtime add_mcp_server requires an assistant identity | Shipped | As of v0.12.26, a runtime MCP declaration is bound to the identity that declared it and is refused without one. Supply --assistant NAME or WAYLAND_ASSISTANT. Refusal is announced on an error frame and an mcp_failed frame, neither fatal, so a host that does not render mcp_failed shows a session with no MCP tools and no visible cause. The identity is provenance, not enforcement. |
Idempotent /mcp add | Shipped | As of v0.12.22, re-adding an already-connected MCP server does not spawn a duplicate connection or child process. |
ACP (Agent Client Protocol)
Section titled “ACP (Agent Client Protocol)”| Capability | Status | Notes |
|---|---|---|
| ACP HTTP/SSE + stdio + WebSocket JSON-RPC 2.0 | Shipped | wcore-acp/src/{server,client,protocol,auth,turn}.rs + a2a/. acp serve CLI subcommand. |
message/send engine bridge | Shipped | The process_message stub is replaced; calls route to the real engine. Test acp_turn_streams_text_then_done passes. |
| A2A task routing | Shipped | A2A handler routes tasks to the engine. Test a2a_on_message_routes_task_to_engine passes. |
| Full session-option parity (system_prompt, complete history) | Partial | Not confirmed across all session options. Prefer --json-stream as the primary embedding surface; ACP is additional. |
| A2A task methods: 4 deferred methods | Not-wired | Four A2A task methods are deferred in the current implementation. The A2A handler echoes ack: for some paths. |
Self-evolution
Section titled “Self-evolution”| Capability | Status | Notes |
|---|---|---|
| GEPA offline evolutionary optimizer | By design | wcore-evolve binary. 4 mutators, plateau termination, graveyard, CuratorPort, PromptStore. Runs as a separate process against the eval harness, not in-session. Online evolution from live sessions is explicitly out of scope until W11+. |
| In-session skill drafter (U6) | Shipped | After 3 successful runs on the same task shape, the drafter auto-writes a skill to disk, registers it in-process, and seeds SkillRouter for the next session. Every draft has needs_review: true. |
Channels
Section titled “Channels”| Capability | Status | Notes |
|---|---|---|
| Slack, Discord, Telegram, Signal, WhatsApp, SMS, Email, Matrix, MS Teams, iMessage | Shipped | Full send and receive for all 10 adapters. Each adapter implements poll_events and ChannelEvent::MessageReceived. MS Teams inbound is via Bot Framework webhook (ingest_activity in wcore-channel-msteams/src/lib.rs); inbound attachments deferred. |
| iMessage | Platform limit | macOS only. Not available on Linux or Windows. |
Per-channel inbound access policy ([inbound] TOML table) | Shipped | InboundPolicy in wcore-channels/src/config.rs. DM allowlist, group policy (Disabled/Open/Allowlist), and require_mention flag. Fail-closed default: DM=Allowlist, Group=Disabled, require_mention=true, empty allowlist. |
| Channel auto-registration | Shipped | wcore-channels-registry auto-registers configured adapters from ~/.wayland/channels/*.toml. |
| Named-channel resolution and delivery | Shipped | As of v0.12.17, named messaging channels resolve reliably by platform and instance name and deliver correctly, including an IMAP email channel. (Core #116) |
Host-delegated send_message with a confirmation gate | Shipped | As of v0.12.20, when the desktop hosts the engine, send_message hands delivery to the desktop’s own channel plumbing over a correlated json-stream round-trip. The host fulfils the send without re-gating, so the engine’s approval gate is the only gate and every protection here is enforced engine-side. send_message is Exec-category and absent from every auto-approve default; “Always allow” deliberately downgrades to per-send approval for this tool, and its tool name can never enter the auto-approve name set even if that set is poisoned (both pinned by tests). The exception is SessionMode::Force, which auto-approves every tool, this one included, before any per-tool rule is consulted - so a session deliberately placed in Force can send without a prompt. Independently security-audited (wayland#543 finding 4), which covers the default modes. |
| Ten channels with declared native actions | Shipped | As of v0.12.26, Slack, Discord, Telegram, Matrix, MS Teams, Email, WhatsApp, Twilio, SMS and the local channel each declare their native action capability, held honest by a cross-adapter conformance matrix with five declared negative adapters. channel actions prints the matrix and --require can gate a deployment on it. Per-platform: Slack chat.update/chat.delete plus a setup probe and auth classifier; Discord edit and delete with configurable API and gateway bases; Telegram edit and delete; Matrix m.replace, redaction and a restart-surviving /sync cursor; MS Teams activity PUT/DELETE and inbound attachment parsing; Email TLS trust anchors and an IMAP poller that no longer discards all but the largest message. |
| Gateway exactly-once delivery ledger | Shipped | As of v0.12.26. Plus an observable drain state, a lifecycle machine and a Windows-safe instance lock. Deliveries whose outcome is unknown are not re-sent to destinations that cannot dedupe. |
| Abandoned deliveries are nameable, acknowledgeable, re-sendable | Shipped | As of v0.12.26, and exempt from compaction until someone has actually looked at them. |
| Single-owner inbound polling lease | Shipped | As of v0.12.26, across all three start_all sites. The installed service outranks an ad-hoc session and the loser reacquires cleanly. |
gateway support-bundle (redacted) | Shipped | As of v0.12.26. Redaction proved clean by canary. |
| DM pairing codes | Shipped | As of v0.13.0, single-use codes wired into the runtime with an operator verb, so pairing a direct-message channel is a deliberate act. |
| Per-conversation autonomous-send rate cap | Shipped | As of v0.12.21, autonomous auto-replies are capped per conversation (default 30 per 10 minutes) so two agents wired to the same channel cannot loop forever. Human and operator sends bypass the cap entirely. (Core #154) |
| Capability | Status | Notes |
|---|---|---|
| 5-field cron expressions, 3 target types | Shipped | wcore-cron. Slash command, channel message, and skill targets. CLI + cronjob LLM tool + detachable daemon. |
| Integrity-tagged job store | Shipped | Per-host keyed integrity tag with three-state tamper detection (valid / no-tag-legacy / mismatch-tamper) in wcore-cron/src/store.rs. This is a dependency-free keyed hash, not a cryptographic HMAC. |
| Leased schedule, one firing process | Shipped | As of v0.12.26, the schedule is leased so exactly one process fires it, every trigger type is reachable from the shipped binary, and event, webhook and poll triggers validate, persist and fire. |
| Daemon skill/channel sinks | Partial | In standalone daemon mode (no live engine session), skill and channel targets log the trigger but do not execute. Slash-command targets work unconditionally. |
Budget
Section titled “Budget”| Capability | Status | Notes |
|---|---|---|
7-axis ExecutionBudget tree, CapWarn / CapBlock | Shipped | wcore-budget. CapWarn at 80%, CapBlock at limit. |
| Budget charge integrity | Partial | charge() trusts caller-supplied USD. BearerToken uses SHA-256(secret ‖ payload), not a true HMAC. Suitable for honest cost tracking; not adversarially tamper-proof. |
| Daily spend ceiling with a durable store | Shipped | As of v0.12.26, with a config path. Proactive budget envelopes sub-allocate to delegated children. |
| Queryable cache and compaction ledger | Shipped | As of v0.12.26. Session-scoped quality, invalidation, token pressure and cost truth, exposed through wayland-core cache (report/list/show/verify). |
| Cost truth records its source | Shipped | As of v0.12.26, so a family-rate estimate is never mistaken for measured spend. Totals roll up across sessions, because restart-fragmented spend is invisible from inside any single one. Cost is attributed to the route rather than the compat profile. Media billing covers TTS, all three vision backends including video_analyze, every billable transcription call and the image subcommand, with units and basis declared. |
| Reasoning budget never starves the visible answer | Shipped | As of v0.12.16, the reasoning budget is bounded so a large amount of internal reasoning can no longer crowd out the visible reply. The user-facing answer always keeps room to complete. |
Computer use (CUA)
Section titled “Computer use (CUA)”| Capability | Status | Notes |
|---|---|---|
| macOS (CGEvent) | Shipped | Requires Accessibility permissions. First-time-per-app HITL approval gate. |
| Linux X11 (XTest) | Shipped | |
| Linux Wayland (wlrctl / grim) | Platform limit | Refuses on restricted compositors: GNOME Mutter and Hyprland do not expose the required Wayland protocols. Works on compositors that implement wlr-layer-shell. |
| Windows (UI Automation) | Shipped |
Browser automation
Section titled “Browser automation”| Capability | Status | Notes |
|---|---|---|
| Camoufox sidecar (default) | Shipped | Requires the Camoufox sidecar running at localhost:9377. WebFetch (non-interactive HTTP fetch) works without the sidecar. |
chromiumoxide CDP backend | Shipped (opt-in build) | Cargo feature chromium. Requires a Chromium binary at runtime. |
| Browserbase cloud backend | Shipped (env-gated) | Cargo feature browserbase. Requires BROWSERBASE_API_KEY + BROWSERBASE_PROJECT_ID at runtime. |
| Arbitrary JS execution | By design | The browser surface is ARIA-tree-first with a defined 18-op surface. Arbitrary JavaScript execution is not exposed. |
| Bounded WebFetch readability extraction | Shipped | As of v0.12.16, WebFetch readability extraction is bounded so a single fetch cannot run away, and its per-turn circuit breaker resets each turn so one bad page does not disable fetching for the rest of the session. |
Authentication and OAuth
Section titled “Authentication and OAuth”| Capability | Status | Notes |
|---|---|---|
--login / --logout Anthropic OAuth | Removed | Anthropic OAuth is not implemented. Running an Anthropic OAuth flow outside Anthropic’s official clients is against their terms, so the engine does not provide one. Use an API key. |
/auth google-meet OAuth | Shipped | Full loopback authorization-code flow in wcore-cli/src/tui/auth.rs; the token exchange is persisted to ~/.wayland/oauth/google_meet.json. End-to-end functional. |
| Encrypted credential vault (OS keychain + Argon2id + XChaCha20-Poly1305) | Shipped | wcore-config/src/ using keyring, argon2, chacha20poly1305, rpassword. |
Host integration (Desktop boundary)
Section titled “Host integration (Desktop boundary)”| Capability | Status | Notes |
|---|---|---|
--json-stream protocol | Shipped | 10 inbound commands, ~25 event types, honest retryable flag, mid-turn Stop. wcore-protocol. |
ApprovalResume command (engine side) | Shipped | Present in wcore-protocol/src/commands.rs. |
ApprovalResume command (Desktop side) | Shipped | Present in the WCoreCommand union (src/process/agent/wcore/protocol.ts:608), handled at index.ts:1717 and sent at index.ts:2055. WCoreManager.ts:1975 resolves a stale or duplicate token as a no-op so a HITL-gated turn cannot hang. Verified 2026-08-30 against Desktop main; this row previously read Not-wired. |
Memory
Section titled “Memory”| Capability | Status | Notes |
|---|---|---|
| 5-partition x 3-tier SQLite store, auto-memorize, decay | Shipped | wcore-memory. Auto-memorize on by default. |
Local BGE embedder (bge-small via candle) | Shipped (default on) | local-embedder cargo feature, on by default in wcore-memory. Opt-out by building without it. |
| OpenAI / Voyage cloud embedders | Shipped (env-gated) | Available when the respective API keys are present. |
| Hashed embedder (default when no provider configured) | Shipped | Used when no embedder backend is configured; functional but produces lower-quality recall. |
Observability
Section titled “Observability”| Capability | Status | Notes |
|---|---|---|
| Trace schema, span sinks, 28-pattern PII scrubber | Shipped | wcore-observability. PII scrubbing on all trace output. |
| OTLP export | Shipped (opt-in build) | Cargo feature otlp in wcore-observability. Off by default; enables opentelemetry-otlp. |
| JSON-stream observability | Shipped | As of v0.12.8, the JSON stream carries structured observability: active-window percentage, agent-run correlation, and structured traces, so a host can follow run progress and context pressure over the protocol. |
Output compaction
Section titled “Output compaction”| Capability | Status | Notes |
|---|---|---|
| Bash and tool output compaction (3-level) | Shipped | wcore-compact. Three levels: off (verbatim), safe (default, sanitize only), full (sanitize + fold repeated lines + compact JSON). Applied per-turn at tool-result ingestion time. Config key [session] compact_level. |
| TOON semantic encoding | Shipped | wcore-compact::toon. Injected as a context-hint prefix; the model emits a compact representation the engine can unpack. Used for long structured outputs. |
Semantic compressor (SemanticCompressor) | Shipped | wcore-compact::semantic. Higher-level compressor that operates on Chunk segments with per-chunk retention decisions. Used for transcript rewrite passes. |
| Per-command compaction level override | Not-wired | No per-tool or per-command override of the compaction level is exposed in the config or protocol yet. The level is session-scoped. |
Context window and active-window kernel
Section titled “Context window and active-window kernel”| Capability | Status | Notes |
|---|---|---|
| Active-window kernel context sizing | Shipped | As of v0.12.8, the engine tracks an active context window that resizes accurately after a model swap, so the budget reflects the model currently in the loop rather than a stale window. |
| Smart auto-compaction at the active-window threshold | Shipped (default off) | As of v0.12.8, the engine can auto-compact when the active window crosses its threshold, with a Flux-aware path and a memory handoff so context is preserved across the compaction. Off by default; enable it explicitly. |
| Bounded project-context injection | Shipped | As of v0.12.17, oversized project context (a large AGENTS.md, deep @-includes, and big preset stacks) is capped before it enters the prompt, so large projects stop ballooning token usage and cost. (Core #115) |
Profiles and isolation
Section titled “Profiles and isolation”| Capability | Status | Notes |
|---|---|---|
| Isolated profiles (CLI-isolation) | Shipped | As of v0.12.7, profiles can run in isolation so a CLI session uses its own profile state without bleeding into other sessions. |
| Serve an isolated profile over ACP | Shipped | As of v0.12.25, acp serve --profile serves a named isolated profile, a profile supervisor routes one process per profile, and a trusted persona roster is enumerated over additive ACP protocol types. A named profile never runs on the default profile’s data. |
Plugins and marketplace
Section titled “Plugins and marketplace”| Capability | Status | Notes |
|---|---|---|
plugin install <name>@<marketplace> CLI | Shipped | wcore-cli::plugin. Resolves plugins from registered marketplace catalogs, lowers foreign formats (Claude Code plugin layout via ClaudeCodeAdapter in wcore-pluginsrc), writes an install plan, and commits to disk. Dry-run (--dry-run) writes nothing. Tested by marketplace_install_e2e and cli_marketplace integration tests. |
| Claude Code marketplace format support | Shipped | wcore-pluginsrc::claude_code::ClaudeCodeAdapter. Detects and lowers Claude Code plugin directories (skills, agents, commands, MCP servers) into the Wayland canonical CanonicalDraft. Hooks from foreign manifests are noted in the IgnoredFeature lossy-translation report and not executed (v1 does not run foreign hooks). |
plugin marketplace add <url> | Shipped | Registers a marketplace catalog by URL or local path. |
CompatibilityGrade degradation report | Shipped | Each install plan surfaces the weakest compatibility grade: UnsupportedBehavior, HooksIgnored, McpCompatible, or ContentCompatible. Degradation is always surfaced, never silent. |
| Prompt-injection risk scan (Lane E2) | Shipped | PlanWarning entries of kind prompt-risk are emitted when asset text contains injection or credential markers. |
Web search
Section titled “Web search”| Capability | Status | Notes |
|---|---|---|
web tool (search, extract, crawl) | Shipped | wcore-tools::web_tools. Single WebTool with an operation discriminator. SSRF and website-policy gating runs before the backend is called for every URL. |
Pluggable WebBackend trait (Exa, Firecrawl, Tavily, Parallel, …) | Shipped | wcore-tools::web_tools::WebBackend. The host wires in a concrete backend; the engine holds no HTTP client. Exa backend in wcore-agent::tool_backends::exa_web (requires EXA_API_KEY). Firecrawl, Tavily, Parallel, and DuckDuckGo backends are referenced in the port notes and ported from wayland-hermes. |
| Parallel multi-backend search ladder | Partial | The WebBackend trait supports multiple backend registrations. Whether the host wires a parallel ladder (dispatching to Exa, Firecrawl, SearXNG, and others in parallel with a result merger) is a host-configuration decision; the tool layer itself does not enforce a specific ladder topology. Verify against the host’s WebBackend wiring in your deployment. |
| Exa extract and crawl operations | Not-wired | ExaWebBackend::extract returns "Exa extract not wired; use the WebFetch tool on a specific URL." and crawl returns "Exa crawl not supported." These operations fall back to the general WebFetch tool. |
Per-tool circuit breaker
Section titled “Per-tool circuit breaker”| Capability | Status | Notes |
|---|---|---|
| Per-tool circuit breaker (Closed / Open / HalfOpen) | Shipped | wcore-tools::registry::ToolRegistry. Every registered tool gets its own CircuitBreaker keyed by tool name. Uses CircuitBreakerConfig::default() (wcore-config::circuit_breaker). State machine: K failures in window open the breaker; after cooldown it moves to HalfOpen, one trial allowed; success closes, failure re-opens. |
| Configurable threshold and window | Shipped | CircuitBreakerConfig fields: fail_threshold (default from wcore-config), window (Duration), cooldown (Duration). Config path: [tools] circuit_breaker.* (see commented example in generated config). |
| Unknown-tool calls | Shipped | Unknown tool names return is_error without tripping any breaker, consistent with H2-R5 test coverage (tool_circuit_breaker_test.rs). |
OpenAI Responses API routing
Section titled “OpenAI Responses API routing”| Capability | Status | Notes |
|---|---|---|
gpt-5* family routed to Responses API | Shipped | wcore-providers::openai_compat::model_uses_responses_api. Any model whose name starts with gpt-5 is routed to POST /v1/responses instead of /v1/chat/completions. The routing decision is a simple prefix check (starts_with("gpt-5")); gateways that proxy gpt-5* over Chat Completions can override via responses_api_override. |
| Responses API request builder | Shipped | wcore-providers::openai_responses::build_responses_body. Builds the /v1/responses body including input item array (user, assistant, tool-result shapes), flat tool schema (convertResponsesTools style), and max_output_tokens (uses max_output_tokens not max_tokens). |
Reasoning effort for gpt-5 family | Shipped | Reasoning effort is forwarded if set; gpt-5* still accepts it (unlike o1*/o3* which reject it). |
| Streaming from Responses API | Shipped | wcore-providers::openai_responses. Stream parser handles response.output_text.delta, response.completed, and tool-call events. Buffer is bounded to prevent unbounded growth. |
Durable Goals
Section titled “Durable Goals”| Capability | Status | Notes |
|---|---|---|
| Durable Goal kernel under all five loop owners | Shipped | As of v0.12.26. Anvil, Council, Crucible, ForgeFlows and Direct share one canonical terminal taxonomy lifted into wcore-types, with a single transition driven from the shipped binary. Kill the process mid-run and the Goal is still there, in state, resumable. |
| Goal control over the host protocol | Shipped | As of v0.12.26. A typed Goal control command set, goal stream for a live view, refusals rendered in the TUI, and durable Goal state shown in the terminal. |
| Durable task ledger with an epoch fence | Shipped | As of v0.12.26. Dependencies are enforced at the durable boundary, an agent releasing a claim must present its own epoch, and a loop-owner claim carries a lease so a dead owner cannot deadlock its Goal. |
Execution backends
Section titled “Execution backends”| Capability | Status | Notes |
|---|---|---|
wayland-core backend: local, ssh, container, cloud | Shipped | As of v0.12.26. One provider-neutral contract with four reference backends. |
| Cloud backend creates, runs and hibernates a machine | Shipped | As of v0.12.26. A cancelled run writes a Cancelled receipt rather than vanishing. |
| Attested node attribution and orphan scanner | Shipped | As of v0.12.26. Nodes carry attested attribution and an orphan scanner sweeps what got left behind. |
receipt verify --against-backend checks identity | Shipped | As of v0.12.26. Identity, not merely integrity. |
Persistent code index
Section titled “Persistent code index”| Capability | Status | Notes |
|---|---|---|
wayland-core index build / status / search / verify | Shipped | As of v0.12.26. An incremental repomap index with git-respecting scope. |
| WAL checkpointed after each refresh | Shipped | As of v0.12.26, so the reported size is steady-state rather than climbing between compactions. |
| Unknown store schema versions refused | Shipped | As of v0.12.26. An index written by a newer Core is refused by name rather than read on a best-effort basis. |
| Semantic search unavailability states a reason | Shipped | As of v0.12.26, index status reports semantic status=unavailable with the reason, instead of silently degrading to keyword matching. |
Backup, restore and rollback
Section titled “Backup, restore and rollback”| Capability | Status | Notes |
|---|---|---|
| Backup archive, verify, restore, write-ahead journal | Shipped | As of v0.12.26. |
| Consistent live-SQLite capture | Shipped | As of v0.12.26. Live SQLite is captured consistently into the journal undo store rather than copied naively across a write. |
Scoped operation journal, migrate rollback-able | Shipped | As of v0.12.26. The journal records declared scope, absent-set and an exact reverse-apply. |
| Refusals happen before the first write | Shipped | As of v0.12.26. Newer-schema archives are refused; older and truncated ones are covered; unrestorable paths are refused before the first write rather than halfway through it. |
| Dead owner’s restore recovered | Shipped | As of v0.12.26, before occupancy and before a new journal is opened. |
Import from other agent CLIs
Section titled “Import from other agent CLIs”| Capability | Status | Notes |
|---|---|---|
migrate importers: openclaw, grok, gemini-cli | Shipped | As of v0.12.26. Typed, redacted, deterministic discovery. |
| Provenance bound to where bytes landed | Shipped | As of v0.12.26. Imported content is genuinely written, and only what was written is counted. The quarantine index is written atomically. Containment was measured at real import scale rather than sampled. |
Workspace trust
Section titled “Workspace trust”| Capability | Status | Notes |
|---|---|---|
| Authority-expanding project config gated on trust | Shipped | As of v0.12.26, and a breaking change for anyone writing .wayland-core.toml. [profiles.*], [mcp.servers.*], [providers.*], hooks, env_passthrough and the sandbox keys are stripped from an untrusted workspace. Grant trust once with --trust-workspace. See Workspace Trust. |
| Trust refusal names the decision and the remedy | Shipped | As of v0.13.0. An untrusted workspace previously reported Profile 'p' not found in config for a profile Core had parsed and then discarded, with the only true account in a tracing::warn! invisible at default verbosity. A profile that genuinely was never written still reads as absent. |
| Symlinked executable surfaces are trustable | Shipped | As of v0.12.26. The fingerprint follows a link and hashes the bytes it resolves to, so a host composing a workspace from its own assets can obtain trust. Rewriting a target or repointing a link voids the grant. Dangling links, link cycles, and links to devices or FIFOs fail closed. |
Project config cannot raise max_tokens / max_turns | Shipped | As of v0.12.26. An untrusted repository cannot widen limits you set. |
Project [memory] cannot defeat a global memory opt-out | Shipped | As of v0.12.26. Cloning a repository cannot silently re-enable memory. |
| Egress master switch is operator-owned | Shipped | As of v0.12.26. A project cannot negotiate it. |
Announced tool calls and unsaved work
Section titled “Announced tool calls and unsaved work”| Capability | Status | Notes |
|---|---|---|
call_announced frame for auto-approved calls | Shipped | As of v0.13.0. Every tool call that skips the approval gate, whether by force mode, an allow-listed tool, a command-scoped grant or a just-granted Always, emits call_announced carrying the same payload as tool_request. Hosts must consume it, not merely tolerate it: the tool_running behind it still has no matching request, and a host failing closed on that will exit the turn. In the TUI it restores the tool card and stages the file the call touched. |
| Unsaved-work guard across shell, editor and redirects | Shipped | As of v0.13.0. The shell cannot discard unsaved work, an Edit cannot drop it as a side effect, and a redirect that would truncate a file with unsaved changes is refused. The guard covers rm and git as well as the editor, keys on one path spelling so it cannot be sidestepped, anchors every copy under a ref so nothing it saves is garbage-collected, and distinguishes a merge in progress from unsaved work. |
| Locks release on drop | Shipped | As of v0.13.0. The session journal’s data-file lock leaked through fork(), blocking an agent behind its own child in 47.6% of reopens under load. The journal now unlocks on drop rather than relying on close(2); the same correction landed on the cron schedule lease, the gateway pid lock, the eval candidate identity lock and snapshot publication. |
| Runs needing unreachable human contact freeze and exit | Shipped | As of v0.13.0, instead of proceeding as though nobody needed to be asked. |
sandbox status does not overclaim on Windows | Shipped | As of v0.13.0, it no longer claims filesystem containment on Windows, where the Job Object does not provide it. Measured, not assumed. A tool description no longer names the flag that bypasses it, startup warnings are said once rather than every turn, and requests that never returned a response are disclosed. |
Supply chain and release integrity
Section titled “Supply chain and release integrity”| Capability | Status | Notes |
|---|---|---|
| Signed release manifest and deterministic SBOM | Shipped | As of v0.12.26. Deterministic CycloneDX SBOM, byte-determinism verified in CI. |
| Keyless Sigstore build provenance on every archive | Shipped | As of v0.12.26. npm published with --provenance. |
Fail-closed self-update | Shipped | As of v0.12.26, self-update verifies the release attestation before it replaces the binary and fails closed if it cannot. |
| Every required leg green on the v0.13.0 release tree | Shipped | Linux containerized 14,656 / 14,656; macOS 14,547 / 14,547; Windows self-hosted 14,174 / 14,174. Zero failures. Plus six platform builds, the eval acceptance gate, and the browser end-to-end suite. The Windows leg runs on real hardware rather than a VM approximation. |
Credential and memory controls
Section titled “Credential and memory controls”| Capability | Status | Notes |
|---|---|---|
| Credential deny-list enforced on every read tool | Shipped | As of v0.12.26. Previously Grep, Glob and Bash consulted a different list from Read, and Grep returns matched line content. |
| Fail-closed credential ladder, no plaintext fallback | Shipped | As of v0.12.26, plaintext credential storage is removed entirely. A host with no secure store refuses to save rather than writing cleartext. |
| Sandbox bypass cannot be activated remotely | Shipped | As of v0.12.26. --dangerously-skip-permissions split into two tiers; sandbox bypass must be asked for by name with --dangerously-skip-permissions-and-sandbox. |
[default] read_only actually enforces | Shipped | As of v0.12.26. It was advisory in paths that mattered. |
memory.enabled = false actually stops recording | Shipped | As of v0.12.26. A memory activation surface shows and switches off exactly what memory puts in your prompt, /memory why and /memory correct show what each item says rather than just its id, and /usermodel displays inferred beliefs marked by origin with a user-authored correction layer that takes render precedence. |
| Project memory stays out of your repository | Shipped | As of v0.13.0, and the project root is resolved before it becomes a key. |
| Capability | Status | Notes |
|---|---|---|
| Voice default-on for macOS and Windows | Shipped | As of v0.12.26, with barge-in made real: killable playback, a wired interrupt and a live readiness gate. |
| Voice on Linux | Offline-only | As of v0.12.26 it is a one-flag opt-in (--features voice plus ALSA dev headers) so the stock binary starts on any host. The product reports voice as absent from the build rather than as a broken device. |
JWT and cryptography
Section titled “JWT and cryptography”| Capability | Status | Notes |
|---|---|---|
JWT signing via aws_lc_rs (RUSTSEC-2023-0071 closed) | Shipped | wcore-providers and wcore-channel-msteams both declare jsonwebtoken = { ..., features = ["aws_lc_rs"] } in their Cargo.toml. This uses AWS-LC (constant-time, FIPS-validated) rather than the pure-Rust ring backend that carried RUSTSEC-2023-0071. aws-lc-rs is already in the dependency tree as rustls’s default crypto provider, so there is no additional link-time cost. |
| Encrypted credential vault (Argon2id + XChaCha20-Poly1305) | Shipped | wcore-config/src/ using keyring, argon2, chacha20poly1305, rpassword. Not affected by RUSTSEC-2023-0071 (uses separate crypto primitives). |