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.
curl -O https://raw.githubusercontent.com/zhixuli0406/DuDuClaw/main/CLAUDE.mdgit clone --depth 1 https://github.com/zhixuli0406/DuDuClawWrote 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.
[](https://agentmods.dev/instructions/zhixuli0406/duduclaw/claude-md)<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>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.
| Model | Per session | Once 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 |
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.
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 (
AgentRuntimetrait) — Claude / Codex / Gemini / Antigravity (agy) / OpenAI-compat five backends,RuntimeRegistryauto-detection, per-agent config inagent.toml [runtime]. Runtime parity (v1.33):RuntimeContextcarriesCapabilitiesConfig; codex/gemini spawn with capability-derived sandbox flags (SandboxLevelReadOnly/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/antigravityexecute()register the duduclaw MCP server in each CLI's native config (codex-coverrides, gemini/antigravity settings.json per-key merge) so non-Claude agents get the full MCP tool surface;agent create --runtimescaffoldsAGENTS.md/GEMINI.mdand rejects typo'd providers;model_matches_provider()warns on[model] preferred↔[runtime] providermismatches - Unified LLM provider layer (
duduclaw-llmcrate, v1.33): the API-level twin of the CLI-levelAgentRuntime— one normalizedChatRequest/ContentPart/StreamEvent/NormalizedUsageshape over four native protocols: Anthropic Messages (layeredcache_control, thinking replay, real SSE), OpenAI Responses API, GeminigenerateContent(thoughtSignatureechoed verbatim), OpenAI-compat chat/completions (8 presets: deepseek/minimax/groq/together/mistral/openrouter/xai/qwen + local; DeepSeekreasoning_content, real SSE).ModelRegistryvendors ~15 models with millicent/MTok prices + price-cliff math + capability flags (user override via~/.duduclaw/models.toml);FallbackRouterimplements 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 parsedserde_json::Valueat the boundary; errors classify into a ten-wayLlmErroraligned withFailureReason. MCP client + tool-loop (mcp_client.rsbehind default-onmcp-clientfeature,tool_loop.rsalways-on): a stdio JSON-RPC MCP client + provider-agnosticrun_tool_loopso the direct-API, local-inference, and the multi-runtime openai-compatAgentRuntimedispatch path get the full MCP tool surface (previously tools were CLI-backend-only; the openai-compatAgentRuntimeused by API-mode Grok/DeepSeek/MiniMax agents sent tools-less messages and could only narrate "I'll go look that up" — nowexecute()drivesrun_tool_loopwith a capability-filteredToolRegistryover a spawned duduclawmcp-server, degrading to plain messages only when no tools are reachable) —ToolRegistryaggregates N MCP servers, the loop feedsToolResultback until the model stops (max-iters cap, per-call errors fed back asis_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.jsonsince 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_agentsMCP tools withreports_tohierarchy. System prompt auto-includes "## Your Team" roster with sub-agents from thereports_tohierarchy (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 walkreports_tountil an ancestor's token is found, then fall back to globalconfig.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_totree is the authority for hierarchical permissions; agents can delegate to their entire sub-tree and escalate to ancestors (any depth, both directions); same-departmentagents 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 fromtool_calls.jsonl(programmatic evidence,resolve_audit_agentattribution, 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 afterCACHE_SPLIT_MARKER; claude_runner uncachedtasks_suffixfor 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, afterCACHE_SPLIT_MARKER/ uncachedtasks_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, inSELF_ECHO_TOOL_NAMES):reasonrequired, supersession chain inworking_state_history.jsonl, optionalexpected_valueCAS (Lettamemory_replacestale-write rejection — concurrent 3-min cron wakes can't stomp each other; expired entries don't satisfy CAS), optionalttl_hoursfor 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.rsRAII 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 viaProgressEvent::TodoUpdate(parses ClaudeTodoWritetool_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 storeteams_conversations.json— the standard Bot Framework proactive pattern; Google Chat via service-accountsend_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 — Telegramreply_to_message+forward_originprovenance, Discordreferenced_message, Slack message-shareattachments[].text(link unfurls excluded), Teamstext/htmlattachment<blockquote>, WhatsAppcontext(annotation only — Cloud API never ships the quoted body); one shared block formatchannel_format::format_quoted_context(CJK-safe 2000-byte cap,QUOTED_SELF_LABELwhen 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 indocs/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_runssemaphore - CronScheduler reads
cron_tasks.jsonl, evaluates cron expressions, fires tasks on schedule.list_cron_tasksreturns 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_upperraise 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 < 5no longer force-confirms after 72h with zero evidence (that was silently producingconfirmedversions with all-zeropost_metrics); it soft-warns at 72h and hard-expires toExpiredNoData(not confirmed, not rolled back) at 14 days. Atomic write (temp + rename) with SHA-256 fingerprint; a SOUL.md already overSOUL_MAX_LINES/SOUL_MAX_BYTES(previously a permanent one-way-valve deadlock, R2) now triggersgvu/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 checksgvu_enabled(previous default mismatch between the struct defaulttrueand the runtime gate'sfalse— R3 — is fixed: fail-closed opt-in everywhere, so an agent needs an explicitgvu_enabled = trueto evolve at all). A stagnation detector (gvu/stagnation.rs, AVO §2.4) scansevolution.dbevery 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 existingrule_lifecyclesemantic-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_matchtrigger tokens (wired toMistakeCategory/FailureReason), ordered strategy, failure history, ≥1 linkedEvalCaseRef(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 Rulesis now signal-match-first + net-score fallback (was pure net-score top-3). One AEE round:gvu/aee/intent.rspicks repair/optimize/innovate deterministically fromagent.toml [evolution] strategy(balanceddefault /innovate/harden/repair_only— replaces raw ε-exploration) →inner_loop.rsruns ≤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.rs—G-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 isNonenot0.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 evalgained--case <id>[,...](exactEvalCaseRefmatch, 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) viaevolution.*/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 playbookAddmust now carry E1EntryAssertions(must_use_tools/must_not_use_tools/output_contains/output_not_contains, ≤6 items × ≤80 chars — WP2.8/D8);playbook/assertions.rsreplays them zero-LLM against recorded eval transcripts, feeding aG-Assertionsgate step ininner_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 existingG-Contractveto 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.rspredicts 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.rsdiffs prediction vs. observation on 4 dimensions and records the transition (transition.rs— SPO fields deliberatelyNoneso transitions stay out of temporal supersession). Every observation carries an explicitObservationFidelity—Full(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; maskedresult_text/input_text): claude/codex/gemini/openai-compat reachFull; 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 astate_updatereply tag with<>stripped) plus a(state, action)visit graph (goal_visit_graph.rs) — repeat-visit streak ≥2 triggers early oscillationneeds_human;foresight_gate.rsflags predicted-failure dispatches;task_rule_induce.rs(A4) deterministically induces task rules from repeated transitions into the existingrule_lifecyclestore (template-based, inject cap 2, same settle/retire lifecycle — NOT playbook entries, per T8/T9). Confirmed post-task facts persist viamerge_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 underconfig.toml/agent.toml [task_forward_model]default off (enabled/calibration_enabled/held_out_gate_enabled).prediction/calibration.rsscores 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-stateHonestLabel(Supported/Candidate/IndistinguishableFromLuck).prediction/rule_gate.rsgates 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 indispatch_engine; channel replies arm the shadow candidates whose playbooksignals_matchtokens hit the turn'sTurnSignalsat 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_rateoverprediction_log; coin-flip fallback under 8 samples). Gate-on channel settles also route injected rules throughsettle_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. Seedocs/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 MCPbelief_submit/belief_settle/belief_stats, settled deterministically against a caller-suppliedrealized_value(three-way Brier, configurable flat band[belief] flat_band_pctdefault 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-rowstats_injectedrecorded 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_mapconfig entry first,zXXXX→XXXXnaming convention as fallback). Stats reusecalibration.rsWilson/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_createacceptsduration_hours(deadline → needs_human, min with global wall-clock) andrisk_boundary(empty ⇒[goal_defaults] baseline_boundaryfive-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):
SqliteMemoryEnginewith episodic/semantic separation and Generative Agents 3D-weighted retrieval. The recency dimension uses Ebbinghaus retrievability (MemoryBank, arXiv:2305.10250):R = exp(-t/S)with stabilityS = base·(1 + k·ln(1+access_count))·(importance/5)— frequently-recalled memories rank higher and survive decay;run_decayarchives entries only when old + low-importance +R < 0.05(replaces the binaryaccess_count == 0heuristic). 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; blendsw_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,MemoryEntryunchanged): (F1) Temporal Memory —memoriesgains 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 existingMistakeNotebook(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-MistakeCategoryunresolved mistakes into one semantic memory rule (reflexion.rs, detached, deterministic synthesis) then marks the sources resolved. Trigger signal is the existingErrorCategory(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 carryrule_stats {helpful, harmful}in metadata (seeded helpful=1 under v1.41 Janus probation — see below); channel reply injects## Learned Rulesranked by net score (cap 3); afterapply_outcome, injected rules settle — Negligible/Moderate → helpful+1, Significant/Critical → harmful+1; net 0 → retired (retired-ruletag, excluded from selection) so stale rules die instead of diluting the prompt. (F3)memory_fetch_batchMCP tool +get_by_idsfetch ≤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 bysource_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 aprobation-ruletag; first harmful settle retires them, helpful≥3 graduates. (4) PORTICO task-scoped grants (arXiv:2606.22504,capability_grants.rs): tools listed inagent.toml [capabilities] scoped_toolsrequire an active grant (MCPcapability_request→ ApprovalBroker, or goal-kickoffgrant:<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 evalgains[[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 pairstool_use↔tool_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_usagerecordscompressed/compression_stages, andcache_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 singlememory_factory::build_memory_engineconstruction point — the operator/dashboard RPC construction point is deliberately ungated (human curation is not screened). (2) Verified-only reflexion:MistakeNotebookentries carryTrajectoryEvidence(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 forduduclaw evaland production) checks that a completion shares a contiguous CJK-safe span with an actual non-error tool result;dispatch_engineruns it before the MAV judge ([dispatch] grounding_precheck_enabled, default on) — hardened with a self-echo deny-list (SELF_ECHO_TOOL_NAMES: tools liketasks_completethat 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.jsonlrecords maskedresult_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), andresolve_audit_agentattributes system-sender dispatches (goal-loop / cron / heartbeat / autopilot, all sixSYSTEM_SENDERS) to the executing agent — fixing the P0 whereDUDUCLAW_DELEGATION_SENDERoverwrote attribution and silently starved every downstream evidence consumer (fidelity stuck atNone, grounding alwaysSkip, 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_souland 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_soulhad zero readers before this) — the only legitimate write paths left are the operator/dashboard and, for a single agent explicitly opted in viacan_modify_own_soul = true, self-write only (never cross-agent). The deadduduclaw-security::rbacmodule (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'sdelegation_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 Rustaudit.rs), validates.env.claude, detects config tampering. All prompts use XML delimiters for injection resistance. Seecommercial/docs/TODO-security-hooks.mdandcommercial/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
CapabilitiesConfiginagent.toml [capabilities]—computer_use,browser_via_bash,allowed_tools,denied_tools.--disallowedToolspassed to Claude CLI.bash-gate.shLayer 1.5 allowlist for Playwright/Puppeteer (requiresDUDUCLAW_BROWSER_VIA_BASH=1env). Seecommercial/docs/TODO-browser-automation.md. - Behavioral contracts (
CONTRACT.toml) withmust_not/must_alwaysboundaries +duduclaw testred-team CLI - Agent behavioral evals (
duduclaw eval, v1.33): golden-task regression for agents —evals/<agent>/*.tomlcases with deterministic tool-call/regex assertions + optional LLM judge (reusesduduclaw-fork::judge); live mode drives the real CLI (captures actualtool_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:--recordrewrites.mcp.jsonto a temp copy pointingDUDUCLAW_HOMEat 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 aserror_max_turns— an assessable failure baseline, not an infra error (infra errors stay hard);duduclaw eval-scaffolddrafts eval cases from an agent's SOUL behavioral rules intoevals-drafts/(free-tier path to the AEE ≥1-EvalCaseRef hard requirement — drafts must be human-reviewed before moving intoevals/); 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). Seedocs/guides/evals.md. - HITL ApprovalBroker (
approval.rs, v1.33): one interrupt/approval primitive spanning MCP tools / autopilot actions / bus tasks — SQLiteapprovals.db(WAL),request/decide/await_decision/expire_stale, TTL-expiry = DENY (fail-closed). Wired into autopilotrequire_approval;agent.toml [capabilities] approval_required_toolsparser; 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-loopneeds_humanescalations 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.listships thesimulationfield). - OpenTelemetry GenAI tracing (
otel.rs, opt-inotelfeature, v1.33):invoke_agent/chat/execute_toolspans following thegen_ai.*semantic conventions, OTLP-exportable (gRPC) to Langfuse/Grafana/Jaeger/Datadog. DEFAULT OFF (zero deps/overhead unlessconfig.toml [telemetry] otlp_endpointset); coexists with the Prometheusmetrics.rslayer. Seedocs/guides/observability.md. - A2A v1.0 Agent Card (
acp/server.rs, v1.33):/.well-known/agent-card.json(v1.0 schema; legacy/agent.jsonalias) with thex-duduclawADR-002 capability-negotiation extension preserved;message/sendis fully wired tobus_queue.jsonl(advisory-locked append, sender identity recorded, honestsubmittedstate — never fakescompleted;tasks/getmaps 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.rsC1), MCP front doors (send_to_agent/spawn_agentC2 with legacycheck_supervisor_relationremoved), task assignment (tasks_create/tasks_updateC3), agent hierarchy creation (create_agent/agent_updateC4 caller-owned-subtree-only), ephemeral spawn (C5 parent==caller). Visibility filtering (C6):list_agents/agent_statusper-caller scope (self + subtree + ancestors + same-dept + white-list;openpolicy 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/setRPC, admin-only) + UI card in advanced settings (radio + pairing editor, no restart needed). ACP entry ([acp] trusted = trueopts intoa2a-clientsender allowlist; default deny). Audit log eventdelegation_deniedcarries sender/target/path_kind/policy. Identity & integrity (v1.52 hardening): HMAC-SHA256 caller token per spawn (DUDUCLAW_AGENT_TOKENenv); PreToolUse hook freezes org fields (agent.toml [agent]name/reports_to/department,config.toml [delegation]/[acp],.mcp.jsonidentity block,.claude/settings.json) to MCP/Edit/Write tools—config mutations routed throughagent_update/dashboard only;require_identity_tokensoft/hard modes in[delegation]. No rank-based auth (hierarchy viareports_totrees 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 viaduduclaw org syncCLI (operator-terminal only, fail-closed in AI sessions),duduclaw org showinspection,duduclaw doctordrift 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_listtools - 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 agoal_modetask (source channel/chat stamped for progress push-back);GoalLoopDriver(30s tick, gated by[dispatch] enabled— default ON since v1.59, opt-out via config or the Settings→Automation「派工引擎」hot-reload switch; the engine + goal-loop driver build/spawn live onMethodHandler::respawn_dispatch_engine/respawn_goal_loop_driverso boot andsystem.update_configshare 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;DispatchEngineacceptance judge is a three-aspect MAV panel (correctness/completeness/safety, one LLM call viarun_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 → earlyneeds_human), all under[goal_loop]config. HITL:needs_humanpushes approve/retry/abort buttons to TG/Discord/Slack/LINE (WP16 codec; text-only fallback elsewhere) + dashboard needs_human board column; per-agent[capabilities] autonomy_levelfive 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 onapproval_required_toolstaking the stricter. Runaway defenses (arXiv 2607.01641): cross-processdispatch_guardsliding-window breaker in duduclaw-core (~/.duduclaw/dispatch_guard.jsonunderwith_file_lock, spawn/ephemeral/cron paths,[dispatch_guard]config), cascadinghop_depthover bus handoffs (envDUDUCLAW_HOP_DEPTH, max 5),termination_manipulationinjection rule (7th input_guard category, weight 30 no instant-block). Seedocs/guides/goal-loop.md. - 兩段式裁決+停滯/收工偵測+交接與目標契約硬化(harness-borrowings 2026-08 Phase 1):三份外部 harness 調研(deepseek-harness/WorkBuddy/grok-build)收斂出的裁決工程借鑑,全部落在既有 MAV 判官與 goal loop 之上,不另起爐灶。兩段式裁決:
dispatch_engine.rssettle 時先跑一個無工具、單次 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_human;system.update_config白名單只收兩值,儀表板「設定→自動化」可切換,只在下次 gateway 真正重啟時生效。交接契約硬化:working_state_handoff新增可選 Ralph 式欄位status/next_steps/evidence/blocker,依 status 強制校驗,超長([memory] working_state_handoff_max_bytes,預設 16384)整筆拒絕絕不截斷。目標契約凍結:/goal/tasks.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_reason(no_progress/budget_exhausted/blocked_needs_decision/infra/restart/unknown,pause_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.tomlexamples優先、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 第五份平行實作);Secretzeroize/Debug 遮蔽/無 Serialize;[mcp_keys]鍵名遮罩補洞;同步路徑網路 backend fail-closed(async 化列 P1)。shared_wiki_deletemain-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.jsonlprovenance 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 補齊六通道、MCPsend_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]]headerssecret://逐請求解析+解析後 CR/LF 重驗、security.credential_inventoryRPC+安全頁憑證來源總表(只報鍵路徑不報值,[mcp_keys]整段跳過——表格鍵名本身就是金鑰)、duduclaw doctor --fix-residue互動式殘留清理、accounts.add不再寫明文孿生鍵;第 6/7 種解密方言收斂(Apps Script 共享密鑰與 inferenceapi_key先前會把secret://參照原樣送給 vendor;BridgeConfig.secret改Secret型別堵 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.rscommit 閘 visible/held-out 混維缺口。批次二(同日):AEE 驗收閘拆維防遮蔽——commit 閘dimensions()並排新增cases_visible/cases_holdout(holdout band 預設主 band 減半、[evolution.noise_band] holdout可設、顯式值鉗不寬於主 band),兩新維 fence-only 只否決不晉升(不重置 anti-drift/不關觀察窗);settlesuite_verdict同修,band 於 commit 時凍結進PendingSettlement.band_holdout(settle 不回讀 config);無 holdout case 行為逐位不變;冠軍 bootstrapinclude_holdout:false蘋果比橘子列拍板項未動。goal 預算耗盡交「最佳輪成品」(goal_budget_best_round.rs純函式三優先序:進過判官團的輪→gap 最少→最後一輪;task_iterations.worker_excerpt於駁回當下快照節錄;judge retry budget 路徑同類接上;零輪誠實空手)。[limits]DocumentLimits(document_limits.rs)守三個下游解析器(soffice 預覽/office_script Python/expert 解壓):解壓總量 256MiB/entry 4096/壓縮比 100:1/XML 深度 128/容器巢狀 4,零遞迴實作,0=預設非無上限;safe_zipheader 謊報洞(宣告 size 累計 vs 實際寫入)一併修補。[office] delivery_gate(artifact_gate.rs,預設開)📎DELIVER 前結構檢查硬失敗(零位元組/magic 不符/zip 損壞)+佔位殘留 warn-only(delivery_gate_placeholder_block可升級硬擋)。agent_id 驗證器五份收斂雙權威版(coreis_valid_agent_id廣義+新is_valid_new_agent_id小寫 slug 契約;MCP 面頭尾連字號漂移修補變嚴;telegram chat_id 兩處刻意不同不併)。 - 第五波(2026-08-15):判官 seam(
judge_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 設計文件結論 SHELVED(commercial/docs/DESIGN-evolution-harness-knobs-2026-08.md:量尺自我認證兩難+樣本量 10³-10⁴/臂不可測;替代品 A1 離線 knob sweep/A2 旋鈕遙測/A3clear_holdout_rotation零呼叫端出口——A3 已 grep 實錘列欠帳)。 - 第六波(2026-08-15,收官波):Agent Mail(
mail.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、ledgermail/mailbox.jsonl照抄 artifacts.jsonl 形狀;死碼email.rs接活;欠:原生 IMAP、channel-registry 整合、autopilot 事件、附件。preset P1(duduclaw-core/preset.rs+duduclaw presetCLI+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.rs+duduclaw 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.rsAPI 模式 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_CACHEinvalidate-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;Odooset_global改disconnect_all+修 profile 變更孤兒 slot bug。仍需重啟:Discord/Slack WS 長駐。P3 env 擦洗——duduclaw-core/spawn_env.rsAGENT_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.rsprovider→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 狀態匯入 P0(
duduclaw-cli/migrate_from/claude_code.rs+claude_code_transcript.rs)——duduclaw migrate-from claude-code(含逐字稿,需--agent)單向匯入 Claude Code 狀態:memory shard→semantic+SPO(store_temporal冪等、valid_from=frontmattermodified)、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.md。plugin 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/GNUPGHOME(spawn_env.rsper-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 viawiki_visible_tocapability. 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::broadcastevent bus (capacity 8192).AutopilotEnginesubscribes toTaskCreated/TaskStatusChanged/ChannelMessage/AgentIdle/CronTickevents, evaluates per-rule conditions (all/any+eq/neq/in/not_in/gt/gte/lt/lte/containsops), 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 MCPautopilot_list; every CRUD call validatestrigger_eventandactionstructure at write time. Every execution appends toautopilot_historywith status + error context. Three-state circuit breaker per rule (Closed/Open/HalfOpen) prevents self-reinforcing loops: 10 fires in 60s trips toOpen(60s cooldown), thenHalfOpenallows 1 probe; retry within the probe window re-trips, a quiet probe window returns toClosed. Transitions are logged toautopilot_historyand the Activity Feed. MCP → engine bridge runs through SQLiteevents.db(WAL + monotonic auto-increment id + background prune at 7-day retention) — replaces the legacyevents.jsonlfile 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 underconfig.toml [tick]/[[tick.sources]], default off — join the autopilot bus as a newAutopilotEvent::Tick(event_name() = "tick", also a legal CEPfirst/thenname), one task per source with a per-sourcemax_events_per_minutecap (floor 1s) and reserved-field-name/prefix rejection at config-load time (fail-closed per source, never aborts gateway boot);websocketis the one push-based kind (each text frame is a payload through the identical pipeline):ws/wssonly, plaintextws://restricted to loopback while every other host must bewss://and re-passes the sharedweb_fetch::validate_urlSSRF gate scheme-mapped to https, optional ≤8×4KB verbatimsubscribeframes, exponential reconnect backoff (startinterval_secs, ×2, cap 60s, +≤25% jitter, reset after a ≥60s session), binary frames dropped and counted asnon_text; every numeric extracted field automatically grows deterministicprev_<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-processTickHubring buffer (256/source — ticks are NOT persisted toevents.dbby default; opt-inpersist_every_nfor an audit trail) that both thedelegatewake-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 unlesson_unavailable = "drop"; verdict parsing strips edge ASCII punctuation from the first token before matching YES/NO). Dashboard:ticks.sources/ticks.recentRPCs feed a read-only "即時監控來源" card on the Autopilot settings tab;tick_events_total/tick_dropped_total/tick_screen_total/tick_wakes_totalPrometheus counters. D5-W2 hardening:http_poll+websocketaccept customheaders(≤8, transport-owned names and CR/LF-bearing values refused at config load; values never logged, never serialized —TickSourceConfighas a hand-writtenDebugand noSerialize, andticks.sourcesexposes onlyheaders_count);websocketgains an idle watchdog + client ping (idle_timeout_secsdefault 300 / floor 30,ping_interval_secsdefault 30 / floor 5,0disables either,idle > pingenforced — any inbound frame resets both clocks, an idle recycle redials immediately and is deliberately not counted as a drop); and everyhttp_pollrequest plus every non-loopbackwssdial re-resolves DNS at request time through the sharedweb_fetch::resolve_public_addrs(all resolved addresses must be public or the whole answer is refused, then pinned — reqwestresolve_to_addrsfor HTTP, aTcpStreamdialled at the vetted addresses with hostname-derived SNI for WS), which also replaced and hardened the single-address re-pin previously inlined inweb_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 whichfactually 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 stayingi64— every mainstream feed ships string prices, sogtand 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-enginenumber_pair); and a payload that resolves none of a source's configuredjson_fieldsis dropped asDropReason::NoFieldsrather than emitted as a field-less tick (checked before the rate cap so control frames cannot starve the emission budget; sources with nojson_fields, and non-JSON payloads, keep theraw_lenbehavior). A fourth round addedround6todelta_<f>(it had only ever been applied topct_<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 likedelta_price gt 0.1;prev_<f>stays verbatim (a reported value, not a derived one) and the integral path bypasses rounding entirely (round6scales by 1e6 and stops being exact past ~9×10⁹). Two residual settings close the round out: per-sourcebaseline_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, keyedhost: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_cachedkeeps its own semantics. Seedocs/features/41-resident-sensing.md. - Odoo ERP bridge (
duduclaw-odoocrate): 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 +OdooConnectorPoolkeyed by(agent_id, profile)replaces the v1.10.1 global singleton; newScope::OdooRead/Write/Executetriplet plusallowed_models/allowed_actions(withwrite:crm.leadqualified-verb form) defence-in-depth filter;tool_calls.jsonlaudit attribution carriesprofile+ok=boolso Odoo activity attributes to the originating agent. Seedocs/rfc/RFC-21-operator-guide.mdfor migration playbook. Test-before-save (v1.13.1):odoo.testRPC accepts inline params — when params includeurl/db/credentials the connector is built from the form values without touchingconfig.toml; omitting the credential field falls back to the stored encrypted secret; inline-mode params go through the same SSRF / HTTPS / db-name validators asodoo.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-identitycrate, RFC-21 §1, v1.11.0):IdentityProviderasync trait with three impls —WikiCacheIdentityProvider(reads<home>/shared/wiki/identity/people/*.md),NotionIdentityProvider(Notiondatabases/querywith configurablefield_map),ChainedProvider(cache → upstream with graceful degrade on outage).identity_resolveMCP tool gated byScope::IdentityReadreturns canonicalResolvedPersonrecords. 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-reasoningshared_wiki_readlookups. - Shared wiki SoT policy (RFC-21 §3, v1.11.0): operators drop
~/.duduclaw/shared/wiki/.scope.tomlto 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). Bothshared_wiki_writeandshared_wiki_deletehonour the policy.wiki_namespace_statusMCP 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: ① duplication → single 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) thatstore_temporalsupersedes automatically; ② curation dilution → four locks (auto/{charter,sop,spec,policy,reference}/is the only writable prefix;author: auto-distill+auto-distilledtag self-label every page — no new frontmatter key is invented becauseparse_wiki_page → serialize_pagesilently drops unknown keys;.scope.tomlis consulted before every write and, unlike the shared-wiki fail-safe, an existing-but-malformed policy stops the auto write;layer: contextkeeps auto pages out ofcollect_by_layer_with_metaso they cost 0 bytes of the injection budget and human curation's injected bytes are unchanged —do_not_injectis deliberately NOT set, sinceWikiStore::searchdrops such pages and auto pages must stay findable); ③ no supersession → deterministic page key (resolve_slugvalidates 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 isknowledge_route.rs: L0 hard exclusions (too short / question /scan_inputhit / fallback narrative), then a zero-LLM signal table (≥65 files, 30–64 asks the utility model via four extra fields folded intobuild_cloud_ingest_prompt_with_knowledge— parsed independently of the fact array so one malformed half cannot break the other, <30 memory path). It runs BEFOREclassify_for_ingestand never reads the assistant reply, fixing the defect where a 2,000-char paste answered in eight characters wasSkip-ed entirely. Circuit breakers: 20 auto pages + 20 grey-band arbitrations per agent per UTC day (auto_wiki_page::try_consume_quota, cross-processwith_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.shareRPCs; removal expires exactly that page's pointer viaexpire_by_subject, NOTinvalidate_by_origin(which stays as the clearly-labelled nuclear option). The 待審知識 tab was removed from the station; theknowledge_quarantineapproval 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.tomlknowledge_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 viacache_control: ephemeral).account_poolwiring (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 accountidor dashboardlabel(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 awarnand falls back to the full set — a stale pool can never brick an agent. Empty/unset ⇒ byte-identical to before. Threaded throughclaude_runner::call_with_rotation(dispatch/cron/heartbeat/goal-loop),channel_reply::call_claude_cli_rotated+call_claude_cli_pty_rotated→rotate_cli_spawn_with_pool(all nine channels), andRuntimeContext.account_pool→runtime/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_TOKENenv var forsetup-tokenaccounts) + 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).LeastCostprefers 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 primitiverotate_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 runclaude auth status" hint. Structured failure records are appended to~/.duduclaw/channel_failures.jsonlfor 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 withoutPATHinheritance. - Cross-Platform PTY Pool + Worker (
duduclaw-cli-runtime+duduclaw-cli-workercrates, v1.15.0): Anthropic blockedclaude -pfor OAuth-subscription accounts in mid-2026; the official fix is to drive the real interactiveclaudeREPL like a human user. v1.15.0 ships that runtime — long-livedclaudesessions through a real PTY (ConPTY on Win 10 1809+, openpty on Unix viaportable-pty) with a sentinel-framed in-band response protocol (no scrollback scraping, no sidecar). Default off; per-agent opt-in viaagent.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_withpublic surface),worker_supervisor.rs(Phase 7 — out-of-processduduclaw-cli-workersubprocess 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/statusloopback-only JSON endpoint).channel_replyPTY branch routes OAuth accounts → interactive REPL and API-key accounts →oneshot_pty_invoke + claude -p;parse_claude_stream_json_complete+StreamDiagnosticsgivechannel_failures.jsonlactionable post-mortem (exit / lines / events / assistant / text_blocks / thinking / tool_use / result_subtype / stop_reason / last_line / stderr_tail).claude_runnerdispatcher-side short-circuit makes channel reply + sub-agent dispatch consistent (skips local-offload + hybrid routing whenpty_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_activemode gauge. Smoke harnessscripts/smoke-pty-pool.{sh,ps1}covers build + cli-runtime + gateway routing-helper + stream-json parser tests;CLAUDE_SPIKE=1runs live interactive spike. All PTY paths fall back to legacytokio::process::Command + claude -pon error — missing worker / unhealthy pool / spawn failure is recoverable, not fatal. Design referencesdorkitude/maude(Unix-only tmux shim) andruntorque/torque(Unix-only UDS PTY supervisor);portable-ptyis what makes one code path span mac/Linux/Windows. Full design + rollout playbook incommercial/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 -pstill works for OAuth-subscription accounts, so the defaultFreshSpawnpath 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-ppath is not affected — it holds no CLI-side session state; per-turn context comes solely fromget_messages(session_id)and session ids are per-conversation (WebChat composeswebchat:<conn>#agent:<id>#conv:<nonce>viacompose_session_id; the--resumedeterministic-id path was removed — all callers passNone). - 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 withcache_control: ephemeralon system prompt → 95%+ cache hit rate. Singletonreqwest::Clientwith 120s timeout. Used as fallback when all OAuth accounts are rate-limited. Layered cache breakpoints: system prompt can be split viaCACHE_SPLIT_MARKERinto ≤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 peragent:modelstream 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.addimmediately launches the channel bot;channels.removeaborts the running task. No gateway restart needed. - Local inference engine (
duduclaw-inferencecrate): UnifiedInferenceBackendtrait with pluggable backends — llama.cpp (Metal/CUDA/Vulkan/CPU viallama-cpp-2), mistral.rs (Rust-native viamistralrs-corewith ISQ on-the-fly quantization, PagedAttention, Speculative Decoding), OpenAI-compatible HTTP (Exo/llamafile/vLLM/SGLang). Hardware auto-detection, GGUF model management (~/.duduclaw/models/), configured viainference.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 confidenceg = 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 callingmlx_lmon 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_contextdefault ON, envDUDUCLAW_MINIMAL_CONTEXT=0/ per-agent off-switch): every official-CLI spawn carries--tools <curated list>(CURATED_BUILTIN_TOOLS/DISPATCH_DEFAULT_BUILTIN_TOOLSinduduclaw-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.jsonagent-file-guard hook;project,localsaves the same tokens while keeping it).estimate_tokenswas 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_listnow 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_spawnpasses 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 fromFailureReason— never raw stderr. - MCP HTTP/SSE Transport (W20-P1/P2, v1.9.4):
duduclaw http-server --bind 127.0.0.1:8765exposes 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.rsmanages 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 functionsis_llm_fallback_error/should_attempt_model_fallbackare unit-tested.claude_runner.rshard-deadline arm now returnsErrcontaining "hard timeout" instead of breaking with partial output, ensuring fallback triggers reliably. UTF-8 truncation useschar_indicesfor 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.rs1685 lines), reliability guarantees (reliability.rs324 lines). HTTP endpoints exposed viahandlers.rsand surfaced in the WebReliabilityPage. - LOCOMO memory evaluation (
python/duduclaw/memory_eval/, v1.9.4 / W21):retrieval_accuracy/retention_rate/locomo_integrity_checkmodules,cron_runnertriggered daily at 03:00 UTC, 5-minutesmoke_testP0,build_golden_qa.pybuilds the gold-standard QA set from LOCOMO data, 200-entrydata/golden_qa_set.jsonlfirst batch.duduclaw-memoryengine 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 atpython/duduclaw/mcp/: API Key auth with key masking, memory tools (store/read/search/namespace/quota) with strict scope enforcement atexecute()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 withtry_sendto avoid reverse-blocking. Op 9 Invalid Session readsd.boolto choose RESUME vs IDENTIFY with 1-5s jitter. Close codes 4007/4009/4003 clear session for fresh IDENTIFY. Backoff cap 300s→60s. HandlesRESUMEDdispatch. - Heartbeat task-board pull is now scheduler-level (v1.9.3):
poll_assigned_tasksmoved out ofexecute_heartbeat(which only ran forenabled=trueagents — 16 of 17 production agents hadenabled=falseand never received task-board pulls) intoHeartbeatScheduler::runtick body. Scans entire agent registry every 30s; existing 1-hour LIKE-marker cooldown prevents stampedes. duduclaw evolution finalizeCLI (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-minObservationFinalizerbackground task that computes post-metrics fromprediction.db+feedback.jsonland confirms / rolls back / extends.
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.
- 8d ago First seen · 176 lines · 25,965 tokens per session scan E ddfd3ecfc54d
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.
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.
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.
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).
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).
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.
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.