DuDuClaw: Instructions file for Claude Code

CLAUDE.md

DuDuClaw CLAUDE.md is an instructions file for Claude Code from zhixuli0406/DuDuClaw. It costs 25,965 tokens per session, scanned A, original, Apache-2.0.

A project instruction set for DuDuClaw, a platform that connects AI coding agents such as Claude Code, Codex, and Gemini through one system. It documents the platform’s runtime, routing, sessions, memory, accounts, local models, and browser automation.

In plain words
What is it for?
Use it when developing or reviewing DuDuClaw’s agent runtimes, configuration, channel routing, session handling, permissions, MCP connections, or automation.
Why use it?
It gives contributors shared architectural rules for changing a system that supports several agent backends and execution permissions.

Instructions file for Claude Code

Written for Claude Code: PreToolUse hook event. Also seen: reads .claude/ paths; mentions CLAUDE.md; mentions subagents.

This is zhixuli0406/DuDuClaw's own configuration. It tells Claude Code how to work on DuDuClaw itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything DuDuClaw configures →

Reuse

Borrowing it

Nothing to install: this file belongs to zhixuli0406/DuDuClaw. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/zhixuli0406/DuDuClaw/main/CLAUDE.md
Clone the repo
git clone --depth 1 https://github.com/zhixuli0406/DuDuClaw

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for DuDuClaw CLAUDE.md

