---
title: Agent, That Really Works — Roadmap
description: Internal product roadmap derived from the HybridClaw manifesto ("The AI Coworker Who's Already On It"). Not linked from the public docs nav.
---

> **Internal document.** This page is intentionally excluded from the docs sidebar, navigation, and search — but it remains web-accessible by direct URL, which is how GitHub issue bodies reference it. Source of truth for roadmap planning. Tracked in the umbrella issue [HybridAIOne/hybridclaw#466](https://github.com/HybridAIOne/hybridclaw/issues/466).

# Agent, That Really Works — Roadmap

Features are grouped into three priority tiers. **P0** = Very High Priority (launch package). **P1** = High Priority (depth). **P2** = Priority (breadth). Sequencing within a tier is driven by technical dependencies.

The roadmap is anchored in the [HybridClaw manifesto — *The AI Coworker Who's Already On It*](../manifesto.md). Numbers in *italic* below each feature link the work back to the principle it serves.

> **Naming convention.** Product, manifesto, and marketing surfaces use **Coworker** (*"hire Lena"*). Code, admin UI, CV, scoreboard, types, and APIs use **Agent**. The two refer to the same entity. This roadmap uses *Agent* in technical descriptions and reverts to *Coworker* when paraphrasing the manifesto. See `docs/content/manifesto.md` for the customer-facing voice.

## Status legend

✅ Done · 🟡 *N/M* partial (children closed/total) · 🔄 PR in flight · ⬜ Not started

| # | Feature | Description | Priority | Status |
|---|---------|-------------|----------|--------|
| 21 | **Business skills and connectors** | Production skills and connector work. See **R21 Production Skills** below for sub-issue rows. *Principle I — the skills are the product.* | P0 | 🟡 17/108 |
| 1 | **Agent-to-agent messaging** | First-class primitive for agents to message, hand off, escalate, federate across instances, and speak multiple transport formats. See **R1 Messaging Work** below for sub-issue rows. *Principle VI.* | P0 | 🟡 8/14 |
| 2 | **Workflow engine — autonomous-by-default with high-stakes escalation** | Declarative YAML workflows. Sequential runner; escalation gates only on high-stakes steps. Return-for-revision rewinds. Built on top of #1. See **R2 Workflow Work** below for sub-issue rows. *Principles II + VI.* | P0 | 🔄 #461 |
| 3 | **Agent scoreboard + auto-`CV.md`** | Per-skill score data model populated from the skill-run event bus. Auto-rendered CV per agent; admin scoreboard; "best at X" recommendation API. See **R3 Scoreboard Work** below for the follow-up row. *Principle IV.* | P0 | ✅ (5/5; follow-up R3.7 ✅ #618; #616, #619 still open) |
| 4 | **Business-secret masking + demasking** | **Substantially built** — round-trip placeholder scheme (`«CONF:RULE_ID»`), `dehydrateConfidential` / `rehydrateConfidential`, streaming-aware rehydrate, scoring + leak scan all live in [`src/security/confidential-redact.ts`](../../../src/security/confidential-redact.ts) + [`confidential-runtime.ts`](../../../src/security/confidential-runtime.ts) + [`confidential-rules.ts`](../../../src/security/confidential-rules.ts). Net-new: (a) first-class `nda` / `price` / `contract` rule kinds (current schema has generic `keyword`/`pattern`), (b) `confidential.dehydrated` / `confidential.rehydrated` audit events. *Principle VII.* | P0 | 🟡 4/6 (round-trip + streaming + scoring shipped; rule-kinds + audit events open) |
| 5 | **Token / money budgets per agent** | Metering substrate done: `UsageTotals` + `monthlySpendUsd()` / `monthlySpendEur()` ([`src/memory/db.ts:3437-3560`](../../../src/memory/db.ts)) + agent-card surfacing. Enforcement remains open. See **R5 Budget Work** below for sub-issue rows. *Principle IX.* | P0 | 🟡 1/8 |
| 6 | **NDA / secret-leak classifier** | **Rule-based offline scanner already shipped** via #406 — [`src/audit/leak-scanner.ts`](../../../src/audit/leak-scanner.ts) (650 lines) reuses `scanForLeaks` from [`confidential-redact.ts:168`](../../../src/security/confidential-redact.ts) with severity/category buckets + CLI. **Inline `post_receive` middleware ✅ via PR #763 (2026-05-01)** — leak scanner now ships as a `ClassifierMiddlewareSkill` adapter with real escalation approvals on `block`, hooked into the executor turn loop. **F3 action mapping ✅ via PR #763** — middleware contract returns `allow` / `block` / `warn` / `transform` / `escalate` and the executor dispatches accordingly. Net-new remaining: (c) optional **F11 LLM-judge fallback** for borderline scores via the F11.4 subscriber pattern, (d) eval suite. *Principle VII.* | P0 | 🟡 3/4 (rule-based scanner ✅ #406; pre-ship hook + F3 action wiring ✅ via PR #763; LLM-judge + eval open) |
| 7 | **Shared enterprise memory** | RAG over team docs / CRM / wiki, available in self-hosted HC. **Substrate already exists**: [`src/memory/`](../../../src/memory/) ships chunker (`chunk.ts`), embeddings (`transformers-embedding-provider.ts`), semantic recall (`semantic-recall.ts`), knowledge graph, consolidation — but agent-scoped, not team-scoped. Net-new: (a) **`source` dimension** on the recall index (agent / team / tenant / external), (b) ingestion CLI for team docs/CRM/wiki sources, (c) per-agent source-scoping policy, (d) retrieval-quality eval suite. **Reuse the existing chunker + embeddings + recall — don't spin up a fresh vector store.** *Principle I.* | P1 | ⬜ (substrate ready) |
| 8 | **Brand-voice + output classifier** | Per-tenant voice profile and pre-ship response classifier. Refactored onto the F8 classifier-middleware contract via PR #763. See **R8 Brand-Voice Work** below for sub-issue rows. *Principle VII.* | P1 | 🟡 3/6 |
| 9 | **Hierarchical swarm — RPC delegation track** | Cross-instance delegation where one instance dispatches a task and awaits a result from another. Shares transport, auth, and audit infrastructure with R1 federation. See **R9 Delegation Work** below for sub-issue rows. *Principle VI.* | P0 | 🟡 2/7 |
| 10 | **Auto-improvement on real tasks** | Trajectory pipeline feeding two improvement tracks: auto harness evolution and fine-tuning. See **R10 Auto-Improvement Work** below for sub-issue rows. *Principle VIII.* | P1 | 🟡 3/8 |
| 11 | **Operator notification windows + escalation routing** | *Reframed under v3 Principle III.* The coworker is always on; this issue covers per-operator notification preferences (when to page vs. queue for the morning summary) and escalation routing through F8. | P2 | ⬜ (2 anti-principle children closed) |
| 12 | **Mobile-first admin (iOS / Android wrapper)** | Responsive admin pages, mobile-friendly approval flow, push notifications, native wrappers via Capacitor or React Native. *Principle X.* | P1 | ⬜ |
| 13 | **Per-client cost & audit reports** | Client tagging on activity, per-client cost rollup extending #5, per-client audit-log filter, branded PDF export. *Principle VII.* | P1 | ⬜ |
| 14 | **SSO + RBAC** | OAuth2 / OIDC framework with Okta, Google Workspace, Microsoft Entra providers. Role + permission model; per-agent access policies for human users. **Reuse OAuth2 client patterns** already in production at [`src/auth/google-auth.ts:200-290`](../../../src/auth/google-auth.ts) (state param + loopback redirect + token exchange) and [`src/auth/codex-auth.ts:460-550`](../../../src/auth/codex-auth.ts) (PKCE) — these are operator-outbound clients but the same patterns transfer to inbound OIDC. Net-new: inbound OIDC verifier, IdP role mapping, per-user session, permission model, per-agent ACL — **don't re-implement auth-code/PKCE**. *Principle VII.* | P1 | ⬜ |
| 15 | **Agent handoff with context transfer** | Extends the `handoff` intent from #1 to carry a context bundle (thread refs, brief, client tags). Recipient absorbs context before resuming. **Scope discipline (added 2026-04-30):** R15 covers *boundary-crossing* handoffs only — different model tier (Haiku → Opus on stakes), different tenant, or different operator. **Do not** use R15 to split a single coherent task across role-named agents (`Planner → Implementer → Tester`); that is the telephone-game anti-pattern flagged in **R31** coordination-patterns reference. If the receiving agent needs full context, the work belongs in one agent — split only when context can be cleanly separated. *Principle VI.* | P2 | ⬜ |
| 16 | **Skill A/B testing + canary deployments** | Variant routing by deterministic hash, per-variant metrics from the event bus, statistical comparison, promotion gate via the eval harness. *Principle VIII.* | P2 | ⬜ |
| 17 | **Agent references / portfolio export** | Anonymized portfolio bundle (work samples + scores) **plus the evolved harness** — long-term memory, skill packages, tool descriptions, middleware — so an exported coworker can be re-instantiated on a different model/provider without re-evolution. AHE paper ([§4.3](https://arxiv.org/html/2604.25850v1)) showed +5.1–10.1pp gains transferring frozen harnesses to weaker bases; also lifts the floor on **R28** fallback. *Principle IV.* | P2 | ⬜ |
| 18 | **Voice / outbound phone channel** | Outbound HTTP plumbing plus STT/TTS substrate are in place. Agent-facing call operations, call-flow control, audit wiring, and SIP remain open. See **R18 Voice Work** below for sub-issue rows. *Principle V.* | P2 | 🟡 1/5 |
| 19 | **Calendar / meeting presence** | Bot joins Zoom / Meet, real-time STT, live notes, post-meeting summary, action-item dispatch via #1 to other agents. *Principle V.* | P2 | ⬜ |
| 20 | **Right-to-be-forgotten / GDPR data export** | Identifier registry, cascading data discovery, audited deletion, machine + human readable export. Hash-chain entry of the deletion preserved. *Principle VII.* | P2 | ⬜ |
| 22 | **Async voice channel** | **STT + TTS substrate already done** in `src/channels/voice/runtime.ts` (ConversationRelay prompt fragments at lines 440-465 for STT; `responseStream.reply` + `formatTextForVoice` at 344-370 for TTS). Net-new is the **inbound message-layer adapter** — voice notes at the channel-message level rather than a synchronous phone call. Reuse `ConversationRelayResponseStream` + `formatTextForVoice`. *Principle V.* | P2 | 🟡 (STT/TTS ✅; message adapter open) |
| 23 | **Whole-instance backup + restore (disaster recovery)** | `hybridclaw backup` + `restore` CLI for WAL-safe SQLite snapshot + zip-archive re-hydration on a fresh host. **Follow-up (added 2026-05-09): warm-restart durability** — atomic session-state writes + auto-resume across in-place restart, checkpoint pruning + disk guardrails. Generalizes R23 from cold-DR to warm-restart so a process kill mid-turn doesn't lose the agent's working state. One-PR scope; reuses the existing snapshot machinery. *Principle VII.* | P1 | ✅ #635 (via PR #428); 🟡 warm-restart follow-up to be filed |
| 24 | **SMS channel via European operator APIs** | Pluggable SMS provider via the existing channel layer — Telekom MMS API, Vodafone Messaging, 1&1 SMS gateway. For transactional B2B messaging (OTPs, alerts) where WhatsApp/Telegram aren't the right modality. **Reuse** Twilio account/auth plumbing from [`src/channels/voice/twilio-manager.ts`](../../../src/channels/voice/twilio-manager.ts) for the Twilio-SMS stopgap path. Add `sms` to `ChannelKind` at [`src/channels/channel.ts:1-13`](../../../src/channels/channel.ts) and a new `src/channels/sms/` runtime. *Principle V.* | P2 | ⬜ |
| 25 | **EU deployment recipes (Hetzner / IONOS / Open Telekom Cloud)** | Operator guides for deploying HybridClaw on each EU cloud provider — Docker Compose, Terraform, secret-store setup, F6-tunnel vs cloud-native ingress, backup wiring (R23). DSGVO talking points for sales. *Principle X.* | P1 (Hetzner) / P2 (IONOS, OTC) | ⬜ |
| 26 | **Fax gateway + outbound skill** | Inbound fax-to-email → existing email channel; outbound fax-send skill with pluggable EU-resident provider (Telekom Cloud Fax / Sinch / Vodafone Fax2Mail / T.38 over R18.7 SIP). *Principle V — DACH B2B Steuerberater + healthcare + legal workflows.* | P2 | ✅ #1053 (skills/fax-send/ + src/fax/ + docs/content/channels/fax.md) |
| 27 | **Async tamper-evident token-usage buffer** | Producer-consumer queue decouples model invocations from synchronous chargeback DB writes; periodic batch flush emits SHA-256-hashed `usage.batch_flushed` audit events. Substrate for R5.x at scale. *Principle VII.* | P1 | ✅ #663 (via PR #467) |
| 28 | **Provider fallback chain (resilience)** | Auth (401/403) → immediate switch; rate-limit (429) → switch + cooldown on primary-leave only; streaming-safe; configured via `HYBRIDAI_FALLBACK_CHAIN`. Implementation at [`src/gateway/provider-fallback.ts`](../../../src/gateway/provider-fallback.ts) (`classifyProviderError`, `tryActivate` with `leavingPrimary` guard, `shouldFallback` streaming gate). *Principle VIII — doesn't break overnight when a provider has an outage.* | P1 | ✅ #413 (merged in `0648606e`) |
| 29 | **Kanban-style admin work board** [#687](https://github.com/HybridAIOne/hybridclaw/issues/687) | Coworker workboard at `/admin/board`: columns Triage → Todo → In Progress → In Review → Done (per-column auto-merge toggle). Per-card surface mirrors the Fusion job-board reference — sub-task progress bar + collapsible step list with strikethrough on completed steps, model badge (Opus/Sonnet/Haiku), files-changed count, worktree pill, linked-task chips, status pills (specifying / paused / merging / queued / blocked), live activity ticker, footer counters (running M/N · blocked · queued · in-review). Subsumes the workflow state visualizer (R2.5 [#434](https://github.com/HybridAIOne/hybridclaw/issues/434)) and the admin inbox (R1.3 [#426](https://github.com/HybridAIOne/hybridclaw/issues/426)) into one surface; feeds the F2 event bus to update without polling. **Dual use (added 2026-04-30):** the same card data model + F2 event stream is the **shared task list** for **R31** agent-team coordination — agents claim cards via R1 envelopes, surface `blockedBy` + dependency edges, and the human-ops view and agent-team view read the same store. See **R29 Board Work** below for sub-issue rows. *Principles IV + X.* | P1 | 🟡 2/8 |
| 30 | **Browser channel/skill ([browser-use](https://github.com/browser-use/browser-use) integration)** [#700](https://github.com/HybridAIOne/hybridclaw/issues/700) | Browser automation substrate with local, managed-cloud, and browser-use-cloud install modes. Session persistence reuses the existing browser profile convention; browser actions must respect F13 credential injection and F14 2FA handover. See **R30 Browser Work** below for sub-issue rows. *Principles V + VII.* | P1 | 🟡 5/10 |
| 31 | **Coordination patterns reference + worked examples** [#704](https://github.com/HybridAIOne/hybridclaw/issues/704) | Names the **two coordination architectures** HybridClaw supports and maps them to existing primitives so skill authors pick correctly: **(1) Sub-agents** — isolated, one-shot, parent-controlled, returns compressed result. Substrate: Claude Agent SDK `Agent` tool with `subagent_type` (already in use by the harness itself). Right when sub-tasks are independent and the parent only needs the final answer (vision-extract, code-review, eval-runner). **(2) Agent teams** — persistent, peer-to-peer, shared task layer. Substrate: **R1** A2A envelopes (peer comms) + **F10** org chart (`peers` / `delegates_to`) + **R29** kanban board as the shared task list (claim/release/`blockedBy`). Right when work has cross-cutting dependencies and agents need to coordinate live. **Decomposition rule:** *split by what an agent needs to know, not by what role it plays* — role-named pipelines (`Planner → Implementer → Tester`) lose information at every handoff (anti-pattern, see R15 scope discipline). Also documents the **five orchestration patterns** (prompt chaining, routing, parallelization, orchestrator-worker, evaluator-optimizer) and maps each to existing or planned primitives: routing → F8 stakes classifier; orchestrator-worker → sub-agents; evaluator-optimizer → R10a harness evolution loop. Deliverable: a section in `docs/content/developer-guide/` with worked examples (browser skill spawning a vision sub-agent for screenshot OCR; multi-agent feature build using R29 task list + R1 envelopes) and a decision tree ("does the receiver need the parent's reasoning? if yes, don't split"). Added 2026-04-30. *Principles IV + VI.* | P1 | ⬜ |
| 32 | **Server maintenance skill — local execution** *(to be filed)* | A persistent agent role with **local shell + systemd + log + filesystem-inspection** capabilities, designed for HybridClaw deployed *on* the target server (chat-ops). Operator talks to it through any existing channel ("why is disk full?", "restart nginx", "tail the auth log"). Skill bundle: `journalctl` reader, `systemctl status/restart/reload`, `df` / `du` / `free` / `top`, `/var/log` tail with leak-scanner ([R6](#)) over outbound responses, package-manager reads, no `apt install` / `rm -rf` without F8 stakes-escalation + F14 operator-confirm. **Reuses:** existing channels, [F8](#) stakes classifier, [F14](#) escalation, [R29](#) board (incidents as cards), [R31](https://github.com/HybridAIOne/hybridclaw/issues/704) sub-agent pattern (parent dispatches isolated log-readers without polluting context). [R14](#) RBAC scopes per-host shell access; [F13](https://github.com/HybridAIOne/hybridclaw/issues/698) audits any credential read. Pairs with [R25](#) EU deployment recipes — every Hetzner / IONOS / OTC deployment ships R32 by default so operators get chat-ops out of the box. Added 2026-04-30. *Principles III + V.* | P1 | ⬜ |
| 33 | **Server maintenance skill — remote SSH** *(to be filed)* | Companion to [R32](#) for the case where HybridClaw runs centrally and reaches one or more managed hosts via SSH. Skill bundle: SSH session pool with per-host `known_hosts` + per-host policy, the same shell/systemd/log surface as R32 but executed remotely, file pulls (sftp), interactive `sudo` flows that escalate to F14 instead of auto-typing the password. **SSH keys are exactly the use case [F13](https://github.com/HybridAIOne/hybridclaw/issues/698) was designed for** — keys reference by `SecretRef`, never returned as a string, never typed into the LLM context. **Reuses:** F13 keystroke-injection pattern (extended from DOM to SSH stdin), [F3](#) per-host ACL predicates (`ssh_exec_allowed`), R14 RBAC, R29 board, R31 sub-agent pattern. **Out of scope:** rolling out config-as-code (that's a different Ansible/Terraform-shaped skill). R33 is interactive ops, not declarative provisioning. Added 2026-04-30. *Principles III + V + VII.* | P1 | ⬜ |
| 34 | **Local-LLM teammate / sovereign delegation** *(to be filed)* | Extends [R9](#) hierarchical swarm so a HybridAI-cloud or self-hosted instance can **delegate to a peer instance running a strong local LLM** (Llama-3.3-70B / Mixtral 8x22B / Qwen2.5-72B / etc. via Ollama / vLLM / TGI / LM Studio) for tasks that must not leave the operator's network. Net-new layers on top of existing R9 + F5 + F10 substrate: **(a) capability advertisement** — peer instances publish their local models into [F5](#) capability matrix (`provider: local`, `host: peer-id`, model + context window + GPU class); **(b) residency / sovereignty policy** via [F3](#) — a skill or task can declare `data_residency: local-only` and the router refuses to dispatch to any cloud provider; **(c) routing layer** — F8/F5 picks a peer that satisfies the policy and has the capability, falling back to operator escalation (F14) if no peer is reachable. **Reuses:** R9 cross-instance delegation tokens + transport ([PR #409](https://github.com/HybridAIOne/hybridclaw/pull/409)), F5 capability matrix (currently per-provider, extends to per-peer-instance), F10 `delegates_to`, R28 fallback chain (peer outage → next peer or escalate). **Composes with R32 / R33** — a maintenance agent on a sovereign-data server can keep logs out of the cloud entirely by handing the LLM step to a local-LLM peer. **Composes with R31** — the sub-agent pattern is what runs on the local-LLM peer (parent on cloud, isolated worker on local). Added 2026-04-30. *Principles VII + VIII.* | P1 | ⬜ |
| 35 | **LLM Council mode — multi-provider deliberation** [#711](https://github.com/HybridAIOne/hybridclaw/issues/711) | Concurrent fan-out across providers, anonymized cross-critique, and chairman synthesis gated by F8 stakes and R5 budget controls. See **R35 Council Work** below for sub-issue rows. *Principles I + IV + VII.* | P1 | ⬜ |
| 36 | **WhatsApp Cloud API channel** [#734](https://github.com/HybridAIOne/hybridclaw/issues/734) | Inbound + outbound via Meta's WhatsApp Cloud API (direct integration, not Twilio's wrapper). Add `whatsapp` to `ChannelKind` at [`src/channels/channel.ts:1-13`](../../../src/channels/channel.ts) and a new `src/channels/whatsapp/` runtime. Registered as **F14** escalation modality so `escalation.interaction_needed` events route to operator phone numbers; quick-reply / text replies (`approve` / `deny` / `yes for session`) feed `handleApprovalResponse` in [`container/src/approval-policy.ts`](../../../container/src/approval-policy.ts) via the same regex path used by terminal approvals. Per-tenant config (business account ID + phone number ID + access token + designated operator numbers); opt-in template messages for the 24-hour window rule; audit-log entries record channel + counterpart phone number on every approval. Driver: WhatsApp is the dominant messaging modality in DACH / LATAM / most of EMEA — for many operators it's where they'd see and respond to an approval ping fastest. Composes with **F14** + **F10** + **R12** + **R37** (Discord peer for ops-team approvals). **F14 modality requirement (added 2026-05-09):** approvals must use WhatsApp's interactive message components (button replies / list replies), not text-regex parsing of free-form replies. Text-regex is brittle on a typing-heavy mobile channel and the audit log loses fidelity. **Pre-production hardening (added 2026-05-09):** rejects unsolicited inbound from non-allowlisted phone numbers by default; per-tenant strangers-allowed override gated behind an explicit operator setting. Added 2026-05-01. *Principle V.* | P2 | ⬜ |
| 37 | **Discord channel + slash-command approval** [#735](https://github.com/HybridAIOne/hybridclaw/issues/735) | Bot-user channel for engineering / ops teams that live in Discord. Add `discord` to `ChannelKind` at [`src/channels/channel.ts:1-13`](../../../src/channels/channel.ts) and a new `src/channels/discord/` runtime. Slash commands `/approve <id>`, `/deny <id>`, `/trust agent <name> <action>`, `/list-pending` feed `handleApprovalResponse` in [`container/src/approval-policy.ts`](../../../container/src/approval-policy.ts). **F14** escalation registration routes `escalation.interaction_needed` events to a configured ops channel + role mention; each escalation creates its own thread so back-and-forth doesn't pollute the channel. Per-guild config (bot token, ops channel ID, role ID, channel allowlist for sensitive escalations); audit records guild ID + channel ID + Discord user ID per approval. Peer to **R36**: WhatsApp targets the individual operator, Discord targets the team channel — both worth shipping. Composes with **F14** + **F10** + **R29** (a `In Review` card mirrors a pending Discord thread) + **R36**. Anti-goal: not a generic Discord-to-LLM bridge for end users. **F14 modality requirement (added 2026-05-09):** prefer interactive components (buttons / select menus on the escalation message) over slash-command-only flows; slash commands stay as the power-user path, but the default UX for an escalation thread is a clickable card. **Pre-production hardening (added 2026-05-09):** guild-scoped role allowlist on every approval; bot reconnects use exponential backoff on transport restart so a flapping gateway doesn't hammer Discord. Added 2026-05-01. *Principle V.* | P2 | ⬜ |
| 61 | **Discord Incoming Webhook channel** [#1009](https://github.com/HybridAIOne/hybridclaw/issues/1009) | Outbound-only Discord webhook adapter for deployments that have a `https://discord.com/api/webhooks/...` URL but do not need a bot token, gateway session, slash commands, or inbound Discord handling. Add `discord_webhook` and `discord_webhook:<target>` as message-tool targets with Discord-compatible content payloads, chunking, retries, rate-limit handling, doctor/status visibility, CLI + admin-console setup, SecretRef-backed default/named targets, collision-free secret IDs, and managed POST-only policy grants scoped to `discord.com/api/webhooks/**`. **Security boundary:** webhook tokens are secrets; URL validation strips userinfo, query, and hash; error, status, and admin surfaces never echo cleartext; v1 stays outbound-only with no inbound, reactions, components, files, or thread APIs. **Relationship to R37:** this is not the Discord bot/channel; R37 owns bot gateway + slash-command approval. **F15 note:** prefer plugin-channel implementation once F15/F16 land; an in-repo shim is acceptable only if needed to preserve parity with `slack_webhook`. Added 2026-05-14. *Principle V.* | P2 | ✅ |
| 38 | **Microsoft Teams channel** | Bot adapter for the Microsoft Teams platform — proactive messaging, mentions, file / image delivery, approval surface (Adaptive Cards). **Already shipped** at [`src/channels/msteams/`](../../../src/channels/msteams/) (`runtime.ts`, `delivery.ts`, `inbound.ts`, `prompt-adapter.ts`, `retry.ts`, `send-permissions.ts`, `stream.ts`, `tool-actions.ts`, `typing.ts`); registered in [`src/channels/channel-registry.ts`](../../../src/channels/channel-registry.ts) with `MSTEAMS_CAPABILITIES`. Filed retroactively after the channel-registry audit on 2026-05-02 surfaced that MS Teams shipped without a roadmap row — included for status-snapshot completeness alongside R36 / R37. B2B-critical for DACH alongside R36 WhatsApp. Composes with **F14** as escalation modality. *Principle V.* Added 2026-05-02. | P1 | ✅ (already shipped) |
| 39 | **Matrix channel — sovereign / EU positioning** | Matrix client adapter (Element / Synapse / self-hosted homeservers). Reaction-based exec approval (operator drops a ✅ on the prompt — same UX pattern as Slack reactions but on a stack the customer can self-host), DM auto-threading, configurable home room. Pairs with **R25** EU deployment recipes for the sovereign-stack story — Matrix homeservers self-host alongside HybridClaw on Hetzner / IONOS / Open Telekom Cloud, no third-party comms vendor in the loop. **F15 prereq** — the in-repo `channel-registry.ts` is currently a hardcoded `Record<ChannelKind, ChannelInfo['capabilities']>` over the existing kinds; Matrix can't be added without unhardcoding it. Composes with **F14** as escalation modality + **R25** EU deployment + **F10** org-chart routing. *Principle V.* Added 2026-05-02. | P1 | ⬜ |
| 40 | **Persistent cross-turn goal primitive (`/goal`)** [#992](https://github.com/HybridAIOne/hybridclaw/issues/992) | Operator-set objective the agent pursues across turns until met or cancelled. Sits between **R2** declarative YAML workflows (rigid, author-defined) and **R29** kanban cards (operator-authored, human-claimed). State persisted alongside the thread; re-injected into every turn header until the agent emits `goal.completed` on **F2** (judged by **F11**) or the user cancels with `/goal cancel`. **High-stakes goal steps still escalate normally via F8** — the goal primitive is intent-persistence, not autonomy-elevation. The cheapest *"act first, asks later"* surface that doesn't make the operator write workflow YAML; complements R2 by covering the open-ended-objective end of the spectrum (R2 covers structured multi-step processes, R40 covers *"keep going until it's done"*). Composes with **F8** + **F11** + **R29** (goals optionally surface as cards) + **R44** achievements (completing a goal can fire a milestone). **Sibling primitive (added 2026-05-09): steering / mid-loop message injection** — distinct from `/goal` (which is *persistent intent*); steering is *transient nudge* injected into the next turn header without restart and without rewriting the goal (`/steer "skip the rebase, just merge"`). One persists across turns, the other lives one turn; both share the same per-thread state hook. Worth filing as R40.x sibling once the goal substrate lands. *Principles II + IV.* Added 2026-05-02; sub-issue table + #992 added 2026-05-13; core primitive shipped via #1004 on 2026-05-14. | P1 | 🟡 11/14 (core shipped via #1004; R40.10 hook partial; board + steering open) |
| 41 | **Background skill-maintenance loop + Autopilot primitive** | Cron-thread-driven curator that runs unattended (overnight by default) to consolidate duplicate skills, prune unused skills (no run in N days), and reclassify archived skills as *"consolidated"* vs *"pruned"* with reason strings. Reuses **F2** events (skill-run frequency telemetry feeds the consolidation decisions), **F4** versioning (every consolidation is a versioned edit, fully rollback-able), **R10.1** trajectories (which skill produced which result), **F11** trace-judge (decides whether two near-duplicate skills should merge). Surface: `runtime/curator/<run-id>/run.json` (machine-readable for **R10a** harness-evolution) + `REPORT.md` (human-readable for the operator). Concrete demonstration of Principle III (*"doesn't clock out"*) that doesn't need a customer task to fire — a coworker tidying its own catalog while the team sleeps. **Anti-pattern to avoid:** agentic background loops that consume budget without producing an operator-visible artifact — every run **must** produce a report, every consolidation **must** be reversible via F4. **Autopilot generalization (added 2026-05-09):** the curator is the *first consumer* of a broader Autopilot primitive — *"cron or webhook → spawn an **R29** card → assign it to an agent"* — that operators can also use for any recurring or event-driven task (nightly close-of-books, inbound-webhook triage, weekly KPI rollup). Concurrency policies per Autopilot rule: **`skip`** (drop the new fire if the previous run is still open), **`queue`** (FIFO behind the running instance, capped depth), **`replace`** (cancel the running instance via **R23** warm-restart and start fresh). Cards spawned by Autopilot carry a `source: autopilot/<rule-id>` edge so operators can find every run of a rule from one card. Composes with **R29** board (cards are the work unit), **R5** budget caps (Autopilot rules respect per-agent caps to prevent budget-burning loops), **F8** stakes gating (high-stakes Autopilot fires escalate before acting), **R47** scheduled-tasks substrate (scheduling layer reused). See **R41 Autopilot Work** below for sub-issue rows. *Principles III + VIII.* Added 2026-05-02. | P1 | ⬜ |
| 42 | **Live model picker with inline credential setup** | Operator UX inside the chat: picker lists configured + unconfigured providers (model list merged from **F5** capability matrix), paste-API-key-inline registers an unconfigured provider on the spot, `d`-keybind disconnects a configured provider, switch model without leaving the conversation. Generalizes **F6.8** (admin UI for tunnel provider config) — same *"configure-without-leaving-the-conversation"* pattern, different resource. Closes one of the load-bearing gaps in **Principle X** (*"hired in sixty seconds"*) on the model-config side: today, switching providers means editing config files. **Reuse:** OAuth / PKCE patterns already in production at [`src/auth/google-auth.ts:200-290`](../../../src/auth/google-auth.ts) + [`src/auth/codex-auth.ts:460-550`](../../../src/auth/codex-auth.ts) for OAuth providers; API-key-paste flow for plain-key providers. Composes with **F5** (catalog source-of-truth) + **R28** fallback-chain CLI peer + **F6.8** admin-UI extension + **F17** managed-policy convention (the inline credential paste should auto-write the provider's policy grant via the same shared helper R45 uses, not reinvent the rule-placement logic). *Principles VIII + X.* Added 2026-05-02. | P1 | ⬜ |
| 43 | **Computer-use track (sibling to R30 browser)** | Universal any-model schema for OS-level UI control — mouse / keyboard / window focus / `set_value` / structured-window enumeration / MIME detection on drops. **Distinct from R30's browser-DOM track:** R30 controls a browser via Playwright; R43 controls the host's UI via a CUA driver. **Background focus-safe mode** so the agent never steals the operator's foreground while it works (the operator-still-driving constraint that browser sessions don't have). **F13 credential injection** extends from DOM elements to OS-level password fields — same opaque-handle discipline. Composes with **R32** (chat-ops on the deployed host can use UI tools when CLI isn't enough), **R30** (CUA as fallback when a SaaS lacks an HTTP API and JS-DOM control is too brittle), and **F14** (any UI flow that hits a 2FA prompt parks via F14, same as the browser path). Sequencing: P1 once R30.2 ships — same `BrowserProvider`-style interface but a different action vocabulary and a different transport, so the provider seam should be designed once. *Principles V + VII.* Added 2026-05-02. | P1 | ⬜ |
| 44 | **Achievements / track-record surface** | User-facing layer over **R3** scoreboard data — scan session history for milestones (first ticket closed, N-th deal won, M-day streak, biggest-wins-in-skill-X) and render as medals on the agent card alongside the per-skill scores already in [`src/skills/agent-cv.ts`](../../../src/skills/agent-cv.ts) / [`src/skills/agent-scoreboard.ts`](../../../src/skills/agent-scoreboard.ts). Closes the *"name, face, voice, CV, references"* loop in **Principle IV** — current R3 ships the *data*, R44 ships the *colleague experience*. Implementation: F2 event subscriber that produces achievement records on milestone triggers; render hook on the existing CV surface; configurable milestone definitions per tenant. Composes with **R3** scoreboard (data source) + **F2** (event-driven trigger) + **R40** `/goal` (goal completion as a milestone class). **Manifest convergence note (added 2026-05-09):** structured per-agent descriptors (tools + dashboard metrics + achievement set) probably want to converge into a single agent-manifest file rather than living split across `AgentConfig`, the R3 CV renderer, and an R44 achievements store. Defer the schema decision until R44 lands — at that point the three surfaces have converged enough to extract one canonical descriptor. *Principle IV.* Added 2026-05-02. | P2 | ⬜ |
| 45 | **Connector setup ergonomics — auto-grant on add, auto-revoke on remove** | Operator-facing roll-out of the **F17** `managed_by_*` policy convention across every "I added a credential, now I have to write yaml" path. **First instance shipped** by [PR #784](https://github.com/HybridAIOne/hybridclaw/pull/784): `hybridclaw secret route add` now writes both the runtime auth-rule *and* the matching `secret_resolve_allowed` policy grant, scoped to host + header + secret + agent, removable in one step. R45 extends the same pattern to: **(a) [#786](https://github.com/HybridAIOne/hybridclaw/issues/786)** `hybridclaw mcp add` (CLI + inline `/mcp add`) — writes the MCP server entry plus per-tool `mcp_tool_allowed` managed rules per discovered tool, scoped to the requesting agent; **(b) [#787](https://github.com/HybridAIOne/hybridclaw/issues/787)** skill install — `SKILL.md` frontmatter declares the credential scopes the skill needs (secret IDs + host / selector + side: DOM keystroke per **F13** vs HTTP header), install prompts inline for missing creds and auto-writes the matching F3 grants, upgrade diffs them, remove cleans them up; **(c) [#788](https://github.com/HybridAIOne/hybridclaw/issues/788)** channel registration — `hybridclaw channel add <kind>` (CLI + inline `/channel add`) prompts for the channel-specific bundle (bot token + channel ID + role ID + allowlist) and writes the narrow inbound + outbound + escalation grants. **Composes with [R42](#)**: the live model picker is the same convention applied to providers — call it out here so R42 implementation reuses the F17 helper instead of reinventing the rule placement. **Trust boundary held**: every managed rule stays narrow (no wildcards), audit log records the connector that wrote it, deny-by-default still applies. **Driver**: every new connector type today re-introduces a yaml-editing step that violates Principle X — R45 is the durable closure. **Scope expansion for R45 #786 (added 2026-05-13)**: the current [#786](https://github.com/HybridAIOne/hybridclaw/issues/786) body covers `stdio` / `sse` / `http` transport entries + managed `mcp_tool_allowed` rules, but omits the **auth half** for OAuth-protected remote MCP servers. Adjacent stack precedent (CoPaw `feat(mcp): add OAuth 2.1 PKCE support for remote MCP servers`) implements the converged shape: **RFC 8414** Authorization Server Metadata discovery, **RFC 9728** Protected Resource Metadata, **RFC 7636** PKCE with `S256` code-challenge, server-side `OAuthSession` state store keyed on a one-shot `state` token with ~10-minute TTL, browser-redirect callback that exchanges the `code` + `code_verifier` for tokens and writes them through the existing `SecretRef` rail. Without this, `hybridclaw mcp add` against any OAuth-protected remote MCP server falls back to hand-editing — defeating the R45 promise for the deployment shape that's becoming dominant. **Companion fix to specify** (cross-stack precedent: nanoclaw `fix: teach agent to use OneCLI gateway credentials after MCP server install` — a 2-line instruction-text correction in `self-mod.instructions.md` + `onecli-gateway/instructions.md` after they wired the same `mcp add` auto-grant): once the managed policy rule lands, the agent's system-prompt scaffolding for newly-installed MCP tools must reflect *credentials present* on the very next turn, not the cached *credentials missing* preamble from before install. Wire this through the same dynamic-context middleware that **A9** carves out (the static-prefix invariant means tool-state changes belong in the post-prefix user block anyway — same primitive, different content). *Principles VII + X.* Added 2026-05-02; OAuth + post-install prompt-sync scope expansion 2026-05-13. | P1 | 🟡 1/4 (HTTP secret route ✅ via PR #784; MCP / skill / channel open) |
| 46 | **Threema channel — Swiss-sovereign / DACH-regulated positioning** [#899](https://github.com/HybridAIOne/hybridclaw/issues/899) | Threema Gateway integration for DACH-regulated and privacy-sensitive operators where WhatsApp is a non-starter and Matrix self-hosting is too much operational lift. Initial scope is a conservative Basic-mode outbound text adapter through Threema Gateway `send_simple`: Gateway ID + API secret, targets by Threema ID / linked phone / linked email, conservative chunking, doctor/status visibility, CLI + admin-console setup, prompt hints, docs, and targeted message-tool tests. **Scoped F15 exception:** pre-F15 a thin `src/channels/threema/` runtime is acceptable as the seam-exerciser already in flight; inbound webhooks, E2E/private-key mode, attachments, rich messages, and future Threema expansion should move through **F15/F16** plugin-loadable channel work. Registered as an **F14** escalation modality and paired with **R25** EU deployment recipes so Hetzner / IONOS / OTC deployments can offer a Swiss-managed operator channel without a non-EU vendor in the loop. Composes with **F14 + F10 + R12 + R25 + R39 + R45 #788**. Anti-goal: not an end-user Threema bot for high-volume consumer support. Added 2026-05-04; issue linked 2026-05-09. *Principle V.* | P1 | ✅ #899 via PR #903 |

| 47 | **Agent- and skill-scoped knowledge collections (KNOWLEDGE.md + QMD)** | Per-agent and per-skill document collections that are only searchable when that agent/skill is active. Two ingestion modes: **(a) `KNOWLEDGE.md` manifest** included in system prompt (or prompt preamble) listing canonical docs/paths/URLs to load for retrieval scope, **(b) QMD-backed index** when available for semantic search over attached corpora. Router enforces strict activation scoping (global docs excluded unless explicitly allowed) so retrieval context stays role-local and principle-of-least-context is preserved. Includes policy/audit hooks for which corpus was queried per answer. *Principles I + VII + X.* Added 2026-05-05. | P1 | ⬜ |
| 48 | **Skill credential lifecycle — declared scopes, acquisition guides, setup prompts, admin surface, runtime preflight** | Closes the *"I added a skill, now what credentials does it actually need and where do I get them?"* gap. Today every skill that needs API authentication (HTTP keys, bearer tokens) or session credentials (browser logins via **F13**) re-invents discovery, acquisition, and storage; there is no skill-side parity with the channel-credential UX. R48 ships the operator-facing surface: **(a)** `SKILL.md` frontmatter declares each credential as `required` or `optional`, with kind (`api_key` / `oauth` / `browser_login` / `bearer` / `header`), the `SecretRef` binding (per **F13** opaque-handle discipline — cleartext never reaches the LLM), and a `how_to_obtain` field (markdown: provider URL, OAuth scopes, browser-login waypoint URL, click-path prose for portals); browser-skills additionally declare a `browser_session` block — `headed: bool`, `requires_logged_in: bool`, and `manual_unlock_reasons: ['captcha', '2fa', 'device_check']` — so **R30** picks the right install mode (headless cloud vs headed local) and **F14** is wired for 2FA / captcha handover before the first run; **(b)** TUI install/setup wizard prompts inline for every required credential and writes to the existing secret store via `SecretRef`; **(c)** `/admin/skills` per-skill credential surface mirrors the channel-credential admin UI — view / add / rotate / remove; **(d)** runtime preflight blocks skill activation when a required credential is missing and emits `escalation.credential_missing` via **F8 / F14** with the `how_to_obtain` guide attached so the operator can resolve it from any escalation channel; **(e)** optional-credential degradation contract — a skill declares which capabilities still work without the optional cred (e.g., read-only mode without admin scope) so the runtime can fall through gracefully instead of hard-failing. **Composes with R45 #787**: R45.b owns the **F3** auto-grant + auto-revoke (rule-placement side); R48 owns the declaration schema + acquisition guide + setup wizard + admin UI + preflight (operator-facing UX). The R48.3 wizard calls into the R45 #787 / **F17** managed-rule helper rather than duplicating rule-placement logic. **Reuses:** **F13** credential rail (✅ #698), **F17** managed-rule helper (#785), **F2** event bus for credential-lifecycle audit events, **F14** escalation modality routing for missing-cred blocks, **R29** kanban board (a preflight block surfaces as a `Blocked: needs credential` card with the guide rendered inline). Anti-goal: not a new secret store and not a new policy engine — both already exist; R48 is purely the lifecycle UX glue. *Principles VII + X.* Added 2026-05-05. | P1 | 🟡 1/8 |
| 49 | **Addressing multiple agents in a chat (operator UX)** | When a single chat thread has more than one agent reachable — multiple coworkers configured for the tenant, an **F10** team org-chart with peers/delegates, or an **R31** agent-team spawned for a piece of work — the operator needs an explicit, uniform way to pick which agent the next turn is directed to. **Substrate:** *(i)* `@<agent>` mentions in the message body parsed pre-routing against the **F7** identity registry (slug + display name); *(ii)* inline `/agent <name>` slash command for an explicit switch; *(iii)* sticky **active agent** state per thread so unaddressed turns continue with the most recently addressed agent (the same active-agent concept **R47.2** scopes retrieval against); *(iv)* selectable agent chips above the composer in the admin chat UI (one tap = `@`-prefix the next message); *(v)* per-channel mention adapters so WhatsApp / Discord / Matrix / MS Teams / Threema each map onto their native mention or thread-routing syntax via the channel runtime, keeping the abstraction uniform across modalities. **Resolution rules:** ambiguous matches resolve via **F10** org-chart context (peers > delegates > global tenant roster); unknown handles fail loud rather than silently routing to a default; `@team` and `@all` are reserved aliases that fan out via **R1** envelopes rather than collapsing into one agent. **Composes with:** **F7** (canonical agent IDs), **F10** (org-chart resolution), **R1** envelope `to` field (the parsed address ends up there), **R31** (operator-led explicit addressing complements skill-author-led routing patterns), **R47.2** (retrieval scope follows the addressed agent automatically), **R29** (board cards record which agent was addressed per turn for audit). **Anti-goal:** not an LLM-side router that *guesses* the right agent from message intent — that's the **R31** routing pattern (and **F8** stakes classifier on the escalation side); R49 is the explicit operator-controlled path so the ambiguous-routing failure mode never silently picks the wrong coworker. Added 2026-05-07. *Principles IV + VI + X.* | P1 | ⬜ |

| 65 | **Multi-agent durable shared-notepad pattern (Git-backed coordination)** | Adopt the [NVIDIA OpenShell multi-agent-notepad](https://github.com/NVIDIA/OpenShell/tree/main/examples/multi-agent-notepad) shape: N worker agents fan out, each writes to a unique path under `runs/<run-id>/notes/agent-N.md` in a Git repo; a synthesis agent reads them and writes `runs/<run-id>/summary.md`. Git supplies durability across sandbox restarts, SHA-based optimistic concurrency on `PUT` (racing writers see HTTP 409 + retry), and a free audit trail (every write is a reviewable commit). Three documented variants: **pile** (map/reduce, low contention — research, multi-perspective review), **append-journal** (single ordered log, hot under multi-writer — switch to Git Data API blobs+tree+single-commit at scale), **indexed memory** (`memory/<topic>.md` keyed reads — survives across runs). Maps to existing primitives: **R31** coordination-patterns reference (name "pile / Git-shared-notepad" alongside sub-agents + agent-teams), **R7** shared-enterprise-memory substrate (when to graduate beyond Git: sustained >10 writes/sec, sub-100ms reads, structured queries → existing `src/memory/` chunker + embeddings + recall), **F3** scoped network policy + **F13** credential injection (sandboxed workers see GitHub PATs only via `SecretRef`, policy restricts writes to `/repos/<owner>/<repo>/contents/runs/<run-id>/**`), **R10.1** trajectories (every run already produces reviewable diffs), **R29** kanban as the live task layer for higher-contention coordination. **OpenShell-runtime adoption is out of scope here** — this row is the *pattern*, not the runtime; HybridClaw's existing sandboxing + F3 policy already cover the credential-isolation story. Deliverable: a coordination-patterns subsection + worked example skill that fans out N research workers and synthesizes via a Git path the operator can review. *Principles VI + VIII.* Added 2026-05-07. | P2 | ⬜ |
| 50 | **Complexity-based prefill model routing** | Pre-prompt complexity classifier routes each turn to the model tier matching the prompt's expected difficulty — cheap model for short lookups / structured edits, mid for routine reasoning, top-tier for hard / open-ended work. Sits **between R28 and R35**: **R28** is sequential failover *after* a provider error; **R35** is parallel deliberation across providers; **R50** is one model picked *up-front* with a smarter heuristic than R28's static priority order. Substrate: signal extracted from the prompt (token count, code-vs-prose ratio, tool-call shape, thread depth, F8 stakes signal) feeds a tiny classifier that emits `tier: cheap | mid | top` + `confidence`; the gateway router consumes the tier when selecting from the **F5** capability matrix; low-confidence routes default to mid; **R5** budget caps still apply post-routing; **R28** fallback chain still kicks in if the chosen tier errors. **Stakes ≠ complexity** but they overlap — F8 stakes already gates *autonomy*; R50 gates *spend per turn*. Composes with **F5** (catalog + per-tier pricing), **F8** (stakes input feature), **R5** (budget enforcement), **R28** (failover after the routed pick), **R35** (council overrides the router for explicitly-deliberation-flagged turns), **R10.1** (routing decisions captured in trajectories so the classifier can be retrained per tenant). Anti-goal: not a multi-call deliberation surface — *one* model is invoked per turn; deliberation belongs to R35. *Principles VIII + IX.* Added 2026-05-09. | P1 | ⬜ |
| 53 | **Firecrawl scrape + crawl skill** [#829](https://github.com/HybridAIOne/hybridclaw/issues/829) | Managed and self-host Firecrawl ingestion for unauthenticated public pages: scrape one URL, crawl a site, map URLs, and run structured JSON-schema extraction. This is the HTTP-fetch-and-parse peer to **R30** browser and **R54** Camofox: use Firecrawl for public static/documentation pages, browser for interaction/login, and Camofox for stealth-sensitive browsing. The managed adapter uses the existing gateway `http_request` secret-injection rail (`FIRECRAWL_API_KEY`) so the key never enters model-visible arguments; self-host mode targets a gateway-reachable Firecrawl origin with optional self-host API auth. Composes with **R47** scoped knowledge collections for ingesting crawled docs into agent/skill-scoped corpora without touching global memory, **F3** host policy for crawl allowlists, and **F13** credential rail. *Principles I + VII.* Added 2026-05-12. | P1 | 🟡 4/7 |
| 56 | **Workspace folder-hygiene skill (LLM-driven, archive-not-delete)** [#939](https://github.com/HybridAIOne/hybridclaw/issues/939) | Persistent housekeeper that keeps each agent's workspace conforming to a canonical layout without deterministic rules. A `folder-hygiene` skill reads a single source-of-truth layout spec (`references/workspace-layout.md` — reserved top-level files inherited from [`templates/`](../../../templates/), reserved directories with purpose statements: `memory/`, `notes/`, `drafts/`, `outputs/`, `inbox/`, `archive/`, `skills/`, naming rules like `memory/YYYY-MM-DD.md`, TTL hints) plus a curated examples corpus (`references/examples.md` — 6–10 worked before/after triage decisions covering the hard cases: half-finished drafts, ambiguous outputs, files dropped at root) and applies *judgment* to a workspace manifest produced by a tiny enumerator script (`scripts/manifest.mjs`: paths + size + mtime + first 200 bytes for ambiguous files; the only deterministic piece). The skill produces a triage plan per file — `keep` / `move <dest>` / `archive` / `ask` — and applies via shell `mv` (never `rm`). **Why LLM, not rules**: semantic placement decisions ("is this scratch still load-bearing? does this belong in `notes/` or `outputs/`?") are exactly what deterministic rules can't do; rule-based hygiene drifts back into mess or fights legitimate workflows. **Safety net**: archive-not-delete (everything goes to `archive/YYYY-MM-DD/`); every run appends a `archive/tidy-log/YYYY-MM-DD.md` entry recording the file, the move, and a one-line *why* — auditable, reversible, and the substrate for sharpening the skill over time (operator corrections become new entries in `examples.md`). **The `inbox/`** is a no-questions-asked landing zone for files the agent can't place — without it, strict layouts fight real work; with it, mess is contained and reviewable. **Trigger**: one line added to [`templates/HEARTBEAT.md`](../../../templates/HEARTBEAT.md) — end-of-session hygiene pass, plan-then-apply, **auto-apply by default** with the tidy-log as the rollback record. `ask` is a first-class outcome — the skill biases toward leaving ambiguous files alone and surfacing a short list rather than forced decisions. **Composes with**: **R47** scoped knowledge (the workspace is one corpus; layout discipline makes per-agent retrieval predictable), **R41** background skill-maintenance loop (curator pattern — a coworker tidying its own catalog while the team sleeps; same auditable-artifact discipline), **F2** event bus (`workspace.tidied` events feed the operator dashboard and **R29** board so the operator sees a one-line summary per pass), **R3** scoreboard (`folder-hygiene` becomes a measured skill — false-archive rate and operator-correction rate feed quality scores), [`templates/`](../../../templates/) (canonical top-level allowlist lives here; layout spec is read against it). **Anti-pattern to avoid**: a deterministic linter that hard-fails on unknown files — that's how every prior attempt drifted into the mess we're trying to leave. **Reference precedent**: [`skills/skill-creator/SKILL.md`](../../../skills/skill-creator/SKILL.md) for the SKILL.md + `references/` + `scripts/` progressive-disclosure shape; AGENTS.md §7.1 for skill placement rules. **Out of scope**: cleaning up `src/` or repo contributor files (this is workspace hygiene, not repo hygiene); a general-purpose file mover (the skill is bounded to one workspace at a time). Added 2026-05-12. *Principles III + VIII.* | P1 | ⬜ |
| 58 | **Shared agent workspace — multi-agent project rooms** [#958](https://github.com/HybridAIOne/hybridclaw/issues/958) | A first-class shared filesystem area that multiple agents can read and write — distinct from each agent's personal workspace. Use case: a sales coworker, a research coworker, and a copywriter coworker all collaborating on the same client engagement need a place to drop briefs, source documents, decisions, drafts, and generated outputs that any of them can pick up — without smuggling files through chat or duplicating into each personal workspace. **Shape**: a shared workspace is its own entity (`shared/<workspace-id>/`) with an ACL listing which agents have `read` / `write`; an agent's runtime can mount one or more shared workspaces alongside its personal workspace under a clear path prefix (`./shared/<workspace-id>/...`) so the path discipline from **R56** layout still applies. Cross-agent coordination uses the same reserved-directory vocabulary (`shared/<id>/inbox/`, `outputs/`, `notes/`, `archive/`) — no new mental model for the operator. **Concurrency**: SHA-based optimistic concurrency on writes (the [R65 Git-backed shared-notepad pattern](#) is the durable-coordination substrate when it applies); for non-coordinating writes the filesystem-level last-writer-wins is acceptable. **Permissions**: per-shared-workspace ACL gated by **R14** RBAC; an agent's policy declares which shared workspaces it may mount; **F3** scoped predicates enforce per-path read/write at runtime; **F13** credential discipline holds (a shared workspace cannot leak a personal-workspace secret). **Hygiene composes with R56**: shared workspaces get their own `references/workspace-layout.md` profile — *more conservative* (no auto-archive of shared artefacts without a quorum or owner ack), `ask` outcomes are the default for ambiguous shared files. **Discovery + browse**: the admin file browser (**R57**) treats shared workspaces as first-class entries alongside agent workspaces, with the ACL visible in the surface. **Composes with**: **R31** coordination patterns (the *agent-team* architecture's filesystem layer; **R31** decision tree should point at R58 when work has cross-cutting durable artefacts), **R29** kanban board (cards can be scoped to a shared workspace; the board is the *task* layer, R58 is the *artefact* layer), [R65 Git-backed shared-notepad](#) (durable-write pattern for the high-contention sub-cases inside a shared workspace), **R7** shared enterprise memory (when shared *retrieval* matters more than shared *files* — R7 is RAG, R58 is files; both can coexist on the same project), **R47** scoped knowledge (a shared workspace can be declared as a KNOWLEDGE.md source for any agent that mounts it). **Anti-goals**: not a general team Dropbox (no human-only files; everything is agent-readable by design); not a replacement for personal workspaces (personal stays the private scratch space); not a content-management system (no versioned approval workflow — that belongs in **R2** workflows). **Out of scope for v1**: granular file-level ACLs (workspace-level only), real-time collaborative editing, external (non-agent) human write access (admin file browser supplies the human edit path). Added 2026-05-12. *Principles I + VI.* | P1 | ⬜ |
| 57 | **Admin file browser for agent workspaces** [#956](https://github.com/HybridAIOne/hybridclaw/issues/956) | Extend `/admin/agents` (currently a curated "Agent Files" list at [`console/src/router.tsx:95`](../../../console/src/router.tsx) backed by `/api/admin/agents/{agentId}/files/{fileName}` with revisions) to a full **tree browser + search** over the agent's entire workspace. Today operators can read and edit a fixed roster of top-level identity files (IDENTITY, SOUL, USER, MEMORY, CV, etc.); everything else the agent produces — drafts, notes, daily memory shards, generated outputs, archived artefacts — is invisible unless the operator SSHes into the host or asks the agent to surface a path. R57 makes the rest of the workspace browsable and searchable from the admin UI. **Scope**: (a) tree view of the workspace rooted at the agent's home, lazy-loaded per directory, with the **R56** reserved-directory vocabulary (`memory/`, `notes/`, `drafts/`, `outputs/`, `inbox/`, `archive/`, `skills/`) rendered with purpose tooltips; (b) full-text + filename search across the tree with type / date / size filters (find an artefact by what it says, not where it lives); (c) per-file view extending the existing read/edit surface — same **F4** revision history, same `/api/admin/agents/.../revisions/...` semantics already wired for the curated files; (d) safe-by-default edits — the existing managed-edit path already records audit and supports revert; R57 inherits that wholesale rather than reinventing it. **Permissions**: **R14** RBAC gates which operators can browse which agents; **F3** scoped predicates restrict read/write per directory (e.g., `archive/` and `skills/` may be read-only to non-admin operators); audit log records every browse + read + edit via **F2**. **Composes with**: **R56** folder-hygiene (the browser is the operator surface for the layout the skill enforces — and the surface where operator *restorations* feed back into R56.7's correction loop), **R58** shared workspaces (same browser, shared workspaces appear as siblings to personal workspaces with the ACL visible), **R29** board (a tidy-run summary card opens a filtered browser view of the affected files), **R3** scoreboard (artefact-quality scores need an operator-clickable path to the artefact). **Reuse** the existing console file-edit components ([`console/src/api/client.ts:391–437`](../../../console/src/api/client.ts) revision endpoints) — don't fork the editor surface. **Anti-goals**: not a general SSH replacement (read + safe edit only — execution stays in the agent), not a Git client (revisions are F4, not Git), not a search engine over the *content* of binary files (text search only at v1; OCR / PDF / docx text extraction is a separate follow-up). Added 2026-05-12. *Principles IV + X.* | P1 | ⬜ |
| 51 | **Daemon mode — HybridClaw as orchestration plane over BYO host-resident agent CLI** *(to be filed)* | Sub-mode where HybridClaw runs as a thin **daemon** that orchestrates whatever agent CLI is already on the operator's PATH (Claude Code, Codex, OpenClaw, Copilot CLI, Cursor Agent, Gemini, Kimi, Pi, Hermes, OpenCode, Kiro CLI) rather than running its own model gateway. The daemon auto-detects installed CLIs, registers each as a distinct `agent_runtime` in the **F5** capability matrix, and dispatches turns to the matching subprocess instead of an HTTP provider. Operators who already pay Anthropic / OpenAI directly via their CLI of choice get the audit / budget / brand-voice / org-chart backbone without re-routing their spend through HybridClaw's gateway. **OSS tier sub-mode**: this is the natural shape for the OSS hybridclaw distribution — competes for the *"add HybridClaw to the agent I already have"* segment without diluting the enterprise-positioned managed-gateway tier. **Defense in depth**: filtered env-vars on subprocess spawn (the agent CLI cannot read daemon auth tokens), workspace-level repo whitelist (scoped to declared paths), token-class prefixes (per **F13** follow-up — `hc_pat_…` vs `hc_daemon_…` so the spawned CLI cannot impersonate operator authority). **Composes with**: **R34** local-LLM teammate (a daemon-mode peer can advertise the local CLI's model into the F5 capability matrix the same way the cloud peer advertises a hosted model); **R9** cross-instance delegation (a daemon-mode instance is just another peer); **F5** capability matrix (per-CLI registration); **F13** credential rail (env-var filter + token-class prefixes); **R45** managed-rule helper (auto-grant CLI-specific F3 rules on detection, auto-revoke on uninstall); **R29** board (daemon tasks land as cards same as gateway tasks). **Out of scope**: replacing the managed gateway in the enterprise tier — daemon mode is a peer of the gateway, not a substitute, and any tenant requiring **R4** confidential-redaction on cloud-LLM traffic still needs the gateway in the path. **Prior art** (BYO-CLI daemon shape): auto-detect ~10 common agent CLIs on PATH, register each as a distinct runtime, scope daemon tokens per `(workspace, daemon-id)`. Added 2026-05-09. *Principles V + VIII + X.* | P1 | ⬜ |
| 52 | **SearXNG metasearch skill** | Privacy-respecting metasearch across configurable engines via SearXNG `format=json`. Public web-search surface for agents that doesn't tie the tenant to a single commercial provider and can be aimed at a self-hosted SearXNG instance for sovereignty. Sub-issues file the client adapter, the `search.web` / `search.images` / `search.news` skill surface, and the per-tenant instance URL + F13 bearer binding. See **R52 SearXNG Work** below for sub-issue rows. Composes with **F3** host policy (which engines/instances are allowed), **F13** credential rail (per-tenant bearer), and **R47** scoped knowledge (search hits feed agent/skill corpora rather than the global store). *Principles I + VII.* Added 2026-05-12. | P1 | ✅ 3/3 |
| 54 | **Camofox stealth-browser provider** | Camoufox-backed `BrowserProvider` for stealth-sensitive scraping where R30's Playwright provider gets fingerprinted or rate-limited. Sibling to R30 (interaction/login) and R53 (HTTP fetch + parse). See **R54 Camofox Work** below for sub-issue rows. Composes with **R30.1** `BrowserProvider` interface, **F13** credential rail, and **F3** host allowlists. *Principles V + VII.* Added 2026-05-12. | P1 | 🟡 1/1 filed |
| 55 | **Video-from-script skill (HeyGen + others)** | Programmatic video creation from a script, starting with HeyGen avatar/voice synthesis. Skill-surface peer to R21.68 image generation and the broader R21.92 Hyperframes track. See **R55 Video Work** below for sub-issue rows. Composes with **F13** credential rail (per-tenant API keys, tight rate limits), **F3** host policy, and the **R21.x** asset-management conventions. *Principle V.* Added 2026-05-12. | P2 | 🟡 2/2 filed |
| 60 | **Per-model behavior overlays — model-specific prompt + runtime contracts** *(to be filed)* | A first-class, per-model overlay applied on top of the byte-static base system prompt (**A9**) when a turn is routed to a model whose behavior diverges from the Anthropic baseline the rest of the stack is tuned against. **Problem**: the gateway already routes across providers ([`src/providers/hybridai-models.ts`](../../../src/providers/hybridai-models.ts), [`src/providers/codex-discovery.ts`](../../../src/providers/codex-discovery.ts), [`src/auth/codex-auth.ts`](../../../src/auth/codex-auth.ts)) but every model gets the same system prompt — so a Claude-tuned prompt that produces good `tool_use` cadence on Sonnet/Opus can produce **narrate-instead-of-act** turns on GPT-5, verbose preambles on Codex, malformed tool calls on smaller Gemini variants, and tool-discipline drift on local-LLM peers. Today the only knob is the global prompt, which has to be tuned to the worst common denominator. **Substrate**: (a) `model_overlay` field on the **F5** capability matrix entry — three substrate blocks per model: `tool_discipline` (when to call another tool / when to retry / when to *not* narrate), `completion_contract` (when a task is done vs. `[blocked]` with missing input), `execution_policy` (a one-line bias on act-vs-deliberate for clear reversible requests); (b) gateway-side applier that concatenates the overlay *after* the static base prefix and *before* the post-prefix dynamic-context middleware (**A9**'s appender), so the cached prefix is `base + overlay(model_id)` — still byte-stable for any given model, cache-keyed on `model_id`; (c) a **narrate-only retry** runtime guard: when the model emits a turn that contains a plan but no tool call or terminal answer, the gateway issues a one-shot retry with a short "execute the plan now" nudge before surfacing the turn (caps at one retry to avoid loops). **Cross-stack precedent**: openclaw ships exactly this for GPT-5 — `src/agents/gpt5-prompt-overlay.ts` gated by `isGpt5ModelId()` wrapping the model in a `GPT5_BEHAVIOR_CONTRACT` with `<tool_discipline>` ("do not stop early when another tool call is likely to materially improve correctness, completeness, or grounding"; "resolve prerequisite lookups before dependent or irreversible actions"; "if a lookup is empty, partial, or suspiciously narrow, retry with a different strategy"; "do not narrate routine tool calls"), `<completion_contract>` ("treat the task as incomplete until every requested item is handled or explicitly marked [blocked] with the missing input"), `<execution_policy>` ("for clear, reversible requests: act"). The matching CHANGELOG line captures the *why*: "Providers/OpenAI: make GPT-5 and Codex runs act sooner with lower-verbosity defaults, visible progress during tool work, and a one-shot retry when a turn only narrates the plan instead of taking action." hermes-agent applies the same shape model-agnostically inside skills ("do not narrate what was just decided. Ask the next required question immediately"; "Never narrate tool usage…") but lacks the per-model overlay primitive — confirms the converged shape is **model-keyed overlay + narrate-only retry**, not a global prompt edit. **Composes with**: **F5** (per-model trait registry is the home for overlay text + the narrate-only retry policy), **A9** (the overlay extends the byte-static prefix but the cache key must include `model_id` so different models hit different cached prefixes; *no per-turn dynamism inside the overlay*), **R28** failover (when failover swaps providers mid-conversation, the overlay set swaps in lockstep with the model — record the swap in **R10.1** trajectories so cache-hit-rate accounting per-model stays clean), **R35** council (each branch invokes its provider with its provider's overlay — overlays make council comparisons fair by neutralizing format-bias rather than testing through it), **R50** complexity routing (when the chosen tier brings a different model, its overlay comes with), **R34** local-LLM peer (a local-LLM peer publishes an overlay alongside its capability advertisement — sovereign-data tenants get the same discipline floor as cloud), **R31** sub-agent patterns + **R51** daemon mode (each child process / CLI runtime declares its overlay so heterogeneous teams share a discipline contract), **F12** Change Manifest (every overlay edit is a falsifiable contract: "this overlay reduces narrate-only turns by N%", verified by the next eval run, rolled back if the predicted impact doesn't materialize), **R10a** auto-harness-evolution (overlays are exactly the kind of editable surface AHE picks up — overlay edits feed the trajectory store + manifest pipeline). **Anti-goals**: not a global prompt rewrite (the base prompt stays Anthropic-baseline); not a per-skill prompt mixin (skills are tool-domain, overlays are model-behavior — orthogonal axes); not a deliberation surface (one overlay per turn applied at routing time; deliberation belongs to **R35**); not a "model fingerprinting" surface (the overlay names the *model id*, not a guessed family — operators control which models get which overlay). **Out of scope for v1**: per-tenant overlay customization (start with built-ins per provider; tenant-side overrides land as a follow-up after the F5 + A9 substrate is stable); overlay marketplace; multi-overlay stacking (one overlay per turn — composability is a v2 concern). **Done criteria**: (1) at least three built-in overlays shipped (GPT-5, Codex, generic-local-LLM) gated by `isGpt5ModelId()`-style matchers on the F5 entry; (2) cache-key includes `model_id` and the snapshot test from **A9** runs per-model rather than globally; (3) narrate-only retry guard fires at most once per turn, emits an **F2** event so the rate is observable; (4) a per-tenant eval run shows `tool_call_density` and `narrate-only-turn` rate improve on at least one non-Anthropic provider without regressing Anthropic. Added 2026-05-13. *Principles VIII + IX.* | P1 | ⬜ |
| 63 | **Mac CUA browser-use provider — background-safe operator's-own-browser control** [#1032](https://github.com/HybridAIOne/hybridclaw/issues/1032) | A third browser-control track for macOS that drives the operator's *own* browser (Safari, Chrome, Firefox, Brave, Arc) via a computer-use driver instead of via Playwright's CDP path (**R30**) or a stealth-Playwright variant (**R54**). **Why a third track**: when the operator is already logged in with their extensions, password manager, and SAML session mid-flight, spinning up a separate Playwright Chromium throws away the session; when a page detects automation (`navigator.webdriver`, CDP fingerprints, behavioral signals), the Playwright path fails where a human-driven browser succeeds; when the surface is `<canvas>` / video / native plugin without a usable DOM, only pixel-and-input control works. **Substrate**: (a) bundled **cua-driver** binary invoked over MCP stdio (transport already established in the gateway), lazy-installed via `hybridclaw doctor cua-mac` and version-pinned via `HYBRIDAI_CUA_DRIVER_VERSION` env var; (b) `MacCuaBrowserProvider implements BrowserProvider` (per **R30.1**) so the action vocabulary (`goto`, `click`, `type`, `screenshot`, `fill`, `selectOption`, `scrollIntoView`) maps onto CUA primitives — `goto` becomes `cmd+L → type URL → return` against the address-bar AX element; `click` becomes `click(x, y)` against the resolved AX element bounds; `fill` becomes `click(element) → type_text_chars`; `selectOption` becomes `click → set_value` against an `AXPopUpButton`; (c) **AX-tree-first targeting** with pixel fallback — element index + window_id is the preferred path (deterministic across retina / HiDPI / zoom states), raw (x, y) is the fallback when AX doesn't expose the target; (d) browser-specific affordances — target browsers by bundle ID (`com.apple.Safari`, `com.google.Chrome`, `org.mozilla.firefox`, `com.brave.Browser`, `company.thebrowser.Browser`); tab control via `cmd+1`..`cmd+9` / `cmd+T` / `cmd+W` / `cmd+shift+]` / `cmd+shift+[`; URL bar focus via `cmd+L`; back / forward via `cmd+[` / `cmd+]`. **Background-safe mode is load-bearing**: the provider **must not** raise the window, warp the cursor, or switch Spaces — input is posted directly to the browser's PID via the driver's event-routing path so the operator can keep using their machine while the agent works. A foreground-stealing fallback (*"raise the window"*) is **not** offered at v1 — when AX-based posting fails on a particular window (some Electron-shell apps under-expose AX), the action returns an error rather than disrupt the operator. **Permission model**: macOS TCC — Accessibility + Screen Recording grants are required, granted to the terminal / app running HybridClaw (not to the cua-driver binary itself); `hybridclaw doctor cua-mac` detects missing grants, prints the deep-link System Settings URLs (`x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility` and `Privacy_ScreenCapture`), and **refuses to advertise the provider into F5** until both grants land — so a skill author never picks R63 in a config that can't run it. **Screenshot path**: three capture modes selectable per call — `som` (Set-of-Marks: screenshot + AX tree + numbered element overlay, for vision-capable models picking elements by index), `vision` (raw JPEG/PNG for pixel-space models), `ax` (AX tree only, no image, cheapest when a model can read structure without seeing pixels); retina-correct via the driver's logical-pixel coordinate space (no manual 2x math at the call site); multi-display via global screen-space origin; output base64-encoded with format detected from magic bytes. **Composes with**: **R30.1** `BrowserProvider` interface (same vocabulary, different transport — a tenant can swap providers per-skill without rewriting calls), **R30.6** F13 keystroke-injection (`type_text_chars` carries `SecretRef` opaque handles the same way the DOM-side keystroke hook does — cleartext never crosses the model boundary), **R30.7** F14 2FA handover (when the screenshot + AX tree show a 2FA modal or device-check waypoint, park to **F14** the same way the DOM track does), **R30.8** per-host policy (URL extracted from the browser's address-bar AX value enforces the **F3** allowlist *before* each navigation completes — the guard sits between `type URL` and `return`), **R30.9** session audit + screenshot trail (every action emits the same F2 events; CUA screenshots land in the same audit store), **R43** computer-use track (R63 is the first concrete consumer of the R43 substrate — the action vocabulary and the background-safe contract land here and R43 generalizes them to non-browser apps), **R54** Camofox (operator picks per-skill: Camofox for stealth-Playwright, R63 for operator's-own-browser, R30.2 for fresh-isolated, R30.3 for managed-cloud — four tracks behind one interface). **Safety guardrails** (hard-blocked at the provider, *before* the F8 stakes gate runs): destructive key combos (`cmd+shift+Q` logout, `cmd+shift+delete` empty-trash, `cmd+ctrl+Q` lock-screen, `cmd+option+shift+Q` force-logout) and shell-injection patterns in `type` payloads (`curl ... \| bash`, `wget ... \| sh`, `sudo rm -rf`, fork-bomb shapes) refuse the action and emit an F2 audit event — these are **not** stakes-escalatable; the model has no plausible business issuing them inside a browser window. **Anti-goals**: not a generic OS-control provider (that's **R43** proper — R63 is the browser-window slice with browser-specific affordances baked in); not a Linux / Windows path (cua-driver depends on macOS-private APIs; cross-platform CUA is a separate row); not a Playwright replacement (R30.2 / R30.3 / R30.4 remain the right path when a *fresh isolated* browser session is what's wanted — R63 is for the operator's *existing* browser); not a screen-scraper for non-browser apps (use **R43** for those); not a recording / replay surface (the audit trail is the artifact). **Out of scope for v1**: AppleScript / Shortcuts integration (separate follow-up if browser-specific automation gaps appear), Safari extension companion (R63 controls the browser from outside; an extension-side companion is a different shape), multi-monitor cursor warping (not needed since v1 doesn't warp at all), macro recording for later replay (operator workflows live in **R2** YAML workflows, not in CUA traces). **Done criteria**: (1) `MacCuaBrowserProvider` implements R30.1 against the five named browsers with smoke tests on at least Safari + Chrome; (2) `hybridclaw doctor cua-mac` correctly detects missing TCC grants and refuses F5 advertisement until granted; (3) background-safe contract verified by an automated test that asserts cursor position + frontmost-window + active-Space are unchanged after a 60-second drive-the-browser sequence; (4) every action emits F2 events readable from R30.9's audit surface; (5) hard-blocked key combos + shell-injection patterns reject deterministically (regression tests); (6) F13 `SecretRef` round-trips through `type_text_chars` without cleartext crossing the model boundary (regression test); (7) AX-tree-first targeting preferred — pixel fallback fires only when the resolved element has no usable AX bounds, captured in an F2 event for observability. *Principles V + VII.* Added 2026-05-15. | P1 | ✅ #1032 via PR #1039 (`src/browser/mac-cua-provider.ts`, `src/doctor/checks/cua-mac.ts`) |
| 62 | **TUI rendering toolkit — stable redraw primitive, no manual row counting** *(to be filed)* | First-class TUI drawing layer that replaces the ad-hoc `process.stdout.write('\r\x1b[2K')` + `moveCursor` + lines-written counting scattered across [`src/tui.ts`](../../../src/tui.ts), [`src/tui-skill-config.ts`](../../../src/tui-skill-config.ts), [`src/tui-slash-menu.ts`](../../../src/tui-slash-menu.ts), [`src/tui-thinking.ts`](../../../src/tui-thinking.ts), and other `src/tui-*.ts` surfaces with a single coherent rendering primitive. **Problem**: every interactive TUI surface today (slash menu, skill picker, approval prompt, thinking spinner, banner, history scrubber, goal continuation, count-judging output) hand-rolls its own redraw — count emitted lines, move the cursor up N rows, clear-line each row, re-emit. Drift compounds: a slash-menu entry that wraps over two terminal columns silently undercounts; an emoji or wide-char glyph throws the column math off; a resize between writes leaves stale rows; concurrent surfaces (spinner above an approval prompt) clobber each other's cursor assumptions. The recent `fix: smooth goal tui and count judging` + `fix: cleanly isolate goal continuations` commits are symptoms of exactly this — the bug surface is *"another place where line-counting drifted"*, not a one-off. **Substrate**: (a) a single `TuiRegion` abstraction — an owned rectangular slice of the terminal that knows its origin, current rendered height, and how to *re-render itself from a virtual buffer* rather than from a count of bytes emitted; the region diffs its previous frame against the next frame and emits the minimum ANSI to converge (à la ink / blessed / notcurses), so callers describe *what should be on screen* instead of *how many rows to delete*; (b) a top-level `TuiCompositor` that owns the absolute cursor, stacks regions in document order (banner → history → live spinner → input → ephemeral overlays like the slash menu or approval prompt), and serializes writes so two regions can update concurrently without fighting over `moveCursor`; (c) a `measure(text, termWidth)` helper that handles wide-chars (CJK), emoji ZWJ sequences, ANSI escapes, and tab expansion correctly — the math currently lives inline at every counting site and is wrong in subtly different ways; (d) resize-safe redraw — `SIGWINCH` invalidates region heights and triggers a full reflow from the virtual buffer rather than relying on stale counters; (e) a *non-TTY fallback* path that emits plain append-only output (the current code paths already branch on `process.stdout.isTTY`, but the branch is duplicated at every site — the toolkit centralizes it). **No visible changes at first**: the rollout is a behind-the-scenes replacement — every existing TUI surface migrates to the new primitive without changing its visible layout, animation, or keybindings; the *test* is that the surface looks identical and the manual-counting bugs disappear. Subsequent features (R29 board ticker, R40 `/goal` continuation, R44 achievement medals in the chat surface) can then build richer compositions without each one re-inventing redraw. **Reuse vs. build**: evaluate ink/blessed/charm-bracelet-lipgloss-port before building from scratch — the prior art is mature. If we adopt a library, wrap it behind a thin `TuiRegion` interface so a future swap is cheap; if we build, keep it tiny (the diff-and-emit core is a few hundred lines). The decision criterion is *whether the library survives non-TTY pipes, our existing slash-menu animation cadence, and the `tui-history` scrollback shape* without us forking it. **Composes with**: every `src/tui-*.ts` surface (migration target), **R40** `/goal` (goal-step continuations were the latest counting-bug site; the goal-header re-render becomes a region update), **R29** kanban board (a TUI-side board view becomes tractable once redraw is reliable), **R44** achievements (medal animations land as ephemeral overlay regions), **F11** trace-judge (count-judging output was a counting-bug site flagged in the recent commits), [`templates/HEARTBEAT.md`](../../../templates/HEARTBEAT.md) heartbeat banner (one of the static regions in the compositor stack). **Anti-goals**: not a full TUI app framework (no widget tree, no focus manager beyond what slash-menu / input already need), not a styling DSL (color + bold + dim is enough — no Tailwind-for-terminals), not a layout engine with flexbox semantics (regions stack vertically; horizontal composition is per-region's job), not a replacement for the web admin console (the toolkit is for the local TUI only — `/admin/*` stays React). **Out of scope for v1**: mouse support, double-buffered alt-screen mode for full-screen TUI apps (the current surfaces all live in the scroll-back stream and that's the right shape — alt-screen breaks copy-paste), per-region animation easing curves (linear is fine), themeable color tokens (defer until R44 / R29 land and force a real palette decision). **Done criteria**: (1) at least the slash menu, skill-config picker, approval prompt, thinking spinner, banner, and goal-continuation header migrated off manual `moveCursor` / lines-written counting; (2) zero remaining call sites of raw `moveCursor` / `\x1b[2K` / line counters outside the toolkit itself (lint rule enforces); (3) resize during an active render produces a correct frame (snapshot test on `SIGWINCH` mid-spinner); (4) wide-char + emoji glyphs render correctly (unit tests on `measure`); (5) non-TTY pipe output is byte-identical to today's append-only path for the migrated surfaces (regression test). *Principles VIII + X.* Added 2026-05-14. | P1 | ⬜ |
| 66 | **TUI copy preserves source Markdown for rendered tables** [#1020](https://github.com/HybridAIOne/hybridclaw/issues/1020) | Follow-up to **#1019**: keep terminal display rendering for Markdown tables, but make copy/export behavior preserve the original Markdown source rather than the bordered terminal table. Copying a rendered assistant reply should yield portable Markdown for docs, issues, chat, and future prompts; inline source markers such as `**Add pricing signals.**` should remain Markdown in copied text instead of ANSI-rendered output. **Scope**: separate display rendering from source serialization, keep stored assistant messages and gateway payloads unchanged, and add regression coverage proving rendered output and copied/source output intentionally differ. Composes with **R62** because the rendering toolkit should treat "what is on screen" and "what gets copied" as distinct buffers. Added 2026-05-14. *Principles VIII + X.* | P2 | ⬜ |
| 64 | **Codex app-server runtime adapter for OpenAI/Codex turns** [#1022](https://github.com/HybridAIOne/hybridclaw/issues/1022) | Optional runtime mode that lets `openai-codex/*` turns run through `codex app-server` while HybridClaw remains the orchestration shell for sessions, gateway routing, approvals, audit, memory review, skills, and operator UX. **Problem**: HybridClaw already has Codex OAuth + model discovery ([`src/auth/codex-auth.ts`](../../../src/auth/codex-auth.ts), [`src/providers/codex-discovery.ts`](../../../src/providers/codex-discovery.ts)) and Responses API calling, but it does not expose the native Codex runtime surface: shell execution, structured patch application, Codex sandbox profiles, native Codex plugins/apps, and ChatGPT-subscription-backed execution through the Codex CLI runtime. **Substrate**: persisted runtime selector defaulting to the current HybridClaw runtime; CLI/TUI/gateway command to inspect/toggle it with next-session semantics; managed `codex app-server` subprocess per turn; approval translation into the existing HybridClaw approval/audit path; HybridClaw MCP callback server exposing safe host tools such as web extraction, browser automation, skills, image/vision, TTS, and gateway operations; migration of eligible user MCP servers and installed Codex plugins into the Codex runtime config under a managed block; projection of completed command/file/MCP events back into HybridClaw's transcript shape so memory nudges, skill reviews, trace export, audit, and trajectory capture keep working. **Composes with**: **R60** per-model behavior overlays (Codex runtime still needs model-specific tool-discipline contracts), **R28** provider fallback (runtime selection must fail loud and fall back only through explicit policy), **R51** daemon mode (same BYO runtime orchestration pattern, but OpenAI/Codex-scoped and first-party), **F13** credential rail (never copy cleartext HybridClaw secrets into Codex config), **F3** policy (sandbox/network/credential grants stay deny-by-default), **R10.1** trajectories (record runtime selection and normalized tool events). **Anti-goals**: not a replacement for the default HybridClaw runtime; not for non-OpenAI providers; not a silent permission broadening; not a second secret store. **Done criteria**: (1) enabling validates the `codex` binary and version with actionable errors; (2) active sessions keep their current runtime and the new selector applies only to the next session or explicit restart; (3) `openai-codex/*` turns complete through `codex app-server` with shell, patch, plan, sandbox, approval, and transcript projection covered by tests; (4) MCP callback exposes at least web extraction, browser automation, skill lookup, image/vision, and TTS; (5) agent-loop-only tools that need in-process turn state are blocked with clear fallback messaging; (6) memory/skill review counters, session transcripts, audit events, and trajectory capture see an equivalent normalized turn shape. Added 2026-05-14. *Principles VIII + X.* | P1 | ✅ #1022 via PR #1031 (`container/src/codex-app-server.ts`, `codex-hybridclaw-mcp.ts`, runtime selector) |
| 59 | **Admin secrets manager — `/admin/secrets` page** *(to be filed)* | Operator-facing surface for the existing secret store (`src/security/runtime-secrets.ts` + `SecretRef` at `src/security/secret-refs.ts`) that today is reachable only via the `hybridclaw secret list / set / show / unset / route` CLI commands ([`src/cli/secret-command.ts`](../../../src/cli/secret-command.ts), [`src/cli/help.ts:745-762`](../../../src/cli/help.ts)). **Scope**: a `/admin/secrets` console page that lists every secret known to the store, **set entries first** (with metadata only — name, last-rotated timestamp, fingerprint / length hint, which connectors / skills / channels reference it) **then unset entries** (declared-but-empty — secrets that some skill manifest or connector route references but the store has no value for). Per-entry actions: **overwrite** (paste a new value — never reveal the current one) and **unset / remove**. **Hard no on read-back**: the cleartext value is **never** returned to the browser, never rendered, never copyable — the page is write-only on the value axis, read-only on the metadata axis. This is the same opaque-handle discipline **F13** enforces at the credential rail (`SecretRef` is the only thing that crosses the LLM boundary), extended to the operator UI: even the operator cannot exfiltrate a secret through the admin surface. **Grouping**: derive categories from existing declaration sources rather than inventing a new taxonomy — (a) **R48** `SKILL.md` frontmatter declares which secrets a skill needs (group: *"used by skill X"*), (b) **R45** #787 / **F17** managed-rule annotations record which connector wrote a route (group: *"channel: discord"*, *"http route: <host>"*), (c) **F5** provider catalog declares which API keys belong to which model provider (group: *"provider: anthropic"*). Unreferenced secrets fall into an *"unattributed"* group surfaced for cleanup. **Permissions**: **R14** RBAC gates which operators can view / overwrite / unset secrets (overwrite is a strictly higher privilege than view); **F3** scoped predicates can narrow further per-secret if a tenant needs operator-team-level segmentation. **Audit**: **F2** events `secret.viewed_metadata` / `secret.overwritten` / `secret.unset` feeding the hash-chain log; every overwrite records the operator identity, timestamp, source IP, and the new-value fingerprint (length + SHA prefix) — *never* the cleartext. **Reuse**: the existing CLI surface is the source-of-truth set of operations; the admin page is a thin HTTP layer over the same `runtime-secrets.ts` API plus an enumeration endpoint that joins skill manifests / connector routes / provider catalog for grouping metadata. **Composes with**: **R45** connector-managed rules (the same `managed_by_*` annotations supply the grouping signal), **R48** skill credential lifecycle (a `Blocked: needs credential` card on **R29** links directly to the matching `/admin/secrets` entry), **R42** live model picker (provider-API-key entries are co-managed — the inline paste path in R42 writes through the same store the admin page reads), **F13** credential rail (the no-read-back contract is the same discipline at a different surface), **R57** admin file browser (sibling admin page; same RBAC + audit shape). **Anti-goals**: not a vault replacement (the store already exists), not a credential *issuer* (no OAuth flows here — those belong on the per-connector setup pages and **R42**), not a value-reveal surface (no eye-icon, no copy-to-clipboard, no temporary-decloak — read-back stays out of the operator UI entirely; rotation is overwrite-only). **Out of scope for v1**: bulk import / export, time-bounded reveal for break-glass debugging (a separate, higher-friction flow if ever needed), per-secret rotation schedules (cron-driven rotation is a follow-up that composes with **R41** Autopilot). Added 2026-05-12. *Principles VII + X.* | P1 | 🟡 1/6 (R59.1 metadata API ✅ via PR #1054) |


## R47 Scoped Knowledge Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R47.1 | Agent runtime | Agent-level knowledge manifest loader (`KNOWLEDGE.md`) with explicit include semantics (paths, globs, URLs, doc IDs) | ⬜ To be filed |
| R47.2 | Retrieval | Activation-scoped retrieval router (only active agent corpus searched by default; explicit opt-in for global corpus) | ⬜ To be filed |
| R47.3 | Indexing | QMD adapter for per-agent corpora (build/update/query lifecycle + cache invalidation) | ⬜ To be filed |
| R47.4 | Skills | Skill-level knowledge attachments searchable only while the skill is active (works for global and agent-local skills) | ⬜ To be filed |
| R47.5 | Security | Policy predicates + audit events for corpus access (`knowledge.query`, `knowledge.source_used`) | ⬜ To be filed |
| R47.6 | UX | Authoring ergonomics: `/knowledge add`, validate manifest paths, preview effective corpus per agent/skill | ⬜ To be filed |
| R47.7 | Quality | Retrieval eval suite (precision/recall + leakage tests proving inactive corpora are never retrieved) | ⬜ To be filed |

## R48 Skill Credential Lifecycle Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R48.1 | Schema | `SKILL.md` frontmatter `credentials:` block — required vs optional, kind (`api_key` / `oauth` / `browser_login` / `bearer` / `header`), `SecretRef` binding, `how_to_obtain` markdown field | ✅ #812 via PR #909 |
| R48.2 | Schema | Browser-skill mode field — `browser_session: { headed: bool, requires_logged_in: bool, manual_unlock_reasons: ['captcha', '2fa', 'device_check'] }` so R30 picks the right install mode and F14 prepares for 2FA handover | ⬜ #813 |
| R48.3 | Setup UX | TUI install/setup wizard — prompts inline for every required credential, writes to secret store via `SecretRef`, calls into the F17 / R45 #787 managed-rule helper for the F3 grant (no duplicate rule-placement logic) | ⬜ #814 |
| R48.4 | Admin UX | `/admin/skills` per-skill credential surface — view / add / rotate / remove, mirrors the channel-credential admin UI, renders the `how_to_obtain` guide inline | ⬜ #815 |
| R48.5 | Acquisition guide | Renderer + content conventions for `how_to_obtain` (API-key portal click-path, OAuth scope list + start-flow button, browser-login waypoint URL); shared between TUI and admin UI | ⬜ #816 |
| R48.6 | Runtime | Preflight check that blocks skill activation when a required credential is missing; emits `escalation.credential_missing` via F8 / F14 with the acquisition guide attached so the operator can resolve from any escalation channel | ⬜ #817 |
| R48.7 | Runtime | Optional-credential degradation contract — skill declares which capabilities still work without the optional cred; runtime selects the fall-through path instead of hard-failing | ⬜ #818 |
| R48.8 | Audit | F2 events `skill.credential_attached` / `skill.credential_rotated` / `skill.credential_removed` / `skill.credential_missing_blocked` feeding the hash-chain audit log | ⬜ #819 |

## R53 Firecrawl Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R53.1 | Managed adapter | Managed Firecrawl API adapter for `scrape`, `crawl`, `map`, and `extract`, using the F13 `FIRECRAWL_API_KEY` credential rail through gateway `http_request` secret injection | ✅ Done #862 via PR #953 |
| R53.2 | Self-host adapter | Open-source Firecrawl self-host adapter for Docker-managed deployments | ✅ Done #863 via PR #978 |
| R53.3 | Skill surface | User-invocable `scrape.url` and `crawl.site` surface with bounded defaults and clear output contracts | ✅ #829 via PR #953 (`skills/firecrawl/`) |
| R53.4 | Extraction | Structured extraction via JSON Schema prompt and Firecrawl v2 extract lifecycle polling | ✅ #829 via PR #953 (`extract.structured` / `extract.status`) |
| R53.5 | Scoped knowledge | R47 ingestion bridge so crawled docs feed agent/skill collections without touching the global corpus | ⬜ To be filed |
| R53.6 | Crawl policy | Per-host crawl policy: rate limits, robots.txt respect, and F3 host allowlists | ⬜ To be filed |
| R53.7 | Decision rules | Documentation for Firecrawl HTTP vs R30 browser vs R54 Camofox | ⬜ To be filed |

## R52 SearXNG Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R52.1 | Client adapter | SearXNG client adapter against `format=json` API — engine selection, query options, result normalisation | ✅ #856 via PR #955 |
| R52.2 | Skill surface | `search.web` / `search.images` / `search.news` skill surface with bounded defaults, paging, and clear output contracts | ✅ #857 via PR #955 |
| R52.3 | Credentials | Per-tenant instance URL + F13 bearer binding so agents only reach the configured SearXNG instance and the bearer never enters model-visible arguments | ✅ #858 via PR #977 |

## R54 Camofox Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R54.1 | Provider | Camofox implementation of the R30.1 `BrowserProvider` interface ([camoufox](https://github.com/daijro/camoufox)) — stealth-mode profile, action vocabulary parity with the Playwright provider | ✅ #869 via PR #954 |

## R55 Video Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R55.1 | Client adapter | HeyGen client adapter — F13 API key, rate-limit-aware (tight per-account quotas), normalised job/asset shape | ✅ #874 via PR #952 |
| R55.2 | Skill surface | `video.from-script` skill — script → avatar/voice synthesis → managed media output, with fallback/warnings | ✅ #875 via PR #979 |

## R56 Folder-Hygiene Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R56.1 | Spec | `references/workspace-layout.md` — canonical layout: top-level allowlist mirrored from `templates/`, reserved directories with purpose statements (`memory/`, `notes/`, `drafts/`, `outputs/`, `inbox/`, `archive/`, `skills/`), naming rules, TTL hints | ⬜ #940 |
| R56.2 | Skill | `skills/folder-hygiene/SKILL.md` — judgment guide (heuristics, freedom levels), `init` (creates missing reserved dirs with `.keep` + one-line purpose READMEs), `audit` (report-only), `tidy` (plan-then-apply); user-invocable and model-invocable | ⬜ #941 |
| R56.3 | Tooling | `scripts/manifest.mjs` — deterministic workspace enumerator: paths + size + mtime + first 200 bytes for ambiguous files, emits JSON; the only non-LLM piece | ⬜ #942 |
| R56.4 | Examples | `references/examples.md` — 6–10 worked before/after triage decisions covering the hard cases (half-finished drafts, ambiguous outputs, files dropped at root); the corpus that makes LLM judgment consistent run-over-run | ⬜ #943 |
| R56.5 | Safety | Archive-not-delete contract — every removed file moves to `archive/YYYY-MM-DD/`; `archive/tidy-log/YYYY-MM-DD.md` records every move with a one-line *why*; `rm` is never invoked | ⬜ #944 |
| R56.6 | Trigger | `templates/HEARTBEAT.md` line — end-of-session hygiene pass, auto-apply by default, `ask` outcome is first-class; opt-out via per-workspace setting | ⬜ #945 |
| R56.7 | Feedback loop | Operator-correction promotion — when the operator restores a mis-archived file, the skill captures the path + reason and appends to `references/examples.md` (versioned via F4 so the corpus is auditable) | ⬜ #946 |
| R56.8 | Audit | F2 events `workspace.tidy_planned` / `workspace.tidy_applied` / `workspace.file_archived` / `workspace.tidy_asked` feeding the hash-chain log and the R29 board | ⬜ #947 |

## R57 Admin File Browser Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R57.1 | API | Workspace tree endpoint — `GET /api/admin/agents/{agentId}/tree?path=&depth=` with lazy children, R14 + F3 filtering, pagination | ⬜ #959 |
| R57.2 | API | Workspace search endpoint — filename + full-text (ripgrep-backed) with type / date / size / path filters, R14 + F3 filtering | ⬜ #960 |
| R57.3 | Console | Tree-view component on `/admin/agents` — lazy-load, R56 reserved-directory tooltips, keyboard nav, URL state | ⬜ #961 |
| R57.4 | Console | Search UI + result navigation — `Cmd/Ctrl+K`, filter chips, snippet preview, click-through to tree | ⬜ #962 |
| R57.5 | Permissions | R14 RBAC actions + F3 per-directory predicates for tree / search / read / write | ⬜ #963 |
| R57.6 | Audit | F2 events `workspace.browsed` / `workspace.searched` / `workspace.file_read` / `workspace.file_edited` / `workspace.access_denied`; feeds R56.7 correction loop on archive restores | ⬜ #964 |

## R58 Shared Workspace Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R58.1 | Data model | `SharedWorkspace` entity + ACL + CRUD API (`/api/admin/shared-workspaces`); materializes reserved subdirectories on create; soft-archive | ⬜ #965 |
| R58.2 | Runtime | Agent mount + path resolution — `./shared/<id>/...` via bind mount or symlink; read-only OS enforcement when ACL is read-only; hot un/remount on ACL change | ⬜ #966 |
| R58.3 | Policy | F3 schema for shared-workspace mount declarations + per-path predicates; layered with OS-level mount perms (defense in depth) | ⬜ #967 |
| R58.4 | Concurrency | SHA-based optimistic write contract — `If-Match` SHA; 409 on conflict with diff snippet; atomic temp-file rename | ⬜ #968 |
| R58.5 | Hygiene | R56 `workspace-layout.shared.md` profile — `ask` is default, auto-archive requires quorum, multi-agent attribution in tidy-log | ⬜ #969 |
| R58.6 | Admin UX | R57 browser support for shared workspaces — `/admin/shared-workspaces`, ACL banner, gated write buttons, quorum-archive approval queue | ⬜ #970 |

## R59 Admin Secrets Manager Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R59.1 | API | Secret enumeration endpoint — `GET /api/admin/secrets` returning name + metadata only (fingerprint, length, last-rotated, set/unset); never cleartext; R14 + F3 filtering | ✅ via PR #1054 (`src/gateway/gateway-admin-secrets.ts`; metadata-only + set/unset; R14/F3 filtering pending R14) |
| R59.2 | API | Secret overwrite + unset endpoints — `PUT /api/admin/secrets/{name}` (body: new value), `DELETE /api/admin/secrets/{name}`; thin wrapper over `runtime-secrets.ts`; rejects read requests by design | ⬜ [#1047](https://github.com/HybridAIOne/hybridclaw/issues/1047) |
| R59.3 | API | Grouping metadata join — enumerate which skills (R48 `SKILL.md`), connector routes (R45/F17 managed rules), and providers (F5 catalog) reference each secret; surface unattributed entries | ⬜ to be filed |
| R59.4 | Console | `/admin/secrets` page — grouped list (set first, then unset), per-entry overwrite + unset actions, no-reveal value field, keyboard nav | ⬜ to be filed |
| R59.5 | Permissions | R14 RBAC actions (`secret.list_metadata`, `secret.overwrite`, `secret.unset`) with overwrite strictly higher than view; F3 per-secret predicates for tenant segmentation | ⬜ to be filed |
| R59.6 | Audit | F2 events `secret.viewed_metadata` / `secret.overwritten` / `secret.unset` with operator identity + IP + new-value fingerprint (length + SHA prefix); never cleartext; hash-chain entry | 🟡 `secret.viewed_metadata` ✅ via PR #1054; `secret.overwritten` / `secret.unset` open (R59.2) |

## R21 Production Skills

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Type | Title | Status |
|----|------|-------|--------|
| R21.1 | Foundation | TypeScript SKILL.md framework | ✅ Done |
| R21.1.1 | Foundation | NexAU-style skill package support | ⬜ To be filed |
| R21.2 | Skill | Salesforce skill | ✅ Done |
| R21.3 | Skill | HubSpot skill | ✅ Done #581 via PR #1029 |
| R21.4 | Skill | SAP ERP skill | ⬜ To be filed |
| R21.5 | Skill | GA4 skill | ✅ Done #583 via PR #981 |
| R21.6 | Skill | NL-to-SQL warehouse skill | ✅ Done #584 via PR #679 |
| R21.7 | Skill | Hetzner DevOps skill | ✅ #649 via PR #1028 (hetzner-cloud / hetzner-dns / hetzner-storage-box) |
| R21.8 | Skill | SAP Analytics Cloud skill | ⬜ To be filed |
| R21.9 | Skill | DATEV skill | ⬜ To be filed |
| R21.10 | Skill | Lexware Office skill | ⬜ To be filed |
| R21.11 | Skill | Invoice harvester skill | 🟡 #688; API adapters via PR #772 |
| R21.11.1 | Skill | Invoice harvester browser scrape adapters | ⬜ #778 |
| R21.12 | Skill | ELSTER skill | ⬜ #689 |
| R21.13 | Skill | XRechnung/ZUGFeRD/Peppol skill | ⬜ #690 |
| R21.14 | Skill | HBCI/FinTS skill | ⬜ #691 |
| R21.15 | Skill | Handelsregister/Bundesanzeiger skill | ⬜ #692 |
| R21.16 | Skill | Schufa/Creditreform skill | ⬜ #693 |
| R21.17 | Skill | Celonis skill | ⬜ #722 |
| R21.18 | Skill | Personio skill | ⬜ #723 |
| R21.19 | Skill | FastBill skill | ✅ #724 via PR #881 |
| R21.20 | Skill | Google Ads skill | ✅ #759 via PR #883 |
| R21.21 | Skill | SAP Utilities maintenance skill | ⬜ To be filed |
| R21.22 | Skill | OT cybersecurity skill | ⬜ To be filed |
| R21.23 | Skill | Energy-infrastructure project-management skill | ⬜ To be filed |
| R21.24 | Skill | IT demand-management skill | ⬜ To be filed |
| R21.25 | Skill | BIM infrastructure-documentation skill | ⬜ To be filed |
| R21.26 | Skill | Plant lifecycle technical-standards skill | ⬜ To be filed |
| R21.27 | Skill | Commercial legal-governance skill | ⬜ To be filed |
| R21.28 | Skill | Finance close-and-reporting skill | ⬜ To be filed |
| R21.29 | Skill | Payroll accounting skill | ⬜ To be filed |
| R21.30 | Skill | Order-to-cash skill | ⬜ To be filed |
| R21.31 | Skill | Record-to-report skill | ⬜ To be filed |
| R21.32 | Skill | Product-design research skill | ⬜ To be filed |
| R21.33 | Skill | Market-research analytics skill | ⬜ To be filed |
| R21.34 | Plugin | Workday HR/payroll read connector | ⬜ To be filed |
| R21.35 | Plugin | Finance-system connector for close, OTC, and R2R workflows | ⬜ To be filed |
| R21.36 | Plugin | CLM/document-repository connector for legal review | ⬜ To be filed |
| R21.37 | Plugin | Figma/design-system connector for product design | ⬜ To be filed |
| R21.38 | Skill | Event guest-relation management skill | ⬜ To be filed |
| R21.39 | Skill | Event microsite publishing skill | ⬜ To be filed |
| R21.40 | Skill | 360 campaign project-control skill | ⬜ To be filed |
| R21.41 | Skill | Pitch-deck and presentation narrative skill | ⬜ To be filed |
| R21.42 | Skill | Brand copywriting QA skill | ⬜ To be filed |
| R21.43 | Skill | Social-first campaign ideation skill | ⬜ To be filed |
| R21.44 | Skill | Photo/video production planning skill | ⬜ To be filed |
| R21.45 | Skill | AI-assisted creative-production governance skill | ⬜ To be filed |
| R21.46 | Skill | Digital product sales-monitoring skill | ⬜ To be filed |
| R21.47 | Plugin | Adobe Creative Cloud asset connector | ⬜ To be filed |
| R21.48 | Plugin | ATS job-posting connector | ⬜ To be filed |
| R21.49 | Skill | Deutsche Bahn business-travel skill (schedule lookup, ticket booking, BahnCard expense reconciliation) | ⬜ To be filed |
| R21.50 | Skill | Lufthansa business-travel skill (NDC booking, status/frequent-flyer lookup, irregular-ops rebooking) | ⬜ #805 |
| R21.51 | Skill | Workday HR-workflow skill (onboarding, time-off, expense, review prep — consumes R21.34 connector) | ⬜ To be filed |
| R21.52 | Skill | Airtable skill (bases/tables search, record CRUD with field-type validation, attachments, formula-field reads) | ✅ #908 via PR #910 |
| R21.53 | Skill | Pipedrive skill (deals/persons/orgs read, stage and probability updates, activity logging) | ⬜ To be filed |
| R21.54 | Skill | Zoho CRM skill (lead/contact/deal CRUD, blueprint transitions, custom-module support) | ⬜ To be filed |
| R21.55 | Skill | Asana skill (project/task CRUD, custom fields, sections, my-tasks lookup) | ⬜ To be filed |
| R21.56 | Skill | Monday.com skill (boards/items/columns via GraphQL, status-column transitions) | ⬜ To be filed |
| R21.57 | Skill | ClickUp skill (spaces/folders/lists/tasks, custom fields, time tracking, dependencies) | ⬜ To be filed |
| R21.58 | Skill | Zendesk skill (tickets, comments, macros, search, requesters, organizations) | ⬜ To be filed |
| R21.59 | Skill | Intercom skill (conversations, contacts, tags, replies, knowledge-base ops) | ⬜ To be filed |
| R21.60 | Skill | Freshdesk skill (tickets, contacts, agents, conversations, status transitions) | ⬜ To be filed |
| R21.61 | Skill | Help Scout skill (mailboxes, conversations, replies, tags, customers) | ⬜ To be filed |
| R21.62 | Skill | Typeform skill (forms metadata, response pull, dedupe on response_id) | ⬜ To be filed |
| R21.63 | Skill | Forms-aggregator skill for Google Forms / Jotform / SurveyMonkey responses (cross-provider harvest + dedupe) | ⬜ To be filed |
| R21.64 | Skill | QuickBooks Online skill (customers, invoices, payments, bills, journal entries, OAuth) | ⬜ To be filed |
| R21.65 | Skill | Xero skill (contacts, invoices, bills, bank transactions, tracking categories, OAuth) | ⬜ To be filed |
| R21.66 | Skill | PayPal skill (transactions search, refunds, invoices, payouts — pairs with the stripe skill) | ⬜ To be filed |
| R21.67 | Skill | Mailchimp skill (audiences, campaigns, transactional via Mandrill — peer to brevo-email plugin) | ⬜ To be filed |
| R21.68 | Skill + Tool | Native `image_generate` tool plus image-generation skill. UX: `prompt`, reference images, aspect ratio, list/readiness with provider contract, managed media output, fallback/warnings, and SSRF-safe reference-image loading. Providers shipped via PR #938: OpenAI / GPT Image, Google Gemini / Nano Banana, xAI / Grok, Black Forest Labs / FLUX (`openai`, `gemini`, `xai`, `bfl`). Per-provider catalog extension pattern tracked under R21.101. | ✅ #936 via PR #938 |
| R21.69 | Skill | Speech-to-text skill (provider-agnostic — local Whisper-compatible backends, OpenAI, Deepgram, AssemblyAI — diarization, timestamps, language detection). Native `audio_transcribe` plus `speech.transcribe` and `speech.detect-language` shipped with transcript artifacts, usage accounting, provider credentials, and fallback handling. | ✅ #999 via PR #1010 |
| R21.70 | Skill | Text-to-speech skill (provider-agnostic — ElevenLabs, OpenAI TTS, Cartesia — voice selection, SSML, streaming). Tool layer `text_to_speech` + skill layer + multi-provider expansion all open; tracked under R21.95 (tool) + #1001 (skill). | ⬜ #1001 |
| R21.71 | Skill | Calendly skill (event types, scheduled events, invitee lookup, no-show flagging, reschedule links) | ⬜ To be filed |
| R21.72 | Skill | Shopify skill (products, orders, fulfillments, customers, draft orders, OAuth) | ⬜ To be filed |
| R21.73 | Skill | WooCommerce skill (orders/products via REST, dedupe-on-order-id, webhook intake) | ⬜ To be filed |
| R21.74 | Plugin | Dropbox connector (file CRUD, shared links, team-namespace support; complements google-workspace Drive) | ⬜ To be filed |
| R21.75 | Plugin | Box connector (folders, files, collaborations, comments, retention policies) | ⬜ To be filed |
| R21.76 | Plugin | OneDrive / SharePoint connector (drives, items, search; pairs with the existing msteams channel) | ⬜ To be filed |
| R21.77 | Skill | Microsoft Teams action skill (post message, list channels, fetch files — distinct from the R38 channel adapter, which is operator-facing only) | ⬜ To be filed |
| R21.78 | Skill | LinkedIn skill (UGC posts via Marketing API, company-page operations, lead-gen forms read) | ⬜ To be filed |
| R21.79 | Skill | Facebook Lead Ads skill (lead-form harvesting, page-posts read, ad-set status) | ⬜ To be filed |
| R21.80 | Skill | X (Twitter) skill (tweet CRUD via v2 API, search, list management — gated by API tier) | ⬜ To be filed |
| R21.81 | Skill | Mixpanel skill (event ingest, JQL reports, cohort export — peer to R21.5 GA4) | ⬜ To be filed |
| R21.82 | Skill | PostHog skill (capture, person properties, feature flags, insights query) | ⬜ To be filed |
| R21.83 | Skill | Stock / equities deep-research skill (announcements, market explorer, financial deep research). DACH-relevant companion to the R21.28–R21.31 finance bundle. | ⬜ To be filed |
| R21.84 | Skill | Financial-services modeling bundle — 3-statement modeling, DCF, LBO, merger, comps, with Excel and PPTX authoring. Bridges R21.28 finance close and R21.41 pitch decks. | ⬜ To be filed |
| R21.85 | Skill | B2B lead-generation skill with ICP scoring. Workflow-shaped complement to the Salesforce / HubSpot connectors (R21.2 / R21.3). | ⬜ To be filed |
| R21.86 | Skill | OSINT / competitive-intelligence skill with sentiment monitoring + change detection. Operational sibling to R21.33 market-research analytics. | ⬜ To be filed |
| R21.87 | Skill | Forecasting / decision-support skill with Brier-scored superforecasting. No prior roadmap analogue. | ⬜ To be filed |
| R21.88 | Skill | RSS / HTTP / GitHub watcher skill — no-agent cron-mode polling. Background-curation companion to R41 skill-maintenance loop. | ⬜ To be filed |
| R21.89 | Skill | Shopify skill (Admin + Storefront GraphQL). Closes a noticeable gap given DACH e-commerce ambitions. | ⬜ To be filed |
| R21.90 | Skill | Airtable skill (records / views / automations). | ⬜ To be filed |
| R21.91 | Skill | Searxng-search skill — privacy-respecting metasearch across configurable engines. Shipped as `search.web`, `search.images`, and `search.news` with authenticated SearXNG configuration under R52. | ✅ via R52 / PR #955 + PR #977 |
| R21.92 | Skill | Hyperframes / website-to-video creative pipeline. Fills the gap between R21.43 social-first ideation and R21.44 photo/video planning. | ⬜ To be filed |
| R21.93 | Skill | Serial / IoT hardware skill targeting RISC-V / ARM microcontrollers. Possible R32 sibling for embedded ops. | ⬜ To be filed |
| R21.94 | Tool | Native `video_analyze` tool via multimodal LLM — sibling to `vision_analyze`. Tool primitive, not a skill. | ⬜ To be filed |
| R21.95 | Tool | Native `text_to_speech` / `tts` tool — host-side `OPENAI_API_KEY` resolution, worker-signature restart-on-config-change, F8 stakes classification, artifact MIME for generated audio. Initial provider: OpenAI TTS. Follow the per-tool-module shape established by R21.68 (`container/src/image-generation.ts` → new `container/src/text-to-speech.ts`); extend `media-generation-usage.ts` + `provider-credentials.ts` rather than introduce a parallel `content-tool-config.ts`. Tool-layer work is the first PR under R21.70 / #1001. | ⬜ rolled into #1001 (PR #377 abandoned 2026-05-13 — superseded by #938's per-tool-module shape) |
| R21.96 | Tool | Native `audio_transcribe` / `transcribe_audio` tool — provider credential resolution, worker-signature restart-on-config-change, F8 stakes classification, transcript artifacts, usage accounting, local/backend auto-detect, and provider fallback. | ✅ #999 via PR #1010 |
| R21.97 | Tool | Native `vision` first-class alias — thin surface over the active multimodal provider's image_url-to-text path. Pairs with R21.94 `video_analyze`. Tool-layer work to be filed standalone once the consuming skills materialize (no skill-layer issue today — vision capability already widely available implicitly through model multimodality). | ⬜ to be filed (PR #377 abandoned 2026-05-13) |
| R21.98 | Tool | Native `diagram_create` / `diagram` tool — Mermaid + SVG generation, artifact MIME for generated diagram files. Initial format: Mermaid. Follow R21.68's per-tool-module shape (new `container/src/diagram-create.ts`). Tool-layer work is the first PR under R21.99 / #1002. | ✅ shipped via #1006 (2026-05-14) |
| R21.99 | Skill | Diagram skill — operator-facing wrapper over the R21.98 `diagram_create` tool. Schema-aware Mermaid (sequence / flowchart / state / ER / class / gantt / git-graph), validation pass before render, embed-ready artifacts, multi-format extension (PlantUML, Graphviz, ExcalidrawJSON) as catalog providers. Composes with **R47** scoped knowledge (rendered diagrams land in agent/skill-scoped artifact store), **F8** stakes (low — output is a file the operator chooses to share). | ✅ shipped via #1006 (2026-05-14) |
| R21.100 | Integration | **Content-tools R5 / R47 / R48 wiring.** Image, speech-to-text, and diagram tools now ship through the per-tool-module shape, but follow-up integration remains: (a) complete **R5** per-agent budget enforcement for all generated-media/tool costs; (b) **R47** scoped-knowledge artifact storage (generated media lands in agent/skill-scoped store, not global); (c) **R48** credential-lifecycle auto-grants beyond declared skill credentials; (d) F8 stakes refinement for public-output content tools such as image generation and future TTS. | ⬜ #1000 |
| R21.101 | Provider | **Content-tool multi-provider extension** — catalog-provider pattern for per-provider adapters, F5 capability-matrix entries, fallback chain on auth/quota errors, and per-provider cost units for R21.100 budget integration. Image providers shipped under R21.68; speech-to-text providers shipped under R21.69/R21.96; diagram adapters shipped under R21.99. Remaining extensions land separately for TTS and later provider additions. | 🟡 #1003 (image/STT/diagram provider paths shipped; TTS provider path open) |
| R21.102 | Skill | Miro skill (board discovery, item reads for summarization/planning, sticky/text/shape/connector/frame writes, board snapshot artifacts, OAuth/token-backed credentials, and preview/approval before high-impact board writes) | ⬜ #1040 |
| R21.103 | Skill | Zabbix monitoring skill (host inventory, current/recent problems, trigger severity summaries, and incident-card handoff). Must use the existing SecretRef runtime secret store for Zabbix API tokens and emit gateway `http_request` payloads from its helper script: JSON-RPC POST to `api_jsonrpc.php`, `Content-Type: application/json-rpc`, `bearerSecretName: "ZABBIX_API_TOKEN"`, and bounded `host.get`, `problem.get`, and `trigger.get` request bodies derived from the official Zabbix API docs. Write-like event actions such as acknowledge, suppress, or close are amber/red and require exact F8/F14 operator grants. Complements R32/R33 server-maintenance skills by turning monitoring state into actionable incidents. | ✅ #1045 via PR #1052 (`skills/zabbix/`) |
| R21.104 | Skill | mittwald platform skill for mStudio / Kundencenter operations. API-first against the [mittwald Developer Portal](https://developer.mittwald.de/de/) surfaces: v2 mStudio API for projects, apps, deployments, runtime environments, databases, domains, and marketplace-extension workflows; v1 Kundencenter API where legacy account data is still required; optional use of the official mittwald CLI / JavaScript / Python / PHP / Go SDKs as implementation references, not hard runtime dependencies. Should integrate with F13 `SecretRef` credentials for mittwald API tokens, F3 host allowlists for `api.mittwald.de`, R48 credential lifecycle metadata, and R32/R33 server-maintenance cards for deployment incidents. Terraform and mittwald MCP docs are companion references, but the skill body must live under `skills/mittwald/` with colocated helpers rather than in gateway core. | ⬜ #1068 |
| R21.105 | Skill | Distil PII redactor skill — local, offline NER-based PII detection + redaction over text/files with setup/stop lifecycle scripts (`skills/distil-pii-redactor/`, no cloud dependency). Defensive companion to **R4** confidential-masking and **R6** leak classifier — redacts personal data before it crosses an external surface. Filed retroactively after the 2026-05-21 skills audit surfaced it shipped without a roadmap row. | ✅ via PR #1056 |
| R21.106 | Skill | Open Telekom Cloud DevOps skill — Hetzner-style infrastructure operations for OTC / T-Systems. API-first against the [Open Telekom Cloud REST API docs](https://docs.otc.t-systems.com/developer/api.html), covering inventory and guarded operations across Elastic Cloud Server, VPC, Elastic IP, load balancing, DNS, EVS/OBS/SFS storage, Cloud Backup and Recovery, Cloud Container Engine, RDS, Cloud Eye, Cloud Trace, Log Tank Service, IAM, KMS, WAF, and quotas/status checks. Must use F13 `SecretRef` credentials for OTC IAM/API signing material, F3 host allowlists for OTC regional endpoints, R48 credential lifecycle metadata, and R32/R33 server-maintenance handoff for deployment incidents. SDKs (`python-otcextensions`, Gophercloud, JavaScript SDK), Terraform/OpenTofu, Ansible, Cloud Create, regions/endpoints docs, and API usage/signature guidance are companion references, but the skill body must live under `skills/open-telekom-cloud/` with colocated helpers rather than in gateway core. Read/list/describe operations are the v1 focus; mutating compute/network/storage/IAM actions are amber/red and require exact F8/F14 approvals. | ⬜ #1069 |

## R1 Messaging Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R1.1 | Core | Persisted A2A envelope store | ✅ Done |
| R1.2 | Core | A2A send-message primitive | ✅ Done #425 via PR #695 |
| R1.3 | Admin | Admin inbox surface for inbound agent work | ⬜ #426 |
| R1.5 | Audit | Hash-chain audit-log integration for saved A2A envelopes | ✅ #429 via PR #1025 (`src/a2a/audit.ts`) |
| R1.6 | Federation | Cross-instance routing in `sendMessage` | ⬜ #717 |
| R1.7 | Federation | Inbound peer endpoint | ⬜ #718 |
| R1.8 | Federation | Envelope schema additions for cross-instance routing | ⬜ #719 |
| R1.9 | Federation | Operator pairing UX | ⬜ #720 |
| R1.10 | Transport | Transport registry and peer descriptor schema | ✅ #765 via PR #777 |
| R1.11 | Transport | A2A outbound adapter | ✅ #766 via PR #795 (retry classification follow-up via PR #884) |
| R1.12 | Transport | A2A inbound adapter and Agent Card endpoint | ✅ #767 via PR #911 |
| R1.13 | Transport | Signed-HMAC webhook outbound adapter with retry and jitter | ✅ #768 via PR #782 |
| R1.14 | Transport | Signed-HMAC webhook inbound adapter | ✅ #769 via PR #799 |
| R1.15 | Transport | A2A streaming SSE for R9 RPC delegation responses | ⬜ #771 |

## R2 Workflow Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R2.1 | Workflow | Declarative YAML workflow schema | 🔄 #461 |
| R2.2 | Workflow | Sequential workflow runner | 🔄 #461 |
| R2.3 | Policy | High-stakes gating semantics through F8 default action | ⬜ To be filed |
| R2.4 | Workflow | Return-for-revision rewind behavior | ⬜ To be filed |
| R2.5 | Admin | Workflow state visualizer | ⬜ #434 |

## R3 Scoreboard Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R3.7 | Scoreboard | Scoreboard follow-up from shipped CV work | ✅ #618 |

## R5 Budget Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R5.1 | Metering | Usage totals and monthly spend surfacing | ✅ Done |
| R5.2 | Enforcement | Soft-warn spend threshold | ⬜ To be filed |
| R5.3 | Enforcement | Hard-stop policy predicate consuming `monthlySpendUsd` | ⬜ To be filed |
| R5.4 | Enforcement | Per-skill budget sub-limits | ⬜ To be filed |
| R5.5 | Admin | Budget admin surface | ⬜ To be filed |
| R5.6 | Audit | Budget warning and enforcement audit events | ⬜ To be filed |
| R5.7 | Metering | **Sub-agent token bucketing into parent run totals.** Every child invocation (sub-agent spawn, **R31** coordination pattern, **R9** delegated task, **R35** council branch, tool-as-LLM call) must roll its `UsageTotals` *upward* into the originating run's bucket so admin surfaces, **R29** card budget chips, and **R5.3** hard-stop predicates read the *true* spend for the parent task, not just the top-level conversation. **Recurring failure modes to specify defensively** (each one has been an independent regression in adjacent agent stacks — bucket → dedupe → header-source → stream → grouping-expression is the typical fix sequence): (a) **bucketing** — child calls bypass the parent's `monthlySpendUsd` counter and only land in their own thread totals, so per-agent caps under-count multi-agent runs; (b) **dedupe by message id** — when both the parent and a synthesizer aggregate the same child message, naive sum double-counts; the aggregation key must be the model-event message id, not the (agent, turn) pair; (c) **header / display source** — UI surfaces (chat header, **R29** card chip, admin spend page) must read from the rolled-up total, not the raw per-turn delta, or the displayed number lags reality; (d) **streaming** — when sub-agent turns stream over **R10.1** trajectory events, the parent total must update incrementally rather than only at child-completion, or long-running sub-agents make the parent budget appear under-spent until the very end; (e) **grouping expression reuse** — the SQL/Kysely expression that groups usage by run must be a single shared helper, not re-implemented per query site, or the aggregation drifts between admin / card / enforcement readers. **Acceptance**: a parent run that spawns N children spends `parent_direct + Σ child_total` against its budget; admin / card / hard-stop / **F2** audit events all read the same number; identical-message-id double-emits collapse to one charge. **Composes with**: **R5.3** hard-stop (must read rolled-up total to be correct under multi-agent runs), **R5.4** per-skill caps (a skill's spend includes its sub-agent fan-out), **R9.7** delegation heartbeat (zombie child tokens still charge until reclaim), **R10.1** trajectory store (per-event usage rows are the rollup source), **R29.2** card chip (reads from rolled-up total). Anti-pattern: charging only the leaf model call — leaves orchestration spend invisible. | ⬜ To be filed |
| R5.8 | Config | **Budget unit selection — USD, EUR, or tokens.** Extend `agents.list[].budget` so operators can cap an agent by money (`USD` / `EUR`) or monthly token volume using the existing `UsageTotals` token fields. Existing money-denominated configs stay backward-compatible; token budgets format clearly in admin surfaces (for example `12.4k / 100k tokens`), share the same 80% soft-warn and 100% hard-threshold semantics, and produce a normalized summary that future **R5.3** hard-stop enforcement can consume without duplicating unit conversion logic. | ⬜ [#1035](https://github.com/HybridAIOne/hybridclaw/issues/1035) |

## R8 Brand-Voice Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R8.1 | Classifier | Brand-voice profile schema | ✅ Done |
| R8.2 | Classifier | Response classifier integration | ✅ Done |
| R8.3 | Middleware | Brand-voice middleware adapter | ✅ PR #408, refactored via PR #763 |
| R8.4 | Admin | Brand-voice profile editor | ⬜ #477 |
| R8.5 | Channels | Per-channel voice variants | ⬜ #478 |
| R8.6 | Policy | Gate enforcement config for brand-voice middleware | ⬜ #682 |

## R9 Delegation Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R9.1 | Auth | Inter-instance authentication with signed tokens | ✅ #480 via PR #890 |
| R9.2 | Delegation | Delegation envelope schema | ✅ #481 via PR #889 |
| R9.3 | Transport | Cross-instance HTTP transport | ⬜ #482 |
| R9.4 | Audit | Cross-instance audit-log linking | ⬜ #483 |
| R9.5 | Admin | Fleet topology admin UI | ⬜ #484 |
| R9.6 | Reliability | Failure handling for offline child instances | ⬜ #486 |
| R9.7 | Reliability | Heartbeat + reclaim + zombie-detection for delegated tasks — periodic worker heartbeat, parent reclaims orphaned tasks after missed-heartbeat threshold, zombie cleanup for workers that died without unwinding state. Generalizes R9.6 from binary up/down to a live liveness signal; composes with **R23** warm-restart durability and the **R29** board's per-card status. | ⬜ To be filed |

## R10 Auto-Improvement Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R10.1 | Trajectories | Store skill-run trajectories as filesystem JSONL under `<runtime>/trajectories/` | ✅ Done |
| R10.2 | Trajectories | Rate and prepare trajectories for improvement loops | ✅ Done |
| R10.3 | Trajectories | Feed trajectory ratings into skill scoring | ✅ Done |
| R10.4 | Fine-tuning | Per-tenant SFT dataset builder | ⬜ To be filed |
| R10.5 | Fine-tuning | Eval-gated SFT promotion workflow | ⬜ To be filed |
| R10.6 | Fine-tuning | Tenant-specific model registry and rollback | ⬜ To be filed |
| R10.7 | Fine-tuning | Fine-tuning audit and cost reporting | ⬜ To be filed |
| R10.8 | Harness evolution | Auto harness evolution loop gated by F12 manifest predictions | ⬜ #686 |

## R18 Voice Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R18.1 | Voice | Outbound HTTP call plumbing | ✅ Done |
| R18.2 | Voice | Agent-facing outbound-call tool or skill | ⬜ To be filed |
| R18.3 | Voice | Call-flow primitive | ⬜ To be filed |
| R18.4 | Audit | Transcript-to-audit-log wiring | ⬜ To be filed |
| R18.7 | Voice | SIP outbound support for operators with PBX/SIP trunks | ⬜ To be filed |

## R29 Board Work

Use these as issue titles. Keep each issue small enough to ship independently. Prior-art notes from [paperclip.ing](https://paperclip.ing) and an adjacent lightweight-governance BYO-CLI board are annotated where relevant — the *primitives* transfer even though HybridClaw doesn't adopt the lightweight-governance positioning.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R29.1 | Card | **Goal / parent breadcrumb on every card** — render the parent-task → parent-goal → top-level objective chain on each row so a 50-card board is scannable by *why*, not just *what*. Pulls from the **R40** `/goal` primitive when present and falls back to the card's `parent` edge otherwise. Long chains collapse to *first › … › current* with a hover-expand. | ⬜ To be filed |
| R29.2 | Card | **Per-agent budget chip** — `used / cap` (e.g. `$3.40 / $60`) on every card whose owning agent has a budget configured. Neutral up to 80%, soft-warn color at 80%, hard color at 100%. Reads the existing **R5** metering substrate (`monthlySpendUsd` / `monthlySpendEur` at [`src/memory/db.ts:3811`](../../../src/memory/db.ts)); no new metering work. Soft-warn fires an F2 event for downstream subscribers; hard cap composes with **R5.3** hard-stop enforcement once that lands. | ✅ [#1023](https://github.com/HybridAIOne/hybridclaw/issues/1023) via PR #1027 (`src/board/budget-chip.ts`, `console/src/components/agent-budget-chip.tsx`) |
| R29.3 | Detail | **Job-detail tabs: Thread · Trace · Approvals** — split the per-card detail surface into three tabs reading the same underlying card. *Thread* is the operator-readable conversation. *Trace* is the F2 tool-call timeline (filterable, links into **R10.1** trajectories and **F11** trace-judge artifacts). *Approvals* is the **F14** escalation history for this card (pending + resolved, with channel + operator + outcome). Cheap UX win versus picking one view; lets humans skim the chat while debuggers dive into the trace. | ⬜ To be filed |
| R29.4 | Detail | **Next-heartbeat indicator on long-running jobs** — render a calendar-style *"next event at HH:MM"* (or *"in 4h 12m"*) on cards owned by agents with a heartbeat schedule, sourced from the heartbeat / scheduler channel. Tooltip shows the cadence (`every 4h`) and the last fire. Helps operators distinguish *idle* from *waiting on its next wake* on persistent-agent cards. | ⬜ To be filed |
| R29.5 | Claim | **Auxiliary-LLM triage before claim** — pre-claim hook runs a cheap-model triage on each card to flag under-specification (missing acceptance criteria, ambiguous scope, dangling dependencies); either auto-fleshes the card via a "specify" pass or parks it for operator clarification before any agent picks it up. Reuses **F11.4** subscriber pattern + **F11** trace-judge for the triage call. Prevents agents from claiming cards they can't complete and from burning budget on under-specified work. Composes with **R40** `/goal` (a goal that produces a card runs through the same triage). | ⬜ To be filed |
| R29.6 | API | **Issue-shaped public API + `@agent` mention spawns a card** — expose the board's card store behind an issue-shaped REST/GraphQL surface (create / assign / comment / close, plus subscribe via **F2**) so external tools and humans can drop work onto an agent the same way they'd assign a GitHub Issue. Mention syntax: a comment that names `@<agent-slug>` on an existing card spawns a new card with the comment thread attached as context, assigns it to the addressed agent, and links it back via the **R29.7** `related` edge. Resolves slugs through the **F7** identity registry; ambiguous mentions fail loud per the **R49** addressing rules. Reuses **R1** envelope `to` field as the routing primitive (a mention is just an envelope from a human actor to an agent actor, see **F7.5**). **Prior art:** the `@agent`-in-comment → new-card UX pattern from BYO-CLI agent boards. Added 2026-05-09. | ⬜ To be filed |
| R29.7 | Schema | **Issue-dependency edges (`blocks` / `blocked_by` / `related`)** — three typed edges between cards, surfaced as chips on the card and as a topology view at the column level. *blocked_by* drives an automatic "Blocked" status pill (already in the **R29** spec) and gates auto-merge in `In Review`; *blocks* is the inverse; *related* is non-gating context (sibling work, prior art, mention-spawn link from **R29.6**). Schema follows GitHub's issue-relationship model — no novelty here, just the absence in our spec. Composes with **F2** (every edge mutation is an event), **R10.1** trajectories (the dependency graph at run-time is captured), **F12** Change Manifest (a fix that closes a `blocks` edge is a falsifiable contract). **Prior art:** typed issue-dependency table (`blocks` / `blocked_by` / `related`) as seen in GitHub Issues and BYO-CLI agent boards. Added 2026-05-09. | ⬜ [#914](https://github.com/HybridAIOne/hybridclaw/issues/914) |
| R29.8 | Schema | **Board card data model + persistence + F4 versioning** — typed card schema (id, title, body, owner, column, status, source, parent, timestamps), SQLite migration, mutation API (`createCard` / `getCard` / `listCards` / `updateCard`), F4 versioning, and F2 event emission. Foundation row every other R29 child reads or writes. Pure data layer; admin UI (R29.11) and F2 subscription bridge (R29.10) ship separately. | ✅ #913 via PR #932 |

## R30 Browser Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R30.1 | Browser substrate | `BrowserProvider` interface and action vocabulary | ✅ #749 via PR #761 |
| R30.2 | Local provider | Local Playwright provider using persistent browser context | ✅ #750 via PR #783 |
| R30.3 | Managed provider | Managed-cloud browser provider with shared navigation guard | ✅ [#1024](https://github.com/HybridAIOne/hybridclaw/issues/1024) |
| R30.4 | Passthrough provider | Browser-use cloud passthrough with metering and audit URLs | ✅ #752 via PR #792 |
| R30.5 | Sessions | Browser profile persistence and container mount integration | ⬜ To be filed |
| R30.6 | Credentials | F13 keystroke-injection wiring for browser fills | ✅ #754 via PR #902 |
| R30.7 | Escalation | F14 2FA handover for browser sessions | ⬜ [#755](https://github.com/HybridAIOne/hybridclaw/issues/755) |
| R30.8 | Policy | Per-host and per-selector browser policy checks | ⬜ To be filed |
| R30.9 | Audit | Browser session event and screenshot audit trail | ⬜ To be filed |
| R30.10 | Evals | Browser automation eval gate and install-mode promotion checks | ⬜ To be filed |

## R35 Council Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R35.1 | Runtime | Council fan-out, critique, and synthesis primitive | ⬜ To be filed |
| R35.2 | Policy | F8-gated activation with R5 budget accounting | ⬜ To be filed |
| R35.3 | Judge | Council-as-judge subscriber for borderline classifier decisions | ⬜ To be filed |
| R35.4 | Admin | R29 board surface for model disagreement | ⬜ To be filed |
| R35.5 | Export | R17 portfolio export of council model configuration | ⬜ To be filed |
| R35.6 | Evals | Council-vs-single-model eval suite | ⬜ To be filed |

## R40 Goal Primitive Work

Use these as issue titles. Keep each issue small enough to ship independently. **R40 sits between** `/ralph` (bounded re-feed at [`src/command-registry.ts:98`](../../../src/command-registry.ts), iteration counter at [`src/agent/executor-types.ts:33`](../../../src/agent/executor-types.ts), no judge) **and** `/fullauto` ([`src/gateway/fullauto.ts`](../../../src/gateway/fullauto.ts) + [`src/gateway/fullauto-runtime.ts`](../../../src/gateway/fullauto-runtime.ts), heavyweight workspace + watchdog + per-session cost cap). `/goal` is the cheap middle: one line of operator intent + a per-thread counter + an F11-judged termination, with no system-prompt mutation, no learnings file, no source-flag flip.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R40.1 | State | `thread_goals` table + migration in [`src/memory/db.ts`](../../../src/memory/db.ts) — columns: `thread_id`, `goal_text`, `status` (`active`/`paused`/`done`/`cleared`), `turns_used`, `max_turns` (default 20), `created_at`, `last_turn_at`, `last_verdict`, `last_reason`, `paused_reason`, `consecutive_parse_failures`, `setter_actor` (F7.5 polymorphic Actor), `target_agent_id` (R49 addressing). **Per-thread, not per-session**, since HybridClaw threads cross channels under R49. | ✅ #1004 |
| R40.2 | Module | New `src/goals/` (`goal-manager.ts`, `goal-judge.ts`, `goal-command.ts`) — **not** under `gateway/` like fullauto. Goals are a thread-level primitive, not a gateway-mode flip. | ✅ #1004 |
| R40.3 | Judge | `goal_judge` auxiliary task registered via the **F11** subscriber framework ([`src/evals/judge-subscriber.ts`](../../../src/evals/judge-subscriber.ts) `registerJudgeSubscriber` at line 91). Reuses F11 dispatch, fail-open semantics, windowed/redacted trace prep. Verdict contract `{"done": bool, "reason": string}`, conservative bias (rare false positives), `temperature: 0`, bounded output. | ✅ #1004 |
| R40.4 | Slash | `/goal` registered in `REGISTERED_TEXT_COMMAND_NAMES` at [`src/command-registry.ts`](../../../src/command-registry.ts). Subcommands: `set` (default) / `status` / `pause` / `resume` / `clear`. Handler at [`src/goals/goal-command.ts`](../../../src/goals/goal-command.ts). On `set`, enqueue the goal text as the first user prompt so the operator doesn't have to send it twice. | ✅ #1004 |
| R40.5 | Loop | `post_turn` subscriber in `src/agent/` (peer of executor lifecycle). After every turn: **(1)** real user messages preempt and pause; **(2)** pending approvals pause without continuing; **(3)** gateway errors and user interrupts pause; **(4)** otherwise call `goal_judge` → set `done`/`paused`/`active` → enqueue continuation. | ✅ #1004 |
| R40.6 | Continuation | Continuation prompt is a **plain user-role message** (no system-prompt mutation, no tool-set swap — **A9** prefix-cache invariant). Body starts `[Continuing toward your standing goal]`, includes the goal and latest judge reason when present, and is tagged `source: 'goal-continuation'` for audit/proactive display only. | ✅ #1004 |
| R40.7 | Backstop | Consecutive-parse-failures auto-pause (3-in-a-row threshold) for cases where the judge model emits prose instead of strict JSON — without it the 20-turn budget burns on judge-returned-empty. | ✅ #1004 |
| R40.8 | Policy | **F8 stakes invariant**: continuation turns route through [`container/src/approval-policy.ts`](../../../container/src/approval-policy.ts) like any other turn. The goal primitive **does not elevate autonomy**; high-stakes tool calls inside a goal turn escalate normally and the escalation pauses the loop until the operator resolves it. | ✅ #1004 |
| R40.9 | Audit | F2 events `goal.set` / `goal.continued` / `goal.paused` / `goal.completed` / `goal.cleared` carrying `thread_id`, `setter_actor`, `target_agent_id`, `turns_used`/`max_turns`. Feeds the hash-chain audit log (Principle VII). | ✅ #1004 |
| R40.10 | Budget | **R5** integration: continuations consume usage like ordinary turns, and the R5.3 hard-stop hook exists to pause active goals with `paused_reason: "agent budget hard-stop"` once the hard-stop emitter ships. Remaining: wire the future R5.3 signal into the hook. | 🟡 hook shipped via #1004; R5.3 emitter open |
| R40.11 | Surface | Goal continuation output flows through the existing proactive-message rail with `goal-continuation` source tagging, so TUI/web/channel surfaces can distinguish goal-driven output from reminders and ordinary user turns. | ✅ #1004 |
| R40.12 | Board | **R29.1** parent-goal breadcrumb: a `/goal`-initiated card carries the goal as `parent_goal` so the breadcrumb renders the chain. **R44** milestone fires on `goal.completed`. | ⬜ To be filed |
| R40.13 | Sibling | **Steering primitive** (transient mid-loop nudge — distinct from `/goal` persistent intent): `/steer "<text>"` injects a one-turn-only message into the next turn header without rewriting the goal or restarting. Shares the same per-thread state hook. File once R40.1–R40.6 land. | ⬜ To be filed |
| R40.14 | Docs | Operator-facing docs covering `set`/`status`/`pause`/`resume`/`clear`, the F8 escalation invariant, the 20-turn default budget, and the user-preemption rule. | ✅ #1004 (`docs/content/reference/commands.md`) |

## R41 Autopilot Work

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| R41.1 | Curator | Background skill-maintenance loop (consolidate / prune / reclassify) — first Autopilot consumer | ⬜ To be filed |
| R41.2 | Primitive | Autopilot rule schema — trigger (`cron` / `webhook`), target agent, card template, concurrency policy (`skip` / `queue` / `replace`) | ⬜ To be filed |
| R41.3 | Runtime | Cron + webhook dispatch → spawn **R29** card with `source: autopilot/<rule-id>` edge → assign to target agent | ⬜ To be filed |
| R41.4 | Concurrency | Concurrency-policy enforcement (skip-when-running, FIFO-queue with capped depth, replace-via-warm-restart) | ⬜ To be filed |
| R41.5 | Policy | **R5** budget-cap + **F8** stakes-gate integration so Autopilot rules cannot bypass per-agent caps or autonomy limits | ⬜ To be filed |
| R41.6 | Audit | F2 events `autopilot.fired` / `autopilot.skipped` / `autopilot.replaced` / `autopilot.queued` feeding the hash-chain audit log | ⬜ To be filed |
| R41.7 | Admin | `/admin/autopilot` rule editor + per-rule run history (every fire is a card, every skip / queue / replace is an audit event) | ⬜ To be filed |

---

## Foundations

Cross-cutting work that several roadmap items depend on. Decomposed under the `foundation` label rather than belonging to any single feature.

- ✅ **F1** — Extend `AgentConfig` with `owner` / `role` / `cv` fields and persistence. `owner` is a typed reference to a canonical user (see F7). Required by #1, #3, #5, #11, #21.
- ✅ **F2** — Unified skill-run event bus (streaming, not post-hoc). Required by #3, #5, #6, #10, #16, F8. **Hook vocabulary** is enumerated in `PluginHookName` at [`src/plugins/plugin-types.ts`](../../../src/plugins/plugin-types.ts) — 14 named hooks cover session / prompt / agent / tool / compaction / memory / gateway lifecycle. **Three additions pending** for the approval-cascade and dispatch surfaces (driven by **F8.9** and the **R29** board's per-card live counters): `before_approval_request`, `after_approval_response`, `gateway_inbound_dispatch`. Lock the wire shape before R6 / R8 / R10a / R29 subscribers diverge.
- ✅ **F3** — Generalize the network-only policy engine into a "predicate → action" engine. Used by #4, #5, #6, #8, #14, F8.
- ✅ **F4** — Versioning + rollback for skills, knowledge, CVs, and classifier weights. Extends `runtime-config-revisions`. Required by Principle VII.
- 🟡 **F5** — Model pricing & capability matrix on top of `model-catalog`. Base catalog ✅ shipped (required by #5 cost compute and routing). **F5.1 (added 2026-05-13)**: extend the per-model entry in [`src/providers/model-metadata.ts`](../../../src/providers/model-metadata.ts) with an optional `model_overlay` field — `{ tool_discipline: string; completion_contract: string; execution_policy: string; narrate_only_retry: boolean }` — and a matcher predicate so a single overlay can claim a family (`isGpt5ModelId()`-style: matches `gpt-5`, `gpt-5-codex`, `gpt-5.1`, `gpt-5.1-codex-max`, …). Land this as the precursor to **row 60** so the schema is settled before any overlay text or applier code is written; otherwise two call sites will diverge on shape. No applier wired yet — F5.1 is just the field + matcher + a registry pass that returns `undefined` overlay for every model still. Required by row 60 and **R10a** harness evolution (overlay edits need a stable schema to record as F12 manifest entries against).
- ✅ **F6** [#576](https://github.com/HybridAIOne/hybridclaw/issues/576) — Deployment-mode + public-URL abstraction is complete for the cloud/local/tunnel foundation scope. Follow-up provider and admin-configuration extensions remain tracked as separate F6 rows below.
- 🟡 **F7** — Global identity primitives. Agent-ID format, canonical user IDs, and local instance-ID allocation are in production ([`src/identity/agent-id.ts`](../../../src/identity/agent-id.ts), [`src/identity/user-id.ts`](../../../src/identity/user-id.ts), and F7.1 ✅ via PR #776); cross-instance resolver and TOFU trust remain. See **Foundation Sub-Issues** below for F7 rows.
- 🟡 **F8** — Autonomy + escalation policy framework. Stakes classification and escalation routing are substantially shipped; policy-pipeline work remains. See **Foundation Sub-Issues** below for F8 rows.
- 🟡 **F9** — Always-on runtime guarantees. Warm process pool and liveness probes are done; restart and fleet visibility remain. See **Foundation Sub-Issues** below for F9 rows.
- 🟡 **F10** — Agent org-chart / team primitive. Schema, persistence, and resolution helpers are done; admin editing remains. See **Foundation Sub-Issues** below for F10 rows.
- 🟡 **F11** — Aux-LLM trace-judge framework. Judge dispatch, trace preparation, and subscriber distribution are done; eval-the-judge remains. See **Foundation Sub-Issues** below for F11 rows.
- ⬜ **F12** [#685](https://github.com/HybridAIOne/hybridclaw/issues/685) — **Change Manifest (AHE-style falsifiable contracts).** Typed metadata on every editable-surface change (system prompt · skill · tool · middleware · sub-agent · config · long-term memory) recording: failure evidence (task IDs + patterns), inferred root cause, targeted fix, predicted impact (`expected_fixes`, `at_risk_regressions`), evidence pointer. Verified by the next eval run; rollback at file granularity; predicted-vs-observed deltas drive an attribution score (paper [§3.3, Algorithm 1, §4.4.2](https://arxiv.org/html/2604.25850v1): 33.7%/51.4% precision/recall on fixes, ~5× random; regression precision/recall 11.8%/11.1% — known blindness, design for it). Composes with F4 versioning + F2 event bus + F11 trace-judge + R3 scoreboard. Substrate for **R10a auto-harness-evolution**. **Evidence-pointer shape (added 2026-05-09):** every manifest record carries `app_name`, `build_sha`, and a remote-provenance triple (origin instance ID + thread ID + run ID) so the pointer remains resolvable across restarts, instances, and tenant exports. Aligns the F12 evidence shape with the **R10.1** trajectory store and R23 backup envelopes — one provenance schema across all three. Anchored in [Lin et al., AHE, 2026-04-28](https://arxiv.org/html/2604.25850v1).
- ✅ **F13** [#698](https://github.com/HybridAIOne/hybridclaw/issues/698) — **Non-LLM credential injection rail** (closed 2026-05-01 via [PR #728](https://github.com/HybridAIOne/hybridclaw/pull/728)). Extends the existing `SecretRef` system ([`src/security/secret-refs.ts`](../../../src/security/secret-refs.ts), [`runtime-secrets.ts`](../../../src/security/runtime-secrets.ts)) — *not a new vault, the store already exists*. F13 adds: (a) a keystroke-layer injection API that resolves a `SecretRef` and types into a Playwright element handle (or equivalent) **without ever returning the cleartext as a string in agent-tool-result scope** — opaque handle in, keystrokes out; (b) per-skill / per-host / per-selector ACL via **F3** (skill `invoice-harvester` may resolve `cred:datev/*` only when typing into `*.datev.de`); (c) audit events on every resolve (skill, selector, host) feeding the hash-chain log; (d) type discipline / lints to prevent accidental string-coercion (`String(ref)`, template interpolation, JSON-stringify) inside skill code. **Orthogonal to R4**: R4 owns text-flow placeholders (NDA / client / price strings traversing prompts); F13 owns DOM-flow injection (credentials never traverse the prompt at all). Composes with **F3** (policy) + **F12** (manifest records cred-binding edits) + **R6** (post-hoc leak scan as defense-in-depth). Required by **R30** (browser channel) + **R21.7–R21.10** (Hetzner / SAP / DATEV / Lexware) + **R21.11–R21.16** (DACH compliance bundle). *Principle VII.* Added 2026-04-30. **Follow-up (added 2026-05-09): token-class prefixes for user vs daemon authority.** Separate prefixes for operator-issued tokens (`hc_pat_…`, equivalent to a personal access token) and daemon-issued tokens (`hc_daemon_…`, scoped per `(workspace, daemon-id)`). Prefix-marked at issuance, validated at the gateway, recorded on every audit event. Two-line audit clarity: a `hc_daemon_…` token can never be silently swapped for a `hc_pat_…`-scoped action, and forensic searches on a leak immediately classify the credential class. Composes with **F8.7** (signed remote-policy authority — daemon tokens cannot author policy) and **R51** daemon mode (the daemon issuance path). **Prior art:** prefix-marked token classes splitting operator-PAT from daemon-issued tokens, as used by BYO-CLI agent daemons.
- ✅ **F14** [#699](https://github.com/HybridAIOne/hybridclaw/issues/699) — **Interactive escalation / 2FA handover primitive** (closed 2026-05-01 via [PR #729](https://github.com/HybridAIOne/hybridclaw/pull/729)). Durable pause-and-resume for any agent step that needs a human in the loop — canonical case is 2FA challenges (TOTP code, push approval, QR scan, SMS code). **Reuses existing approval-prompt wire format** at [`src/gateway/pending-approvals.ts:18-30`](../../../src/gateway/pending-approvals.ts) (`PendingApprovalPrompt` + `APPROVAL_PROMPT_DEFAULT_TTL_MS`) — but the current 120s in-memory TTL is unfit for 2FA handover; F14 needs **F4-backed durable park** with extended TTL. F8 escalation routing already emits `escalationRoute` + `escalationTarget`. The runtime: *(i)* detects the challenge (skill-declared waypoint or selector heuristic + LLM "I'm stuck on a 2FA page" signal), *(ii)* parks the session (Playwright frame state + screenshot + URL persisted via F4), *(iii)* emits `escalation.interaction_needed` on the F2 event bus with context + modality hint (`totp` · `push` · `qr` · `sms` · `recovery_code`), *(iv)* routes to the operator via **F8** + **F10** — push notification, SMS (R24), WhatsApp ([R36 #734](https://github.com/HybridAIOne/hybridclaw/issues/734)), Discord ([R37 #735](https://github.com/HybridAIOne/hybridclaw/issues/735)), email, mobile admin (R12), Telegram, *(v)* accepts the operator response via a typed return channel (`{kind: 'code', value: '123456'}` · `{kind: 'approved'}` · `{kind: 'scanned'}`), *(vi)* resumes the session — TOTP/SMS codes go in via **F13** so cleartext never reaches the LLM. **Design rule: never auto-fill 2FA, even when the second factor is technically resolvable as a `SecretRef`.** Reasons: (a) Principle VII audit story is cleaner with operator-in-loop; (b) push / QR / hardware-key can't be auto-filled anyway; (c) auto-filling TOTP defeats the spirit of 2FA. Generalizes beyond browser — any tool needing human-in-loop mid-execution (sensitive write to CRM, contract send, wire transfer) uses the same pause-and-resume primitive. Composes with **F8** + **F10** + **R12** mobile admin + **R24** SMS + **R29** board (paused sessions surface as `blocked: needs 2FA` cards). Required by **R30** (every enterprise SaaS login is 2FA-gated) + every R21.x skill that fronts a SaaS portal. *Principles II + V + VII.* Added 2026-04-30.
- ⬜ **F15 — Plugin-loadable channel registry.** Today [`src/channels/channel-registry.ts`](../../../src/channels/channel-registry.ts) is a hardcoded `Record<ChannelKind, ChannelInfo['capabilities']>` over the in-repo channels (`discord`, `email`, `imessage`, `msteams`, `signal`, `slack`, `telegram`, `threema`, `voice`, `whatsapp`, plus internal `tui` / `heartbeat` / `scheduler`). F15 makes the registry plugin-loadable so a plugin under [`src/plugins/`](../../../src/plugins/) can register a channel without touching core — declares setup wizard, send / receive hooks, slash-command surface, webhook delivery, prompt adapter. Bundled platforms ship as plugins themselves so the seam is exercised. **Pre-req for R39** (Matrix) and any future channel additions beyond scoped in-repo exceptions like R46; without it, every new channel is a `src/channels/` rewrite. Composes with the existing `PluginManager` + [`src/plugins/plugin-install.ts`](../../../src/plugins/plugin-install.ts) infra. **Scope expansion (added 2026-05-09):** the seam should also cover **model providers** (the gateway's hardcoded provider switch) and **MCP/tool registrations** so "everything ships as a plugin" is the durable shape, not just channels. Migrating the existing bundled-platform set in-place is more tractable than a re-platforming — each provider/channel becomes a plugin shipped from this repo, exercising the install rail end-to-end. *Principle V.* Added 2026-05-02.
- ⬜ **F16 — Plugin install from URL + signed manifest verification.** Extends the existing [`src/plugins/plugin-install.ts`](../../../src/plugins/plugin-install.ts) infrastructure (already does dependency planning + binary checks) with: (a) install from a direct HTTP(S) URL pointing at a `hybridclaw.plugin.yaml`, (b) signed-manifest verification (publisher key, content hash, version pin), (c) sig-mismatch refuses install. Required for the **F15** plugin model to flex outside the bundled set — without URL install, plugins can only ship via the vendored repo. Composes with **F4** versioning + **R23** backup (rollback on bad install) + **F15** registry (plugin-shipped channels install through this rail). *Principle VII.* Added 2026-05-02.
- ⬜ **F17** [#785](https://github.com/HybridAIOne/hybridclaw/issues/785) — **Generalized `managed_by_*` policy convention.** Reusable primitive that lets connector-setup commands (HTTP secret route, MCP add, skill install, channel register, provider connect) auto-write a narrowly-scoped F3 policy rule under a managed namespace and clean it up on disconnect. Pioneered ad-hoc by [PR #784](https://github.com/HybridAIOne/hybridclaw/pull/784) for HTTP secret routes (`src/policy/secret-route-policy.ts` writes a `secret_resolve_allowed` rule scoped to host + header + secret + agent, marked `managed_by_secret_route: true`); F17 extracts the read-modify-write helper into a shared module so every connector type follows the same convention without re-implementing rule placement, idempotency, removal, and audit emission. **Trust boundary held**: managed rules stay narrow (no wildcards), deny-by-default still applies, user-authored rules are never overwritten. **Audit primitive**: every managed-rule mutation emits `policy.managed_rule_added` / `policy.managed_rule_removed` so operators can see which connector wrote which grant. **Required by R45** consumer wiring (#786 MCP, #787 skill, #788 channel) and by **R42**'s inline credential paste flow. Composes with **F3** policy engine + **F13** credential rail + **R23** backup (managed rules round-trip through restore). *Principles VII + X.* Added 2026-05-02.

## Foundation Sub-Issues

Use these as issue titles. Keep each issue small enough to ship independently.

| ID | Area | Todo | Status |
|----|------|------|--------|
| F6.1 | Public URL | Deployment-mode config schema | ✅ Done |
| F6.2 | Public URL | `TunnelProvider` interface and ngrok reference implementation | ✅ Done |
| F6.3 | Public URL | Tunnel health check and auto-reconnect with capped-backoff jitter | ✅ Done |
| F6.4 | Public URL | Admin surface for public URL, tunnel status, and manual reconnect | ✅ Done |
| F6.5 | Public URL | Deployment-mode and public-URL docs | ✅ #570 |
| F6.6 | Public URL | Tailscale Funnel provider | ✅ #644 |
| F6.7 | Public URL | Cloudflare Tunnel provider | ✅ #645 via PR #794 |
| F6.8 | Public URL | Admin UI for tunnel provider configuration | ⬜ #681 |
| F7.1 | Identity | Canonical user IDs | ✅ #571 via PR #776 |
| F7.2 | Identity | Instance-ID allocation | ✅ #572 via PR #796 |
| F7.3 | Identity | Cross-instance identity resolver | ✅ #573 via PR #882 |
| F7.4 | Identity | TOFU trust ledger for peer instances | ✅ #574 via PR #898 |
| F7.5 | Identity | **Polymorphic `Actor` type unifying user + agent on the F2 event stream** — collapse `userId` and `agentId` into one `Actor { type: 'user' \| 'agent', id }` shape so every F2 audit event, **R29** card-mutation log, **R3** scoreboard entry, and **R20** GDPR query reads from one identity surface. Reuses **F7.1** canonical user IDs and the existing agent-id format ([`src/identity/agent-id.ts`](../../../src/identity/agent-id.ts)) — no new ID space, just a tagged-union wrapper. Composes with **R29.6** issue API (a mention is an `Actor → Actor` envelope), **F2** event schema (one `actor` field replaces the user/agent split), **R20** GDPR (one cascading-data-discovery query per Actor). **Prior art:** polymorphic `actor_type + actor_id` activity-log shape used by BYO-CLI agent boards to unify human and agent identities. Added 2026-05-09. | ⬜ To be filed |
| F8.1 | Policy | Autonomy levels | ✅ Done |
| F8.2 | Policy | Stakes classifier | ✅ Done |
| F8.3 | Policy | Escalation routing | ✅ Done |
| F8.4 | Policy | Runtime default-action config knob | 🟡 Substantially shipped via #608 and #641 |
| F8.5 | Audit | Dedicated autonomy/escalation audit-event type | ⬜ To be filed |
| F8.6 | Policy | Hook-fed approval rule pipeline | ✅ #731 via PR #800 |
| F8.6.1 | Policy | Hardline blocklist pre-step for unrecoverable commands | ⬜ To be filed |
| F8.7 | Policy | Signed remote policy authority over R1 federation | ✅ #732 via PR #886 |
| F8.8 | Policy | Behavioral anomaly reranker over tool-call sequences | ✅ #733 via PR #905 |
| F8.9 | Policy | External approval-loop hooks for tenant-side risk signals | ⬜ To be filed |
| F9.1 | Runtime | Warm process pool and cold-start budget | ✅ #590 |
| F9.2 | Runtime | Per-coworker liveness probe — **constants (added 2026-05-09): poll every 3s, heartbeat every 15s, mark offline at 45s** (3× heartbeat). Defaults match the BYO-CLI agent-daemon convention; encode as named constants so **R29.4** next-heartbeat indicator and **R9.7** zombie-detection consume one source of truth. | ✅ #591 via PR #694 |
| F9.3 | Runtime | Auto-restart with backoff — reuses the F9.2 offline-at-45s threshold as the restart trigger; backoff schedule capped to align with **R23** warm-restart durability (no restart attempt during a checkpointed mid-turn resume). | ⬜ #592 |
| F9.4 | Runtime | Fleet red/green dashboard | ⬜ #593 |
| F10.1 | Org chart | Team schema and tree validation | ✅ Done |
| F10.2 | Org chart | Persisted team structures via F4 | ✅ #595 |
| F10.3 | Org chart | Resolution helpers for managers, peers, and escalation chains | ✅ #596 |
| F10.4 | Org chart | Admin UI to view and edit org chart | ⬜ #597 |
| F11.1 | Judge | Judge interface and cheap-model dispatch | ✅ Done |
| F11.2 | Judge | Windowed and redacted trace preparation | ✅ #621 |
| F11.3 | Judge | Eval-the-judge suite | ✅ #622 via PR #904 |
| F11.4 | Judge | Subscriber pattern with progressive trace-debugger artifacts | ✅ #623 via PR #901 |

## Cross-Cutting Work

Engineering hygiene that ships alongside P0:

- ⬜ **A1** — End-to-end smoke scenario exercising #1 + #2 + #3 + #4 + #5 + #6 in one run.
- ✅ **A2** — `CHANGELOG.md` with manifesto-principle tags per entry.
- ✅ **A3** — Test-fixtures library (agents, clients, threads, secrets).
- ⬜ **A4** — CI cost-regression gate against the eval suite.
- ⬜ **A5** — Threat-model document for any feature touching secrets or keys.
- ⬜ **A7** — Per-PR docs / help parity check. CI step that diffs the set of slash commands, CLI subcommands, skill commands, and channel-config knobs against the rendered docs surface (`/help`, `docs/content/`, the `/commands` UI). Fails the PR when a new command/option lands without a docs entry, and when a command is removed without removing its doc. Doc drift is already a problem on the `/commands` surface; this is the cheapest CI guardrail that prevents it. Added 2026-05-09.
- ⬜ **A6** [#701](https://github.com/HybridAIOne/hybridclaw/issues/701) — Browser-agent eval suite via [browser-use/benchmark](https://github.com/browser-use/benchmark): **BU Bench V1** (100 tasks aggregating WebBench + Mind2Web 2 + GAIA + BrowseComp + custom, encrypted to prevent training contamination) for skill scoring across Opus / Sonnet / Haiku, and **Stealth Bench V1** (71 tasks across hosted-browser providers — `browserbase`, `browserless`, `hyperbrowser`, `anchor`, `onkernel`, `steel`, `local_headful`, `local_headless`) as a vendor-selection scorecard for the **R30** cloud install mode. Two run modes: *(i) substrate eval* — score browser-use as-is against our chosen install mode and model, gating R30 install-mode promotion in CI; *(ii) harness adapter* — wrap the HybridClaw agent loop to consume the same encrypted task JSON, feeding **R10.1** trajectory collection so **R10a** harness evolution targets browser skills (the Web-Bench analogue to AHE's Terminal-Bench, [paper §4.1](https://arxiv.org/html/2604.25850v1)). Feeds **F5** capability matrix with browser-skill scores per model. *Caveat:* the benchmark repo currently has no `LICENSE` file (constituent task sources are MIT except GAIA which is encrypted-only) — pin as submodule rather than vendor pending clarification with browser-use. Added 2026-04-30.
- ⬜ **A8** — Generic bot-to-bot loop protection in the channel-turn kernel. Every channel runtime that accepts bot-authored inbound (any future `allowBots` path) must map its inbound event into a uniform participant fact set — `{account_or_scope, conversation_id, sender_bot_id, receiver_bot_id}` — and core tracks the pair in both directions with a sliding-window budget + cooldown. **Defaults**: `maxEventsPerWindow: 20`, `windowSeconds: 60`, `cooldownSeconds: 60`; suppress the pair for the cooldown after the budget is exceeded. **Configuration precedence (highest → lowest)**: per-conversation override (`channels.<channel>.<room>.botLoopProtection`) → per-account override (`channels.<channel>.accounts.<account>.botLoopProtection`) → channel default (`channels.<channel>.botLoopProtection`) → shared default (`channels.defaults.botLoopProtection`) → built-in. `enabled: false` only for channels whose policy intentionally allows unbounded bot-to-bot exchange. **Opt-in rule**: a channel may only enable the guard once it can reliably identify *both* participants of the bot pair from its inbound surface (e.g., Slack `bot_id`, Discord `author.bot`, Matrix configured bot accounts, Google Chat `sender.type=BOT`); channels without that signal stay on their existing self-message + access-policy filters. **No effect** on human-authored messages, single-bot deployments, self-message filtering, or one-shot bot replies under the budget. Hygiene posture: this is a generic kernel guard living next to the message-tool dispatch path — not per-channel ad-hoc heuristics — so adding a new channel doesn't re-invent the defense. Composes with **F2** event bus (suppression decisions emit `channel.bot_loop_suppressed` for the operator dashboard + **R29** board), **F3** policy (per-account / per-conversation overrides expressible as policy), **F14** escalation (sustained suppression escalates to the operator for review). Pairs naturally with the slack-webhook (#990) and **R46** Threema rows — neither accepts bot-authored inbound today, but the kernel must exist before any channel flips `allowBots: true`. *Principles VII + VIII.* Added 2026-05-13.
- 🟡 **A9** — **System prompt is byte-static within a session (prefix-cache invariant).** Anthropic's prefix cache requires byte-stable system prompts to score a hit; any mutation between turns — wall-clock timestamps, rotating identity preambles, per-turn memory dumps, freshly-rendered tool catalogs, locale strings, randomized greeting variants — collapses the cache and pays full prompt cost every turn. The first implementation pass moved date, host, daily memory, session-summary, and retrieved-context data into the post-prefix dynamic context block and added stability/trace-export tests. Remaining work: lint rule and per-PR rendered-prompt diff. **Invariant**: the system block emitted by `buildSystemPromptFromHooks` (and any sibling builder) must be a pure function of *session-stable* inputs (agent identity, skill catalog at session-start, tool catalog, persistent policy text) — dynamic context (current date, fresh memory, retrieved snippets, turn counters, current goal state) belongs in a separate **user-role context block** appended *after* the cached prefix, not interleaved into the system prompt. **CI guardrail (remaining hygiene)**: lint against `new Date()` / `Date.now()` / `Math.random()` / `process.uptime()` / `os.hostname()` and similar non-stable sources inside any file under `src/agent/prompt-*` or any function transitively reachable from a system-prompt builder; add a per-PR check that diffs the rendered system prompt against `main` for a fixture session and surfaces changed bytes. **Why an A-row, not a feature row**: this is engineering hygiene every prompt-touching change must respect, not a one-shot feature; cost and latency consequences compound silently the longer it goes unguarded. Composes with **F11** trace-judge (cache-hit-rate becomes a measurable trajectory signal), **R10.1** trajectories (cache stats per turn captured), **R5** budget (cache hits are the cheapest way to keep turns inside the cap), **F12** Change Manifest (any system-prompt edit declares whether it preserves cache stability and what the expected hit-rate impact is). **Anti-pattern to avoid**: a one-off fix without the CI guard; the same shape grows back the next time someone adds "a small dynamic hint" to the system prompt. **Done criteria**: stability test + lint rule + per-PR diff all in CI; existing dynamic content relocated to the post-prefix dynamic-context block; docs note in `docs/content/developer-guide/` explaining the contract for future prompt-touching work. *Principles VIII + IX.* Added 2026-05-13. Updated 2026-05-14.

---

## How to read this

**P0 (#21 + #1–6)** is the launch package. Read it as the smallest set of features that makes the manifesto demonstrable end-to-end:

- **#21** implements Principle I — *the skills are the product*. Without shippable skills, everything else is a runtime, not a coworker.
- F8 + #2 implement Principle II — autonomy by default, escalate on stakes.
- F9 implements Principle III — always on, no warm-up.
- #3 + F10 implement Principle IV — colleague with a CV; org chart not flat list.
- #1 + #2 + F10 implement Principle VI — coworkers in teams.
- #4 + #6 + F4 implement Principle VII — trust + audit + reversibility.
- #5 implements Principle IX — thinks before spending.
- F1 + F2 + F3 are prerequisites for the above.

**P1 (#7–10, #12–14)** is depth work. Each item compounds with one or more P0 features:

- Shared memory (#7) and auto fine-tuning (#10) close the data flywheel — both feed back into the skill scoreboard (#3) and the leak classifier (#6).
- Hierarchical swarm (#9) extends the A2A primitive (#1) across host instances; depends on F6 + F7.
- Per-client reports (#13) and SSO/RBAC (#14) are operational table stakes once a fleet is in use.
- Mobile admin (#12) is the surface for Principle X on a phone.

**P2 (#11, #15–20)** is breadth. Each item is independently shippable but most depend on at least one P1 item:

- Operator notification windows (#11) was reframed away from "agent goes offline" semantics; demoted from P1 → P2.
- Handoff context transfer (#15) makes #1 + #2 feel finished.
- A/B testing (#16) compounds with #10.
- Voice (#18) and calendar (#19) are channel expansions on top of the existing channel layer.
- RTBF (#20) is the GDPR baseline; mostly implementation work on top of the audit log.


## Skill Boundaries

To keep roadmap execution aligned with **Principle I** and avoid accidental core bloat, apply this guardrail to every roadmap issue and PR:

- **Placement preference (hard order):** **Skill > Plugin > Gateway/Agent `src`**. Start in `skills/<name>/`; if reuse across skills/channels/operators is needed, promote to a plugin; touch gateway/container core only for unavoidable platform seams.
- **Gateway change admission test:** a core change is allowed only if at least one is true: (a) security boundary (F3/F8/F13/F14), (b) cross-skill/plugin primitive reused by 3+ surfaces, (c) transport/runtime substrate impossible to host in a skill or plugin.
- **Plugin promotion trigger:** when logic is tenant-portable and reused by multiple skills/channels, package it as a plugin (`src/plugins/` + install rail), not duplicated helpers across skills.
- **Plugin-first channel rule:** new channels ship as plugins once F15/F16 land; avoid direct `src/channels/*` expansion except for foundational substrate fixes.
- **Issue template addition (R21.x, R30, channel work):** add a required "Why not a skill-only change?" section plus a "core LOC budget" estimate to force explicit tradeoffs before implementation.
- **Review metric:** track per-issue `skill LOC : core LOC` ratio; target **>= 4:1** for feature work (exceptions documented for foundation issues like F2/F4/F7/F8).
- **Done criteria update:** every feature PR must show (1) skill entrypoint path, (2) core seam touched, (3) rationale for each non-skill file changed.

## Skill/Plugin Review

Review existing roadmap items with the new preference order (**Skill > Plugin > Gateway/Agent `src`**):

- **#18 Voice / outbound phone channel:** keep Twilio runtime substrate thin in core; implement call-flow orchestration + operator UX as a channel plugin and expose task-specific behaviors via skills.
- **#19 Calendar / meeting presence:** treat each meeting provider connector (Zoom/Meet) as plugin surfaces; keep summarization/action-item behavior in skills.
- **#24 SMS channel:** implement provider adapters as plugins (Twilio/Telekom/Vodafone), keeping only shared channel contracts in core.
- **#26 Fax gateway + outbound skill:** gateway stays transport seam; provider integrations should be plugin packages, while fax workflows remain in skills.
- **R36 / R37 / R39 / R46 / R61 channel expansions:** execute future expansion through F15/F16 plugin registry + signed install path, not direct core channel additions.
- **R21.x SaaS adapters (especially R21.17–R21.20, R21.12–R21.16):** default to skill-owned adapters; extract shared auth/session/tooling to plugins only when reused by multiple skills.

Operationally: any issue in the list above should add a "Skill-only? Plugin? Core?" decision note before implementation begins.

## Sequencing rules

- **Foundations first.** F1, F2, F3 unblock the majority of P0 children. F4 and F5 unblock specific items. F6 and F7 are critical-path the moment any cross-instance work or local-install demo is involved. F8, F9, F10 are needed as soon as the launch demo (A1) tries to honour Principles II / III / VI.
- **Skills early.** #21.1 (skill packaging framework) should land before any of #21.2-#21.6 (the five production skills). Without the framework each skill reinvents lifecycle + permissioning.
- **Skill body MUST live under `skills/<name>/` with colocated helpers.** No reach-back into `src/`. Skills are synced into `/workspace/skills/<name>` at agent runtime — `src/` paths are not accessible there ([`skills/hybridclaw-help/SKILL.md:98`](../../../skills/hybridclaw-help/SKILL.md) is the canonical statement). Reference precedent: [`skills/office/`](../../../skills/office/) (SKILL.md + `.cjs` helpers + `helpers/`). Anti-pattern caught and corrected during PR [#772](https://github.com/HybridAIOne/hybridclaw/pull/772) review (initial implementation put ~2,000 lines in `src/invoices/` with a thin pointer-only SKILL.md). Every R21.x issue body should pin this placement explicitly — at-risk issues to update: R21.17 [#722](https://github.com/HybridAIOne/hybridclaw/issues/722), R21.18 [#723](https://github.com/HybridAIOne/hybridclaw/issues/723), R21.19 [#724](https://github.com/HybridAIOne/hybridclaw/issues/724), R21.20 [#759](https://github.com/HybridAIOne/hybridclaw/issues/759), R21.12–R21.16 [#689–#693](https://github.com/HybridAIOne/hybridclaw/issues/689), and R32/R33 server-maintenance bundle.
- **A2A before workflow.** #1 must ship at least to 1.2 (send/receive runtime API) before #2.2 (sequential runner) becomes useful.
- **F7 before A2A federation + R9.** R1.6–R1.9 (#717–#720, A2A federation) and R9.1–R9.6 (#480–#484, #486, RPC delegation) both depend on F7.1–F7.4 (#571–#574) shipping first — canonical IDs, instance-id allocation, resolver, and TOFU trust are the substrate both tracks consume. Gate F7 children at P0 to keep both cross-instance tracks unblocked.
- **Two cross-instance tracks, one shared infra.** R9 (delegation, RPC) and R1.6–R1.9 (federation, messaging) are different features but share transport (#482), auth (#480 + #574), and audit (#483). Sequence the shared infra before either feature track tries to integrate.
- **R1.10 transport registry before any encoder.** R1.11–R1.15 ([#766](https://github.com/HybridAIOne/hybridclaw/issues/766), [#767](https://github.com/HybridAIOne/hybridclaw/issues/767), [#768](https://github.com/HybridAIOne/hybridclaw/issues/768), [#769](https://github.com/HybridAIOne/hybridclaw/issues/769), [#771](https://github.com/HybridAIOne/hybridclaw/issues/771)) all register against the R1.10 ([#765](https://github.com/HybridAIOne/hybridclaw/issues/765)) transport-adapter interface + peer-descriptor schema. Building any encoder against an ad-hoc shape means refactoring it the moment the second encoder lands. Land R1.10 as a tiny first PR (interface + default `internal` adapter wired into R1.6 routing), then A2A and webhook adapters become parallel tracks. R1.15 SSE streaming is a follow-up to R1.11 + R1.12 — don't pre-plan the SSE wiring inside the first A2A PRs.
- **Webhook outbound (R1.13) before A2A outbound (R1.11) for early integrations.** Webhook is dramatically simpler (POST + HMAC, no Agent Card discovery, no JSON-RPC server). Shipping R1.13 first unlocks Zapier / n8n / monitoring integrations on day one and exercises the R1.10 registry shape with a simple encoder before A2A's heavier surface lands. A2A outbound stays P0 (it's the rich path) but is not the path of first integration.
- **F8 alongside #2.** #2.3 (gating semantics) should not land before F8.4 (default-action runtime) — otherwise #2 hard-codes approval-by-default and has to be refactored.
- **Trajectory capture starts early.** 10.1 (trajectory collection) should land alongside F2, well before the rest of #10 — the data is the asset.
- **Leak classifier needs a dataset.** 6.1 (classifier dataset) gates 6.2 / 6.3; budget for labeling time.
- **Avoid net-new channels until P0 ships.** New channel work (#18, #19) is deferred to P2 even where infrastructure exists.
- **F12 before R10a.** The Change Manifest (F12) is a hard prereq for the harness-evolution loop (R10.8) — without falsifiable per-edit contracts the loop drifts and there is no rollback signal. Land F12 alongside F11.4 so the manifest can reference distilled evidence by file path.
- **R29 board reads F2, not the DB.** The kanban surface must subscribe to the skill-run event bus (F2) for live state, not poll. Otherwise the "running 4/6" footer lies under load.
- **R30 before R21.11.x / R21.15 / R21.16.** The scrape-path adapters in the DACH compliance skills (R21.11.x #778 invoice scrape adapters, Handelsregister, Schufa) cannot exit quarantine without the R30 browser substrate + F13 credential injection + F14 2FA handover. The **API-adapter half of R21.11 has shipped without R30** (PR #772, 2026-05-02 — Stripe/AWS/Azure/Google Ads are pure REST). Don't start the *scrape* skill bodies for these issues until R30(a) local install mode has landed.
- **F13 + F14 before R30.** ✅ Both prereqs now done (F13 #698 via PR #728, F14 #699 via PR #729 — 2026-05-01). R30 (#700) is unblocked and is the next critical-path foundation for the DACH compliance bundle (R21.11 invoice harvester, R21.15 Handelsregister, R21.16 Schufa). **R30 children R30.1–R30.10 should be filed as separate issues to enable parallel execution** — see *Next parallel work* below.
- **R31 before any new multi-agent skill design.** Before filing a new skill that decomposes work across multiple agents, the author must pick the R31 architecture (sub-agent vs agent-team) and justify the split against the *"split by context, not by role"* rule. Catches role-named pipelines (`Planner → Implementer → Tester`) before they ship and lose information at every handoff. R29 board provides the shared-task-list substrate for the agent-team path.
- **R32 before R33.** The local-execution maintenance skill (R32) defines the shell / systemd / log capability surface; R33 reuses that surface over SSH transport. Building R33 first means inventing a transport-coupled API that R32 then has to retrofit — wrong direction. Build R32 against a transport-agnostic skill interface, then R33 plugs SSH in.
- **F13 before R33.** R33's SSH-key handling depends on F13's keystroke-/stream-injection rail — without it, SSH private keys end up as strings in the LLM context the first time a host is touched. Acceptable to demo R32 alone before F13 lands (no remote credentials), but R33 should not start.
- **R9 + F5 before R34.** R34 is a thin policy + advertisement layer on top of R9 cross-instance delegation and F5 capability matrix. Don't build the routing logic until both substrates are stable.
- **F8.6 before F8.7 + F8.8.** Both extensions plug into the rule-pipeline shape that F8.6 introduces. Building them on the current monolithic `evaluateToolCall` ([`container/src/approval-policy.ts:1286-1498`](../../../container/src/approval-policy.ts)) means refactoring twice — once into a one-off branch, then again when F8.6 lands. Land F8.6 first, then F8.7 (remote policy) and F8.8 (anomaly reranker) become rule additions instead of function rewrites.
- **F7 + R1 federation before F8.7.** Signed remote policy updates need canonical agent / instance IDs (F7.1–F7.4 #571–#574) to verify the authority and the R1.6–R1.9 federation transport (#717–#720) to receive them. Building F8.7 before either substrate means inventing a one-off transport + auth shape that gets thrown away.
- **R10.1 trajectories before F8.8.** The Markov / frequency baseline trains on prior approved tool-call sequences. Without R10.1 trajectory storage there is nothing to fit. F8.8 cold-starts (abstain until N≥50 approved trajectories per agent) so it's safe to ship F8.8 against a still-warming trajectory store, but R10.1 must be live first.
- **R36 / R37 land independently.** Channel rows have no ordering constraint vs. F8.x or each other; they're additive registrations on F14's modality list. Either can ship alone if the other slips.
- **R35 needs F8 + F11.4 + R5 before production.** Council mode without the F8 stakes gate runs N× cost on every turn — disable until F8.4 default-action wiring is solid. R35.3 (council-as-judge) cannot land before F11.4 subscriber pattern. Per-tenant council-fired-per-day rate caps must consume R5 metering before any tenant outside dogfooding gets council enabled. **R35 ≠ R28**: R28 is failover (sequential), R35 is deliberation (parallel) — they share provider config but not the runtime path; do not collapse them.
- **F15 before R39 / any new channel.** F15 unhardcodes [`src/channels/channel-registry.ts`](../../../src/channels/channel-registry.ts). Adding **R39** Matrix (or any future channel) without F15 forces a core edit instead of a plugin install. R36 (WhatsApp), R37 (Discord), **R38** (MS Teams ✅), **R46** (Threema Basic outbound), and **R61** (Discord Incoming Webhook) all live as in-repo channels under the *current* hardcoded registry — treat R46 as a scoped exception already in flight, and route future channel expansion through F15/F16.
- **F2 vocabulary additions before F8.9.** F8.9 approval hooks are useless without (a) **F11.4** subscriber pattern to receive results and (b) the two missing hook names (`before_approval_request`, `after_approval_response`) registered in `PluginHookName`. Land the F2 vocabulary additions first, then F8.9 wires the cascade.
- **F8.6 step 0 hardline blocklist before F8.6 cascade refactor.** The blocklist is config-file-driven and orthogonal to the predicate pipeline; ship it as a pre-step so the cascade refactor doesn't have to also invent the blocklist semantics in the same PR. Step 0 also gives F8.7 (remote policy authority) something it explicitly cannot override — the trust boundary is clearer when the floor exists before delegation does.
- **R30.2 before R43.** R43 computer-use track reuses the same provider-interface shape as R30 (`launchPersistentContext`-style lifetime, F13 keystroke hook, navigation guard pattern). Building R43 first means inventing a provider abstraction R30 has to retrofit. Sequence R30.2 → R30.6 (F13 wiring) → R43 to avoid the rewrite.
- **Redaction defaults are non-negotiable per Principle VII.** *"The model never sees a real secret"* is not a tunable. Any PR that proposes flipping confidential-redaction off-by-default is rejected at review; tenant overrides require an explicit per-tenant flag *and* an audit-event entry on every override-active turn. Applies to **R4** confidential-rules, **F13** credential injection, **R6** leak classifier, and any future masking surface. Prevents drift from imported defaults.
- **F17 + R45 #787 before R48.3 wizard.** R48 ships the operator-facing UX (declaration schema, acquisition guide, setup wizard, admin surface, preflight); R45 #787 owns the F3 auto-grant + auto-revoke. R48.3's install wizard must call into the F17 managed-rule helper rather than re-implement rule placement — otherwise R48 and R45 land two divergent install-prompt code paths. R48.1 (frontmatter schema) and R48.5 (acquisition-guide renderer) can ship ahead of F17, as they don't write policy. R48.2 browser-mode field gates **R30** install-mode selection and **F14** preparation for captcha / 2FA waypoints — file before R30.5 (sessions) so the install-mode picker has the metadata it needs.
- **F17 before R45 children + R42.** F17 extracts the shared `managed_by_*` helper. The R45 children ([#786](https://github.com/HybridAIOne/hybridclaw/issues/786) MCP, [#787](https://github.com/HybridAIOne/hybridclaw/issues/787) skill install, [#788](https://github.com/HybridAIOne/hybridclaw/issues/788) channel registration) and **R42**'s inline credential paste should consume that helper, not re-implement read-modify-write logic per connector — otherwise four divergent rule-placement code paths land in parallel. Acceptable to ship F17 alongside the first child rather than strictly before, but the first child PR must include the [`src/policy/secret-route-policy.ts`](../../../src/policy/secret-route-policy.ts) retrofit so PR #784's call site converges with the new helper at the same time.
- **F7 user-id propagation before R5 / R14 enforcement.** Channel dispatch today routes off `channel-id` (the platform's per-conversation identifier). Budgets (**R5**) and RBAC (**R14**) actually want to attribute to the canonical *user* — same human across Slack DM, WhatsApp, and email is one budget bucket and one role binding, not three. F7.1 ✅ ships the canonical user ID; the missing piece is propagating it through every channel runtime's inbound dispatch so R5's `monthlySpendUsd` and R14's permission checks can key on user, not channel. File a small F7.x ("user-id propagation through channel dispatch") before R5.3 hard-stop and R14 land — otherwise both features ship with a channel-keyed shape that has to be refactored. Added 2026-05-09.
- **F8.6 → hooks-system generalization (future direction).** Now that F8.6 ✅ has refactored the cascade into a typed rule pipeline, the natural next step is to expose the same hook surface as a *generalized* event-driven system — observers (read-only listeners), interceptors (can mutate the call), and approval hooks (gate the call) — so plugins and skills can subscribe to tool-call lifecycle without each one inventing its own modal. Generalization path, not a P-tier item; mention here so when a third "I need to hook into approvals from a plugin" request lands the answer is the generalization, not a fourth one-off. Added 2026-05-09.
- **DeltaChat as a sovereignty-channel candidate.** Email-native end-to-end-encrypted messaging via DeltaChat fits between **R39** Matrix (self-hosted homeserver) and **R46** Threema (Swiss-managed) on the sovereignty axis: the substrate is plain IMAP/SMTP, the E2E layer is Autocrypt, the operator already has the credentials. Worth filing once **F15** plugin-channel registry lands — minimal incremental effort over the existing `email` channel runtime. Not yet a roadmap row; track here so the F15 plugin-channel exemplars include it. Added 2026-05-09.
- **R36 / R37 ops hardening as a prerequisite for leaving dogfood.** Channel runtimes for high-volume IM platforms need outbound-rate-limit pacing, exponential-backoff reconnects on transport flap, per-platform cache tuning (Telegram's media cache, Discord's gateway intent dedupe), and bounded-retry on send failures. Cheap individually; gate **R36 / R37** dogfood-graduation on these landing rather than treating them as post-launch fast-follows. Added 2026-05-09.
- **F7.5 polymorphic Actor before R29.6 issue API.** R29.6 mention-spawn semantics route an envelope from a human actor to an agent actor through the **R1** envelope `to` field; without F7.5 unifying the two identity surfaces, R29.6 has to special-case `userId | agentId` at every call site and the **R20** GDPR query has to walk two trees instead of one. F7.5 is a tagged-union wrapper, not a new ID space — small, but should land first. Added 2026-05-09.
- **R29.7 dependency edges before R29 auto-merge wiring.** The "Blocked" status pill and `In Review` auto-merge gate both consume `blocked_by`. Without R29.7 the auto-merge toggle has no signal to gate on and the status pill is hand-rolled per use. Land R29.7 alongside the first board PR rather than as a follow-up. Added 2026-05-09.
- **R51 daemon mode complements R34, does not subsume it.** R34 local-LLM teammate is *peer-instance-with-local-model*; R51 is *peer-instance-with-host-resident-CLI*. Both register into the **F5** capability matrix and both reuse **R9** cross-instance delegation, so the routing layer should be designed once across both. Sequence **F5** capability-matrix per-peer extension (R34 substrate) before R51's per-CLI registration so daemon mode plugs into the same shape rather than inventing a parallel registry. The token-class prefixes (F13 follow-up) and the env-var filter at subprocess spawn are R51 hard prereqs — the daemon cannot ship without them or it leaks operator authority into the spawned CLI. Added 2026-05-09.
- **F13 token-class prefixes before R51 daemon mode.** Daemon-issued tokens (`hc_daemon_…`) must be distinguishable from operator-issued PATs (`hc_pat_…`) at issuance, validation, and audit time before the daemon issuance path ships. Without prefix discipline, a leaked daemon token is indistinguishable from an operator credential during a forensic scan. Added 2026-05-09.

## Out of scope

- Net-new chat channels are P1+ work and only after **F15** unhardcodes the channel registry — they ship as plugins, not core edits to `src/channels/`.
- Generic "more skills" beyond the production-grade five in #21 — additional skills are folded into the same pipeline, not added as feature-count items.
- Anything that requires the end user to open the desktop app (Principle V).
- Per-coworker "away" / clock-out semantics — explicitly anti-Principle III.
