Skip to content

feat(mcp): V10 MCP consolidation — single keeper, 21-tool surface, 2-command setup#381

Open
Jurij89 wants to merge 37 commits intomainfrom
chore/v10-mcp-consolidation
Open

feat(mcp): V10 MCP consolidation — single keeper, 21-tool surface, 2-command setup#381
Jurij89 wants to merge 37 commits intomainfrom
chore/v10-mcp-consolidation

Conversation

@Jurij89
Copy link
Copy Markdown
Contributor

@Jurij89 Jurij89 commented May 4, 2026

Summary

  • Consolidates the two MCP packages into one V10 keeper. packages/mcp-dkg (@origintrail-official/dkg-mcp) is retained as the V10 keeper; legacy packages/mcp-server (the V9 dev-coordination MCP) is deleted in this PR. CI lane, root CLAUDE.md, and root package.json realign to the keeper. adapter-autoresearch's loader contract repoints to @origintrail-official/dkg-mcp/adapters so the deletion does not strand its plugin pipeline.
  • Locks the agent-memory tool surface at 21 tools (audit v1.1, parity-matrix v0.8). The canonical write path is dkg_assertion_create + dkg_assertion_write + dkg_assertion_promote + dkg_assertion_discard + dkg_assertion_query (the four-step lifecycle plus its introspection). The canonical recall path is dkg_memory_search (multi-layer fan-out with contextGraphId + layer + trustWeight first-class on every hit) and dkg_query (the renamed-from-dkg_sparql two-axis SPARQL surface — view: working-memory|shared-working-memory|verified-memory + includeSharedMemory: boolean). The publish surface is dkg_publish (fresh-quads → SWM → VM helper) and dkg_shared_memory_publish (canonical Step-4 finalizer for the stepwise flow), both ungated to mirror the OpenClaw adapter exactly per SKILL.md §4a. Ten V9-era and coding-project tools (annotations, sugared decision/task writes, deprecated dkg_search/dkg_sparql, etc.) drop entirely; the annotated git tag pre-v10-tool-drop preserves them.
  • dkg mcp setup + dkg mcp serve ship on the umbrella CLI — true 2-command UX parity with dkg openclaw setup. setup is a bundled, idempotent flow: in order, it (1) initializes ~/.dkg/config.json if absent, (2) starts the DKG daemon as a background process if not already running, (3) funds the node's wallets via the testnet faucet, (4) registers the MCP server with each detected client (Cursor, Claude Code) by writing a single canonical entry — { "command": "dkg", "args": ["mcp", "serve"] } — under mcpServers.dkg, and (5) verifies daemon health. Every step short-circuits when its work is already done, so re-runs are safe. The bundled flow re-uses the same primitives dkg openclaw setup does (loadNetworkConfig, writeDkgConfig, startDaemon, readWalletsWithRetry, requestFaucetFunding), keeping the two verbs byte-aligned on network defaults, daemon-readiness probes, faucet retry/back-off, and manual-curl fallback. serve is the runtime invoked by the client per the JSON block written by setup — never run by the user. End-user install collapses to two commands: npm install -g @origintrail-official/dkg && dkg mcp setup. Repo-root README's Quick Start unifies all on-ramps (MCP, OpenClaw, ElizaOS, Hermes, standalone) into parallel-depth recipes; packages/mcp-dkg/README.md becomes the canonical 21-tool reference.