README.md
[![agentmods](https://agentmods.dev/badge/instructions/zhixuli0406/duduclaw/claude-md.svg)](https://agentmods.dev/instructions/zhixuli0406/duduclaw/claude-md)
Your own site
<a href="https://agentmods.dev/instructions/zhixuli0406/duduclaw/claude-md"><img src="https://agentmods.dev/badge/instructions/zhixuli0406/duduclaw/claude-md.svg" alt="Measured on agentmods" height="20"></a>
Per session 25,965 This file is loaded in full into every session.
When invoked 25,965 The same file — it is already loaded in full.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe. ✓ AI security review Fable 5.1 · 7 Sept 2026 📄 Read the review
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.25965 $0.25965
Opus 5 $0.12982 $0.12982
Sonnet 5 $0.05193 $0.05193
Haiku 4.5 $0.02596 $0.02596

Measured 8d ago against content hash ddfd3ecfc54d, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-08, from the pricing page.

Security

Grade A, and why

DuDuClaw CLAUDE.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 8d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

CLAUDE.md · 176 lines

How it starts

The opening of the file, as written. The whole thing — 176 lines — stays where its author put it; the contents beside it link to each section on GitHub.

DuDuClaw Project Guidelines

Architecture Overview (v1.15.0)

DuDuClaw is a Multi-Runtime AI Agent Platform — supporting Claude Code / Codex / Gemini CLI as AI backends via a unified AgentRuntime trait with auto-detection and per-agent configuration. DuDuClaw provides the plumbing: channel routing, session management, memory, evolution, multi-account rotation, local LLM inference, and browser automation.

Key architectural decisions:

  • Multi-Runtime (AgentRuntime trait) — Claude / Codex / Gemini / Antigravity (agy) / OpenAI-compat five backends, RuntimeRegistry auto-detection, per-agent config in agent.toml [runtime]. Runtime parity (v1.33): RuntimeContext carries CapabilitiesConfig; codex/gemini spawn with capability-derived sandbox flags (SandboxLevel ReadOnly/WorkspaceWrite/FullAccess — no more blanket --full-auto/yolo; antigravity has no equivalent flag and warns per spawn); PTY-pooled sessions inject per-agent --allowedTools/--disallowedTools (previously zero restrictions reached the pool); codex/gemini/antigravity execute() register the duduclaw MCP server in each CLI's native config (codex -c overrides, gemini/antigravity settings.json per-key merge) so non-Claude agents get the full MCP tool surface; agent create --runtime scaffolds AGENTS.md/GEMINI.md and rejects typo'd providers; model_matches_provider() warns on [model] preferred[runtime] provider mismatches
  • Unified LLM provider layer (duduclaw-llm crate, v1.33): the API-level twin of the CLI-level AgentRuntime — one normalized ChatRequest/ContentPart/StreamEvent/NormalizedUsage shape over four native protocols: Anthropic Messages (layered cache_control, thinking replay, real SSE), OpenAI Responses API, Gemini generateContent (thoughtSignature echoed verbatim), OpenAI-compat chat/completions (8 presets: deepseek/minimax/groq/together/mistral/openrouter/xai/qwen + local; DeepSeek reasoning_content, real SSE). ModelRegistry vendors ~15 models with millicent/MTok prices + price-cliff math + capability flags (user override via ~/.duduclaw/models.toml); FallbackRouter implements per-(provider,model) cooldowns and context-window-aware candidate filtering (NOTE 2026-08 audit: zero production call sites — it is library code awaiting wiring, not live behavior). Tool-call args are always parsed serde_json::Value at the boundary; errors classify into a ten-way LlmError aligned with FailureReason. MCP client + tool-loop (mcp_client.rs behind default-on mcp-client feature, tool_loop.rs always-on): a stdio JSON-RPC MCP client + provider-agnostic run_tool_loop so the direct-API, local-inference, and the multi-runtime openai-compat AgentRuntime dispatch path get the full MCP tool surface (previously tools were CLI-backend-only; the openai-compat AgentRuntime used by API-mode Grok/DeepSeek/MiniMax agents sent tools-less messages and could only narrate "I'll go look that up" — now execute() drives run_tool_loop with a capability-filtered ToolRegistry over a spawned duduclaw mcp-server, degrading to plain messages only when no tools are reachable) — ToolRegistry aggregates N MCP servers, the loop feeds ToolResult back until the model stops (max-iters cap, per-call errors fed back as is_error). Real SSE streaming on all four providers.
  • MCP Server (duduclaw mcp-server) exposes channel, memory, agent, skill, task, shared wiki, and autopilot tools to AI Runtime via JSON-RPC 2.0 over stdin/stdout. Registered globally in ~/.claude/settings.json (auto-migrated from per-agent .mcp.json since v1.8.4)
  • Agent directories are Claude Code compatible: each contains .claude/, SOUL.md, CLAUDE.md. Agent-specific MCP servers (e.g. Playwright) still use per-agent .mcp.json; the DuDuClaw MCP server is registered globally in ~/.claude/settings.json
  • Sub-agent orchestration via create_agent / spawn_agent / list_agents MCP tools with reports_to hierarchy. System prompt auto-includes "## Your Team" roster with sub-agents from the reports_to hierarchy (v1.8.2). Channel bot tokens cascade up this same hierarchy (v1.8.28 — resolve_agent_channel_token_via_reports_to): cron / delegation forwarding first check the agent's own [channels.<ch>], then walk reports_to until an ancestor's token is found, then fall back to global config.toml. Prevents 401 Unauthorized in multi-bot setups where a sub-agent without its own Discord bot token would otherwise fall to a different global bot that lacks access to the team root's threads. Delegation authorization (v1.52 — duduclaw-core/delegation_policy.rs): reports_to tree is the authority for hierarchical permissions; agents can delegate to their entire sub-tree and escalate to ancestors (any depth, both directions); same-department agents may coordinate (configurable via [delegation] policy); cross-team collaboration via explicit white-list pairs. MCP/bus/task/ACP paths all enforce the predicate; fail-closed DENY writes audit log.
  • Session Manager persists conversations in SQLite with 50k token auto-compression (CJK-aware token estimation)
  • Native multi-turn session management (v1.8.1): Claude CLI --resume <session-id> with SHA-256 deterministic session ID + fallback to history-in-prompt; per-turn tail trimming (>800 chars, CJK-safe; DuDuClaw heuristic — turn format follows the ChatML/ShareGPT convention, not a published Hermes feature); Direct API prompt cache with "system_and_3" breakpoint strategy; session compression summaries injected into system prompt (not conversation turns)
  • Cross-invocation action continuity (recent_actions.rs, 2026-08): sessions are per-conversation, so an agent's scheduled/heartbeat/goal-loop runs and its channel replies can't see each other's actions — asked "did you do X?" an agent consulting only live tool state would deny actions its own audit trail records (blocked/rejected orders are invisible to live state; LWM D2 incident). Every invocation now opens with a ## 近期自身行動(稽核紀錄) section compressed from tool_calls.jsonl (programmatic evidence, resolve_audit_agent attribution, failures/blocked calls included) plus a hard instruction to answer self-questions from durable records, never live tool state alone. Injected on both prompt paths (channel_reply dynamic tail after CACHE_SPLIT_MARKER; claude_runner uncached tasks_suffix for dispatch/cron/heartbeat/reminder/ephemeral). config.toml [memory] recent_actions_enabled (default on) / recent_actions_count (default 10, cap 50); 256KB tail-read, consecutive-duplicate collapse, 2400-byte section cap, empty feed → zero injection, all failures fail-open to "no section"
  • Cross-wake working state (working_state.rs, 2026-08, LWM D3 incident — "three stop-loss lines in one day"): per-agent authoritative key-value state + handoff note, durable across ALL trigger sources. Operational rules living only in prose notes are ghost memory (A-TMA arXiv:2607.01935) — each fresh wake re-derives them from whichever note it happens to read. Now the gateway injects a ## 工作狀態(唯一權威…) section into every wake-up's dynamic tail (before the recent-actions feed, after CACHE_SPLIT_MARKER / uncached tasks_suffix), wording marks conflicting note values as superseded history (A-TMA read-time labeling) and carries the ASSUME-INTERRUPTION write-back instruction. Updates are explicit MCP tool calls ONLY (working_state_set/clear/handoff/get — never parsed from completions; all writes audit-logged, in SELF_ECHO_TOOL_NAMES): reason required, supersession chain in working_state_history.jsonl, optional expected_value CAS (Letta memory_replace stale-write rejection — concurrent 3-min cron wakes can't stomp each other; expired entries don't satisfy CAS), optional ttl_hours for day-scoped rules (expired entries leave the authority view but stay readable), 32-key cap refused-with-listing (consolidate, don't sprawl). Store: <agent_dir>/state/working_state.json, with_file_lock + atomic rename, BTreeMap deterministic serialization. config.toml [memory] working_state_enabled (default on) gates injection only; empty state → zero injection; every failure fails open to "no section". Follow-up deferred: sleep-time consolidation (journal → handoff briefing), dashboard card.
  • File-based IPC (bus_queue.jsonl) for inter-agent delegation; AgentDispatcher consumes and spawns Claude CLI subprocesses
  • Container sandbox (Docker / Apple Container) for agent task isolation with --network=none, tmpfs, read-only rootfs
  • Python subprocess bridge for skill vetting
  • Eleven channels: Telegram (long polling), LINE (webhook), Discord (Gateway WebSocket with tokio::select! heartbeat), Slack (Socket Mode), WhatsApp (Cloud API webhook, signature fail-closed), Feishu (webhook), Google Chat (webhook, JWT-verified, service-account send), Microsoft Teams (Azure Bot / Connector v3, JWT-verified), WeCom (HMAC-SHA1 + AES-256-CBC), DingTalk (HMAC-SHA256 + time window), WebChat (WebSocket). (Older docs said "nine" — wecom/dingtalk were added later; 2026-08 audit corrected the count.) Channel UX layer (v1.35): per-platform markdown rendering (markdown_render.rs — block IR → Telegram HTML / Slack native markdown block / WhatsApp markup / Feishu Card 2.0 / Google Chat markup / Teams markdown / LINE plain text; CJK-width-aware monospace tables where native tables are unsupported); typing indicators (channel_typing.rs RAII guards — TG sendChatAction / DC typing / LINE loading / WA typing_indicator / Slack assistant.threads.setStatus / Teams typing activity; Google Chat uses placeholder + edit-in-place); live long-task progress via ProgressEvent::TodoUpdate (parses Claude TodoWrite tool_use from stream-json into a 📋 task board, delivered edit-in-place on TG/Slack/GChat/Teams/Discord, throttled elsewhere, deleted when the final reply lands). Delegation callback forwarding covers all 8 external channels (Teams via a persisted conversation-reference store teams_conversations.json — the standard Bot Framework proactive pattern; Google Chat via service-account send_text_to_space); Computer Use senders exist for all channels (GChat/Teams photo upload falls back to a text notice). Inbound quoted-reply context (2026-08): replying to (quoting) a message now carries the quoted content into the agent input on the five channels whose payload embeds it — Telegram reply_to_message + forward_origin provenance, Discord referenced_message, Slack message-share attachments[].text (link unfurls excluded), Teams text/html attachment <blockquote>, WhatsApp context (annotation only — Cloud API never ships the quoted body); one shared block format channel_format::format_quoted_context (CJK-safe 2000-byte cap, QUOTED_SELF_LABEL when the quoted author is the bot itself), and replying to the bot's message counts as an @mention in Telegram/Discord mention-only groups. Remaining channels need API round-trips or the platform withholds content — tracked in docs/todo/TODO-channel-quote-context-remaining.md
  • BroadcastLayer tracing layer streams real-time logs to WebSocket subscribers
  • Ed25519 challenge-response auth for secure WebSocket connections
  • Unified heartbeat scheduler — per-agent cron/interval for bus polling + GVU silence breaker, max_concurrent_runs semaphore
  • CronScheduler reads cron_tasks.jsonl, evaluates cron expressions, fires tasks on schedule. list_cron_tasks returns all tasks (no longer filters by default_agent, v1.8.3)
  • Prediction-driven evolution engine: Prediction-error-driven evolution (Active Inference / Dual Process Theory) — zero LLM cost for ~90% of conversations. Dual Process Router: Negligible/Moderate errors → zero cost, Significant → GVU reflection, Critical → emergency GVU loop. MetaCognition self-calibrates error thresholds every 100 predictions (negligible_upper/significant_upper raise back toward default after a long clean stretch, not just tighten — v3 Phase 0 R7 fix, previously one-directional drift).
  • GVU self-play loop (Generator→Verifier→Updater) — legacy SOUL.md path, opt-in only via agent.toml [evolution] legacy_soul_evolution = true (AEE below is the v3 default): TextGrad feedback, max 3 rounds, judge floor 0.7. SOUL.md versioning with 24h observation period + auto-rollback; observation now has a real ceiling (v3 Phase 0 R5 fix) — conversations_count < 5 no longer force-confirms after 72h with zero evidence (that was silently producing confirmed versions with all-zero post_metrics); it soft-warns at 72h and hard-expires to ExpiredNoData (not confirmed, not rolled back) at 14 days. Atomic write (temp + rename) with SHA-256 fingerprint; a SOUL.md already over SOUL_MAX_LINES/SOUL_MAX_BYTES (previously a permanent one-way-valve deadlock, R2) now triggers gvu/consolidate.rs — a whole-file rewrite back under cap, gated by six controls (byte-identical persona/identity partitions via SHA-256, structure lock, and a hard "post-compression Measure score ≥ pre-compression" check) so it can't degrade into ACE-style context collapse. Every trigger path (channel ε-exploration, silence timer, sub-agent dispatch) now shares one per-agent cooldown (agent.toml [evolution] gvu_cooldown_minutes, default 60) and checks gvu_enabled (previous default mismatch between the struct default true and the runtime gate's false — R3 — is fixed: fail-closed opt-in everywhere, so an agent needs an explicit gvu_enabled = true to evolve at all). A stagnation detector (gvu/stagnation.rs, AVO §2.4) scans evolution.db every 30 min for consecutive-rejected / D-days-zero-apply / repeated-rejection-reason signals and posts to the Activity Feed + dashboard once per stagnation state (previously: dead ends were invisible).
  • Agentic Evolution Engine (AEE)the v3 default evolution path (gvu/aee/), superseding "rewrite the whole SOUL.md" as the target: SOUL.md is a read-only persona layer for agents (see Security layer below); the evolving artifact is the playbook (crates/duduclaw-gateway/src/playbook/), an ACE-style (arXiv:2510.04618) condition-action rule set stored as an extension of the existing rule_lifecycle semantic-memory rows — no new store. Each entry is gene-shaped (EvoMap/evolver GEP protocol, schema-only reference — no code/deps vendored): category (repair/optimize/innovate), signals_match trigger tokens (wired to MistakeCategory/FailureReason), ordered strategy, failure history, ≥1 linked EvalCaseRef (entries with none are refused at write time), capsule-style application log (outcome/score) + success_streak. Content is capped compact (≤400 chars — 2604.15097 found that expanding gene entries into documents hurts); merges are deterministic (no LLM); near-duplicate detection uses char n-gram cosine at a deliberately conservative 0.92 (a false merge silently loses a distinct rule, worse than a redundant one) and rejects-with-audit rather than silently dropping. Injection into ## Learned Rules is now signal-match-first + net-score fallback (was pure net-score top-3). One AEE round: gvu/aee/intent.rs picks repair/optimize/innovate deterministically from agent.toml [evolution] strategy (balanced default / innovate / harden / repair_only — replaces raw ε-exploration) → inner_loop.rs runs ≤3 generate/gate/shadow-apply/score/revise rounds (nothing persists until commit) → Gate/Measure split replaces the old 8-layer all-veto chain: Gate (verifier_gate.rsG-Safety/G-Contract/G-Canary-Static/G-Schema/G-Capacity, deterministic, zero LLM, keeps veto) runs first so a doomed candidate never pays for a judge call; Measure (verifier_measure.rs — eval case pass rate, L3 judge downgraded to one score dimension where a failed call is None not 0.0, anti-sycophancy, novelty, mistake-relevance) has no veto → commit gate is matches-or-improves (AVO P7) against the reigning champion (champion.rs — a whole-playbook snapshot hash, not per-entry, so one improved rule can't hide three regressed ones) within a configurable noise band (agent.toml [evolution.noise_band]), with anti-drift companions against repeated tie-commits → entry-level accept/rollback settles per entry against its own linked eval case (aee_settle_hours, default 24h) so a regression only rolls back the one entry that caused it. duduclaw eval gained --case <id>[,...] (exact EvalCaseRef match, unlike substring --filter), --exclude-dir <name> (held-out rotation), --report <path>; AEE calls it via subprocess + JSON report (config.toml [evolution] eval_suites_root/eval_binary), never in-process, to stay runtime-agnostic across claude/codex/gemini/antigravity/openai-compat. duduclaw playbook export --agent <id> dumps an agent's active entries as GEP-shaped gene JSON (local file only, no hub). Dashboard: Memory page "自主學習" (evolution) tab — mode banner, version history, stagnation card, rejection-telemetry chart, consolidation log, playbook entry cards (export / manual retire) via evolution.*/playbook.* RPCs. Full design: commercial/docs/DESIGN-evolution-v3-aee.md; rollout plan: commercial/docs/TODO-evolution-v3-2026-08.md; user-facing walkthrough: docs/features/38-aee-playbook-evolution.md. v1.53 additions: every playbook Add must now carry E1 EntryAssertions (must_use_tools / must_not_use_tools / output_contains / output_not_contains, ≤6 items × ≤80 chars — WP2.8/D8); playbook/assertions.rs replays them zero-LLM against recorded eval transcripts, feeding a G-Assertions gate step in inner_loop.rs (no transcript → degrade to advisory, never silently pass). A reward-hack audit (gvu/reward_hack.rs, WP2.10/C4) screens candidate entries for H1 eval-prompt leakage (n-gram overlap ≥0.6), H2 tautologies, and H3 failure-suppression — folded into the existing G-Contract veto family (no new layer, per D11); H4 judge-pleasing phrasing is Measure-side telemetry only. duduclaw playbook migrate-soul --agent <id> [--apply] (WP1.4) extracts behavioral rules from a legacy SOUL.md into draft playbook entries for human review before apply. Still deferred from the same plan: hypothesis-object observation windows (C1) and LLM-assisted refactor-toward-simplicity (C3).
  • Task-level forward model (harness→LWM plan A, v1.53): a predict-act-verify world-model layer on the goal loop, runtime-agnostic, config.toml [task_forward_model] (default off). Before dispatch, prediction/task_forward.rs predicts the task outcome via a 4-tier degradation chain (per-(agent, tool-class) statistics → marginal statistics → prior → optional LLM — cold start costs zero LLM); after settle, task_observe.rs diffs prediction vs. observation on 4 dimensions and records the transition (transition.rs — SPO fields deliberately None so transitions stay out of temporal supersession). Every observation carries an explicit ObservationFidelityFull (native tool events), McpOnly (the main branch: audit-log evidence only), None — never silently conflated. NativeToolEvent (runtime/mod.rs) is the runtime-neutral tool-event collector (task-local + (task_id, round) bridge; masked result_text/input_text): claude/codex/gemini/openai-compat reach Full; the PTY-pool path deliberately has no collector; codex/gemini event field names are dual-name tolerant pending a real-CLI spot-check. Native evidence is hoisted once per settle and shared by all three consumers (forward-model observe / grounding / judge digest). The goal loop injects a structured <state> block (goal_state.rs, XML-escaped; agent updates it via a state_update reply tag with <> stripped) plus a (state, action) visit graph (goal_visit_graph.rs) — repeat-visit streak ≥2 triggers early oscillation needs_human; foresight_gate.rs flags predicted-failure dispatches; task_rule_induce.rs (A4) deterministically induces task rules from repeated transitions into the existing rule_lifecycle store (template-based, inject cap 2, same settle/retire lifecycle — NOT playbook entries, per T8/T9). Confirmed post-task facts persist via merge_goal_state_json. Design: commercial/docs/design-task-forward-model-2026-08-06.md.
  • Calibrated forward model + held-out learning gate (v1.54): domain-agnostic (confidence, realized_outcome) layer on top of the task forward model, all three sub-switches under config.toml/agent.toml [task_forward_model] default off (enabled/calibration_enabled/held_out_gate_enabled). prediction/calibration.rs scores settled predictions with proper, bounded scores (Brier/RPS, never log score) and a Murphy decomposition (reliability/resolution/uncertainty — only rising resolution counts as real skill) against a frozen baseline, yielding a three-state HonestLabel (Supported/Candidate/IndistinguishableFromLuck). prediction/rule_gate.rs gates reflexion-derived rules the same way: evidence-backed lessons inject normally, evidence-less inductive lessons are born as shadow candidates and only promote once their out-of-sample Wilson lower bound (Bonferroni-corrected across concurrent candidates) beats the baseline, with keep-better demotion on regression. Shadow-scoring runs on both settle paths (2026-08-12 closed the dialogue-side debt): task settles score signal-matched (goal_kind: tag) shadow candidates in dispatch_engine; channel replies arm the shadow candidates whose playbook signals_match tokens hit the turn's TurnSignals at prompt-build time (playbook::collect_armed_shadow — never injected) and grade exactly those ids at outcome settle (rule_lifecycle::score_shadow_candidates_by_ids, hit ⇔ Significant/Critical) against the agent's dialogue climatology (PredictionEngine::high_risk_base_rate over prediction_log; coin-flip fallback under 8 samples). Gate-on channel settles also route injected rules through settle_injected_rules_held_out (dispatch parity); gate-off stays byte-identical to the pre-gate lifecycle. Not trading-specific — any agent using tool calls benefits. See docs/features/39-calibrated-forward-model.md.
  • Belief Loop (prediction/belief.rs, 2026-08, domain-agnostic on purpose): the agent-facing twin of the task forward model — structured beliefs about the external world (any subject: a ticker, an index, a KPI…), each carrying subject/horizon(free-form label, ≤40 chars)/direction/probability vs a submit-time judgment baseline value (ref_value), via MCP belief_submit/belief_settle/belief_stats, settled deterministically against a caller-supplied realized_value (three-way Brier, configurable flat band [belief] flat_band_pct default 0.3%, TickHub cross-check with 1% tolerance refusing divergent self-reported reality). Two programmatic injection hooks (never agent recall — arXiv:2605.29463): goal-dispatch prompts get a ## 信念校準 calibration section (<30 settled ⇒ counts only; per-row stats_injected recorded because "injecting history improves calibration" has NO first-hand evidence — deliberately shipped as an evaluable experiment), autopilot tick wake-ups get a ## 信念對照 belief-vs-live-value diff line (tick field resolution: explicit [belief] tick_subject_map config entry first, zXXXX→XXXX naming convention as fallback). Stats reuse calibration.rs Wilson/proper-scoring (no second statistics dialect); dashboard = Foresight page 信念與驗證 tab (belief.recent/belief.summary, manager-gated, three honest states). Calibration is scored separately from task outcomes and never conflated (arXiv:2607.03015). Per-goal layer (same design doc §6): tasks.goal_create accepts duration_hours (deadline → needs_human, min with global wall-clock) and risk_boundary (empty ⇒ [goal_defaults] baseline_boundary five-line default), boundary injected into every dispatch round + the MAV judge's safety aspect. Design: commercial/docs/DESIGN-market-belief-loop-2026-08.md (9 research-derived hard constraints; six-track 2026-08-14 literature sweep; investment is the first validated pilot use case, in the design doc's appendix — the platform itself doesn't know or care what the subject domain is).
  • Cognitive memory (optional): SqliteMemoryEngine with episodic/semantic separation and Generative Agents 3D-weighted retrieval. The recency dimension uses Ebbinghaus retrievability (MemoryBank, arXiv:2305.10250): R = exp(-t/S) with stability S = base·(1 + k·ln(1+access_count))·(importance/5) — frequently-recalled memories rank higher and survive decay; run_decay archives entries only when old + low-importance + R < 0.05 (replaces the binary access_count == 0 heuristic). HippoRAG-lite graph retrieval (graph_rank.rs, arXiv:2405.14831): Personalized PageRank (d=0.5, ≤20 iterations) over the v1.19.0 SPO triple graph — currently-valid facts only, CJK-safe whole-word seeding; blends w_graph (0.15) into the re-ranking and appends up to 3 graph-only two-hop hits FTS missed; no seed match → byte-identical to FTS-only. MemGPT 3-layer system (Core Memory, Recall Memory, Archival Bridge, Budget Manager, Consolidation Pipeline, 6 MCP tools) was removed in v1.8.1 (−1,985 LOC)
  • Memory Intelligence (v1.19.0) — three W18/W19-designed features implemented non-invasively on the live SqliteMemoryEngine (no schema rewrite, MemoryEntry unchanged): (F1) Temporal Memorymemories gains temporal/knowledge-graph columns (valid_from/valid_until/superseded_by/supersedes/subject/predicate/object/confidence/metadata) via the idempotent migration loop + two indexes; store_temporal(entry, TemporalMeta) does automatic conflict resolution (same (agent, subject, predicate) supersedes the prior fact and links a supersession chain); search()/search_layer() default-filter to currently-valid rows; get_history()/get_at() expose chain + point-in-time. (F2) Reflexion Loop bridges the existing MistakeNotebook (not a new store): F2a injects an agent's recent unresolved mistakes into the answering prompt (## Past Mistakes to Avoid, CJK-safe topic match + recency fallback); F2b consolidates ≥3 same-MistakeCategory unresolved mistakes into one semantic memory rule (reflexion.rs, detached, deterministic synthesis) then marks the sources resolved. Trigger signal is the existing ErrorCategory (Significant/Critical, MetaCognition-adaptive) — NOT the GVU Verifier (which validates SOUL.md proposals). Rule lifecycle (ACE arXiv:2510.04618 / ExpeL arXiv:2308.10144, prediction/rule_lifecycle.rs): consolidated rules carry rule_stats {helpful, harmful} in metadata (seeded helpful=1 under v1.41 Janus probation — see below); channel reply injects ## Learned Rules ranked by net score (cap 3); after apply_outcome, injected rules settle — Negligible/Moderate → helpful+1, Significant/Critical → harmful+1; net 0 → retired (retired-rule tag, excluded from selection) so stale rules die instead of diluting the prompt. (F3) memory_fetch_batch MCP tool + get_by_ids fetch ≤100 entries by ID in one call (namespace/ownership enforced, partial hits → missing_ids)
  • Trusted memory & judge hardening (v1.41) — five paper-driven upgrades: (1) write-time origin binding (TMA-NM arXiv:2606.24322, duduclaw-memory/src/origin.rs): every memory write carries an origin class with a non-malleable trust ceiling (origin_trust = min(caller, ceiling, derived_from)); unattributed writes default to 0.6 not 1.0; reaffirmation is Sybil-resistant — only ≥2 distinct non-self-derived origin classes can bump confidence (+0.1/step, cap 1.0), agent self-summaries and tool echoes never corroborate each other; all production write paths stamp explicit origins. (2) GovMem promotion gate (arXiv:2607.02579): reflexion consolidation groups mistakes by source_kind (decision_gap vs task_failure counted separately) and requires ≥2 distinct sessions + ≥2 distinct normalized descriptions before promoting — correlated same-session observations no longer masquerade as independent evidence. (3) Janus probation (arXiv:2606.31121): new consolidated rules seed helpful=1 with a probation-rule tag; first harmful settle retires them, helpful≥3 graduates. (4) PORTICO task-scoped grants (arXiv:2606.22504, capability_grants.rs): tools listed in agent.toml [capabilities] scoped_tools require an active grant (MCP capability_request → ApprovalBroker, or goal-kickoff grant:<tool> tags); grants are revoked at every task terminal state (accept/reject/needs_human/cancel/escalate) plus TTL sweep — authority does not outlive the task phase; enforced fail-closed at the MCP dispatch gate and CLI spawn disallowedTools. (5) trace grounding (GroundEval arXiv:2606.22737): duduclaw eval gains [[expect.grounded]] deterministic assertions (tool must have a non-error result sharing a ≥N-char CJK-safe span with the final answer; failures classify as MAST FM-3.3), the eval transcript parser now pairs tool_usetool_result, and the MAV acceptance judge receives a <tool_activity> audit digest so self-reported result summaries are checked against actual tool activity. Plus cache-aware compression guard (arXiv:2607.12161): the reply-path compression pipeline is skipped when recent cache efficiency >50% and budget overshoot <15% (compressing marginally costs more via cache-prefix rebuild than it saves); token_usage records compressed/compression_stages, and cache_attribution_snapshot() finally has a consumer (hourly top-10 cache-break causes → log + evolution event).
  • Memory trustification & grounded dispatch (harness→LWM plan B, v1.53): (1) anti-fake-surprise novelty gate (duduclaw-memory/src/novelty_gate.rs): semantic-layer writes are screened by char n-gram cosine at 0.92 (same yardstick as playbook dedup) — near-duplicates are rejected-with-telemetry instead of accumulating as false "surprise" (arXiv:2606.29182: 37.5% false surprise without pruning); fail-open when no embedder is attached, F1 temporal-supersession/reaffirmation paths exempt; [memory] novelty_gate (default on) is honored through the single memory_factory::build_memory_engine construction point — the operator/dashboard RPC construction point is deliberately ungated (human curation is not screened). (2) Verified-only reflexion: MistakeNotebook entries carry TrajectoryEvidence (tool_name / error_kind / assertion_failed / source_span) extracted programmatically from transcripts; self-reported mistakes without evidence no longer feed F2b consolidation (Honest Lying, arXiv:2605.29463 — self-reports are untrusted). (3) Grounded dispatch precheck: duduclaw-core/src/grounding.rs (one shared module for duduclaw eval and production) checks that a completion shares a contiguous CJK-safe span with an actual non-error tool result; dispatch_engine runs it before the MAV judge ([dispatch] grounding_precheck_enabled, default on) — hardened with a self-echo deny-list (SELF_ECHO_TOOL_NAMES: tools like tasks_complete that echo the agent's own summary can never self-ground) and input-overlap subtraction (text the agent itself passed into the tool call doesn't count as evidence). (4) Audit log as evidence source: tool_calls.jsonl records masked result_text/input_text (mask-before-truncate; 3-pass secret masking covering JSON-kv, bare-prefix, plain-kv plus connection-string / lowercase-bearer / CJK-adjacent patterns; 16MB rotation; 0600 perms), and resolve_audit_agent attributes system-sender dispatches (goal-loop / cron / heartbeat / autopilot, all six SYSTEM_SENDERS) to the executing agent — fixing the P0 where DUDUCLAW_DELEGATION_SENDER overwrote attribution and silently starved every downstream evidence consumer (fidelity stuck at None, grounding always Skip, judge saw zero evidence).
  • Security layer: SOUL.md drift detection (SHA-256), prompt injection scanner (6 rule categories), JSONL audit log, per-agent key isolation. SOUL.md read-only for agents (Evolution v3 WP1.1): MCP agent_update_soul and the Write/Edit/Bash file-protect hooks now refuse an agent-identity caller writing its own or any other agent's SOUL.md, closing a previously-dead gate (agent.toml [permissions] can_modify_own_soul had zero readers before this) — the only legitimate write paths left are the operator/dashboard and, for a single agent explicitly opted in via can_modify_own_soul = true, self-write only (never cross-agent). The dead duduclaw-security::rbac module (zero callers workspace-wide) was removed; its one live piece of behavior moved to this MCP-front-door check, its other (validate_agent_creation) was already superseded by v1.52's delegation_policy.
  • Claude Code security hooks (.claude/hooks/): 3-phase progressive defense — Layer 1 deterministic blacklist, Layer 2 obfuscation/exfiltration detection (YELLOW+), Layer 3 Haiku AI judgment (RED only). Threat level state machine (GREEN→YELLOW→RED) with auto-escalation/degradation. Protects Write/Edit/Read of sensitive files, scans for secret leaks, audits all tool calls (async JSONL compatible with Rust audit.rs), validates .env.claude, detects config tampering. All prompts use XML delimiters for injection resistance. See commercial/docs/TODO-security-hooks.md and commercial/docs/code-review-security-hooks.md.
  • Browser automation & computer use (5-layer auto-routing): L1 API Fetch → L2 Static Scrape → L3 Headless Browser (Playwright MCP) → L4 Sandbox Browser (container-isolated) → L5 Computer Use (virtual display). Deny-by-default via CapabilitiesConfig in agent.toml [capabilities]computer_use, browser_via_bash, allowed_tools, denied_tools. --disallowedTools passed to Claude CLI. bash-gate.sh Layer 1.5 allowlist for Playwright/Puppeteer (requires DUDUCLAW_BROWSER_VIA_BASH=1 env). See commercial/docs/TODO-browser-automation.md.
  • Behavioral contracts (CONTRACT.toml) with must_not / must_always boundaries + duduclaw test red-team CLI
  • Agent behavioral evals (duduclaw eval, v1.33): golden-task regression for agents — evals/<agent>/*.toml cases with deterministic tool-call/regex assertions + optional LLM judge (reuses duduclaw-fork::judge); live mode drives the real CLI (captures actual tool_use), replay mode re-parses recorded transcripts offline for CI; JSON report + non-zero exit gates PRs. The external yardstick independent of the GVU verifier for a self-evolving platform (design hook to feed SOUL.md 24h observation-window post-metrics). v1.53 eval hardening: --record rewrites .mcp.json to a temp copy pointing DUDUCLAW_HOME at the eval home + DUDUCLAW_MCP_API_KEY=eval-local (recording has zero production side effects and can't leak real MCP keys into transcripts); a run that dies on any max-turns cap parses as error_max_turns — an assessable failure baseline, not an infra error (infra errors stay hard); duduclaw eval-scaffold drafts eval cases from an agent's SOUL behavioral rules into evals-drafts/ (free-tier path to the AEE ≥1-EvalCaseRef hard requirement — drafts must be human-reviewed before moving into evals/); premium team deployment auto-installs bundled eval suites (premium_templates::install_eval_suite — dual-location resolution, rename-safe agent-field rewrite, never clobbers an existing dest). See docs/guides/evals.md.
  • HITL ApprovalBroker (approval.rs, v1.33): one interrupt/approval primitive spanning MCP tools / autopilot actions / bus tasks — SQLite approvals.db (WAL), request/decide/await_decision/expire_stale, TTL-expiry = DENY (fail-closed). Wired into autopilot require_approval; agent.toml [capabilities] approval_required_tools parser; converges the three ad-hoc approval impls (browser router / channel confirmation / governance workflow) onto one auditable store. Simulate-before-act (harness→LWM plan D, v1.53): approval requests carry a structured simulation of what the action would do — ActionGuard's maybe-irreversible judgment produces the narrative (fail-closed semantics unchanged), and goal-loop needs_human escalations attach a three-step simulated trajectory (15s timeout; on timeout the request degrades to no-simulation rather than blocking); wiki-derived context for simulations is restricted to read-only namespaces and can never decide irreversibility (no self-certification). The dashboard approval card renders the simulation (approvals.list ships the simulation field).
  • OpenTelemetry GenAI tracing (otel.rs, opt-in otel feature, v1.33): invoke_agent / chat / execute_tool spans following the gen_ai.* semantic conventions, OTLP-exportable (gRPC) to Langfuse/Grafana/Jaeger/Datadog. DEFAULT OFF (zero deps/overhead unless config.toml [telemetry] otlp_endpoint set); coexists with the Prometheus metrics.rs layer. See docs/guides/observability.md.
  • A2A v1.0 Agent Card (acp/server.rs, v1.33): /.well-known/agent-card.json (v1.0 schema; legacy /agent.json alias) with the x-duduclaw ADR-002 capability-negotiation extension preserved; message/send is fully wired to bus_queue.jsonl (advisory-locked append, sender identity recorded, honest submitted state — never fakes completed; tasks/get maps bus observations back to A2A states).
  • A2A delegation isolation (v1.52): Organizational boundaries enforce access control on inter-agent delegation — policy engine (duduclaw-core/delegation_policy.rs): six-rule predicate (self-delegation forbidden, system senders bypass, hierarchical authority bidirectional, same-department horizontal, white-list pairs, else DENY); enforcement chokes (v1.52): dispatcher bus consumption (gateway/dispatcher.rs C1), MCP front doors (send_to_agent/spawn_agent C2 with legacy check_supervisor_relation removed), task assignment (tasks_create/tasks_update C3), agent hierarchy creation (create_agent/agent_update C4 caller-owned-subtree-only), ephemeral spawn (C5 parent==caller). Visibility filtering (C6): list_agents/agent_status per-caller scope (self + subtree + ancestors + same-dept + white-list; open policy shows all). Policy modes ([delegation] policy): department (predefined+default), hierarchy (no horizontal), open (legacy escape hatch). White-list config (allow = [["a","b"]] pairs, bidirectional, ignores malformed/self entries). Dashboard management (delegation.get/set RPC, admin-only) + UI card in advanced settings (radio + pairing editor, no restart needed). ACP entry ([acp] trusted = true opts into a2a-client sender allowlist; default deny). Audit log event delegation_denied carries sender/target/path_kind/policy. Identity & integrity (v1.52 hardening): HMAC-SHA256 caller token per spawn (DUDUCLAW_AGENT_TOKEN env); PreToolUse hook freezes org fields (agent.toml [agent] name/reports_to/department, config.toml [delegation]/[acp], .mcp.json identity block, .claude/settings.json) to MCP/Edit/Write tools—config mutations routed through agent_update/dashboard only; require_identity_token soft/hard modes in [delegation]. No rank-based auth (hierarchy via reports_to trees only, per §2.7). Org authority store (v1.52 WP22 hardening): central ~/.duduclaw/org.toml (org_store.rs) seed-once on first gateway boot from agent.toml manifests; org mutations thereafter via duduclaw org sync CLI (operator-terminal only, fail-closed in AI sessions), duduclaw org show inspection, duduclaw doctor drift detection. Manual agent.toml edits no longer auto-propagate. Cross-agent file isolation: PreToolUse + sandbox (workspace-write blocks ~/.duduclaw/ for non-Claude runtime) prevent agent self-mutation of org settings affecting delegation decisions (FullAccess sandbox exempt, operator choice).
  • Skill ecosystem: GitHub Search API live indexing of real skill repos, 24h local cache, weighted search, MCP skill_search / skill_list tools
  • Skill auto-synthesis (Phase 3-4): Gap accumulator detects repeated domain gaps → synthesizes skills from episodic memory (Voyager-inspired) → sandbox trial with TTL → cross-agent graduation. MCP tools: skill_security_scan, skill_graduate, skill_synthesis_status
  • Task Board: SQLite-backed task management with status/priority/assignment tracking, real-time Activity Feed via WebSocket. Two access layers: Dashboard WebSocket RPC (tasks.list/create/update/remove/assign, activity.list) for the web UI; Agent-facing MCP tools (tasks_list, tasks_create, tasks_update, tasks_claim, tasks_complete, tasks_block, activity_list, activity_post) that let agents see their own queue, claim work, and post progress — fulfilling the Multica "Agent-as-teammate" design. Pending tasks (up to 5) are auto-injected into the agent system prompt.
  • Autonomous Goal Loop (goal_loop.rs + goal_notify.rs + dispatch_engine.rs, v1.37): user-facing outer loop turning one-shot Q&A into "give a goal → agent loops to completion → stuck escalates to human". /goal <描述> [|| <驗收標準>] chat command creates a goal_mode task (source channel/chat stamped for progress push-back); GoalLoopDriver (30s tick, gated by [dispatch] enableddefault ON since v1.59, opt-out via config or the Settings→Automation「派工引擎」hot-reload switch; the engine + goal-loop driver build/spawn live on MethodHandler::respawn_dispatch_engine / respawn_goal_loop_driver so boot and system.update_config share one path) dispatches via message_queue without the heartbeat 1h cooldown (heartbeat excludes goal tasks to avoid double-dispatch), retries immediately with judge feedback on rejection; DispatchEngine acceptance judge is a three-aspect MAV panel (correctness/completeness/safety, one LLM call via run_utility_prompt → account rotator, all-pass to accept, fail-closed parse) — DONE only via verifier approval, never agent self-report (LoopTrap defense). Hard guards: iteration cap (default 5 — lowered from 8 in the Iterative Kanban round; older docs saying 8 are stale), wall-clock 24h, concurrency 3, in-flight dedup, no-progress oscillation detection (two identical rejection feedbacks → early needs_human), all under [goal_loop] config. HITL: needs_human pushes approve/retry/abort buttons to TG/Discord/Slack/LINE (WP16 codec; text-only fallback elsewhere) + dashboard needs_human board column; per-agent [capabilities] autonomy_level five levels (operator/collaborator/consultant/approver*/observer — collaborator/consultant require kickoff approval via ApprovalBroker, fail-closed TTL). ActionGuard three-value irreversibility ([capabilities] irreversible_tools/maybe_irreversible_tools: always→human, maybe→LLM judge fail-closed, never→auto) layered on approval_required_tools taking the stricter. Runaway defenses (arXiv 2607.01641): cross-process dispatch_guard sliding-window breaker in duduclaw-core (~/.duduclaw/dispatch_guard.json under with_file_lock, spawn/ephemeral/cron paths, [dispatch_guard] config), cascading hop_depth over bus handoffs (env DUDUCLAW_HOP_DEPTH, max 5), termination_manipulation injection rule (7th input_guard category, weight 30 no instant-block). See docs/guides/goal-loop.md.
  • 兩段式裁決+停滯/收工偵測+交接與目標契約硬化(harness-borrowings 2026-08 Phase 1):三份外部 harness 調研(deepseek-harness/WorkBuddy/grok-build)收斂出的裁決工程借鑑,全部落在既有 MAV 判官與 goal loop 之上,不另起爐灶。兩段式裁決dispatch_engine.rs settle 時先跑一個無工具、單次 LLM 呼叫的便宜 evaluator(三值 continue/candidate_complete/blocked),只有完成候選才進現行三面向 MAV 判官團;evaluator 任何故障一律降級直接跑 MAV([dispatch] two_stage_judge,預設開)。MAV prompt 加了反棘輪/只稽核不自建證據/反契約外擴張/自稱完成不是證據四條紀律,並補上兩個既有 fail-open 洞(截斷面板 JSON 不再落回舊版掃描器誤判 PASS;PASS 須是回覆第一行的開頭 token)。停滯偵測升級goal_gap_fingerprint.rs):從駁回回饋抽 path:line 與反引號關鍵詞正規化成指紋,換句話說的同一個 gap 也判成同一次卡住(無引用時退回逐字比對);提前收工偵測goal_bail_detect.rs):九條 zh+en 正則比對 agent 回合最後一段文字,命中記遙測(goal_loop_bail_pattern_total{pattern})並把提示帶進下一輪判官/evaluator 輸入,不自行駁回。重啟不自動復活[goal_loop] resume_on_restart = "auto"|"pause"WP-E 2026-08 起預設 pause,機制首次上線時原預設 auto),pause 時 gateway 開機把 in-flight goal 任務轉 needs_humansystem.update_config 白名單只收兩值,儀表板「設定→自動化」可切換,只在下次 gateway 真正重啟時生效。交接契約硬化working_state_handoff 新增可選 Ralph 式欄位 status/next_steps/evidence/blocker,依 status 強制校驗,超長([memory] working_state_handoff_max_bytes,預設 16384)整筆拒絕絕不截斷。目標契約凍結/goaltasks.goal_create 建立時把驗收標準凍結成 acceptance_criteria_baseline,判官與 evaluator 一律讀這份基準;agent 身分 tasks_update 改 goal 任務驗收標準一律拒絕並留審計(goal_contract_frozen),僅操作者可經儀表板編輯顯示用副本;/goal|| 時回覆附四要素(目標/輸入/輸出格式/約束)與 3-5 條 outcome 式驗收標準建議。設計全文 commercial/docs/DESIGN-harness-borrowings-2026-08.md,調研全文 research/harness-2026-08/
  • Goal Loop 第二梯人為信號補完+spawn 准入排隊+ActionGuard/MCP 安全收斂(harness-borrowings 2026-08 第二梯):needs_human 帶封閉六類 pause_reasonno_progress/budget_exhausted/blocked_needs_decision/infra/restart/unknownpause_reason.rs,觸發現場靜態標記、絕不從 judge_feedback 反解),/goals 看板/詳情/通道通知三處渲染分類;已認領任務靜默逾 [goal_loop] progress_report_minutes(預設 10 分,0 關)以 Activity Feed 事件為訊號源(非 lease-renewer 會刷新的 updated_at)通報一次,純提醒不介入;單輪同工具同(遮罩)參數連擊 3/5/8 觸發零 LLM 的 <state> advisory(goal_tool_streak.rs[goal_loop] tool_streak_advisory 預設開)。Ephemeral spawn 准入排隊(行為變更)spawn_admission.rs 超限從硬拒絕改有界 FIFO 排隊([dispatch] admission 預設 "queue""fail" 回退),TTL 過期落稽核、turn 終態作廢遲到票券、上限 0 鉗 1。ActionGuard 封閉列舉:maybe-irreversible 判官改吃 21 項固定 token 的 ActionGuardFinding,prompt 建構參數型別排除原文——攻擊者可控文字編譯期進不了判官 prompt。MCP 三缺口:key registry mtime 感知 per-call 重驗(輪替/撤銷下一呼叫生效、重載失敗 fail-closed);denied_tools/allowed_tools 補上 McpDispatcher 分派總門強制(先前只轉譯 CLI flag);scope/grants/denied 拒絕落稽核(error_class)。agent.toml 影子直讀統一(R2 前置):5 檔 toml::Value 手刻 reader 收斂到 duduclaw_core::agent_toml::AgentTomlSections 單一型別化解析點(lenient 錯型降級不炸 agent、缺鍵方向逐欄鎖測試含歷史怪癖 opt_float_strict),並修掉 agent_update 覆寫時整段刪除未型別化區塊的資料遺失 bug;讀取刻意不加快取維持即時生效;影子 reader 全貌 62 處/16 檔,餘者列於 preset 設計文件。通知靜默修復:googlechat/teams 的自我設定型憑證不再被 token 判定誤判為未設定(needs_human/evolution 通知恢復);reminder 改走統一 create_sender 十通道(webchat 明確拒絕防假成功)。AI 團隊召喚卡片:團隊卡顯示成員構成/真人保留崗位/任務示例(team.toml examples 優先、worker 摘要回退),召喚=experts.install_builtin
  • credentials 讀取單一化+wiki ACL 型別化+產物物件化+計畫模式(harness-borrowings 2026-08 第三波):duduclaw-security::secret_ref 新增 SecretRef/Secret/SecretStatus,取代多套手刻「_enc 解密失敗退明文」實作——修掉 secret://<backend>/<name> 參照字面值被當真憑證送給 vendor API 的 bug(設計文件四路徑+dispatcher.rs 第五份平行實作);Secret zeroize/Debug 遮蔽/無 Serialize;[mcp_keys] 鍵名遮罩補洞;同步路徑網路 backend fail-closed(async 化列 P1)。shared_wiki_delete main-agent 判定從無錨定 contains(role="main") 改型別化 [agent] role(堵冒充刪頁洞,雙向回歸測試)。影子 reader 第二期:capabilities/budget/evolution/skills/mcp.external/os_watch/pty/agent 各區段全遷 AgentTomlSections,指派範圍影子 reader 歸零(全貌 62 處/16 檔;刻意不遷:原樣回吐/寫入路徑/read-modify-write)。任務產物物件化(I-2b)artifacts.jsonl provenance ledger(declared/swept/uploaded/produced/unknown 五 origin+exact/inferred 歸屬標示、上傳與 unknown 永不被時窗推定;合併鍵用真實 basename 防 CJK sanitize 誤併),任務詳情「產物」分頁+/files 來源欄/任務篩選+開機冪等回填;已知限制(goal 派工路徑無封存副本)已於第四波補上。靈感畫廊 /gallery(newIn 1.60.0):22 組產業劇本 examples 扇出成果卡,一鍵做同款預填交辦面板。「想一想」計畫模式(I-1c):交辦第三模式——tasks.goal_create(plan_first) 同步產計畫→needs_human(blocked_needs_decision)+獨立 plan_pending 欄位(與 judge_feedback 生命週期分離)→核准後首輪注入 <execution_plan> 一次性消費;規劃器失敗 fail-closed 到 infra通知同族收尾channel_sender::resolve_channel_target 單一來源,autopilot notify 補齊六通道、MCP send_message 十通道;殘留兩項(第三份 sender 拷貝、雙 snowflake 驗證器)已於第四波收斂。
  • 第四波(harness-borrowings 批次一,2026-08-15):credentials P1——secret://keychain(OS 鑰匙圈,feature 關閉時明確報錯非靜默查無)與 secret://file(固定 root 集+canonicalize containment+64KB 上限+world-writable 拒絕)兩個本機 backend、[[tick.sources]] headers secret:// 逐請求解析+解析後 CR/LF 重驗、security.credential_inventory RPC+安全頁憑證來源總表(只報鍵路徑不報值,[mcp_keys] 整段跳過——表格鍵名本身就是金鑰)、duduclaw doctor --fix-residue 互動式殘留清理、accounts.add 不再寫明文孿生鍵;第 6/7 種解密方言收斂(Apps Script 共享密鑰與 inference api_key 先前會把 secret:// 參照原樣送給 vendor;BridgeConfig.secretSecret 型別堵 Debug 洩漏)——七種方言至此全數收斂。goal 產物封存:accept 時將歷輪寫出檔案封存至既有 attachments/(agent_id 白名單→canonicalize 圈定→單檔 20MB/單批 100MB cap→失敗留痕不炸 settle,冪等)。通知同族終章:autopilot 第三份手刻 sender 移除(slack 通知自始未送出的活 bug 一併修復)、Discord snowflake 驗證統一至 duduclaw_core::is_valid_discord_snowflake。openapi.yaml 通道 enum 補齊十一通道。調研:AutoDesign(arXiv 2608.13560)+OfficeCLI 報告落 research/harness-2026-08/;AutoDesign 鏡頭實錘 verifier_measure.rs commit 閘 visible/held-out 混維缺口。批次二(同日):AEE 驗收閘拆維防遮蔽——commit 閘 dimensions() 並排新增 cases_visible/cases_holdout(holdout band 預設主 band 減半、[evolution.noise_band] holdout 可設、顯式值鉗不寬於主 band),兩新維 fence-only 只否決不晉升(不重置 anti-drift/不關觀察窗);settle suite_verdict 同修,band 於 commit 時凍結進 PendingSettlement.band_holdout(settle 不回讀 config);無 holdout case 行為逐位不變;冠軍 bootstrap include_holdout:false 蘋果比橘子列拍板項未動。goal 預算耗盡交「最佳輪成品」(goal_budget_best_round.rs 純函式三優先序:進過判官團的輪→gap 最少→最後一輪;task_iterations.worker_excerpt 於駁回當下快照節錄;judge retry budget 路徑同類接上;零輪誠實空手)。[limits] DocumentLimitsdocument_limits.rs)守三個下游解析器(soffice 預覽/office_script Python/expert 解壓):解壓總量 256MiB/entry 4096/壓縮比 100:1/XML 深度 128/容器巢狀 4,零遞迴實作,0=預設非無上限;safe_zip header 謊報洞(宣告 size 累計 vs 實際寫入)一併修補。[office] delivery_gateartifact_gate.rs,預設開)📎DELIVER 前結構檢查硬失敗(零位元組/magic 不符/zip 損壞)+佔位殘留 warn-only(delivery_gate_placeholder_block 可升級硬擋)。agent_id 驗證器五份收斂雙權威版(core is_valid_agent_id 廣義+新 is_valid_new_agent_id 小寫 slug 契約;MCP 面頭尾連字號漂移修補變嚴;telegram chat_id 兩處刻意不同不併)。
  • 第五波(2026-08-15)判官 seamjudge_mode.rs)——[dispatch] judge = mav(預設,逐位相同)/evaluator_only(低成本弱驗收,evaluator 故障→needs_human 絕不自動過)/external(外部指令裁決,spawn 失敗/逾時/非零碼/壞 JSON 全降級回 MAV+審計 judge_seam_degraded,feedback 當 DATA 先截斷再 scan_input)/human_only(一律人工驗收),未知值回退 mav(最強非最便宜)、judge_command 刻意不開放 RPC、每次裁決時讀 config(與 two_stage_judge 同套熱生效)——「一切皆插件」第一個真 seam,eval_backed 以「同一條 subprocess 路徑不寫兩份」刻意不做。AEE bootstrap 同形量測include_holdout: false→true,繼承性預設非決策;舊快照單邊跳過自癒;反向驗證實錘第一輪 holdout 1.0→0.0 舊行為判 improves 提交)。agent_id 同族二期(ipc/trust_store 收斂、vault key 128→64、兩處過時註解誠實化)。web:SecretSourceField 憑證來源選擇器(四表單,env/keychain/file 引導組字+反解);任務詳情四分頁(產物/檔案/變更/過程,badge 計數、keepMounted 保狀態、needs_human 卡位置不變審批動線零增加)。B6 設計文件結論 SHELVEDcommercial/docs/DESIGN-evolution-harness-knobs-2026-08.md:量尺自我認證兩難+樣本量 10³-10⁴/臂不可測;替代品 A1 離線 knob sweep/A2 旋鈕遙測/A3 clear_holdout_rotation 零呼叫端出口——A3 已 grep 實錘列欠帳)。
  • 第六波(2026-08-15,收官波)Agent Mailmail.rs/mail_worker.rs/mail 頁 newIn 1.60.0 雙導覽清單)——per-agent 信箱、入站 Gmail API/drop folder(<home>/mail/inbound/*.eml)、到達即觸發預設關且注入掃描標記信永不觸發、外發一律 ApprovalBroker 確認mail_send 只建草稿回 pending_confirmation,實寄由 worker settle——broker 零修改所以三個既有決策入口自動全通)、信件內容雙路徑同一 DATA 圍欄、Scope::MailRead/MailSend 不可外部授予、跨 agent 過 delegation_policy、ledger mail/mailbox.jsonl 照抄 artifacts.jsonl 形狀;死碼 email.rs 接活;欠:原生 IMAP、channel-registry 整合、autopilot 事件、附件。preset P1duduclaw-core/preset.rsduduclaw preset CLI+agent create --preset)——綁定權威 preset_bindings.toml、agent.toml 唯讀鏡像、解析物化到 agent 目錄外 agent_resolved/(防自改繞過,R2b:agent_toml::load() 重導向讓 12 個已收斂 reader 自動吃到)、org 欄位帶值整包拒絕/敏感段靜默剝除、9 個部門 preset(premium);欠 dashboard 視覺卡。Code Mode Phase 0 量測閘tool_loop_probe.rsduduclaw cost tool-loop)——fact-check 實錘 repo 有兩個同名 openai_compat.rs 且 compat 協定顯式 cache 斷點是 byte-identical 空操作(CacheHint 序列化時結構性丟棄),G0-G3 四判準(G3 快取吸收≥50% 否決)、probe 疊在既有遙測零行為變更;本機 INSUFFICIENT_DATA 即設計文件 R1 風險的第一份實證。credentials async 化收尾(三路轉 async、網路 backend 全路徑可用、sync 版生產呼叫端清零;accounts.add 回歸測試補齊)+第 8 處 secret:// 洩漏修補runtime/openai_compat.rs API 模式 bearer token 字面值)+潛伏地雷 key_vault.rs 整檔刪除(ciphertext 當 key 回傳、零呼叫端三重確認)。判官 seam 儀表板下拉(設定→自動化,使用者視角文案+external env 繼承在 guide 誠實揭露)。duduclaw evolution clear-holdout-rotation(A3 出口)+AEE 每輪快照 14 旋鈕進 aee_round 事件(A2,死 schema 接活);knob 快照 goal 結算半邊列欠帳。
  • 第八波(2026-08-16,credentials 收官)P2 零重啟輪換——帳號池寫入觸發 rotator 快取失效(claude_runner ROTATOR_CACHE invalidate-on-write 取代 5 分鐘 TTL;跨行程 CLI 直寫留 30 分鐘 backstop);Telegram poll_loop 每輪重解析 token(不再烤進 api_base);六 webhook 通道(feishu/whatsapp/wecom/dingtalk/googlechat/msteams)inbound 驗簽 per-request resolve 比照 line,outbound 衍生 token 保留 doctrine §2.4 TTL;Odoo set_globaldisconnect_all+修 profile 變更孤兒 slot bug。仍需重啟:Discord/Slack WS 長駐。P3 env 擦洗——duduclaw-core/spawn_env.rs AGENT_CLI_ENV_ALLOWLIST 白名單 spawn env(濾除所有 *_API_KEY/*_TOKEN/*_SECRET/*_PASSWORD,vendor 金鑰改呼叫端顯式注入;型別層測試焊死無密鑰形狀名字;env -i 真 OAuth 活測最小集足夠),claude_runner/channel_reply/pty_runtime+oneshot(clear_env 參數)皆套;duduclaw-core/provider_env.rs provider→env 表 3→1 收斂;行為變更:白名單排除 SSH_AUTH_SOCK/GNUPGHOME(靠 SSH/GPG 的 git push agent 受影響,待拍板改 per-agent 授權);judge_mode env 繼承刻意不改(第五波文件化取捨,改需同步 goal-loop.md)。secret:// 收斂第二輪:account_rotator 2 處+mcp.rs 2 處手刻 decrypt 收斂 SecretRef(順帶修 Odoo 加密指標字面值外送洩漏)——至此殘留清單 #4-6 全清。
  • 第九波(2026-08-16,狀態同步+插件能力)runtime 狀態匯入 P0duduclaw-cli/migrate_from/claude_code.rsclaude_code_transcript.rs)——duduclaw migrate-from claude-code(含逐字稿,需 --agent)單向匯入 Claude Code 狀態:memory shard→semantic+SPO(store_temporal 冪等、valid_from=frontmatter modified)、CLAUDE.md→agent wiki(layer=context 不佔注入預算、trust=0.3)、session 逐字稿→精簡對話+零 LLM 摘要(classify_line 噪音濾除只留 human prompt+assistant text,先對真實 ~/.claude 實測才落碼——有效訊號僅約 1.5%);origin=import(trust≤0.7 強制、不偽裝一手觀察)、內容一律 DATA、redaction 預設開(--no-redact 關,general RuleEngine+secret_redact;shard 只套 secret_redact 免毀可用性)、skill 過 skill_security_scan;dry-run 真實活測 53 專案 1114 項、注入掃描正確擋可疑 shard、無 panic(未 --apply);欠:--apply/worktree .git 指標/dashboard RPC 接線/P1(skills·byte-cursor 增量·codex·gemini·antigravity·grok 平台)。設計全文 commercial/docs/DESIGN-runtime-state-sync-2026-08.mdplugin P2 通道能力表channel_capabilities.rs)——11 通道×7 能力+進度節流單一權威表,收斂 10 處硬編節流字面值與散落的 file/photo/typing 支援判斷,不支援能力從靜默 no-op 改為 log_unsupported/debug_unsupported 留痕;保守用不變量測試鎖定與 decision_markup/channel_editable/typing 本體一致(不改寫本體);欠:handlers/goal_notify 的 gc/teams workaround(home_dir 分歧)、line.rs Step/ModelInfo 過濾缺口。Opus spawn 事故:第八/九波期間 Opus 子代理連續 spawn 即死(0 工具、數秒返回),實作全改 Sonnet 完成;設計文件 commercial/docs/DESIGN-roadmap-post-v1.60-2026-08.md 收錄七到九波路線圖與跨波拍板項。
  • 第十波(2026-08-16,收尾批)per-agent git 憑證授權[capabilities] git_credentials 預設 false)——合規恢復 git push/GPG 簽章:開啟才讓該 agent spawn 子行程額外拿 SSH_AUTH_SOCK/SSH_AGENT_PID/GPG_TTY/GNUPGHOMEspawn_env.rs per-agent 追加層+審計 git_credentials_env_granted 只記名不記值+真子行程 env toggle 活測),預設關與第八波逐位相同;揭露:授權=交出操作者完整 ssh-agent/gpg 身分(協定無更細粒度介面),故逐 agent 明確授權。+claimable_tasks 排除 archived、I-3c 共用 needs_human 重試補 note 欄(後端本就支援)、line.rs Step/ModelInfo 過濾缺口(discord 同缺記後續)、account_rotator provider 表收斂(三份收成兩份)。終驗 core 516/security 340/agent 199/gateway 5459/web 綠。
  • Shared Knowledge Base: Cross-agent wiki at ~/.duduclaw/shared/wiki/ for SOPs, policies, product specs. Wiki target classification (agent/shared/both), visibility control via wiki_visible_to capability. MCP tools: shared_wiki_ls, shared_wiki_read, shared_wiki_write, shared_wiki_search, shared_wiki_delete, shared_wiki_stats, wiki_share
  • Autopilot rule engine: Event-driven automation built on a tokio::broadcast event bus (capacity 8192). AutopilotEngine subscribes to TaskCreated / TaskStatusChanged / ChannelMessage / AgentIdle / CronTick events, evaluates per-rule conditions (all/any + eq/neq/in/not_in/gt/gte/lt/lte/contains ops), and dispatches three action types: delegate (enqueue bus task for target agent), notify (send to channel), run_skill (invoke skill — skill name + target agent validated via alphanumeric allowlist + canonicalize() path containment). Rule CRUD is exposed via dashboard RPC (autopilot.list/create/update/remove/history) and agent-facing MCP autopilot_list; every CRUD call validates trigger_event and action structure at write time. Every execution appends to autopilot_history with status + error context. Three-state circuit breaker per rule (Closed / Open / HalfOpen) prevents self-reinforcing loops: 10 fires in 60s trips to Open (60s cooldown), then HalfOpen allows 1 probe; retry within the probe window re-trips, a quiet probe window returns to Closed. Transitions are logged to autopilot_history and the Activity Feed. MCP → engine bridge runs through SQLite events.db (WAL + monotonic auto-increment id + background prune at 7-day retention) — replaces the legacy events.jsonl file bus so there's no rotation race, no partial-line hazard, no permission concern.
  • Resident sensing (tick_config.rs / tick_source.rs / tick_source_poll.rs / tick_source_ws.rs / autopilot_screen.rs): external data streams — http_poll / command / file_tail / websocket, declared under config.toml [tick] / [[tick.sources]], default off — join the autopilot bus as a new AutopilotEvent::Tick (event_name() = "tick", also a legal CEP first/then name), one task per source with a per-source max_events_per_minute cap (floor 1s) and reserved-field-name/prefix rejection at config-load time (fail-closed per source, never aborts gateway boot); websocket is the one push-based kind (each text frame is a payload through the identical pipeline): ws/wss only, plaintext ws:// restricted to loopback while every other host must be wss:// and re-passes the shared web_fetch::validate_url SSRF gate scheme-mapped to https, optional ≤8×4KB verbatim subscribe frames, exponential reconnect backoff (start interval_secs, ×2, cap 60s, +≤25% jitter, reset after a ≥60s session), binary frames dropped and counted as non_text; every numeric extracted field automatically grows deterministic prev_<f>/delta_<f>/pct_<f> companions so a rule writes {"field":"pct_price","op":"gt","value":2} with no new condition operator. Recent observations live in an in-process TickHub ring buffer (256/source — ticks are NOT persisted to events.db by default; opt-in persist_every_n for an audit trail) that both the delegate wake-up prompt (context_ticks, default 10, cap 50) and an optional per-rule local-model screening layer (action.screen) read from. Screening is local-only (never escalates to cloud) and fail-open by default (unavailable/timeout/unparseable verdict → dispatch anyway unless on_unavailable = "drop"; verdict parsing strips edge ASCII punctuation from the first token before matching YES/NO). Dashboard: ticks.sources/ticks.recent RPCs feed a read-only "即時監控來源" card on the Autopilot settings tab; tick_events_total/tick_dropped_total/tick_screen_total/tick_wakes_total Prometheus counters. D5-W2 hardening: http_poll + websocket accept custom headers (≤8, transport-owned names and CR/LF-bearing values refused at config load; values never logged, never serialized — TickSourceConfig has a hand-written Debug and no Serialize, and ticks.sources exposes only headers_count); websocket gains an idle watchdog + client ping (idle_timeout_secs default 300 / floor 30, ping_interval_secs default 30 / floor 5, 0 disables either, idle > ping enforced — any inbound frame resets both clocks, an idle recycle redials immediately and is deliberately not counted as a drop); and every http_poll request plus every non-loopback wss dial re-resolves DNS at request time through the shared web_fetch::resolve_public_addrs (all resolved addresses must be public or the whole answer is refused, then pinned — reqwest resolve_to_addrs for HTTP, a TcpStream dialled at the vetted addresses with hostname-derived SNI for WS), which also replaced and hardened the single-address re-pin previously inlined in web_fetch_cached. Third live-fire round (real Kraken wss feed) corrected three pipeline defects: the D2 delta baseline is now per-field last-seen (prev_<f> compares against the last tick in which f actually appeared — wholesale map replacement let interleaved heartbeat frames erase it, measured at ~90% of ticks producing no delta); extracted numeric strings are coerced to JSON numbers ("63669.60000"63669.6, integers staying i64 — every mainstream feed ships string prices, so gt and the delta trio were silently dead; leading zeros / leading + / non-finite stay strings, and the coercion is confined to the tick extraction layer, never the global rule-engine number_pair); and a payload that resolves none of a source's configured json_fields is dropped as DropReason::NoFields rather than emitted as a field-less tick (checked before the rate cap so control frames cannot starve the emission budget; sources with no json_fields, and non-JSON payloads, keep the raw_len behavior). A fourth round added round6 to delta_<f> (it had only ever been applied to pct_<f>): float subtraction of two decimal prices leaves last-bit noise that, post-F2, reached rule comparisons and wake-up prompts directly and flipped thresholds like delta_price gt 0.1; prev_<f> stays verbatim (a reported value, not a derived one) and the integral path bypasses rounding entirely (round6 scales by 1e6 and stops being exact past ~9×10⁹). Two residual settings close the round out: per-source baseline_max_age_secs (default 3600, 0 = never) gives each field's delta baseline a shelf life — past it the baseline is forgotten, the observation reads as a first tick (no delta trio) and re-establishes the baseline, so a field that stopped reporting for a day cannot manufacture a giant fictional move; and global [tick] dns_ttl_secs (default 60, 0 = per-request) lets each source task reuse its already-screened address set for the TTL (lock-free, task-local, keyed host:port), which strengthens rather than weakens the rebinding defence — what is cached is a vetted public address set, and flipping an answer requires a fresh resolution. web_fetch_cached keeps its own semantics. See docs/features/41-resident-sensing.md.
  • Odoo ERP bridge (duduclaw-odoo crate): JSON-RPC middleware supporting CE/EE, 17 MCP tools (CRM/Sales/Inventory/Accounting), EditionGate auto-detection, event polling + webhook. RFC-21 §2 (v1.11.0): per-agent credential isolation — agent.toml [odoo] overrides + OdooConnectorPool keyed by (agent_id, profile) replaces the v1.10.1 global singleton; new Scope::OdooRead/Write/Execute triplet plus allowed_models / allowed_actions (with write:crm.lead qualified-verb form) defence-in-depth filter; tool_calls.jsonl audit attribution carries profile + ok=bool so Odoo activity attributes to the originating agent. See docs/rfc/RFC-21-operator-guide.md for migration playbook. Test-before-save (v1.13.1): odoo.test RPC accepts inline params — when params include url/db/credentials the connector is built from the form values without touching config.toml; omitting the credential field falls back to the stored encrypted secret; inline-mode params go through the same SSRF / HTTPS / db-name validators as odoo.configure (cannot bypass safety rules); scrub_odoo_error() caps connector failure text at 240 chars before forwarding to the dashboard to avoid leaking HTML error pages or URLs with query strings.
  • Identity Resolution (duduclaw-identity crate, RFC-21 §1, v1.11.0): IdentityProvider async trait with three impls — WikiCacheIdentityProvider (reads <home>/shared/wiki/identity/people/*.md), NotionIdentityProvider (Notion databases/query with configurable field_map), ChainedProvider (cache → upstream with graceful degrade on outage). identity_resolve MCP tool gated by Scope::IdentityRead returns canonical ResolvedPerson records. Channel reply auto-injects an XML-delimited <sender> block into the system prompt (resolved once per turn) so SOUL.md "reject non-project members" rules become evaluable from data instead of mid-reasoning shared_wiki_read lookups.
  • Shared wiki SoT policy (RFC-21 §3, v1.11.0): operators drop ~/.duduclaw/shared/wiki/.scope.toml to declare which top-level namespaces (identity/, access/, policies/, ...) are owned by an external sync. Three modes — agent_writable (default, no change vs. v1.10.1), read_only { synced_from = "<capability>" } (only that capability may write), operator_only (never via MCP). Both shared_wiki_write and shared_wiki_delete honour the policy. wiki_namespace_status MCP tool exposes the active policy. Absent / malformed file ⇒ no policy, fail-safe.
  • Wiki ↔ memory boundary (v1.33, re-opened by WP5c v1.50): conversation distillation feeds two sinks. Ordinary conversational knowledge still lands in the memory system (temporal supersession); durable reference documents (charter / SOP / spec / policy) are auto-filed as agent-local wiki pages. The v1.33 ban on automatic wiki writes is lifted, with each of its three original objections answered structurally: ① duplicationsingle sink: the document's full text exists ONLY as the wiki page, memory keeps a ≤200-char pointer triple (subject = wiki:auto/<doc_type>/<slug>, predicate = documented_in) that store_temporal supersedes automatically; ② curation dilutionfour locks (auto/{charter,sop,spec,policy,reference}/ is the only writable prefix; author: auto-distill + auto-distilled tag self-label every page — no new frontmatter key is invented because parse_wiki_page → serialize_page silently drops unknown keys; .scope.toml is consulted before every write and, unlike the shared-wiki fail-safe, an existing-but-malformed policy stops the auto write; layer: context keeps auto pages out of collect_by_layer_with_meta so they cost 0 bytes of the injection budget and human curation's injected bytes are unchanged — do_not_inject is deliberately NOT set, since WikiStore::search drops such pages and auto pages must stay findable); ③ no supersessiondeterministic page key (resolve_slug validates an LLM slug against ^[a-z0-9][a-z0-9-]{0,63}$, else <doc_type>-<sha8(NFKC title)>), identical content is a no-op, different content overwrites and appends a revision-log line. Grading is knowledge_route.rs: L0 hard exclusions (too short / question / scan_input hit / fallback narrative), then a zero-LLM signal table (≥65 files, 30–64 asks the utility model via four extra fields folded into build_cloud_ingest_prompt_with_knowledge — parsed independently of the fact array so one malformed half cannot break the other, <30 memory path). It runs BEFORE classify_for_ingest and never reads the assistant reply, fixing the defect where a 2,000-char paste answered in eight characters was Skip-ed entirely. Circuit breakers: 20 auto pages + 20 grey-band arbitrations per agent per UTC day (auto_wiki_page::try_consume_quota, cross-process with_file_lock). Every gate degrades to the memory path, never to a failure. Curation station (KnowledgeCuration.tsx) gains a 自動建檔 audit tab — wiki.auto_pages / wiki.promote / wiki.archive / wiki.share RPCs; removal expires exactly that page's pointer via expire_by_subject, NOT invalidate_by_origin (which stays as the clearly-labelled nuclear option). The 待審知識 tab was removed from the station; the knowledge_quarantine approval backend is untouched (burst detection still produces items, released via the inbox). Unchanged from v1.33: session-stable wiki injection (15-min pinned selection + CACHE_SPLIT_MARKER), injection dedup (wiki wins over memory key facts), and .scope.toml knowledge_owner = "memory" excluding a namespace from injection; default = wiki-owned.
  • Per-agent model routing (SDK-first design): agent.toml [model]preferred (Claude SDK model), local.model (local GGUF), local.use_router (confidence router), api_mode (cli/direct/auto), account_pool (which rotator accounts this agent may use). Hybrid routing: ① Local offload (Router-confirmed simple queries) → ② CLI + OAuth rotation (primary brain, subscription quota) → ③ Direct API + API Key (paid fallback, 95%+ cache via cache_control: ephemeral). account_pool wiring (2026-08): previously a serialized-but-unread setting (the dashboard picker wrote it, no backend consumed it). It now narrows the rotator candidate set — applied after the provider/health/cooldown/budget filters and before the strategy runs, so Priority/LeastCost/Failover/RoundRobin are untouched. Entries match account id or dashboard label (exact, trimmed, ASCII-case-insensitive — never substring, per coding convention 2). Fail-open: a pool that matches no available account (stale ids, all cooling down) logs a warn and falls back to the full set — a stale pool can never brick an agent. Empty/unset ⇒ byte-identical to before. Threaded through claude_runner::call_with_rotation (dispatch/cron/heartbeat/goal-loop), channel_reply::call_claude_cli_rotated + call_claude_cli_pty_rotatedrotate_cli_spawn_with_pool (all nine channels), and RuntimeContext.account_poolruntime/claude.rs (multi-runtime choke-point + failover substitutions). Agent-less system callers (GVU/utility, night engine, dashboard widget & expert-pack generation) pass &[].
  • Multi-OAuth account rotation: OAuth sessions (Claude Pro/Team/Max via claude auth status + CLAUDE_CODE_OAUTH_TOKEN env var for setup-token accounts) + API keys, with 4 strategies (Priority/LeastCost/Failover/RoundRobin), health tracking, rate-limit cooldown (2min), billing-exhaustion cooldown (24h), budget enforcement, token expiry tracking (30d/7d warnings). LeastCost prefers OAuth → API. Both the sub-agent dispatcher path (claude_runner::call_with_rotation) and the user-facing channel reply path (channel_reply::call_claude_cli_rotated → testable primitive rotate_cli_spawn) go through the rotator — fixes intermittent "Claude Code not found" errors that previously appeared when the single default OAuth session was cooling down. Channel replies classify failures (FailureReason::RateLimited / Billing / Timeout / BinaryMissing / SpawnError / EmptyResponse / NoAccounts / Unknown) and render category-specific zh-TW messages instead of the misleading "please run claude auth status" hint. Structured failure records are appended to ~/.duduclaw/channel_failures.jsonl for dashboard surfacing. which_claude() / which_claude_in_home() probe Homebrew (Intel + Apple Silicon), Bun, Volta, npm-global, .claude/bin, .local/bin, asdf shims, and NVM version directories so launchd-launched gateways discover the binary without PATH inheritance.
  • Cross-Platform PTY Pool + Worker (duduclaw-cli-runtime + duduclaw-cli-worker crates, v1.15.0): Anthropic blocked claude -p for OAuth-subscription accounts in mid-2026; the official fix is to drive the real interactive claude REPL like a human user. v1.15.0 ships that runtime — long-lived claude sessions through a real PTY (ConPTY on Win 10 1809+, openpty on Unix via portable-pty) with a sentinel-framed in-band response protocol (no scrollback scraping, no sidecar). Default off; per-agent opt-in via agent.toml [runtime] pty_pool_enabled = true. Gateway integration in three new modules: pty_runtime.rs (adapter, RuntimeMode::{FreshSpawn, PtyPool} per-agent routing, acquire_and_invoke / acquire_and_invoke_with public surface), worker_supervisor.rs (Phase 7 — out-of-process duduclaw-cli-worker subprocess gated by [runtime] worker_managed = true; SIGTERM/SIGKILL sequenced into the gateway graceful-shutdown future after prediction-engine flush, before axum drains), runtime_status.rs (Phase 8.5 — GET /api/runtime/status loopback-only JSON endpoint). channel_reply PTY branch routes OAuth accounts → interactive REPL and API-key accounts → oneshot_pty_invoke + claude -p; parse_claude_stream_json_complete + StreamDiagnostics give channel_failures.jsonl actionable post-mortem (exit / lines / events / assistant / text_blocks / thinking / tool_use / result_subtype / stop_reason / last_line / stderr_tail). claude_runner dispatcher-side short-circuit makes channel reply + sub-agent dispatch consistent (skips local-offload + hybrid routing when pty_pool_enabled = true). Phase 8 Prometheus observability — pty_pool_* counters (acquires / cache-hit / spawn / 3 eviction reasons / 4 invoke outcomes / duration histogram), worker_health_misses_total + worker_restarts_total, pty_pool_managed_worker_active mode gauge. Smoke harness scripts/smoke-pty-pool.{sh,ps1} covers build + cli-runtime + gateway routing-helper + stream-json parser tests; CLAUDE_SPIKE=1 runs live interactive spike. All PTY paths fall back to legacy tokio::process::Command + claude -p on error — missing worker / unhealthy pool / spawn failure is recoverable, not fatal. Design references dorkitude/maude (Unix-only tmux shim) and runtorque/torque (Unix-only UDS PTY supervisor); portable-pty is what makes one code path span mac/Linux/Windows. Full design + rollout playbook in commercial/docs/runtime-pty-pool-design.md + commercial/docs/TODO-cli-pty-pool-worker.md. Status (2026-07) — kept as standby, default off: Anthropic's 2026-06-15 programmatic-usage split (that would have broken OAuth -p) was paused on the day; claude -p still works for OAuth-subscription accounts, so the default FreshSpawn path is fully functional and PTY pool is not required — flip it on only if Anthropic re-activates the split. Known limitation (must understand before enabling): pool sessions are keyed by (agent, cli_kind, bare_mode, account, model) with no conversation dimension, so a multi-conversation agent's REPL is shared across conversations and bleeds context (conversation B sees conversation A's workflow state). The default fresh-spawn -p path is not affected — it holds no CLI-side session state; per-turn context comes solely from get_messages(session_id) and session ids are per-conversation (WebChat composes webchat:<conn>#agent:<id>#conv:<nonce> via compose_session_id; the --resume deterministic-id path was removed — all callers pass None).
  • CostTelemetry: SQLite-backed token usage tracking with cache efficiency analytics (cache_read / (input + cache_read + cache_creation)), 200K price cliff warning, adaptive routing (auto prefer_local when cache_eff < 30%). MCP tools: cost_summary, cost_agents, cost_recent.
  • Direct API client (direct_api.rs): Bypasses Claude CLI for pure chat, calls Anthropic Messages API with cache_control: ephemeral on system prompt → 95%+ cache hit rate. Singleton reqwest::Client with 120s timeout. Used as fallback when all OAuth accounts are rate-limited. Layered cache breakpoints: system prompt can be split via CACHE_SPLIT_MARKER into ≤3 independently-cached blocks (static / semi-stable) so a semi-stable change doesn't invalidate the whole prefix; call_direct_api_attributed(scope, …) hashes each cached block per agent:model stream and classifies every prefix invalidation (cold / none / system_block_N / layout) — cache_attribution_snapshot() tells you which block keeps breaking the cache, not just that efficiency is low.
  • Channel hot-start/stop: Dashboard channels.add immediately launches the channel bot; channels.remove aborts the running task. No gateway restart needed.
  • Local inference engine (duduclaw-inference crate): Unified InferenceBackend trait with pluggable backends — llama.cpp (Metal/CUDA/Vulkan/CPU via llama-cpp-2), mistral.rs (Rust-native via mistralrs-core with ISQ on-the-fly quantization, PagedAttention, Speculative Decoding), OpenAI-compatible HTTP (Exo/llamafile/vLLM/SGLang). Hardware auto-detection, GGUF model management (~/.duduclaw/models/), configured via inference.toml. MCP tools: model_list, model_load, model_unload, inference_status, hardware_info, route_query.
  • Confidence Router: Three-tier query routing (LocalFast → LocalStrong → CloudAPI) based on heuristic confidence scoring — token count, keyword complexity detection, CJK-aware token estimation. Configurable thresholds and keyword lists in inference.toml [router]. Router escalation: when confidence is low, automatically falls back to Claude API through the AccountRotator. Calibrated cascade routing (arXiv:2410.10347, opt-in via [router] post_hoc_enabled): after a local tier answers, post-hoc confidence g = sigmoid(α·exp(mean_logprob) + β) (Platt scaling) decides accept-vs-escalate (LocalFast → LocalStrong → cloud); the OpenAI-compat backend captures logprobs when enabled; logprobs-absent or disabled paths behave exactly as ex-ante routing.
  • InferenceManager: Multi-mode auto-switching state machine with priority: Exo P2P cluster → llamafile → Direct backend → OpenAI-compat → Cloud API. Periodic health checks with automatic failover between modes.
  • Exo P2P cluster client (exo_cluster.rs): HTTP client for Exo distributed inference, cluster discovery, health monitoring, automatic endpoint failover. Enables 235B+ models across multiple machines.
  • llamafile manager (llamafile.rs): Subprocess lifecycle management for Mozilla's single-binary LLM inference — auto-start/stop, health monitoring, ready-wait polling, OpenAI-compatible API on localhost. Zero-install portable inference across 6 OS.
  • MLX bridge (mlx_bridge.rs): Python subprocess calling mlx_lm on Apple Silicon for local text generation, LoRA adapter support for agent personality.
  • Token/prompt compression (gateway/prompt_compression.rs): budget-enforcement pipeline on the reply path — TurnTrim (per-turn 800/200-char tail trim; formerly HermesTrim) → DropOldestToolEchoes → BisectAndSummarize, cost-pressure aware, CJK-safe token estimation. (The former three-strategy compressor in the inference crate — Meta-Token/LTSC, LLMLingua-2 bridge, StreamingLLM — was removed in v1.33: it was reachable only via manual MCP tools and duplicated this live pipeline.) minimal_context spawn (第七波, [runtime] minimal_context default ON, env DUDUCLAW_MINIMAL_CONTEXT=0 / per-agent off-switch): every official-CLI spawn carries --tools <curated list> (CURATED_BUILTIN_TOOLS/DISPATCH_DEFAULT_BUILTIN_TOOLS in duduclaw-core/types.rs; capability-explicit wins, only-narrows) + --setting-sources project,local — measured 35,892→10,974 fixed overhead/spawn (~69%). Deliberately NOT --setting-sources "" (would disable the cwd .claude/settings.json agent-file-guard hook; project,local saves the same tokens while keeping it). estimate_tokens was CJK-recalibrated (codepoint-classed, was chars/1.5 underestimating ~22%). The context-bloat motive behind the SHELVED oauth_direct path (commercial/docs/DESIGN-oauth-direct-llm-2026-08.md) is answered here at zero ToS risk; the biggest remaining fixed cost is DuDuClaw's own ~191 MCP tool schemas — handle_tools_list now filters by caller capability (discoverable ⊆ callable) but aggressive scaffold-agent curation is DEFERRED (MCP tools/list is the declaration surface; hiding undeclared tools makes them uncallable without dynamic list_changed/meta-invoke).
  • MCP tools (inference): model_list, model_load, model_unload, inference_status, hardware_info, route_query, inference_mode, llamafile_start, llamafile_stop, llamafile_list.
  • Evolution external factors: User feedback, security events, channel metrics, Odoo business context, peer agent signals feed into prediction engine and GVU reflections
  • API key encryption: AES-256-GCM stored as base64 in config (all tokens including channel tokens)
  • Summarized-failure retry (context decontamination, arXiv:2605.08563): rotate_cli_spawn passes a deterministic one-line failure summary into the retry attempt after model-behavior failures (Timeout / EmptyResponse) via a <retry_context> block appended to the user message; infra failures (rate limit / billing / auth) keep the prompt byte-identical to preserve prompt cache. Zero LLM cost, synthesized from FailureReason — never raw stderr.
  • MCP HTTP/SSE Transport (W20-P1/P2, v1.9.4): duduclaw http-server --bind 127.0.0.1:8765 exposes Bearer-authenticated REST + SSE endpoints — POST /mcp/v1/call (single JSON-RPC tool call), GET /mcp/v1/stream (long-lived SSE event stream), POST /mcp/v1/stream/call (async + SSE result push), GET /healthz (no auth). Token bucket rate limit (OpType::HttpRequest, 60 req/min). mcp_sse_store.rs manages SSE connections with broadcast channels. Complements stdio transport for external HTTP clients.
  • LLM fallback chain (gateway/llm_fallback.rs, v1.9.4): primary model timeout/503/429/overloaded auto-switches to fallback model. Pure functions is_llm_fallback_error / should_attempt_model_fallback are unit-tested. claude_runner.rs hard-deadline arm now returns Err containing "hard timeout" instead of breaking with partial output, ensuring fallback triggers reliably. UTF-8 truncation uses char_indices for safe char-boundary slicing (no multi-byte panics at byte 512).
  • Evolution Events system (gateway/evolution_events/, v1.9.4 expansion): 30+ event schema definitions (schema.rs +483 lines), async batch+retry emitter (emitter.rs +190 lines), query interface (query.rs 1685 lines), reliability guarantees (reliability.rs 324 lines). HTTP endpoints exposed via handlers.rs and surfaced in the Web ReliabilityPage.
  • LOCOMO memory evaluation (python/duduclaw/memory_eval/, v1.9.4 / W21): retrieval_accuracy / retention_rate / locomo_integrity_check modules, cron_runner triggered daily at 03:00 UTC, 5-minute smoke_test P0, build_golden_qa.py builds the gold-standard QA set from LOCOMO data, 200-entry data/golden_qa_set.jsonl first batch. duduclaw-memory engine adds batch query API for evaluation.
  • Python agents routing module (python/duduclaw/agents/, v1.9.4): capability-based agent routing — capabilities/ (manifest loader + matcher), routing/ (router + resolution + memory_resolver). MCP layer at python/duduclaw/mcp/: API Key auth with key masking, memory tools (store/read/search/namespace/quota) with strict scope enforcement at execute() entry (memory:write / memory:read — patches the v1.9.3 auth gap where any valid API key bypassed scope limits).
  • Discord Gateway hardening (v1.9.2): real op 6 RESUME — persists session_id + resume_gateway_url + sequence across reconnects (no longer issues fresh IDENTIFY every time). select! stall watchdog breaks if no traffic for 2× heartbeat interval (fixed 18-min silent zombie state). Heartbeat channel capacity 1→16 with try_send to avoid reverse-blocking. Op 9 Invalid Session reads d.bool to choose RESUME vs IDENTIFY with 1-5s jitter. Close codes 4007/4009/4003 clear session for fresh IDENTIFY. Backoff cap 300s→60s. Handles RESUMED dispatch.
  • Heartbeat task-board pull is now scheduler-level (v1.9.3): poll_assigned_tasks moved out of execute_heartbeat (which only ran for enabled=true agents — 16 of 17 production agents had enabled=false and never received task-board pulls) into HeartbeatScheduler::run tick body. Scans entire agent registry every 30s; existing 1-hour LIKE-marker cooldown prevents stampedes.
  • duduclaw evolution finalize CLI (v1.9.1, stable in v1.9.4): one-shot recovery for SOUL.md observation windows that should already have closed. --dry-run / --agent <id> filters. Backstop for the 30-min ObservationFinalizer background task that computes post-metrics from prediction.db + feedback.jsonl and confirms / rolls back / extends.

Read the full file on GitHub · 176 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 8d ago First seen · 176 lines · 25,965 tokens per session scan E ddfd3ecfc54d

Subscribe to this mod's changes

DuDuClaw CLAUDE.md is an instructions file published in the GitHub repository zhixuli0406/DuDuClaw (47 stars, last pushed yesterday), licensed Apache-2.0. It adds 25,965 tokens to every session, about $0.1298 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other instructions, from other repositories

next.js AGENTS.md

AGENTS.md instructions for vercel/next.js, covering next.js development guide, codebase structure, monorepo overview, core package: packages/next and other important packages.

vercel/next.js · 7,296 tokens

codex AGENTS.md

AGENTS.md instructions for openai/codex, covering rust/codex-rs, the codex-core crate, code review rules, crate api surface and model visible context.

openai/codex · 5,153 tokens

vscode buildNext.instructions.md

Working notes and architecture documentation for the new esbuild-based build system in build/next. Use when making changes to the new build pipeline (transpile/bundle commands, NLS plugin, source-map handling, resource copying, or self-hosting watch tasks).

microsoft/vscode · 6,785 tokens

vscode oss-third-party-notices.instructions.md

Instructions for microsoft/vscode, covering vs code oss third-party-notices pipeline, architecture, pipeline flow in ci, applying the notice (cutover) and fallback chain (never fail the build).

microsoft/vscode · 5,001 tokens

langchain AGENTS.md

AGENTS.md instructions for langchain-ai/langchain, covering global development guidelines for the langchain monorepo, corridor security analysis, project architecture and context, monorepo structure and development tools & commands.

langchain-ai/langchain · 4,469 tokens

spec-kit AGENTS.md

AGENTS.md instructions for github/spec-kit, covering agents.md, about spec kit and specify, quickstart — add a new integration in 5 steps, integration architecture and integrationmanifest — file tracking.

github/spec-kit · 7,104 tokens