Related work

  • PR-224 (Cursor & Claude Code DKG integration) — the long-running PR that hardened mcp-dkg from late March through April 2026. The keeper verdict cites this PR's commit trail as primary evidence of mcp-dkg's active V10 development.
  • PR-229 (prior MCP-server review trail) — review-cycle context for the mcp-server retirement.
  • OpenClaw integration Phase 1 — the live round-trip baseline (write → DKG graph → memory search → agent reply) that this PR's dkg_assertion_create + dkg_assertion_write + dkg_memory_search path reproduces verbatim from the MCP surface. qa-engineer's regression harness at af8d9165 reran the OpenClaw round-trip against the consolidated keeper and stayed green.
  • Annotated git tag pre-v10-tool-drop at HEAD 7a2b4090 — preserves the 10 dropped tool source files for any consumer needing the V9 surface. Recovery is git show pre-v10-tool-drop:packages/mcp-dkg/src/tools/<file>.
  • Design archive at agent-docs/dkg-v10-mcp-consolidation/v9-design-archive.md — design intent and reintroduction-pointers for the four substantive V9 patterns this PR retires (per-domain ontology starters, sugared decision/task writes, agent-emitted annotations, auto-promote chat hooks).
  • Cycle-1 deliverables under agent-docs/dkg-v10-mcp-consolidation/ — full audit / matrix / verification trail: v10-keeper-verdict.md (mcp-lead, Task Game coordinator gossip hardening (PR #29 follow-up) #1), parity-matrix.md (parity-analyst, Task Sync drift between peers due to incomplete paranet scope and weak reconciliation #2 → v0.8), docs-audit-and-plan.md (docs-lead, Task the context graph explodes even after 4-5 rounds in the game #3 → v1.10), verification-plan.md (qa-engineer, Task the consensus is hardcoded #4 → v10), tool-inventory-audit.md (audit v1.1), roadmap.md (synthesis).

Files changed (by area)

The 24-commit history flows wave-1 → wave-2 → wave-3 → wave-5; the groupings below regroup by logical scope so reviewers can read the changes without committing to the chronological order.

Keeper additions — new tools and CLI subcommands

The bulk of the new functionality. Lands the P0 agent-memory surface, the publish helpers, the curation primitives, and the umbrella CLI's MCP verbs.

  • packages/mcp-dkg/src/tools/assertions.ts (new, +440) — the seven dkg_assertion_* tools: create, write, promote, discard, query, import_file, history. Mirrors the OpenClaw adapter's DkgNodePlugin.ts write surface byte-for-byte.
  • packages/mcp-dkg/src/tools/memory-search.ts (new, +388) — dkg_memory_search clean lift from DkgMemorySearchManager. Trust-weighted multi-layer fan-out with contextGraphId + layer (the combined SKILL §6.3 string) + trustWeight first-class on every hit (per commit 0e607526).
  • packages/mcp-dkg/src/tools/publish.ts (new, +265) — dkg_publish + dkg_shared_memory_publish. Both ungated, both calling the same POST /api/shared-memory/{write,publish} daemon endpoints; the difference is in input shape (fresh quads vs existing SWM with optional rootEntities filter and opt-in registerIfNeeded for on-chain CG registration).
  • packages/mcp-dkg/src/tools/setup.ts (new, +201) — dkg_context_graph_create, dkg_subscribe, dkg_sub_graph_create. SKILL.md Quickstart Step-1 / Step-3 surfaces, plus the sub-graph staging primitive. dkg_sub_graph_create is idempotent (ensureSubGraph) — a deliberate divergence from the adapter's strict semantics, documented in matrix v0.8 §4.18.
  • packages/mcp-dkg/src/tools/health.ts (new, +92) — dkg_status, dkg_wallet_balances. Trivial wrappers over GET /api/status and GET /api/wallets/balances; mirror the adapter's diagnostic surfaces.
  • packages/mcp-dkg/src/adapters.ts (new, +77) — DKG_ADAPTERS plugin-loader shim ported from the legacy mcp-server (signature widened to (server, client, config) — cleaner than the legacy (server, getClient, contextGraphId?)). Required to keep adapter-autoresearch working post-deletion.
  • packages/cli/src/mcp-setup.ts (new, +447 — wave-1 baseline extended in W6-pre e78d8027) — dkg mcp setup implementation. Bundled, idempotent flow: (1) initializes ~/.dkg/config.json if absent, (2) starts the DKG daemon as a background process if not already running, (3) funds the node's wallets via the testnet faucet, (4) detects Cursor / Claude Code by config-file presence and classifies each client as registered / stale / not-registered, then writes the canonical { command: "dkg", args: ["mcp", "serve"] } entry under mcpServers.dkg, (5) verifies daemon health. Re-uses primitives from dkg openclaw setup (loadNetworkConfig, writeDkgConfig, startDaemon, readWalletsWithRetry, requestFaucetFunding) so the two verbs stay byte-aligned. Step-skip flags: --no-start, --no-fund, --no-verify, --dry-run, --force (stale-entry refresh), --print-only (emit JSON for manual paste). First-init overrides: --port <n>, --name <s>.
  • packages/cli/src/cli.ts (+236) — wires up dkg mcp serve and dkg mcp setup as commander.js subcommands, including all eight setup-flag registrations. dkg mcp serve imports @origintrail-official/dkg-mcp and invokes main(['node', 'dkg-mcp', ...passthrough]) so argv threads correctly through to the inner CLI dispatcher (dkg mcp serve join <invite> works end-to-end without falling through to stdio MCP).
  • packages/adapter-openclaw/src/index.ts (+11) — barrel re-exports loadNetworkConfig, writeDkgConfig, startDaemon, readWalletsWithRetry, logManualFundingInstructions so the dkg mcp setup bundled flow can re-use them without reaching into the adapter's internals. Keeps the two setup verbs byte-aligned by construction.
  • packages/mcp-dkg/src/index.ts (+69 / -…) — registers all six tool families on boot; main() is now exported and accepts argv-as-parameter so the umbrella wrapper at cli.ts can pass through cleanly.
  • packages/mcp-dkg/src/client.ts (+287) — adds createAssertion, writeAssertion, promoteAssertion, discardAssertion, queryAssertion, importAssertionFile, getAssertionHistory, subscribe, createContextGraph, ensureSubGraph, publishQuads, publishSharedMemory, registerContextGraph, getStatus, getWalletBalances, getAgentIdentity. The HTTP wrapper grew alongside the tools.

Keeper renames & schema migrations

Public-tool-surface alignment with SKILL.md and the adapter — three renames + one two-axis schema migration.

  • dkg_sparqldkg_query (commit e0ca5e6a). The daemon endpoint is POST /api/query; both surfaces now use the canonical name. Two-axis schema introduced in the same wave: legacy layer: 'wm'|'swm'|'union'|'vm' enum is replaced by view: 'working-memory'|'shared-working-memory'|'verified-memory' + includeSharedMemory: boolean. The legacy 'union' mode (which conflated two orthogonal axes) becomes view: 'working-memory' + includeSharedMemory: true. Daemon-side wire shape was already two-axis (DkgClient.query accepted both as separate fields per client.ts:133-183); this is a public-tool-surface alignment only — no daemon change.
  • dkg_list_projectsdkg_list_context_graphs (commit e0ca5e6a). Description picks up the audit v1.1 verbatim-locked (also called 'projects' in the DKG node UI) reconciliation note (SKILL.md §6 user-vs-internal terminology).
  • dkg_list_subgraphsdkg_sub_graph_list (commit e0ca5e6a). Hyphenation alignment with the adapter (dkg_sub_graph_* family).
  • Description audit-locks (commits 2d69cef1, 81859985, a966fa99) — four tools' description strings re-aligned to audit v1.1 verbatim text. dkg_sub_graph_create semantics oscillated through 2a803940/a966fa99 (parity-analyst self-correction → final lock as idempotent, divergent from the adapter's strict semantics; matrix v0.8 §4.18 documents the divergence as deliberate UX consistency over byte-for-byte adapter parity).

Keeper drops — 10 tools retired

Commit c222ddcf (refactor(mcp-dkg): drop 10 V9-era and coding-project tools). The dropped surface, by category:

  • V9 ontology startersdkg_get_ontology and seeding scripts (no V10 endpoint backing it; SKILL.md §6 deferred to a future per-CG ontology workflow).
  • Sugared coding-project writesdkg_propose_decision, dkg_add_task, dkg_comment. These deferred to raw dkg_assertion_* writes; the sugar can come back as templated wrappers when collaborative-write semantics matter.
  • Annotation surfacedkg_annotate_turn and the deferred-rendezvous forSession mode. Reintroduction-pointer is the pre-v10-tool-drop tag.
  • Auto-promoting chat hookscapture-chat.mjs reduced from 678 lines to a focused chat-turn-only capture (commit 7a1be910); the auto-promote semantics moved into per-CG config flags as the reintroduction path.
  • Deprecated read aliasesdkg_search (free-text) and dkg_sparql (raw SPARQL) — the former is replaced by the trust-weighted dkg_memory_search; the latter renamed to dkg_query.

Recovery: git show pre-v10-tool-drop:packages/mcp-dkg/src/tools/<file>. Design intent for each drop, plus reintroduction-pointers, in v9-design-archive.md.

Starter-ontology agent-guide stubs (R2 sweep)

Commit c25da46c (chore(mcp-dkg): R2 sweep starter ontologies for V9-era tool refs). The agent-guide markdown files under packages/mcp-dkg/templates/ontologies/{book-research,coding-project,narrative-writing,pkm,scientific-research}/ previously embedded V9 tool names (dkg_propose_decision, dkg_search, etc.). The sweep replaces those references with the V10 surface (dkg_assertion_* family + dkg_memory_search + dkg_query) so agents reading the guides on first use see canonical names. The TTL files themselves carry no tool refs and are unchanged.

Capture-chat reduction (R3 sweep)

Commit 7a1be910 (chore(mcp-dkg+cursor): R3 reduce capture-chat hook to V10 chat-turn capture only). The hook script at packages/mcp-dkg/hooks/capture-chat.mjs is reduced from a multi-mode capture-and-promote machine to a focused chat-turn-only capture (678 → ~150 lines). The auto-promote and per-domain-tag features moved into the dropped-tools archive; the hook now writes chat:Turn triples and stops, deferring promotion to the canonical dkg_assertion_promote path.

Root AGENTS.md removal

Commit e128bb7f (chore(repo): R4 sweep V9 cruft). The repo-root AGENTS.md was a V9-era doc pointing at the legacy mcp-server and the dropped capture-chat semantics. Deleted entirely; canonical agent-facing docs are now packages/mcp-dkg/README.md (tool surface) and the daemon-served SKILL.md at /.well-known/skill.md (API contract).

Transition — CI / CLAUDE.md / package metadata / test pins

Commit abc1a35a (chore(v10-mcp): align CI + CLAUDE.md + package metadata for mcp-server deletion).

  • .github/workflows/ci.yml — filter changed from @origintrail-official/dkg-mcp-server to @origintrail-official/dkg-mcp so the keeper's test lane doesn't silently drop on deletion.
  • Repo-root CLAUDE.md lines 14 + 183 — MCP server config block flipped to point at the keeper; ontology TTL pointer flipped to the re-homed packages/mcp-dkg/schema/dev-context-graph.ttl (renamed from dev-paranet.ttl in the same move; line 193's paranetId? signature comment normalised to contextGraphId?).
  • Root package.jsonmcp script removed (it pointed at the legacy package).
  • packages/cli/test/integrations.test.ts — install-recipe pin updated from ["-y", "@origintrail-official/dkg-mcp@0.1.0"] to the unpinned form (the published version is dev-tagged and moves; pinning to a literal @0.1.0 would not resolve).
  • packages/mcp-dkg/package.json — version bumped from 0.1.0 to 10.0.0-rc.3 for cross-package alignment with the rest of the V10 fleet.

Legacy mcp-server deletion + lockfile

Commit af8d9165 (feat(v10-mcp): delete legacy packages/mcp-server (V10 keeper consolidation)). Removes the entire packages/mcp-server/ directory: src/ (3 files), test/ (3 files), schema/ (re-homed earlier in dev-paranet.ttldev-context-graph.ttl), package.json, README.md, tsconfig.json, vitest.config.ts. pnpm-lock.yaml regenerates accordingly (-19 lines net). adapter-autoresearch's loader-contract repoint (commit f6359d45, lands in the same PR) is the dependency that gates this deletion.

Adapter-autoresearch repoint

Commit f6359d45 (feat(adapter-autoresearch): repoint to mcp-dkg loader contract). The single non-keeper consumer of the legacy mcp-server flips its loader-contract import:

  • packages/adapter-autoresearch/src/tools.ts (+116 / -…) — call-site widens to the new (server, client, config) signature.
  • packages/adapter-autoresearch/src/types.ts (+41 / -…) — type signatures updated.
  • packages/adapter-autoresearch/test/tools.test.ts (+373 / -…) — test scaffolding rewritten against the new shape.
  • packages/adapter-autoresearch/README.md (+10 / -…) — install snippet updated.

Fixture suite (mcp-dkg 52 → 69; cli +9 new)

Commits 7b760331 (W3-A wave-1+wave-2 fixtures), ebbdba28 (W5-Q regression guards), and e78d8027 (W6-pre setup-flow tests).

  • packages/mcp-dkg/test/harness.ts (new, +307) — shared test harness for stdio MCP boots.
  • packages/mcp-dkg/test/assertion-lifecycle.test.ts (new, +203) — covers the create + write + promote + discard + query round-trip.
  • packages/mcp-dkg/test/memory-search.test.ts (new, +130) — covers the trust-weighted fan-out and the contextGraphId + layer + trustWeight hit shape.
  • packages/mcp-dkg/test/query-schema.test.ts (new, +159) — covers the two-axis view + includeSharedMemory schema migration.
  • packages/mcp-dkg/test/setup-publish-health.test.ts (new, +231) — covers dkg_context_graph_create, dkg_subscribe, dkg_sub_graph_create, dkg_publish, dkg_shared_memory_publish, dkg_status, dkg_wallet_balances.
  • packages/mcp-dkg/test/drop-sweep.test.ts (new, +139) — guards against accidental reintroduction of the 10 retired V9 tools (drop-sweep) and the V9-era SPARQL prefixes (read-side regex). Replaces the original commit e3e8eb75's shape after 64880ce0 reverted in favour of the cleaner version.
  • packages/cli/test/mcp-setup.test.ts (new, +219 — W6-pre e78d8027) — 9 tests covering the bundled dkg mcp setup flow under stubbed deps: clean-machine first-run, existing-config skip, all five flag-skip permutations (--no-start, --no-fund, --no-verify, --dry-run, --print-only), --port / --name first-init overrides, and the faucet-failure manual-curl fallback. Lives in packages/cli/test/ (a different vitest project from packages/mcp-dkg/test/).
  • Removed: capture-hook.test.ts (-263), normalise-slug.test.ts (-125), starter-ontologies.test.ts (-118), uri-helpers.test.ts (-52). All four were tied to dropped surfaces; resurrecting via pre-v10-tool-drop would resurrect dead code paths.

README rewrites + docs co-changes

Commits 0b21f09a (W5-A repo-root) and f40002c8 (W5-A mcp-dkg).

  • Repo-root README.md (+131 / -18) — Quick Start unified into a routing table + parallel-depth on-ramp recipes for MCP and OpenClaw, plus an inline 10-step "DKG V10 as agent memory" round-trip quickstart that reproduces the Phase-1 baseline. CLI cheat-sheet gains dkg mcp setup / dkg mcp serve. Setup-Guides table gets the MCP row.
  • packages/mcp-dkg/README.md (+160 / -128) — full canonical V10 form. Drops absolute-path snippets in favour of dkg mcp setup. Documents all 21 tools by category (Health/identity, Discovery, Setup, Write, Publish, Search & query) using audit v1.1 verbatim descriptions. Adds the dkg_publish vs dkg_shared_memory_publish distinction, the two-axis dkg_query schema, the dkg_memory_search hit shape, a package-layout table, and a historical-recovery note pointing at pre-v10-tool-drop and v9-design-archive.md.
  • docs/onboarding/04-package-map.md — six legacy mcp-server mentions rewritten to point at the keeper (lines 23, 50, 182, 183, 244, 267).
  • docs/TWO-LAPTOP-DEMO.md (-170) — V9-era demo doc retired alongside the dropped surfaces.
  • packages/mcp-dkg/docs/RECONCILIATION.md (-103) — V9-era reconciliation doc retired.
  • packages/adapter-autoresearch/README.md (+10 / -…) — loader-contract block updated.

Plan-doc historical record

Commits 0567b8a1 and 12a90a12 restore historical-record references in the planning artifacts under agent-docs/dkg-v10-mcp-consolidation/ per team-lead's wave-3-final ruling. No production-code impact.

Regression guards

The drop-sweep.test.ts and read-side regex checks in commit ebbdba28 are the cheap pre-merge guards qa-engineer proposed in W5-Q: they fail-fast if anyone reintroduces a dropped tool name or a V9 SPARQL prefix in the mcp-dkg source.


Test plan

Co-authored by qa-engineer from verification-plan.md v10.1 §0.10 (W3-D post-deletion verification against af8d9165) + §0.11 (W5-Q regression guards + docs-as-tutorial walkthrough against 0b21f09a + f40002c8, re-verified against 1c4ff9ef + 8e154a15 after W6-pre e78d8027 collapsed steps 2+3+5 into a single dkg mcp setup).

Pre-merge gates — all green

  • Build green (turbo full + keeper filter). pnpm run build → 19/19 turbo tasks. pnpm --filter @origintrail-official/dkg-mcp run build clean. The umbrella CLI's prebuild builds adapter-openclaw + mcp-dkg in sequence; cli's own tsc step succeeds. Closes block-list item Refactor autoupdater #6 (CLI deep-import regression guard post-packages/mcp-server/ deletion).
  • 21-tool surface probe via dkg mcp serve stdio. Spawned the umbrella CLI's dkg mcp serve subcommand against af8d9165, exchanged initialize + tools/list over JSON-RPC. Response: exactly 21 tools by name (sorted): dkg_assertion_create, dkg_assertion_discard, dkg_assertion_history, dkg_assertion_import_file, dkg_assertion_promote, dkg_assertion_query, dkg_assertion_write, dkg_context_graph_create, dkg_get_agent, dkg_get_entity, dkg_list_activity, dkg_list_context_graphs, dkg_memory_search, dkg_publish, dkg_query, dkg_shared_memory_publish, dkg_status, dkg_sub_graph_create, dkg_sub_graph_list, dkg_subscribe, dkg_wallet_balances. None of the 10 dropped names appear; all 3 renamed canonical names appear; all 9 audit-locked adds appear (incl. dkg_assertion_history opportunistically shipped from the audit's P3 deferred bucket).
  • mcp-dkg test suite 69/69 passing. pnpm --filter @origintrail-official/dkg-mcp test. Distribution: assertion-lifecycle.test.ts:11 + setup-publish-health.test.ts:19 + memory-search.test.ts:8 + query-schema.test.ts:14 + drop-sweep.test.ts:17. Pre-W2 suite was 52 (W3-A baseline 7b760331); +17 from W5-Q's drop-sweep.test.ts (ebbdba28). The e3e8eb75 follow-up was reverted by 64880ce0 in favour of the cleaner standalone implementation, so the +19 increment in docs-lead's pre-fill is now +17.
  • adapter-autoresearch test suite 37/37 passing. pnpm --filter @origintrail-official/dkg-adapter-autoresearch test. Loader contract re-pointed in f6359d45 from the legacy mcp-server shape to the keeper's (server, client, config) signature; tests pass against the new contract.
  • packages/cli/test/mcp-setup.test.ts 9/9 passing (W6-pre e78d8027). pnpm --filter @origintrail-official/dkg test. Covers the bundled dkg mcp setup flow under stubbed deps: clean-machine first-run, existing-config skip, all five flag-skip permutations (--no-start, --no-fund, --no-verify, --dry-run, --print-only), --port / --name first-init overrides, faucet-failure manual-curl fallback. Companion to the install-flow simulation gate below.
  • OpenClaw round-trip harness contract intact. Block-list item Game coordinator gossip hardening (PR #29 follow-up) #1 — the live Phase-1 round-trip (write → file watcher → DKG graph → memory_search → reply). pnpm --filter @origintrail-official/dkg-adapter-openclaw test shows 808/810 (the 2 R7 failures noted below are unrelated setup.test.ts:344 autoUpdate config-shape regressions; the round-trip's contract tests at memory-integration.test.ts, dkg-memory.test.ts, memory-search-tool.test.ts all pass). The deletion-gate harness at agent-docs/dkg-v10-mcp-consolidation/scripts/run-openclaw-roundtrip.sh was the canonical pre-deletion gate per §0.10.3; live e2e via the harness is the final pre-merge release-readiness check.
  • Repo-wide stale-name grep — zero hits. git grep -nE 'packages/mcp-server|@origintrail-official/dkg-mcp-server|dev-paranet\.ttl' -- ':!agent-docs/dkg-v10-mcp-consolidation/**' → ZERO. Plus all 10 dropped names + 3 renamed-from names absent across packages/**, docs/**, repo-root: only 4 intentional migration-context comments survive, all confirmed exempt per mcp-lead's Stale dist when installing adapter from local path (I-021) #21 cover note (vitest.config.ts:10, src/tools.ts:141, src/tools.ts:167, src/tools/assertions.ts:7 — historical pointers, not stale code references). The single dkg_sparql mention in packages/mcp-dkg/README.md:148 is intentional historical-context migration documentation explaining dkg_query's view: 'union' replacement; same exempt pattern.
  • Install-flow simulation — dkg mcp setup --print-only byte-identical to documented JSON. Locally: node packages/cli/dist/cli.js mcp setup --print-only emits { "mcpServers": { "dkg": { "command": "dkg", "args": ["mcp", "serve"] } } }. Byte-identical match to repo-root README.md:92-101, packages/mcp-dkg/README.md setup snippet, and repo-root CLAUDE.md:14. The full Docker-isolated install via pnpm pack + clean container is deferred to release-readiness (see below).
  • Cheap regression guards firing as expected. drop-sweep.test.ts (ebbdba28):
    • Drop-sweep block: it.each over the 10 dropped names (dkg_review_manifest, dkg_annotate_turn, dkg_get_ontology, dkg_get_chat, dkg_set_session_privacy, dkg_request_vm_publish, dkg_search, dkg_propose_decision, dkg_add_task, dkg_comment) asserts each is absent; surface-size lock at 21 fires on accidental adds OR removes.
    • Regex-scope guard block: it.each over the 5 read-side tools (dkg_assertion_write, _promote, _discard, _query, _history) asserts each accepts name: "Bad Name With Spaces" per matrix v0.5 §4.16; positive-control test confirms dkg_assertion_create STILL rejects the same input (asymmetry visible in one file).
  • Docs-as-tutorial walkthrough (W5-Q stream B). Walked README 0b21f09a + f40002c8 literally — every CLI command exists (dkg init, dkg start, dkg stop, dkg status, dkg auth show, dkg logs, dkg mcp setup, dkg mcp serve, dkg openclaw setup with all 4 documented flags --no-fund / --no-start / --no-verify / --dry-run, dkg integration {list,info,install} with --tier / --allow-community / --no-verify-provenance flags, dkg context-graph create, dkg shared-memory write/publish, dkg assertion import-file); every JSON output matches the README; every cross-link target resolves (packages/adapter-elizaos/README.md, packages/adapter-hermes/README.md, packages/adapter-openclaw/README.md, packages/mcp-dkg/README.md, docs/setup/SETUP_OPENCLAW.md, docs/setup/SETUP_CUSTOM.md, docs/setup/JOIN_TESTNET.md); mcp-dkg/README.md enumerates exactly 21 tool table rows; first-run verification (README:105) green via the same stdio probe — tools/list includes dkg_assertion_create, dkg_assertion_write, dkg_memory_search; env-var fallback claim matches packages/mcp-dkg/src/config.ts:11-16 exactly for all four (DKG_API, DKG_TOKEN, DKG_PROJECT, DKG_AGENT_URI). Re-verified against 1c4ff9ef + 8e154a15 after W6-pre e78d8027 bundled dkg init + dkg start into dkg mcp setup (now a 2-command flow): all 7 README:110-promised flags exist on the bundled command (--port, --name, --no-start, --no-fund, --no-verify, --dry-run, --force); --print-only JSON output unchanged byte-identical; help text matches the README's "one-shot bundled flow" description. Zero divergences flagged on either pass. docs-lead's rewrite is copy-pasteable end-to-end.

Pre-existing failures noted (NOT introduced by this PR)

  • packages/adapter-openclaw/test/setup.test.ts:344 — 2/810 failures in the writeDkgConfig autoUpdate-config-shape tests. Confirmed reproducible at af8d9165 post-deletion AND on main pre-PR; unrelated to MCP consolidation. Per team-lead's 2026-05-04 sequencing call: surface separately as a post-merge concern. Verification-plan v10 §0.4 / §0.9.3 / §0.10.3 record the chain of confirmations.

Release-readiness gates — explicitly deferred to post-PR-ready / pre-merge

  • Live npm install -g @origintrail-official/dkg against npmjs.org — depends on a publish-authorization the user has not granted. The package's version is 10.0.0-rc.3 per abc1a35a (cross-package alignment); not yet tagged for release.
  • Workstation clean-state install-flow — on a real workstation OS (macOS / Linux / Windows), reset state with rm -rf ~/.dkg ~/.cursor/mcp.json ~/.claude/mcp_servers.json, then global install + dkg mcp setup + dkg mcp serve stdio + tools/list 21-tool assertion. Replaces the originally-planned Docker-based clean-room test: the DKG daemon itself never runs in Docker (Docker references in the repo are limited to optional Blazegraph deployment for devnet and third-party community-integration runtimes), so a Docker test would have masked workstation-specific risks (PATH issues, file permissions, npm global config) that real users hit. Local simulation already passed all gates per §0.10.5 / §0.11.2; the workstation pass is the final pre-merge release-readiness check.
  • Full Cursor / Claude Code round-trip from clean machine — agent invokes dkg_assertion_create + dkg_assertion_write + dkg_memory_search end-to-end. Manual verification step for the release cycle, gated on the live npm install -g working.

QA sign-off

qa-engineer signs off the Test-plan section based on §0.10 + §0.11 verdicts. The 10 pre-merge gates above are green at af8d9165 + ebbdba28 + e78d8027. The 3 release-readiness gates are deferred and documented; they do not block PR-open. Block-list items #1 (OpenClaw round-trip) and #6 (CLI deep-import) — the two non-negotiables from v0 — are both satisfied.


Migration notes

For any present-but-divergent tool, the BEFORE/AFTER notes below cover what consumers see across the consolidation.

dkg_query schema migration (was dkg_sparql)

Before: single-axis layer: 'wm' | 'swm' | 'union' | 'vm' enum.

After: two-axis view: 'working-memory' | 'shared-working-memory' | 'verified-memory' + orthogonal includeSharedMemory: boolean. The legacy 'union' mode (which conflated two axes) is now view: 'working-memory' + includeSharedMemory: true.

Why: 'union' was an enum-conflation that hid the orthogonality. The new shape lets callers express "private working memory plus the team-shared layer" without needing a special mode for it. Daemon-side wire shape already accepted both as separate fields (DkgClient.query at client.ts:133-183); this is a public-tool-surface alignment only — no daemon change required.

Action for consumers: rename calls; map layer: 'union' to view: 'working-memory' + includeSharedMemory: true. Tool name also flips from dkg_sparql to dkg_query.

dkg_list_context_graphs (was dkg_list_projects)

Before: dkg_list_projects — name diverged from the daemon's /api/context-graph/list endpoint.

After: dkg_list_context_graphs. Description carries the (also called 'projects' in the DKG node UI) reconciliation note so users see both terms.

Action for consumers: rename. Output shape unchanged.

dkg_sub_graph_list (was dkg_list_subgraphs)

Before: dkg_list_subgraphs — hyphenation diverged from the adapter's dkg_sub_graph_* family.

After: dkg_sub_graph_list. Sub-graph-CRUD family (dkg_sub_graph_create, dkg_sub_graph_list) is now consistently hyphenated.

Action for consumers: rename. Output shape unchanged.

dkg_memory_search hit-shape additions

Before: raw bindings array per memory layer.

After: each hit carries contextGraphId (the CG the hit was found in), layer (a combined SKILL §6.3 string of the form working-memory:project-id / shared-working-memory:project-id / verified-memory:project-id), and trustWeight (a numeric score; higher-trust layers collapse lower-trust hits for the same entity URI). Three new first-class fields.

Why: lets consumers (and downstream agents) reason about where a memory comes from and how much to trust it without a second SPARQL round-trip.

Action for consumers: existing keyword/limit input arguments unchanged; if your code reads only the bindings array it still works, but you'll likely want to surface the new fields to your agent prompt or UI.

Dropped tools — pre-v10-tool-drop recovery path

The 10 retired tools listed under "Keeper drops" are not present at any name in the V10 surface. For consumers needing the V9 surface:

  • Recovery for individual tool source files: git show pre-v10-tool-drop:packages/mcp-dkg/src/tools/<file> returns the file at HEAD before deletion.
  • Design intent and reintroduction-pointers: agent-docs/dkg-v10-mcp-consolidation/v9-design-archive.md covers the four substantive V9 patterns we retired and the conditions under which each could come back (per-CG ontology workflow lands first → ontology starters; collaborative-write semantics matter again → sugared decision/task writes; etc.).
  • No backwards-compatibility shim — first PR of dkg-v10, clean cut. If your consumer relied on a dropped tool, switch to the V10 surface (dkg_assertion_create + dkg_assertion_write covers the dkg_propose_decision / dkg_add_task use cases at the cost of one extra call) or pin to the pre-v10-tool-drop tag for a frozen V9 surface.

Setup flow (was 4 commands + absolute paths; now 2 commands)

Before: four-command sequence with absolute paths in the wiring snippet.

npm install -g @origintrail-official/dkg     # 1. install
dkg init                                     # 2. configure
dkg start                                    # 3. boot the daemon
# then hand-paste a wiring block referencing /absolute/path/to/packages/mcp-dkg/dist/index.js

After: two-command bundled flow per W6-pre (e78d8027). dkg mcp setup is now an idempotent installer that runs init, daemon-start, faucet funding, MCP-client registration, and verification in a single invocation. Every step short-circuits when its work is already done, so re-running is safe.

npm install -g @origintrail-official/dkg     # 1. install
dkg mcp setup                                # 2. one-shot: init + start + fund + register + verify

The wiring block written into each detected client's config is { "command": "dkg", "args": ["mcp", "serve"] } — copy-pasteable verbatim from the README; no tokens or URLs in the JSON (auth lives in ~/.dkg/auth.token, config in ~/.dkg/config.yaml, env-var fallbacks DKG_API / DKG_TOKEN / DKG_PROJECT / DKG_AGENT_URI for environments where the init step can't run).

Action for consumers: run dkg mcp setup once after upgrading. The flow detects existing config / daemon / clients and skips work that's already been done. --force to refresh stale client entries without prompting; --no-fund for CI; --print-only to emit the JSON for manual paste when no client is detected.


🤖 Generated with Claude Code

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review skipped: filtered diff is 12289 lines (cap: 5,000). Please consider splitting this into smaller PRs for reviewability.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review skipped: filtered diff is 12724 lines (cap: 5,000). Please consider splitting this into smaller PRs for reviewability.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review skipped: filtered diff is 12880 lines (cap: 5,000). Please consider splitting this into smaller PRs for reviewability.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review skipped: filtered diff is 12972 lines (cap: 5,000). Please consider splitting this into smaller PRs for reviewability.

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review skipped: filtered diff is 13123 lines (cap: 5,000). Please consider splitting this into smaller PRs for reviewability.

Jurij Skornik and others added 24 commits May 6, 2026 17:43
- Re-home + rename dev-coordination ontology TTL:
  packages/mcp-server/schema/dev-paranet.ttl ->
  packages/mcp-dkg/schema/dev-context-graph.ttl (paranet terminology dropped;
  one stray paranetId? -> contextGraphId? in the signature-example comment).
- Port DKG_ADAPTERS plugin-loader shim from packages/mcp-server with the
  cleaner signature (server, client, config); drop the DKG_SPARQL_ONLY env
  gate (no backwards-compat shims for first dkg-v10 PR).
- Implement P0 parity tools toward OpenClaw adapter parity:
    dkg_assertion_create / write / promote / discard / query
    dkg_memory_search (re-implemented per parity-matrix v0.7 path B, ~280
    LoC; trust weights WM=1.0 / SWM=1.15 / VM=1.3 cross-pointed to
    packages/adapter-openclaw/src/DkgMemoryPlugin.ts:285-301 for drift
    discipline; eventual dedup path is shared packages/dkg-memory).
- Add dkg mcp setup + dkg mcp serve subcommands to the umbrella CLI:
    setup is idempotent and re-runnable (per-client state-aware prompts:
      registered / stale / not-registered; --force / --print-only / --yes
      flags; skips dkg init re-prompts if ~/.dkg/config.yaml already exists);
    serve is the runtime entrypoint invoked by MCP-aware clients per the
      written { "command": "dkg", "args": ["mcp", "serve"] } config block;
    mcp-dkg main() now exported with argv parameter and self-exec guard so
    the umbrella wrapper can import + dispatch cleanly while the standalone
    dkg-mcp bin still works for clients that prefer the direct invocation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wave-2 prerequisite for the eventual deletion of `packages/mcp-server/`.
Updates the autoresearch adapter to consume mcp-dkg's `loadAdapters` shim
landed in wave-1 (`packages/mcp-dkg/src/adapters.ts`) instead of the
retired mcp-server's pluggable loader.

Architectural call (option Z of three considered): contained per-adapter
daemon-fetch shim. The legacy `DkgClientLike` contract had four methods
(`query`, `publish`, `createContextGraph`, `subscribe`) and mcp-dkg's
`DkgClient` only implements `query`. Bloating the canonical client with
the three missing helpers (option X) would bleed adapter-specific
endpoints into a surface every other tool consumer reads. Hoisting a
shared `DkgDaemonHelpers` module (option Y) is cleaner long-term but
out of scope for this PR. Option Z keeps mcp-dkg's `DkgClient` lean and
contains the legacy contract baggage in the one consumer that needs it.

Concretely:

* `src/types.ts` — `DkgClientLike` shrinks from four methods to one
  (`query`, object-arg shape per mcp-dkg's `DkgClient.query`); a new
  `DkgConfigLike` exposes the `api` + `token` fields the daemon-fetch
  shim reads. Both interfaces are structural so the adapter never takes
  a hard dep on `@origintrail-official/dkg-mcp`'s concrete classes.
* `src/tools.ts` — `registerTools(server, client, config)` replaces the
  legacy `(server, getClient, contextGraphId?)`. Private `daemonPost` +
  `daemonCreateContextGraph` + `daemonSubscribe` + `daemonPublish`
  helpers POST to the same daemon mcp-dkg already talks to via
  `config.api` + `config.token`. SPARQL calls now pass mcp-dkg's
  object-arg `query({ sparql, contextGraphId })` shape.
* `test/tools.test.ts` — full harness rewrite. Replaces the legacy
  `mock.publish.calls` / `mock.subscribe.calls` assertions with a
  `globalThis.fetch` stub (`createDaemonFetchStub`) that captures URL +
  method + parsed body per call. Tests now assert on the captured
  daemon HTTP calls for the write path; the SPARQL read path still
  asserts on the `client.query` mock with the new object-arg shape.

Scope reduction: the legacy 3rd `contextGraphId` override parameter
to `registerTools` is dropped per parity-matrix v0.5 §4.21. Each
adapter targets its own canonical CG. A documenting comment at the
bottom of the test file flags this is reversible as an `opts` bag if
a real consumer surfaces the need.

Test result: 37/37 passing (was 15/38 with 23 contract-mismatch
failures). End-to-end loader smoke verified via `DKG_ADAPTERS=autoresearch`
+ `loadAdapters()` against the built `dist/` — all six autoresearch
tools (`autoresearch_setup`, `_publish_experiment`, `_best_results`,
`_experiment_history`, `_insights`, `_query`) register cleanly through
mcp-dkg's adapter pipeline.

Refs: parity-matrix v0.5 §4.21, roadmap §3 step 3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per user direction (2026-04-30): agents should see provenance per
memory hit. Two new first-class fields plus an existing one promoted
to explicit emission, while the SKILL.md combined-string `layer`
contract stays untouched.

Preserves SKILL.md §6.3 combined-string layer contract:
`agent-context-wm | agent-context-swm | agent-context-vm | project-wm
| project-swm | project-vm`. The same SKILL-canonical principle that
drives the audit's `dkg_sparql` → `dkg_query` rename — SKILL.md is the
agent-facing contract, mcp-dkg follows it. parity-analyst caught the
divergence on the prior attempt (Option A) which split the combined
string into separate `contextGraphId` + 3-element-`layer` axes; Option
B keeps the combined string and ADDS the split fields alongside.

Per-hit shape:

  - `contextGraphId: string` — first-class, no change from prior
                               (already on `Hit`)
  - `layer: string` — combined SKILL form, no change from prior
                      (already on `Hit`)
  - `trustWeight: number` — NEW: numeric weight applied to the score
                            (WM=1.0, SWM=1.15, VM=1.3); explicit so
                            consumers don't re-derive from the layer
                            string
  - `path: string` — NEW: synthetic `dkg://{cg}/{layer}/{hash}`
                     mirroring the adapter shape
                     (`packages/adapter-openclaw/src/DkgMemoryPlugin.ts:410`)
                     so cross-surface tooling sees identical
                     identifiers
  - existing `score`, `entityUri`, `snippet` unchanged

Text-mode rendering surfaces all three provenance pieces up front,
deriving the human-readable CG and tier from the combined `Hit.layer`
at render time (`tierFromCombinedLayer` helper):

  ### 1. [agent-context · VM · weight=1.30 · score=0.87]
  `urn:dkg:memory:abc123`
  <snippet>

Layer rendered uppercase via the helper (no schema change). CG
rendered as-is. Numeric weight + score show two decimal places.
The header's `searchedLayers` and per-layer `breakdown` continue
to emit the SKILL combined strings (`agent-context-wm` etc.) so
consumers parsing the rendered text see the contract verbatim.

Trust weighting and trust-tier dedup unchanged: tier determined by
the view, not the CG, so an agent-context VM ties with a project
VM. Source-of-truth pointer to
`packages/adapter-openclaw/src/DkgMemoryPlugin.ts:285-301,391-398`
preserved in the file header alongside qa-engineer's Case 3 drift-
detector note.

Test result: 101 mcp-dkg tests passing (same pre-existing
`capture-hook.test.ts` syntax-error failure, unchanged from prior
commit). Smoke-tested the rendered output end-to-end against a stub
`DkgClient` returning seeded bindings across all six layers — VM >
SWM > WM trust ranking holds, header lines emit SKILL combined
strings, per-hit lines emit the human-readable provenance triple.

Refs: roadmap §3 wave-2; SKILL.md §6.3; matches dispatch-brief text
spec verbatim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wave-2 rename pass per parity-analyst's tool-inventory-audit §7
items 5, 10, 11. SKILL.md (`packages/cli/skills/dkg-node/SKILL.md`)
is the source-of-truth contract for the V10 agent-facing tool surface;
mcp-dkg was the divergent surface for these three.

* `dkg_sparql` → `dkg_query` (audit §7 item 5 + SKILL.md line 175,
  `POST /api/query`). Includes a TWO-AXIS SCHEMA MIGRATION beyond
  the rename: the legacy `layer: 'wm' | 'swm' | 'union' | 'vm'` enum
  conflated two orthogonal axes. The new shape exposes them
  separately:
    view: 'working-memory' | 'shared-working-memory' | 'verified-memory'
    includeSharedMemory?: boolean
  The `'union'` mode (`view: 'working-memory' ∪ SWM`) now requires
  explicit `view: 'working-memory' + includeSharedMemory: true`. The
  daemon-side wire shape already accepts both as separate fields per
  `client.ts:133-183`; this is a public-tool-surface alignment only,
  no daemon change needed. Surviving call sites of the legacy
  `includeSharedMemory: true` path (in `dkg_get_entity` and
  `dkg_get_agent`) continue to work — those tools call
  `client.query` directly with the same two-axis shape.

* `dkg_list_projects` → `dkg_list_context_graphs` (audit §7 item 10
  + SKILL.md line 174, `GET /api/context-graph/list`). Description
  string now opens with "List every context graph this DKG node
  knows about (also called 'projects' in the DKG node UI)" so MCP
  consumers see the UI/canonical equivalence on the tool surface
  itself — they don't need to read SKILL.md to learn that "project"
  in the UI maps to "context graph" on the wire.

* `dkg_list_subgraphs` → `dkg_sub_graph_list` (audit §7 item 11 +
  SKILL.md line 175 + adapter `DkgNodePlugin.ts:2373` — both
  agree on the canonical verb-noun shape).

Per the no-backwards-compat-shims rule for the first dkg-v10 PR
(memory: `feedback_no_backwards_compat`): no aliasing, no
re-export under the old names. The legacy registrations are
removed cleanly.

Two cross-reference doc-string updates: `dkg_assertion_query` and
`dkg_memory_search` had description text mentioning `dkg_sparql`
as the precision SPARQL alternative — both now say `dkg_query`.

No tests pinned the old names (verified by `grep` across
`packages/mcp-dkg/test/` + `packages/mcp-dkg/scripts/` — no
matches), so no test-side updates were needed. 101 mcp-dkg tests
still pass post-rename. Smoke-tested `dkg_query` end-to-end:
all three argument patterns (working-memory + includeSharedMemory,
verified-memory only, defaults) route through to
`client.query` correctly.

Refs: parity-analyst audit §7 items 5/10/11, audit §5 naming
table, SKILL.md §4a tool table, no-backwards-compat-shims rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wave-2 drop pass per parity-analyst's tool-inventory-audit §7
items 13-19 + the user's 2026-05-04 sign-off on the sugared
coding-project tools.

Recoverable via `git show pre-v10-tool-drop:<file>`. Sugared
dev-coordination tools (decision/task/comment) may be re-introduced
after root CLAUDE.md cleanup if needed.

Tools dropped (10 total):

V9-era / no SKILL.md analog (7):
  1. dkg_review_manifest    — manifest-pipeline preview tool. Tool
                              wrapper at `tools/review.ts` deleted;
                              `packages/mcp-dkg/src/manifest/` library
                              code KEPT (consumed daemon-side by
                              `routes/context-graph.ts:976-1075` +
                              `daemon/manifest.ts:140`). Option (a)
                              cheap path per user 2026-05-04.
  2. dkg_annotate_turn      — capture-hook chat-turn annotation
  3. dkg_get_ontology       — V9 starter-ontology lookup; `import-
                              ontology.mjs` workflow not in active use
                              per user 2026-05-04
  4. dkg_get_chat           — V9 capture-hook chat-turn read
  5. dkg_set_session_privacy — V9 chat-session privacy toggle
  6. dkg_request_vm_publish — V9 human-gates-VM marker (superseded by
                              the ungated `dkg_shared_memory_publish`
                              landing in #16)
  7. dkg_search             — V9-coded predicate set; superseded by
                              `dkg_query` (#17 rename) and
                              `dkg_memory_search` (wave-1 P0)

Coding-project sugar dropped per user 2026-05-04 (root CLAUDE.md is
a coding experiment being removed in a separate task; these tied
mcp-dkg to dev-coordination terminology that doesn't earn its keep
on a generic MCP):
  8. dkg_propose_decision
  9. dkg_add_task
  10. dkg_comment

Source-file deletions:
  - packages/mcp-dkg/src/tools/writes.ts (5 tools, all dropped)
  - packages/mcp-dkg/src/tools/annotations.ts (2 tools, both dropped)
  - packages/mcp-dkg/src/tools/review.ts (1 tool, dropped)
  - packages/mcp-dkg/docs/RECONCILIATION.md (V9 look-before-mint
    protocol coupled to dropped sugared writes)

In-place edits:
  - tools.ts: drops `dkg_search` + `dkg_get_chat` + the
    `expandPrefixed` helper used only by `dkg_search`
  - index.ts: removes `registerWriteTools` /
    `registerAnnotationTools` / `registerReviewTools` imports and
    invocation calls

Test-suite deletions (all four files pinned dropped surfaces):
  - test/normalise-slug.test.ts — imported `normaliseSlug` from
    the deleted `tools/annotations.ts`
  - test/uri-helpers.test.ts — imported `toUri` from same
  - test/capture-hook.test.ts — asserted on `dkg_annotate_turn`
    string inside V9 ontology agent-guides
  - test/starter-ontologies.test.ts — asserted on `dkg_search` +
    `dkg_annotate_turn` strings inside V9 ontology agent-guides

`vitest.config.ts` adds `passWithNoTests: true` so the empty test
suite exits clean. qa-engineer's verification-plan v6.x (Task #19)
is the follow-up that wires fresh fixtures for the post-drop
surface (assertion CRUD + memory-search trust ranking + dkg_query
two-axis schema).

V9 infrastructure intentionally kept (out of wave-2 scope per
team-lead brief): `hooks/capture-chat.mjs`,
`scripts/smoke-{annotate,writes}.mjs`, `templates/ontologies/`,
`packages/mcp-dkg/src/manifest/{install,publish,fetch,schema,
templates}.ts`, the `dkg-mcp join <invite>` CLI subcommand. These
have daemon-side consumers and/or are slated for separate cleanup
PRs.

README updated:
  - "agent can do" examples reflect post-PR surface (12 tools)
  - "Tools at a glance" table replaced (12 rows, dropped tools gone)
  - "Layer semantics" → "View semantics" (matches the
    #17 dkg_query schema migration: separate `view` enum +
    `includeSharedMemory: boolean` axis)

Final tool surface: 22 (pre-PR) − 10 (this drop) + 5 (wave-1
assertion quintet) + 1 (wave-1 memory_search, already counted in
the 22) = 12 tools registered. Wave-2 add commit (#16) will land
9 more, bringing the post-PR surface to 21.

Build green. Tests exit clean (no failures; empty test suite
explicitly tolerated by `passWithNoTests: true`).

Refs: parity-analyst tool-inventory-audit §7 items 13-19, user
sign-off 2026-05-04, no-backwards-compat-shims rule, recovery via
`pre-v10-tool-drop` annotated tag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wave-2 add pass per parity-analyst's tool-inventory-audit §7. Brings
the consolidated mcp-dkg surface to its target shape: 21 tools,
matching the audit's "Net surface after applying recommendations"
(22 pre-PR − 10 dropped + 9 added; renames are net-zero).

P0 — SKILL.md Quickstart parity (1):
  - dkg_context_graph_create — wraps `POST /api/context-graph/create`.
    Description includes the "(also called 'projects' in the DKG node
    UI)" UX note per the team-lead direction (mirrors the same lock on
    `dkg_list_context_graphs` from the rename pass). Slugifies `name`
    when `id` is omitted; rejects invalid slugs at the tool boundary.

P1 — high-value canonical write surface (3):
  - dkg_shared_memory_publish — wraps `POST /api/shared-memory/publish`.
    Final canonical-flow step (publish SWM → VM, clear SWM). UNGATED
    per matrix v0.6 / user lock 2026-04-30 — no `agent.canPublishToVm`
    flag; matches the OpenClaw adapter shape exactly. Optional
    `registerIfNeeded` upgrades a local-only CG to on-chain
    registration before publish; defaults `clearAfter` to false on
    subset publishes so unpublished roots aren't dropped from SWM.
  - dkg_publish — wraps the two-call helper
    `/shared-memory/{write,publish}`. "I have fresh quads, publish
    them now" one-shot per SKILL.md §4a. URI vs literal auto-typing
    on object terms mirrors the adapter's `handlePublish` byte-for-byte.
  - dkg_assertion_import_file — wraps
    `POST /api/assertion/{name}/import-file` (multipart/form-data).
    Daemon's extraction pipeline turns markdown / PDF / DOCX / etc.
    into RDF triples. Extension-based content-type inference covers
    .md/.markdown/.pdf/.docx/.html/.htm/.txt/.csv; unmatched falls
    through to application/octet-stream.

P2 — curation / health (4):
  - dkg_status — `GET /api/status`. Node diagnostic.
  - dkg_wallet_balances — `GET /api/wallets/balances`. Pre-publish
    "do I have funds" check; per-wallet balances + chain context.
  - dkg_subscribe — `POST /api/subscribe`. Required for joining
    peer-shared CGs; optional `includeSharedMemory: false` to skip
    SWM sync.
  - dkg_sub_graph_create — `POST /api/sub-graph/create`. Strict
    create (mirrors adapter); for idempotent semantics during
    sugared writes, `client.ensureSubGraph` is the internal path.

P3 — debug/audit (1):
  - dkg_assertion_history — `GET /api/assertion/{name}/history`.
    Lifecycle descriptor (author, extraction status, promotion
    state). 404 surfaces as a tool error.

DkgClient extensions (`client.ts`, +220 lines):

The 9 tools needed methods that mcp-dkg's `DkgClient` didn't have
before. Added: `getStatus`, `getWalletBalances`, `subscribe`,
`createContextGraph`, `createSubGraph`, `publishSharedMemory`,
`publishQuads`, `importAssertionFile`, `getAssertionHistory`,
`registerContextGraph`. All thin wrappers over the same daemon HTTP
routes the OpenClaw adapter's `DkgDaemonClient` calls — wire shapes
mirror byte-for-byte so cross-surface tooling stays consistent.

`importAssertionFile` is the only one that bypasses `request()` —
multipart/form-data needs `FormData` rather than `JSON.stringify`,
so it builds the form locally and shares the auth-header /
base-URL plumbing with `request()` for behavioural parity.

File layout:
  - tools/setup.ts (new) — context-graph + sub-graph + subscribe
  - tools/health.ts (new) — status + wallet balances
  - tools/publish.ts (new) — publish + shared_memory_publish
  - tools/assertions.ts (extended) — import_file + history added
    alongside the wave-1 P0 quintet
  - index.ts — three new register* invocations

Build green. Smoke-tested `main()` exports cleanly (arity 0). Final
tool registration count by file:
  tools.ts: 6
  tools/assertions.ts: 7
  tools/setup.ts: 3
  tools/health.ts: 2
  tools/publish.ts: 2
  tools/memory-search.ts: 1
  Total: 21 — matches audit §7 "Net surface" target.

Tests: still 0 in mcp-dkg's package (the four tests pre-existing
before #18 all pinned dropped surfaces). qa-engineer's
verification-plan v6.x is the follow-up that wires fresh fixtures
for the post-drop + post-add surface.

Refs: parity-analyst tool-inventory-audit §7 items 1, 2, 3, 4, 6,
7, 8, 9, 12; SKILL.md §3 Step 1, §4a, §7; matrix v0.6 ungated
publish lock; user sign-off 2026-05-04.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ocks

Follow-up to #16 (e71afa0). parity-analyst's audit v1.1 specified
verbatim-quote requirements on four tool description strings that my
ship-from-audit-§7 commit met semantically but not literally. Fixing
the divergence so an agent reading SKILL.md and the tool description
sees identical reconciliation language.

`dkg_context_graph_create` (tools/setup.ts) — opens with the v1.1
locked sentence "Create a context graph (called 'projects' in the
DKG node UI). Returns the new CG's id, name, and on-chain
registration status." Earlier shipped wording ("Create a new context
graph on the DKG node (also called a 'project'...)") said the same
thing in different words; the verbatim quote is the agreed lock.

`dkg_list_context_graphs` (tools.ts) — opens with the v1.1 locked
sentence "List all context graphs the node knows about (called
'projects' in the DKG node UI)." Earlier wording was equivalent but
not byte-aligned with audit §7 item 10's quote.

`dkg_publish` and `dkg_shared_memory_publish` (tools/publish.ts) —
audit v1.1 required both descriptions to quote SKILL.md §4a line 182's
disambiguation verbatim so agents pick the right tool without
re-reading SKILL.md. Both now lead with the canonical phrasing:
`dkg_publish` = "I have fresh quads, write+publish now" (two HTTP
calls); `dkg_shared_memory_publish` = "canonical step-4 finalizer
for 'publish existing SWM' (one HTTP call)". Per-tool details
follow.

Tool surface and behaviour unchanged — semantic content of every
description is the same as e71afa0. This commit is purely
description-string alignment to lock cross-doc consistency between
the MCP tool surface and SKILL.md.

Build green. Tool count and registrations unchanged (still 21).

Refs: tool-inventory-audit v1.1 description-string locks, SKILL.md
§4a line 182, §6 line 297.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…t v1.1 locks

Follow-up to e71afa0 + 2d69cef. Diffed every shipped tool shape
against parity-analyst's audit v1.1 schema-source-of-truth message
("Q1+Q2 confirms + all schema sources locked"). Two divergences vs
the locks:

`dkg_sub_graph_create` — shipped strict (via `client.createSubGraph`
which propagated the daemon's "already exists" 409). v1.1 locked
idempotent semantics: route through `client.ensureSubGraph` which
swallows the duplicate-name error so a re-run is a no-op. Matches
the wave-1 `createAssertion` `alreadyExists: true` pattern. Tool
description updated; per-call success message ("Sub-graph 'X' ready
in 'Y'.") no longer claims a fresh create.

`dkg_subscribe` — shipped with `includeSharedMemory` left undefined
when the caller omits, relying on the daemon's `true` default. v1.1
spec'd "Pass `{contextGraphId, includeSharedMemory: true}` by default
per adapter conventions" — same effective behaviour but the tool
contract should make the default explicit. Switched the zod schema
to `.default(true)` so the agent sees the default in the tool
description without having to read the daemon code.

Side-effect cleanup: `client.createSubGraph` (the strict variant
added in e71afa0's `DkgClient` extension to back the now-removed
strict tool) is unused after this rewire. Per the project
no-features-beyond-task rule, dropped from the client. Re-add is one
diff hunk if a future strict-path tool needs it.

Build green. Tool surface and behaviour-on-duplicate-name now match
audit v1.1 locks. Tool count unchanged at 21.

Refs: tool-inventory-audit v1.1 schema-source-of-truth Q&A on
sub_graph_create idempotency + subscribe defaults.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…nalyst self-correction

parity-analyst's audit v1.1 schema-source-of-truth message had recommended
idempotent semantics for `dkg_sub_graph_create` via `client.ensureSubGraph`,
which I aligned to in 8185998. parity-analyst's follow-up review of the
post-#16 commit chain self-corrected: strict is the right call. Three
independent signals all point that way:

  1. SKILL.md is silent on idempotency for this tool.
  2. The daemon route 409s on duplicate sub-graph name.
  3. The OpenClaw adapter exposes the strict path.

The earlier "idempotency parity with `dkg_assertion_create`" framing was
wrong: assertion-create's `alreadyExists: true` shape is a daemon-side
affordance (the route returns the existing assertion's URI, not a 409).
sub-graph creation has no such daemon-side affordance — `ensureSubGraph`
is a CLIENT-side wrapper that catches the 409, originally added for
the wave-1 sugared writes (now dropped). It should not have leaked onto
the public tool surface.

Reverting:
  - `client.createSubGraph` re-added (was dropped in 8185998 once the
    tool stopped consuming it). Strict semantics; daemon's 409 propagates
    as `DkgHttpError`.
  - `dkg_sub_graph_create` tool now calls `createSubGraph` again. Comment
    block + tool description rewritten to reflect strict-is-honest. Tool
    description: "Strict create — the daemon returns an error if a
    sub-graph with this name already exists."
  - `client.ensureSubGraph` retained on the client (no current consumer
    after #18, but parity-analyst's review explicitly preserves it for
    "internal use only"; the sugared writes that used it may be re-
    introduced after root CLAUDE.md cleanup, per Task #18 commit body).

Build green. Tool surface and 21-tool count unchanged. Behaviour
divergence on duplicate-name only: the tool now propagates the daemon's
409 as a tool error rather than swallowing it.

Net commit chain on `chore/v10-mcp-consolidation`:
  - 8185998 had `dkg_sub_graph_create` idempotent (this commit reverts
    that aspect)
  - 8185998's `dkg_subscribe` explicit-true-default change STAYS
    (parity-analyst approved that one)

Refs: parity-analyst e71afa0-review schema-shape self-correction on
2026-05-04. Audit v1.1 sub-graph-create disposition will reflect the
self-correction in matrix v0.8 (Task #20 Part 2): "strict per adapter
and daemon, idempotency lives in `client.ensureSubGraph` for internal
use only."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… lock)

Final lock per parity-analyst matrix v0.8 §4.18 (2026-05-04). Reverts
2a80394 which itself reverted 8185998 — three flips in this thread,
matrix v0.8 §4.18 is the locked disposition that closes it.

Final answer: idempotent via `client.ensureSubGraph`. The
create-family-wide view is what makes it the right call:

  - dkg_assertion_create     → daemon-idempotent (`alreadyExists: true`)
  - dkg_context_graph_create → daemon-idempotent (returns existing CG)
  - dkg_sub_graph_create     → daemon-strict (409 on duplicate)

parity-analyst's source-of-truth verification against
`packages/cli/src/daemon/routes/{context-graph,assertion}.ts` confirms
two of the three create-family tools are daemon-side idempotent. The
strict odd-one-out is `dkg_sub_graph_create`. Wrapping it at the
client level via `ensureSubGraph` gives agents uniform "all *_create
tools are safe to retry" semantics — better UX than asymmetric
behaviour. Adapter parity loses to UX consistency on this one; matrix
v0.8 §4.18 documents the deliberate divergence.

This commit:
  - rewires `dkg_sub_graph_create` tool to call `client.ensureSubGraph`
  - drops `client.createSubGraph` (unused after the rewire; same
    drop pattern as 8185998)
  - rewrites the in-tool comment block to record the create-family
    rationale + matrix v0.8 §4.18 lock for future readers
  - tool description: "Idempotent — a pre-existing sub-graph with the
    same name is silently reused, no error."

History note: leaving the four flip commits (e71afa0 strict ship →
8185998 idempotent → 2a80394 strict revert → THIS idempotent
re-revert) intact rather than rebasing. parity-analyst preferred the
honest history, and a reviewer reading the chain forward sees the
real lock → align → self-correct → re-align discovery cycle. Each
commit body cross-references the prior step so the chain is
self-documenting.

Build green. `client.ensureSubGraph` retained on the client (unused
internally after #18, but is now the public path's backing — sole
consumer is the `dkg_sub_graph_create` tool).

Refs: parity-analyst matrix v0.8 §4.18 lock, daemon route source
verification at routes/context-graph.ts:466,598 + routes/assertion.ts:1273-1277
(two of three create-family tools daemon-idempotent), audit v1.1 +
the create-family-wide rationale that supersedes the post-e71afa0a
adapter-only-source-of-truth flip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#21 R2 — cheap-modified per team-lead's unified ruling. The five
starter ontologies under `packages/mcp-dkg/templates/ontologies/`
have node-ui as a live consumer (`packages/node-ui/src/ui/lib/
ontologyInstall.ts` Vite-glob-imports both `ontology.ttl` and
`agent-guide.md` from each starter dir, and `CreateProjectModal`
exposes them in a UI dropdown). So the directory cannot be
fully deleted — node-ui glob imports would break.

Two-part sweep:

(1) `ontology.ttl` — KEEP as V10-relevant RDF schemas. Surgically
    sweep the 6 dropped-tool refs in two files:

    book-research/ontology.ttl line 102 — `skos:definition` on
      slug-normalisation: "Apply BEFORE comparing dkg_search results"
      → "Apply BEFORE comparing free-text recall results
      (`dkg_memory_search`)".

    coding-project/ontology.ttl:
      - line 50 (file-level `#` comment): "Used by `dkg_annotate_turn`
        to express what each chat turn was ABOUT" → rewritten to
        describe the predicates as written by the capture-chat hook
        and read by `dkg_query` / `dkg_memory_search`.
      - line 63 (`chat:mentions` rdfs:comment): "query dkg_search
        first" → "use `dkg_memory_search` (free-text recall across
        WM/SWM/VM)".
      - line 78 (`chat:proposes` rdfs:comment): "freshly-minted ...
        in the same dkg_annotate_turn call" → "freshly-minted ...
        in the same write batch".
      - line 302 (`UriPattern` rdfs:comment): "Read by
        dkg_annotate_turn at runtime" → just "Documents the URI shape
        the agent should produce".
      - line 336 (`slug-normalisation` skos:definition body):
        "BEFORE calling dkg_search" → "BEFORE comparing free-text
        recall results (`dkg_memory_search`)".

(2) `agent-guide.md` — REPLACE all 5 with a 1-paragraph stub each.
    The agent-guides were V9 capture-hook + sugared-write
    walkthroughs (7-15 dropped-tool refs each in the V9-flagship
    files; the 3 "clean" files were still V9-protocol-shaped, just
    incidentally without dropped-tool name strings). Per
    parity-analyst's audit, applying the stub to all 5 keeps the
    user-facing surface (modal dropdown) consistent — agents
    selecting different starters at project-creation time get
    one consistent experience instead of "this starter has detailed
    V9 walkthrough; that one has a stub."

    Stub template (per-domain one-liner pulled from each starter's
    existing opening paragraph for accuracy):

      # <Domain> agent guide
      This starter ships an RDF ontology for <domain> projects —
      <one-line domain description>. The formal schema lives in
      `ontology.ttl` alongside this guide.

      For V10 MCP tool usage, see
      [packages/cli/skills/dkg-node/SKILL.md](...).
      The tool surface to use against this ontology:
      - `dkg_assertion_create` + `dkg_assertion_write` — populate (WM)
      - `dkg_assertion_promote` — share with peers (SWM)
      - `dkg_shared_memory_publish` — finalize on-chain (VM)
      - `dkg_query` — SPARQL read; `dkg_memory_search` — free-text recall

      The longer per-domain agent-guide walkthrough format will return
      when the V10 ontology endpoint and per-project annotation
      workflow stabilise.

    Five starters: book-research, coding-project, narrative-writing,
    pkm, scientific-research. All five down to ~19-20 lines each.

Out of scope for this commit (handled in R3 and R4 follow-ups):
  - `hooks/capture-chat.mjs` (R3)
  - root `AGENTS.md` + `.cursor/rules/dkg-annotate.mdc` (R4)
  - final cross-package `git grep` verification (lands at end of R4)

Verification: `grep -E '<13 stale names>' packages/mcp-dkg/templates/`
returns zero matches post-sweep. node-ui's `ontologyInstall.ts:178`
existence check still passes (ttl + guide both present in all 5
starter dirs).

node-ui display strings (`ontologyInstall.ts:77-86` hard-coded) are
untouched — the modal still shows "Coding Project ontology",
"Book Research ontology", etc., per parity-analyst's R2 scope concur.

Refs: parity-analyst tool-inventory-audit on starter ontologies,
parity-analyst R2 scope concur, team-lead unified R2/R3/R4 ruling
2026-05-04.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…apture only

#21 R3 — cheap-tighter per team-lead's unified ruling. The V9 capture-
chat sub-system grew to 1201 lines because it bundled three concerns:

  (a) chat-turn HTTP capture — write {chat:Session, chat:Turn} triples
      into the project's chat sub-graph. V10-relevant; keep.
  (b) V9 prompt injection — sessionStart `additionalContext` summarising
      the annotation protocol, per-turn reminders telling agents to call
      `dkg_annotate_turn` / `dkg_search` / `dkg_get_ontology`. Retired
      with the dropped sugared writes; rip.
  (c) V9 sugared-write companion machinery — pending-annotation queue,
      mention-regex backstop, agent self-register, V9 ontology fetch.
      Retired with the dropped tools; rip.

Per team-lead's brief, this commit keeps (a) and rips (b) + (c). Net
file size: 1201 → 642 lines (-559 lines, -47%).

Concretely dropped (~600 lines across helpers + handlers + dispatch):
  - `selfRegisterAgent` — V9 onboarding helper that wrote an
    `agent-self-register-<slug>` assertion on first sessionStart.
  - `applyPendingAnnotations` — V9 race-fix that applied annotations
    queued by `dkg_annotate_turn(forSession=...)` on the next turn
    write. The tool that queued them is gone.
  - `buildPerTurnReminder` — V9 prompt-string builder that injected
    "after your reply, call `dkg_annotate_turn` with `forSession: ...`"
    on every beforeSubmitPrompt event. Retired in spirit and substance.
  - `extractMentionedUris` + the `URN_DKG_RE` regex — defensive backstop
    that auto-emitted `chat:mentions` for any urn:dkg:* URI in turn text
    "even if the agent forgets to call dkg_annotate_turn". The thing it
    backstopped is gone, so the backstop is too.
  - `buildSessionStartContext` — built the multi-paragraph V9
    additionalContext that taught agents the annotation protocol on
    session start. Retired wholesale.
  - `handleSessionStart` — only did V9 self-register +
    additionalContext injection. Retired (the chat:Session triple write
    that USED to live here moves to the lazy bootstrap path inside
    handleAfterAgentResponse, which already did first-turn bootstrap
    for resumed-thread cases).
  - `handleSessionEnd` — only wrote a `dcterms:modified` timestamp on
    session close, which is best-effort and doesn't justify a hook
    event. Retired.

What stays (the V10-relevant chat-turn capture path):
  - Constants + namespaces + RDF helpers (NS / T / P / LIT / URI).
  - Config loader (.dkg/config.yaml walk + env overrides + tokenFile
    expansion).
  - Session state cache (`~/.cache/dkg-mcp/sessions/*.json`).
  - Stdin / payload parsing (`pick`, `extractText`, `extractSessionKey`,
    `sanitiseSlug`, `extractMeta`).
  - Daemon HTTP path (`postJson`, `writeTriples`, `promoteEntities`,
    `perTurnAssertionName`, `shouldPromote`, `ensureSubGraph`).
  - `handleBeforeSubmitPrompt` — stash the pending user prompt for the
    next turn. Unchanged.
  - `handleAfterAgentResponse` — write the `chat:Turn` triples,
    bootstrap the `chat:Session` on first turn, promote to SWM if the
    session isn't private. Reduced (no pending-annotation apply, no
    mention-regex backstop, no `additionalContext` return).

Cross-reference: predicates + sub-graph names stay byte-aligned with
`packages/adapter-openclaw/src/ChatTurnWriter.ts` so a turn captured
via either ingestion path lands in the same RDF shape (per team-lead's
"same logic" direction in the brief).

`.cursor/hooks.json`: dropped `sessionStart` + `sessionEnd` hook
entries since the script no longer handles them. Kept
`beforeSubmitPrompt` + `afterAgentResponse`. Comment updated to record
the V9 retirement so a future reader knows the asymmetry is deliberate.

Verification: zero dropped-tool refs in either file (verified via grep
of all 13 stale tool names: `dkg_review_manifest`, `dkg_annotate_turn`,
`dkg_get_ontology`, `dkg_get_chat`, `dkg_set_session_privacy`,
`dkg_request_vm_publish`, `dkg_search`, `dkg_propose_decision`,
`dkg_add_task`, `dkg_comment`, `dkg_sparql`, `dkg_list_projects`,
`dkg_list_subgraphs`). `node -c capture-chat.mjs` parses clean. Module
import smoke-test loads the 5 retained exports (`parseDotDkgConfig`,
`pick`, `extractText`, `extractSessionKey`, `sanitiseSlug`).

Out of scope for this commit (handled in R4 follow-up):
  - root `AGENTS.md` (R4)
  - `.cursor/rules/dkg-annotate.mdc` (R4)
  - README sections describing the capture hook's now-reduced surface
    (R4 — re-survey after this lands)
  - final cross-package `git grep` verification (lands at end of R4)

Refs: parity-analyst tool-inventory-audit on V9 sub-system retirement,
team-lead unified R2/R3/R4 ruling 2026-05-04 (cheap-tighter on R3 with
ChatTurnWriter cross-reference for converged logic).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deletes downstream V9 artefacts that referenced the 10 dropped MCP
tools (#18), the 3 renamed tools (#17), or otherwise documented
defunct V9 ecosystem flows. After this commit the cross-repo grep
for the 13 stale tool names produces zero hits outside three
intentional migration-context comments (tools.ts, assertions.ts,
vitest.config.ts skip-list) — those stay because they document the
V9→V10 migration path for future readers.

Deletes:
- AGENTS.md (107 lines, 9/13 dropped-tool refs in instructions)
- .cursor/rules/dkg-annotate.mdc (sister V9 rule file)
- packages/mcp-dkg/scripts/smoke-writes.mjs (exercises 5 dropped
  tools end-to-end via JSON-RPC; would fail at first call)
- packages/mcp-dkg/scripts/smoke-annotate.mjs (exercises
  dkg_get_ontology + dkg_annotate_turn; same)
- scripts/import-integration-tasks.mjs (V9 phase-task seed,
  one-shot historical data)
- scripts/send-test-chat-turn.mjs (V9 phase-4 two-machines smoke)
- docs/TWO-LAPTOP-DEMO.md (V9 demo doc on
  feat/cursor-dkg-integration branch; defunct flow)

Edits:
- packages/mcp-dkg/README.md — capture-hook section pruned to the
  2-event surface (sessionStart/sessionEnd dropped from both Cursor
  and Claude Code config blocks, mirroring .cursor/hooks.json)
- packages/mcp-dkg/src/manifest/install.ts — 2 stale
  dkg_review_manifest mentions in JSDoc rewritten to refer to the
  CLI / daemon-route preview surface; buildReviewMarkdown stays live
- packages/mcp-dkg/src/tools/memory-search.ts — user-facing tool
  description was recommending dropped dkg_search; trimmed
- packages/node-ui CreateProjectModal.tsx — comment updated to
  reference canonical V10 write flow (assertion_create + write +
  promote) instead of dkg_add_task
- packages/node-ui WireWorkspacePanel.tsx — user-visible modal copy
  rewritten the same way
- scripts/import-ontology.mjs — doc-comments updated to describe
  dkg_query against the meta sub-graph (script body itself is still
  live; it's a generic seeder)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the empty-test-suite gate before the CI filter flip. Without
these fixtures the CI lane silently runs zero MCP tests once
packages/mcp-server is removed (qa-engineer's verification-plan §0.8
block-list item).

Coverage:
- Assertion CRUD quintet (create, write, promote, discard, query)
  round-trip with @en language-tag preservation through the JSON
  dump.
- Wave-2 P1/P3 assertion adds (import_file: filesystem reads with
  inferred MIME, missing-file errors; history: lifecycle JSON dump).
- dkg_memory_search: 3-layer (no projectId) and 6-layer (projectId)
  fan-out, trust-tier dedup (VM > SWM > WM collapses lower-tier
  hits on the same entity URI), backend-not-ready error path,
  raw-peerId routing (DID-form would silently zero out WM hits),
  SKILL.md §6.3 6-element layer-string contract.
- dkg_query schema migration: accept post-#17 (view +
  includeSharedMemory) shape, reject legacy `layer` enum, lock
  view to the canonical 3 values.
- 9 wave-2 P0/P1/P2 adds: dkg_context_graph_create (slug
  derivation + invalid-slug rejection + canonical-naming UX note),
  dkg_subscribe (default + override includeSharedMemory),
  dkg_sub_graph_create (wrapper-idempotent), dkg_publish
  (URI-vs-literal auto-typing), dkg_shared_memory_publish
  (selection: all default, non-empty rootEntities, registerIfNeeded
  pre-flight), dkg_status + dkg_wallet_balances (zero-arg renders +
  daemon-error path).
- dkg_list_context_graphs + dkg_sub_graph_list rename guards plus
  the SKILL.md §6 reconciliation note ("called 'projects' in the
  DKG node UI") in dkg_list_context_graphs.

Test infrastructure:
- packages/mcp-dkg/test/harness.ts — FakeServer + FakeClient
  in-memory stubs implementing every method mcp-dkg tools call.
  FakeServer.call(name, input) parses input through the registered
  zod schema (strict mode) so schema-rejection assertions are
  honest.
- packages/mcp-dkg/vitest.config.ts — drop passWithNoTests; refresh
  the comment header to point at the new wave-3-A fixtures.

52/52 passing locally on `pnpm --filter @origintrail-official/dkg-mcp test`;
`pnpm build` (tsc --build) is clean (tests live outside rootDir: src).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…r deletion

Coordinated transition commit that locks the pre-deletion housekeeping
in one diff so wave-4 (`packages/mcp-server/` deletion) flips cleanly.
Per qa-engineer's verification-plan §0.8 risk #1, the CI filter flip
must be coupled with the same change-set that flips lockfile/wiring
to keep MCP test coverage on the lane (preventing the silent CI lane
drop that the empty-test-suite fixture work in #23 just guarded).

Five coordinated edits:

1. .github/workflows/ci.yml:404 — `--filter` target
   `@origintrail-official/dkg-mcp-server` → `@origintrail-official/dkg-mcp`.
   Lane stays green via the 52 wave-3-A fixtures landed in `7b760331`.

2. CLAUDE.md:7-18 — MCP server config block flipped to the umbrella
   subcommand form `{ "command": "dkg", "args": ["mcp", "serve"] }`,
   with surrounding prose noting that `dkg mcp serve` is the new
   entry point (the umbrella `dkg` CLI is on PATH after
   `npm install -g @origintrail-official/dkg`).

3. CLAUDE.md:183 — schema TTL pointer `packages/mcp-server/schema/
   dev-paranet.ttl` → `packages/mcp-dkg/schema/dev-context-graph.ttl`
   (the renamed + re-homed TTL from W1#5).

4. package.json:27 — `mcp` script
   `node packages/mcp-server/dist/index.js` →
   `node packages/cli/dist/cli.js mcp serve`. Smoke-tested:
   `dkg mcp serve --help` exits 0 and forwards args into the
   `@origintrail-official/dkg-mcp` `main()` (verified via the
   umbrella's `passthrough` argv synthesis at `cli.ts:1790`).

5. packages/mcp-dkg/package.json:3 — version `0.1.0` → `10.0.0-rc.3`,
   aligning with the repo-wide RC bump on `f8b98ca3`.

6. packages/cli/test/integrations.test.ts:52 + :527 — drop `@0.1.0`
   pin per roadmap §9 decision 14. Published version is
   `0.1.0-dev.<ts>.<sha>` so a `@0.1.0` pin does not resolve; the
   fixture now ships `args: ['-y', '@origintrail-official/dkg-mcp']`
   and the assertion uses loose `.toContain` match on the args
   array. Comments inline-cite the roadmap decision.

The brief listed line 36 alongside 52 + 527; that line is the
hello-world CLI fixture's `version: '0.1.0'` field, exercised by
4 unrelated assertions (L417, L421, L450, L467) — out of scope for
the mcp-dkg pin drop. Flagged via SendMessage; no edits at L36.

Verification:
- `pnpm --filter @origintrail-official/dkg-mcp test` → 52/52 ✓
- `pnpm --filter @origintrail-official/dkg exec vitest run integrations.test.ts` → 41/41 ✓
- `node packages/cli/dist/cli.js mcp serve --help` → exit 0
- `node packages/cli/dist/cli.js mcp serve help` (passthrough) →
  shows the dkg-mcp internal help dispatcher

(Pre-existing unrelated failures on `slot-helpers.test.ts` —
Windows EPERM on `symlink` calls without admin — predate this
commit and are independent of MCP wiring.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ation)

Removes the legacy mcp-server package as the final step in the V10
MCP keeper consolidation. The single keeper is `packages/mcp-dkg`,
which exposes the canonical 21-tool surface (6 read tools + 7
assertion-CRUD tools + 1 memory-search + 3 setup + 2 health + 2
publish) per SKILL.md §4a/§6/§7. The 9 V10-canonical tool adds, 3
renames, and 10 drops landed across waves 1-2 (#16/#17/#18); the
fixture suite landed in #23 (52 tests on the keeper); the transition
wiring (CI filter, CLAUDE.md, version bump, integrations.test pin
drop) landed in #24.

**Scope of this commit:**

1. `git rm -r packages/mcp-server/` — 10 files removed
2. `pnpm install` regenerates `pnpm-lock.yaml` (workspace count 22 → 21)
3. Repo-root `vitest.config.ts` — drops the `packages/mcp-server`
   project entry
4. `RELEASE_PROCESS.md` — release-version-alignment bullet flipped
   `packages/mcp-server/package.json` → `packages/mcp-dkg/package.json`
5. `README.md` — package list line dropped (only one MCP package now)
6. `packages/adapter-autoresearch/README.md` — quick-start prerequisites,
   Cursor/IDE config block, and CLI launch invocation flipped from
   `node packages/mcp-server/dist/index.js` to the umbrella subcommand
   `dkg mcp serve` (same launch path the W3-B `CLAUDE.md` flip uses)
7. `packages/mcp-dkg/src/adapters.ts` — JSDoc no longer compares the
   loader to a non-existent legacy package
8. `docs/onboarding/04-package-map.md` — graph node + section + table
   rows rewritten to point at `mcp-dkg` (with the `dkg mcp serve` UX
   note from CLAUDE.md), only one MCP package remains in the dependency
   summary table
9. `docs/experiments/openclaw-benchmark/scripts/run-exp-b.sh` — the
   experiment runbook's `mcpServers` JSON flipped to the umbrella CLI
   form
10. `docs/PHASE2_ARCHITECTURE_PLAN.md` + `docs/plans/PLAN_REALTIME_SUBSCRIPTIONS.md`
    — historical plan/architecture docs surgically updated. Both
    docs reference the legacy package as a then-current implementation
    site. Rather than blanket-rewriting (which would falsify the
    historical record), the package-name string is replaced with a
    "now removed; see `pre-v10-tool-drop` tag" annotation that
    preserves the architectural argument while satisfying the brief's
    "ZERO hits" requirement on `git grep`.

**Verification:**
- `pnpm install` → 21 workspaces, lockfile regenerated cleanly
- `pnpm run build` → 19/19 turbo tasks green (was 20+ before)
- `pnpm --filter @origintrail-official/dkg-adapter-autoresearch test` → 37/37 ✓
  (the loader-shim consumer was repointed in W2#15 — deletion has no
  effect on it)
- `pnpm --filter @origintrail-official/dkg-mcp test` → 52/52 ✓
- `git grep "packages/mcp-server\|@origintrail-official/dkg-mcp-server\|mcp-server-dist"`
  → ZERO hits across the entire repo

**Recovery:** for any historical content (the dropped tool wiring,
the legacy connection.ts, the dev-paranet.ttl, the wider test suite),
checkout the `pre-v10-tool-drop` annotated tag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
W3-C's `af8d9165` trimmed the legacy-loader-comparison comment
(`Compared to the legacy mcp-server loader …`) when sweeping
`packages/mcp-server` references. Per team-lead's expanded W3-B
ruling on adapter-context comments, this comment is exempt and stays
as migration context — same precedent already established for
`packages/mcp-dkg/src/tools.ts` ("Replaces the legacy
`dkg_sparql` registration"), `packages/mcp-dkg/src/tools/assertions.ts`
("than the sugared `dkg_propose_decision` / `dkg_add_task` write
tools"), and `packages/mcp-dkg/vitest.config.ts` (skip-list
explanation).

Restored shape with one path correction: the original referenced
`packages/mcp-server/src/index.ts`, which no longer exists. Anchored
the historical pointer to the `pre-v10-tool-drop` tag instead so a
future reader can recover the original loader shape without chasing
a dead path.

No build/test impact: the comment is JSDoc-only.
- `pnpm --filter @origintrail-official/dkg-mcp build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 52/52 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
W3-C's `af8d9165` over-scrubbed two frozen-in-time planning docs
when sweeping the literal `packages/mcp-server` string toward the
"ZERO hits" goal. Per team-lead's Option B ruling on historical
fidelity, planning docs that describe the architecture as it was
at plan-authoring time should NOT be rewritten to reflect a later
post-consolidation reality — same posture as the migration-context
JSDoc comments preserved in `packages/mcp-dkg/src/tools.ts`,
`assertions.ts`, and `vitest.config.ts`.

Reverts to original V9-era references:
- `docs/PHASE2_ARCHITECTURE_PLAN.md:115` — restores the trio
  in-repo-client list (`packages/mcp-server`, `packages/mcp-dkg`,
  `packages/node-ui`); drops the post-consolidation parenthetical
- `docs/PHASE2_ARCHITECTURE_PLAN.md:121` — restores "older `mcp-server`
  releases" enumeration
- `docs/PHASE2_ARCHITECTURE_PLAN.md:222` — restores the original
  `packages/mcp-server` test-coverage bullet (with the
  `connection.ts` route-coverage rationale) plus the
  `packages/mcp-dkg` follow-up bullet
- `docs/plans/PLAN_REALTIME_SUBSCRIPTIONS.md:300` — restores
  `packages/mcp-server/src/index.ts` as the original implementation
  site referenced by the §3.2 plan

Final cross-repo grep state: 3 deliberate residual hits across
these two files, deliberately preserved as point-in-time records.
Recovery for any historical content remains via the
`pre-v10-tool-drop` annotated tag.

No build/test impact:
- `pnpm --filter @origintrail-official/dkg-mcp test` → 52/52 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…l ruling

Reverts `0567b8a1` (which restored Group B planning-doc references to
their original V9-era form on a misread of team-lead's "Option B
authorized" message). Team-lead's follow-up clarified that the
combined approach actually shipped in `af8d9165` + `c77c277b` —
line-by-line surgical scrub with `pre-v10-tool-drop` tag-pointer
annotations — is the better posture across the board:

- No broken pointers for future readers to chase down.
- Historical context preserved (annotations explicitly say
  "see `pre-v10-tool-drop` tag" so the original architectural
  argument is recoverable).
- Clean repo-wide grep — no "but ignore these residual hits"
  carve-outs in any verification step.
- Internally coherent with how `adapters.ts:18` was restored in
  `c77c277b`.

This commit's tree state is identical to `c77c277b`, satisfying
team-lead's "wave-3 is final at HEAD c77c277" ruling. Done as a
revert (not a force-push or hard reset) so qa-engineer's in-flight
#26 verification work is not disrupted by branch-history rewrites.

Affected files (re-scrubbed per `af8d9165`):
- `docs/PHASE2_ARCHITECTURE_PLAN.md:115` — drops the trio in-repo-client
  list back to the post-deletion duo + parenthetical pointer
- `docs/PHASE2_ARCHITECTURE_PLAN.md:121` — restores "the historical
  legacy MCP package (now removed; see `pre-v10-tool-drop` tag)" form
- `docs/PHASE2_ARCHITECTURE_PLAN.md:222` — restores the merged
  `packages/mcp-dkg` test-coverage bullet with the historical
  fourth-client annotation
- `docs/plans/PLAN_REALTIME_SUBSCRIPTIONS.md:300` — restores
  `packages/mcp-dkg/src/index.ts` pointer (was the now-removed legacy
  package at plan-authoring time; see `pre-v10-tool-drop` tag)

Cross-repo grep for `packages/mcp-server | @origintrail-official/dkg-mcp-server
 | mcp-server-dist`: ZERO hits.

No build/test impact (docs-only).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes the two W3-A close-out asks from qa-engineer's verification-plan
v7.4 sign-off. Both are cheap regression-resistance fixtures that don't
admit a regression today (the underlying invariants already hold) but
guard against future accidental drift during refactors.

**Follow-up 1 — Wave-2 #18 drop-sweep** (`query-schema.test.ts`):
Asserts every one of the 10 dropped tool names is absent from the
fully-registered tool surface. Loads every bundle (read + assertion +
memory-search + setup + health + publish) so a tool re-introduced via
*any* registrar trips the assertion. Source for the dropped-name list:
qa-engineer's verification-plan §0.8 fixture 4 verbatim list +
pre-v10-tool-drop tag.

**Follow-up 2 — read-side regex-scope guard** (`assertion-lifecycle.test.ts`):
Asserts the four read-side assertion tools (`write`, `promote`,
`discard`, `query`) accept rich non-slug names like
"Bad Name With Spaces". The bug-class qa flagged: implementer copies
`/^[a-z0-9-]+$/` from `dkg_assertion_create` to all five tools because
they look symmetric — but read-side tools must operate on assertion
names authored by other agents (whose names don't conform to the slug
shape). v0.5 §4.16 alignment paragraph.

Test count: 52 → 54.
- `pnpm --filter @origintrail-official/dkg-mcp test` → 54/54 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two future-regression tests per verification-plan v8 §0.10.7 items 1-2:

1. **Drop-sweep** — assert that none of the 10 tool names removed in
   c222ddc (W2-#18) reappear in tools/list output. The bug-class-most-
   likely is a well-meaning re-registration in a future cycle slipping
   past review because the surface size shifts from 21 to 22. Caught at
   the suite level, not the surface-probe level.

2. **Read-side regex-scope guard** — per matrix v0.5 §4.16 alignment
   paragraph, the /^[a-z0-9-]+\$/ regex on the assertion `name` argument
   is creator-side input validation only. Read-side / lookup-side tools
   (write/promote/discard/query/history) MUST NOT inherit it. Test
   passes a non-conforming name through each read-side tool and asserts
   the schema does NOT reject it. Plus a positive control on
   dkg_assertion_create rejecting the same input — the asymmetry is
   visible in this file alone.

Single new file: packages/mcp-dkg/test/drop-sweep.test.ts (17 tests).
Suite goes from 52 → 71 tests; all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
qa-engineer landed `ebbdba28` (`drop-sweep.test.ts`) covering the same
two W3-A close-out follow-ups I'd implemented in `e3e8eb75` — but with
strictly better coverage:

1. **Drop-sweep**: qa uses `it.each` over the 10 dropped names PLUS a
   surface-size assertion locked at 21. The size lock is a bonus catch
   that fails loudly on accidental add OR remove, which my single
   `for`-loop implementation lacked.
2. **Regex-scope guard**: qa covers all 5 read-side tools
   (`write/promote/discard/query/history` — I missed `_history`) AND
   adds a positive-control test confirming `dkg_assertion_create`
   STILL rejects `"Bad Name With Spaces"`. The asymmetry is visible
   in a single file rather than split across two.

Reverting `e3e8eb75` so the branch carries one canonical implementation
of these guards (qa's), not two. Test surface goes 71 → 69, still well
above the 54-baseline that the W3-A close-out targeted.

No qa coordination needed — this is straightforward deduplication after
parallel-contributor races; both fixtures shipped to the same branch
within minutes of each other and qa's is the better one.

Verified locally:
- `pnpm --filter @origintrail-official/dkg-mcp test` → 69/69 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…W5-A)

Replace the bullet-list "For AI agents" callouts with a routing table
plus dedicated MCP and OpenClaw subsections at parallel depth, followed
by a 10-step "DKG V10 as agent memory" round-trip quickstart that
reproduces the validated Phase-1 flow end-to-end.

The MCP path lands the canonical `dkg mcp setup` + `dkg mcp serve`
verbs and the actual JSON block the umbrella CLI emits today
(`{ "command": "dkg", "args": ["mcp", "serve"] }`); the OpenClaw path
gets the same six-bullet shape (install → setup → restart → 4-line
verification → flags → troubleshooting). The CLI commands cheat-sheet
gains the two new `dkg mcp` verbs alongside `dkg openclaw setup`, and
the Setup Guides table gets an MCP row.

Per audit-and-plan v1.10:
- `agent-context` is the canonical CG (lazily auto-created)
- `dkg_assertion_create + dkg_assertion_write + dkg_memory_search`
  are the names that prove the round-trip
- `dkg_publish` vs `dkg_shared_memory_publish` distinction documented
  in the quickstart
- env-var fallbacks (`DKG_API`/`DKG_TOKEN`/`DKG_PROJECT`/`DKG_AGENT_URI`)
  surfaced in HTTP-401 troubleshooting

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the absolute-path Cursor/Claude Code wiring snippets in favour of
the umbrella CLI's `dkg mcp setup` + `dkg mcp serve` verbs (writes the
canonical `{ "command": "dkg", "args": ["mcp", "serve"] }` block into
every detected client). Document the full 21-tool surface organized
into six categories (Health/identity, Discovery, Setup, Write,
Publish, Search & query) with audit-locked descriptions lifted from
each tool's `description` field.

Folds in:
- Three-command install path (`npm install -g @origintrail-official/dkg
  && dkg init && dkg start && dkg mcp setup`)
- Manual config block for environments where `dkg mcp setup` can't run
- Monorepo / contributor `pnpm exec tsx` form for from-source work
- Canonical round-trip recipe (links the repo-root quickstart)
- `dkg_publish` vs `dkg_shared_memory_publish` distinction per
  SKILL.md §4a; both ship ungated to match the OpenClaw adapter
- `dkg_query` two-axis schema (`view` + `includeSharedMemory`)
- `dkg_memory_search` hit shape (`contextGraphId`, `layer`,
  `trustWeight`)
- env-var fallbacks (`DKG_API`/`DKG_TOKEN`/`DKG_PROJECT`/
  `DKG_AGENT_URI`) for HTTP-401 troubleshooting
- Package layout pointing at the actual six tool registration files
- Historical-recovery note for the 10 dropped V9 tools (annotated tag
  `pre-v10-tool-drop`, design archive at
  `agent-docs/dkg-v10-mcp-consolidation/v9-design-archive.md`)
- Schema reference renamed `dev-context-graph.ttl` (was
  `dev-paranet.ttl`)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Jurij Skornik and others added 13 commits May 6, 2026 17:45
…and UX parity

Per user explicit ask (#30): MCP setup must be a two-command flow
matching `dkg openclaw setup` exactly. Previously it took 4 commands:

  npm install -g @origintrail-official/dkg
  dkg init
  dkg start
  dkg mcp setup

Now it's two:

  npm install -g @origintrail-official/dkg
  dkg mcp setup

**Implementation strategy:** zero re-implementation of init/start
logic — `dkg mcp setup` re-uses the same primitives `dkg openclaw
setup` does (`loadNetworkConfig`, `writeDkgConfig`, `startDaemon`,
`readWalletsWithRetry`, `logManualFundingInstructions` from
`@origintrail-official/dkg-adapter-openclaw`; `requestFaucetFunding`
from `@origintrail-official/dkg-core`). Behaviour stays byte-aligned
across the two setup verbs (network defaults, config-merge semantics,
daemon-readiness probe, faucet retry/back-off, manual-curl fallback).

**Step order** (each step idempotent and skippable):
  1. Init `~/.dkg/config.json` if absent (falls through silently when
     it already exists — preserves the existing idempotent re-run posture)
  2. Start the daemon via `startDaemon(effectivePort)` — no-op when a
     healthy daemon is already reachable on the configured port
  3. Optionally fund the node's wallets via testnet faucet
  4. Detect MCP-aware clients, classify state (registered / stale /
     not-registered), and write the canonical
     `{ command: "dkg", args: ["mcp", "serve"] }` block
  5. Optional verification probe against `/api/status`

**Flag posture** mirrors `dkg openclaw setup`:
  --port <n>     Override API port (default 9200)
  --name <s>     Override agent name (used only on first init)
  --no-start     Skip daemon start (configure only)
  --no-fund      Skip wallet funding via testnet faucet
  --no-verify    Skip post-setup verification probe
  --dry-run      Preview steps without writing or starting anything
  --force        Refresh every detected client regardless of state
  --print-only   Emit canonical JSON only; skip every other step
  --yes          Auto-confirm registrations (default)

**Files:**
- `packages/adapter-openclaw/src/index.ts` — re-export
  `loadNetworkConfig`, `writeDkgConfig`, `startDaemon`,
  `readWalletsWithRetry`, `logManualFundingInstructions` from the
  package barrel so non-OpenClaw consumers can re-use them without
  deep-imports.
- `packages/cli/src/mcp-setup.ts` — rewrite to the bundled flow.
  Existing client-detection / classification / write logic preserved
  (well-tested + already idempotent); init + daemon-start + faucet
  added in front of it. Helper-injected `McpSetupActionDeps` so the
  action is unit-testable without touching the real filesystem or
  spawning the daemon.
- `packages/cli/src/cli.ts:1797+` — register the new flags on
  `dkg mcp setup` and dynamic-import the deps from
  `@origintrail-official/dkg-adapter-openclaw` +
  `@origintrail-official/dkg-core`. Same import surface (and same
  package-resolution failure mode) as `dkg openclaw setup`.
- `packages/cli/test/mcp-setup.test.ts` — 9 new tests:
  clean-machine bundled flow, idempotent skip on existing config,
  --no-start, --no-fund, --dry-run, --print-only short-circuit,
  out-of-range --port, --port + --name override threading,
  faucet-failure manual-fallback. All stub the deps surface.

**Verification:**
- `pnpm --filter @origintrail-official/dkg build` → clean
- `pnpm --filter @origintrail-official/dkg-adapter-openclaw build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 69/69 ✓ (no MCP regressions)
- `pnpm --filter @origintrail-official/dkg exec vitest run mcp-setup.test.ts integrations.test.ts openclaw-setup-cli-args.test.ts` → 54/54 ✓
- `dkg mcp setup --help` → renders all 9 new flags
- `dkg mcp setup --print-only` → emits `{ command: "dkg", args: ["mcp", "serve"] }`

docs-lead now updates the README's MCP section to the 2-command flow;
qa-engineer re-verifies the docs walkthrough against the new behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
W6-pre (`e78d8027`) bundled `dkg init` + `dkg start` + `dkg mcp setup`
into a single `dkg mcp setup` invocation. Update repo-root README to
reflect the new shape:

- Routing-table label: "three commands" → "two commands"
- Quickstart code block: drop `dkg init` and `dkg start` lines; the
  bundled flow now runs all 5 steps (init → start → fund → register
  → verify) end-to-end.
- Inline 5-step prose enumerating what `dkg mcp setup` does, plus the
  full step-skip flag matrix (`--no-start`, `--no-fund`, `--no-verify`,
  `--dry-run`, `--force`, `--print-only`).
- 10-step round-trip outline collapses steps 1-3 (install / init /
  start) into "install" + "set up", dropping one numbered step.

`dkg mcp setup` short-circuits when its work is already done, so
re-runs stay safe. Auth and config still live in `~/.dkg/auth.token`
and `~/.dkg/config.yaml`; the JSON block written into the client
config is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the repo-root README rewrite in `1c4ff9ef`. The bundled
`dkg mcp setup` flow from W6-pre (`e78d8027`) now runs init,
daemon-start, faucet funding, MCP-client registration, and
verification in a single invocation. Update the Install section to
reflect this:

- Two-command quickstart (`npm install -g @origintrail-official/dkg`
  + `dkg mcp setup`) replacing the previous four-command sequence.
- Inline 5-step enumeration of what `dkg mcp setup` does in order,
  plus the step-skip flag matrix (`--no-start`, `--no-fund`,
  `--no-verify`, `--dry-run`, `--force`, `--print-only`,
  `--port <n>`, `--name <s>`).
- Note that the bundled flow re-uses the same primitives
  `dkg openclaw setup` does so the two verbs stay byte-aligned on
  network defaults, daemon-readiness probes, faucet retry/back-off,
  and manual-curl fallback.

The 21-tool surface, view semantics, capture-hook docs,
troubleshooting matrix, and package layout sections are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ivity (F1)

qa-review-round-1 F1: the W2 #17 schema migration replaced the
single-axis `layer: 'wm'|'swm'|'union'|'vm'` enum with the two-axis
`view + includeSharedMemory` shape, but the migration was applied
to `dkg_query` only. `dkg_get_entity` (`tools.ts:219`) and
`dkg_list_activity` (`tools.ts:304`) still exposed the legacy
`layer` enum on their public input schemas — even though the
internal handlers already mapped to the canonical scope object.

Concrete inconsistency a caller hits: an agent learns
`view: 'verified-memory'` from `dkg_query`, then calls
`dkg_get_entity({ uri, layer: 'verified-memory' })` — zod rejects
with `Invalid enum value`. Forces a per-tool API context-switch.

This commit:
- Migrates both tools' public input schemas to `view +
  includeSharedMemory`, matching `dkg_query`.
- Preserves the historical `layer: 'union'` default (WM∪SWM) when
  callers supply neither `view` nor `includeSharedMemory`. The
  internal scope-object mapping is unchanged on the wire.
- Updates the "no triples found" rendering on `dkg_get_entity` to
  print the canonical `view=...` label instead of `layer=...`.
- Adds a sweep test in `query-schema.test.ts` asserting NO public
  tool exposes the legacy `layer` field — same bug-class guard as
  the drop-sweep block in `drop-sweep.test.ts`. Plus four
  per-tool acceptance/rejection cases (`view: 'verified-memory'`
  accepted, `layer: 'union' / 'wm'` rejected) and a default-shape
  guard confirming the V9-era `WM∪SWM` default still routes
  correctly.

No daemon-side change required — wire-shape was already two-axis
(`DkgClient.query` accepts both `view` and `includeSharedMemory`
as separate fields per `client.ts:133-183`); this is a
public-tool-surface alignment only.

Test count: 69 → 75.
- `pnpm --filter @origintrail-official/dkg-mcp build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 75/75 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…reate (F2)

qa-review-round-1 F2: `dkg_context_graph_create` wrapped
`client.createContextGraph(...)` but the client method's return type
was `{ created, uri }` with no idempotency flag — the daemon's HTTP
409 on duplicate id was caught at the tool layer as a generic
"Failed to create" error, so a caller couldn't programmatically
distinguish "duplicate" from "real failure". Forced the awkward
workaround in the tool description: "Call `dkg_list_context_graphs`
first to see if one with this name already exists" — an extra
HTTP round-trip on the agent for information the create call should
have returned.

The sister tool `dkg_assertion_create` does this right:
`assertions.ts:87-89` reads `result.alreadyExists` and emits a
distinct "already exists" message. The two tools had inconsistent
handling of the same daemon-side idempotency contract; this commit
unifies them.

This commit:

- `packages/mcp-dkg/src/client.ts` — `createContextGraph` now
  catches the daemon's HTTP 409 + `already exists | duplicate |
  conflict` body shape and returns `{ created, uri, alreadyExists:
  true }` instead of throwing. New return type
  `{ created: string; uri: string; alreadyExists: boolean }` mirrors
  `createAssertion`'s pattern at `client.ts:331-354`.
- `packages/mcp-dkg/src/tools/setup.ts` — `dkg_context_graph_create`
  reads `result.alreadyExists` and renders a distinct "Context
  graph 'X' already exists" message vs the "Created context graph
  'X'" path. Description rewritten to drop the
  `dkg_list_context_graphs` workaround sentence and explicitly
  document the idempotency contract.
- `packages/mcp-dkg/test/harness.ts` — `FakeClient.createContextGraph`
  mirrors the real client's idempotency contract (returns
  `alreadyExists: true` for duplicate ids, `false` otherwise).
- `packages/mcp-dkg/test/setup-publish-health.test.ts` — two new
  tests: first-create vs second-create message asymmetry, and a
  description-text guard asserting the workaround sentence is gone
  + the idempotency contract is documented.

Test count: 75 → 77.
- `pnpm --filter @origintrail-official/dkg-mcp build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 77/77 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
qa-review-round-1 F6: `mcp-setup.ts:283-322` only reconciled
`effectivePort` against the persisted config inside the `else`
branch (when `writeDkgConfig` ran). When the existing-config skip-
write branch was taken (`configExists && !opts.name && !opts.port`),
`effectivePort` stayed at the CLI default 9200 even when
`~/.dkg/config.json` had a different `apiPort`.

Concrete reproducer (from qa-review-round-1.md F6): a user who
previously ran `dkg openclaw setup --port 9300` (so the persisted
config has `apiPort: 9300`) and then runs `dkg mcp setup` with no
flags would:
  1. Hit the existing-config branch — print "Node config exists;
     leaving untouched" — but `effectivePort` still 9200.
  2. Start the daemon on 9200 instead of 9300.
  3. Verification probe hits the wrong port.
  4. Registered MCP entry implicitly references the wrong daemon.

Fix: lift the read-back logic into a helper
(`reconcileFromPersistedConfig`) that runs unconditionally on every
branch where the persisted config is on disk — both the skip-write
branch (existing-config) and the write-then-read branch (writeDkgConfig
just ran). The helper is also tolerant of corrupt JSON / missing
fields (the previous behaviour silently used pre-merge values; same
posture preserved).

This commit:
- `packages/cli/src/mcp-setup.ts` — extract the read-back into
  `reconcileFromPersistedConfig`; call it from both branches.
- `packages/cli/test/mcp-setup.test.ts` — two new tests covering
  the post-fix behaviour: (a) existing config with `apiPort: 9300`
  + no flags → `startDaemon` receives 9300, not 9200; (b) same
  shape with `--no-start` runs without throwing on the read-back
  branch (companion structural test).

Test count for cli/test/mcp-setup.test.ts: 9 → 11.
- `pnpm --filter @origintrail-official/dkg build` → clean
- `pnpm --filter @origintrail-official/dkg exec vitest run mcp-setup.test.ts` → 11/11 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… daemon-409 flag (F12)

qa-review-round-2 F12: `dkg_shared_memory_publish`'s
`registerIfNeeded` branch tolerated the already-registered case via
`message.includes('already registered')` — a locale-fragile
substring match against an unstructured daemon error message.
Three failure modes the substring approach exposed:

  1. If the daemon's wording ever changes ("CG X is already registered
     on-chain" → "X is already on-chain" / "duplicate registration"),
     the substring check fails: a real already-registered case
     surfaces as a hard "Failed to register context graph: ..." error
     AND blocks the publish step.
  2. Conversely, if a future error message contained the substring
     "already registered" for an unrelated reason, the tool would
     silently swallow a real failure.
  3. Localisation drift in error messages (English-only assumption).

Fix: push the typed signal into the client, mirroring the F2 pattern
on `createContextGraph`. The daemon's `/api/context-graph/register`
already returns HTTP 409 on the already-registered case
(`packages/cli/src/daemon/routes/context-graph.ts:520-524`), so the
client can branch on `err.status === 409` (a typed boolean signal)
and surface `alreadyRegistered: true` as a first-class field in
the return type. The tool then branches on the typed flag — no
substring text match anywhere in the path.

This commit:

- `packages/mcp-dkg/src/client.ts` — `registerContextGraph` now
  catches `DkgHttpError` with `status === 409` and returns
  `{ registered, alreadyRegistered: true }` rather than throwing.
  New return type `{ registered, onChainId?, txHash?, hint?,
  alreadyRegistered: boolean }` mirrors `createAssertion` and
  `createContextGraph` shapes.
- `packages/mcp-dkg/src/tools/publish.ts` —
  `dkg_shared_memory_publish`'s registerIfNeeded branch reads
  `result.alreadyRegistered` and only sets `registration` (the
  success-summary record) when it was newly-registered. Non-409
  failures now propagate as tool errors without the substring
  filter — the swallow-on-substring failure mode is gone.
- `packages/mcp-dkg/test/harness.ts` — `FakeClient.registerContextGraph`
  returns the new shape with `alreadyRegistered: false` by default;
  callers can override per-test for the alreadyRegistered case.
- `packages/mcp-dkg/test/setup-publish-health.test.ts` — updated
  the existing `registerIfNeeded: true` test to the new shape.
  Added two F12-locked tests: typed-flag tolerance (publish proceeds,
  success summary doesn't claim "Registered on-chain"), and
  non-409-failure propagation (a thrown rpc-unreachable error
  surfaces as a tool error).

Test count: 77 → 79.
- `pnpm --filter @origintrail-official/dkg-mcp build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 79/79 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
qa-review-round-1 F3 + qa-review-round-2 F13: `dkg_publish` and
`dkg_shared_memory_publish` ship ungated (matrix v0.6 user-locked,
parity with OpenClaw). The original F3 ask was a loud pre-publish
chain-warning; user explicitly opted for option (a) WITHOUT
warning prose ("we don't do that anywhere at the moment, can add
later if needed"). This commit collapses F3 entirely into F13's
chain-provenance echo so callers can verify post-hoc which chain
the publish landed on.

The daemon's `/api/shared-memory/publish` response does NOT include
`chainId` in the JSON body — the value is threaded through the
tracker only (`packages/cli/src/daemon/routes/memory.ts:483-488`).
The cleanest path is reading from the existing
`/api/wallets/balances` endpoint (which already exposes `chainId`
as a first-class field) once the publish succeeds.

This commit:

- `packages/mcp-dkg/src/tools/publish.ts` — adds a
  `resolveChainId(client)` helper that reads the daemon's
  configured chainId via `getWalletBalances()` and returns `null`
  on probe failure (best-effort, non-fatal). Both `dkg_publish`
  and `dkg_shared_memory_publish` summaries now append a
  `Chain: <chainId>` line when resolution succeeds.
- `dkg_shared_memory_publish` — also echoes the resolved
  `accessPolicy` in the registration line when `registerIfNeeded`
  ran (e.g. `Registered on-chain: chain:cg (accessPolicy=1)`).
  Caller can verify the daemon committed the value they
  requested without a separate read-back call.
- `packages/mcp-dkg/test/setup-publish-health.test.ts` — five new
  F3+F13 tests: chainId echoed on `dkg_publish`, chainId echoed
  on `dkg_shared_memory_publish`, graceful omission when the
  wallet-balances probe fails (publish itself stands), accessPolicy
  echoed on the registration line, and a
  no-warning-prose guard locking the user's explicit posture (no
  "spends gas" / "verify chainId" / generic "warning" copy in
  either response).

Test count: 79 → 84.
- `pnpm --filter @origintrail-official/dkg-mcp build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 84/84 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… (F11)

qa-review-round-2 F11 + user steer ("investigate so we are sure"):
the canonical wire form for `accessPolicy` is the numeric `0|1`
per the daemon, not the string `'open'|'private'`. Confirmed by
reading the two daemon-side handlers:

  - `packages/cli/src/daemon/routes/context-graph.ts:455` —
    `accessPolicy: typeof accessPolicy === 'number' ? accessPolicy : undefined`
    in the `POST /api/context-graph/create` handler. Strings are
    silently dropped to undefined.
  - `packages/cli/src/daemon/routes/context-graph.ts:509-510` —
    `if (accessPolicy !== undefined && (accessPolicy !== 0 && accessPolicy !== 1))`
    in the `POST /api/context-graph/register` handler returns
    HTTP 400 with the explicit error
    `'"accessPolicy" must be 0 (open) or 1 (private)'`. Strings
    are rejected at the wire boundary.

The mcp-dkg implementation already uses the canonical numeric
form (`packages/mcp-dkg/src/tools/publish.ts:192-197` —
`z.union([z.literal(0), z.literal(1)])`). The divergent side was
the parity-matrix v0.8 §4.10 line 291 spec doc, which had
`z.enum(['open', 'private'])` — a string-form recommendation
that would have failed at the daemon if implemented. The matrix
doc lives under `agent-docs/` (gitignored team-workspace artefact);
parity-analyst owns the corresponding spec-doc realignment in
their next matrix-version cycle.

This commit's contribution: four schema-shape lock tests in
`setup-publish-health.test.ts` so a future re-alignment to the
matrix's pre-correction recommendation can't regress silently.

  - `accessPolicy: 0` accepted (open)
  - `accessPolicy: 1` accepted (private)
  - `accessPolicy: 'open'` rejected at the schema layer
  - `accessPolicy: 2` rejected (out-of-range numeric)

The string-rejection test mirrors the daemon's strict guard at
the wire boundary so the mcp-dkg public surface fails fast on
the same shapes the daemon would 400 on.

Test count: 84 → 88.
- `pnpm --filter @origintrail-official/dkg-mcp test` → 88/88 ✓

parity-analyst hand-off: matrix v0.8 §4.10 line 291 needs to flip
from `z.enum(['open', 'private'])` to
`z.union([z.literal(0), z.literal(1)])` to match implementation
+ daemon canonical. No code change needed on their end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eachability (F14)

qa-review-round-2 F14: pre-fix outer guard at `mcp-setup.ts:334`
was

  if (shouldFund && !dryRun && shouldStart) { ... }
  else if (!shouldFund) { console.log('Skipping wallet funding (--no-fund)'); }

Two failure modes:

  1. **Silent omission on `--no-start`**: when the user passed
     `--no-start` with default fund=true, `shouldStart` was false →
     funding skipped → BUT the `else if (!shouldFund)` branch never
     fired (fund was still true). User saw NO funding-step output at
     all — neither attempted nor skipped.
  2. **Blocked legitimate re-run**: daemon already running from a
     prior invocation, faucet was down on first run, user re-runs
     to retry funding. They had to remember to NOT pass
     `--no-start` for funding to attempt at all.

Fix per qa's recommendation: decouple the funding decision from
`shouldStart`. New flow:

  - `--no-fund` → existing explicit-skip log (intact, no behaviour
    change)
  - `--dry-run` → existing dry-run log (intact, no behaviour change)
  - Otherwise → probe daemon reachability at `/api/status` on
    `effectivePort` (same endpoint `startDaemon` uses for readiness
    + the existing verify-step probe). If reachable, proceed with
    funding regardless of which invocation started the daemon. If
    not reachable, log explicit "Skipping wallet funding (daemon
    not reachable on port X)" — replaces the silent omission.

This commit:

- `packages/cli/src/mcp-setup.ts:334-388` — refactor the outer
  guard to the new three-branch shape (--no-fund / --dry-run /
  probe + faucet). Inner faucet logic (URL resolution, wallet
  read-back, retry/back-off, manual-curl fallback) is unchanged.
- `packages/cli/test/mcp-setup.test.ts` — rewrite the existing
  `--no-start` test to reflect the new contract (faucet skipped
  via the explicit "daemon not reachable" log line, not via the
  pre-fix conflation). Add two new F14-locked tests:
    - `--no-start` with daemon-already-reachable → funding
      proceeds (the legitimate-re-run case the bug blocked)
    - `--no-fund` + `--no-start` → explicit-skip log fires; the
      unreachable log MUST NOT fire (short-circuit precedence)
  Tests use `vi.spyOn(globalThis, 'fetch')` to deterministically
  exercise the probe path.

Docs: no README/CLAUDE.md edits needed — the existing prose
neither documented nor implied the bug-state, so the new
behaviour matches the documented contract.

Test count for cli/test/mcp-setup.test.ts: 11 → 13.
- `pnpm --filter @origintrail-official/dkg build` → clean
- `pnpm --filter @origintrail-official/dkg exec vitest run mcp-setup.test.ts` → 13/13 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… posture (F27)

qa-review-round-5 F27: `packages/mcp-dkg/test/harness.ts:62-68`
claimed to mirror the production MCP SDK but ran zod with
`.strict()` mode at parse — production SDK silently DROPS unknown
keys, it does not reject them. Three tests in
`query-schema.test.ts` were F27-bug-class: they asserted that
legacy `layer: 'union' | 'wm' | 'swm' | 'vm'` is *rejected* on
tools whose schemas no longer declare it. Those tests passed in
the harness (because of `.strict()`) but would not have passed
against the real SDK — production would parse cleanly with the
unknown key dropped, then run the handler with V10 default scope.

The bug-class is "harness false confidence": tests describing a
harness artefact rather than the production surface. Specifically
the F1 sweep tests (post-#17 + post-F1 schema migration) at
query-schema.test.ts:56-69, :155-162, :176-183 each used the
`rejects.toThrow()` shape pinned to the harness's strict mode.

This commit:

- `packages/mcp-dkg/test/harness.ts:68` — drop the `.strict()`
  modifier from the inline zod object schema. Add a JSDoc note
  explaining the production-MCP-SDK posture so future contributors
  don't reintroduce strict mode by accident.
- `packages/mcp-dkg/test/query-schema.test.ts` — rewrite the three
  F27-bug-class tests to assert production behaviour:
    * `dkg_query` legacy `layer: 'wm|swm|union|vm'` → silent drop
      at parse, handler runs with default scope (no `view`, no
      `includeSharedMemory`). Asserts the legacy key does NOT
      leak through to the wire.
    * `dkg_get_entity` legacy `layer: 'union'` → silent drop, the
      handler's no-`view` branch supplies the V9-era WM∪SWM
      default (`includeSharedMemory: true`) on the wire — the
      legacy semantic is preserved by accident-of-default, not
      by an explicit `union` mapping.
    * `dkg_list_activity` legacy `layer: 'wm'` → twin to the
      `dkg_get_entity` case. Crucially: `layer: 'wm'` does NOT
      route to a WM-only query (the explicit-strict semantic
      pre-F1 had); it drops entirely and uses the WM∪SWM
      default. This documents a real V9→V10 behaviour shift the
      pre-F27 harness was hiding.

The other 9 `rejects.toThrow()` tests qa's audit flagged as safe
— declared-field validation (regex on assertion-name slugs, enum
on view, required fields) is not affected by strict mode and
behaves identically against the real SDK. Untouched.

Test count: 88 → 88 (3 rewrites, no count change).
- `pnpm --filter @origintrail-official/dkg-mcp test` → 88/88 ✓

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…etch timeout (W7-2 R6)

qa-engineer's R6 polish-triage list (qa-review-round-6.md). Single
commit batching the 9 review-cycle accumulation-polish items so
the diff is reviewer-friendly. None of these are correctness
gates; they're docs/comments/defensive hardening that close the
last review-finding bucket before merge.

Items in commit order:

- **F8 + F15** (`packages/mcp-dkg/src/tools.ts:160-168`) — drop the
  "to get the WM∪SWM union the legacy `dkg_sparql` exposed as
  `layer: \"union\"`" historical-baggage sentence from `dkg_query`'s
  description. Replaced with the cleaner forward-only phrasing
  "Set `includeSharedMemory: true` alongside `view: \"working-memory\"`
  to query WM ∪ SWM in one call." Same edit applied to
  `packages/mcp-dkg/README.md:156` so the README's tool-table
  matches the description an LLM actually sees over MCP.
  qa-review-round-1 F8 + qa-review-round-2 F15.

- **F18** (`packages/mcp-dkg/src/cli/index.ts:1-22`) — JSDoc
  rewrite. Drop the V9-era "Phase 8 day 2" / "Phase 8 day 3"
  milestone language; describe the current operator-facing
  surface (`join`, `status`, `help`) and re-route distribution
  prose through the umbrella `dkg mcp serve` form (production
  path) with the `dkg-mcp` direct-bin retained for monorepo dev
  + direct npm-install consumers. qa-review-round-3 F18.

- **F20** (`packages/mcp-dkg/src/sparql.ts:5`) — single-word edit:
  "v9 ontology" → "V10 ontology". Drift survivor from the
  W2-D R4 sweep. qa-review-round-4 F20.

- **F22** (`packages/mcp-dkg/src/sparql.ts:54-61`) — defensive
  hardening: `escapeSparqlLiteral` now strips null bytes BEFORE
  the other escapes. SPARQL engines (oxigraph et al.) reject
  null bytes outright today, so this is no observable behaviour
  change in normal use — but it guards against a future engine
  swap or any truncate-at-null-byte parsing path that would
  silently change query semantics. qa-review-round-4 F22.

- **F4** (`packages/mcp-dkg/src/tools/assertions.ts:196-200`) —
  comment clarification on `entities ?? []`. The pre-F4 comment
  implied the public API allowed the empty-array sentinel; the
  rewritten comment makes it explicit that the tool blocks
  empty-array from callers and that the daemon's empty-array
  sentinel is hidden inside the wrapper. qa-review-round-1 F4.

- **F7** (`packages/cli/src/mcp-setup.ts:173-180`) — `classify()`
  now treats both `undefined` (key absent) and `null` (key
  present but explicitly nulled) as `not-registered`. Pre-F7 a
  `{ dkg: null }` entry classified as `stale`, which made the
  operator log claim there was a current value to refresh — the
  registration outcome under `--force` was identical, but the
  stderr log was confusing. qa-review-round-1 F7.

- **F23** (`packages/mcp-dkg/src/tools.ts:222-228, 320-326`) —
  description-string clarification on `dkg_get_entity` +
  `dkg_list_activity` `view` fields. The semantic asymmetry
  between explicit `view: 'working-memory'` (strict WM unless
  `includeSharedMemory: true`) and omitted `view` (default WM∪SWM)
  is now explicit in both schemas: explicit selection is STRICT,
  omitting `view` gets the V9-era `layer: 'union'` shape. Per
  team-lead's MINOR ruling: keep the opt-in-to-strict semantics,
  document it in the schema description. qa-review-round-5 F23.

- **F25** (`packages/cli/src/mcp-setup.ts:316-336`) — F6's
  reconcile-from-persisted-config call lifted out of the
  per-branch conditionals into a single up-front read before the
  branch decision. Pre-F25 the dry-run preview used the
  CLI-default `apiPort` (9200) even when the persisted config
  had a different port — the preview lied. Side benefit: collapses
  the two duplicate reconcile calls into one. qa-review-round-5 F25.

- **F26** (`packages/cli/src/mcp-setup.ts:393, 501`) — both
  `/api/status` probes (F14's daemon-reachability probe before
  funding, plus the verification probe at the end of setup)
  now bound the fetch with `AbortSignal.timeout(2000)`. A
  partially-up daemon (port bound but unresponsive) would have
  hung setup indefinitely pre-F26. Two-line defensive fix at
  each site; no behaviour change in the happy path.
  qa-review-round-5 F26.

Existing test suites cover the changed surfaces — F25's
behaviour shift on dry-run preview, F26's timeout fallback
(treated as "not reachable" same as connection-refused), F7's
null-handling, F23's description-only edit, and the rest are
docs/comments. No new tests required; existing tests at 88+54
(mcp-dkg + cli) hold.

- `pnpm --filter @origintrail-official/dkg-mcp build` → clean
- `pnpm --filter @origintrail-official/dkg build` → clean
- `pnpm --filter @origintrail-official/dkg-mcp test` → 88/88 ✓
- `pnpm --filter @origintrail-official/dkg exec vitest run mcp-setup.test.ts integrations.test.ts` → 54/54 ✓

F24 (`resolveChainId` extra HTTP roundtrip) tracked as post-merge
follow-up per qa+team-lead — daemon-side improvement opportunity,
not a client fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The W3-B transition commit's rebase against latest main produced a
conflict in package.json (main added 'check:npm-metadata' alongside
the legacy 'mcp' script we were rewriting). The Edit-tool resolution
landed but the conflict-marker block was inadvertently committed in
the same step. This commit removes the stale markers and keeps the
intended merged form: the new mcp script form + main's
check:npm-metadata addition.

No behaviour change beyond restoring valid JSON.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Jurij89 Jurij89 force-pushed the chore/v10-mcp-consolidation branch from fc2b375 to 1190795 Compare May 6, 2026 15:53
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex review skipped: filtered diff is 13119 lines (cap: 5,000). Please consider splitting this into smaller PRs for reviewability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant