Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 22 additions & 0 deletions .ai/adr/0001-codebase-decision-records.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ADR 0001 — Codebase decision records live in agent memory

- **Status**: Accepted
- **Date**: 2026-05-26

## Context

The docs refresh separates public product documentation from codebase memory. Existing repo-level ADRs are primarily useful to agents and maintainers working in the codebase. They are not part of the initial public docs experience unless a specific decision is needed to help humans or agents understand DKG behavior.

## Decision

Repo-level ADRs and implementation decision records belong in `.ai/adr/`, with `.ai/decisions.md` acting as the index. Public docs should not expose ADRs by default. If a decision is necessary for public understanding, write a user-facing architecture or concept page derived from the decision rather than publishing the raw ADR. Track `.ai/adr/*.md` and `.ai/decisions.md` in git; keep other `.ai/` scratch files ignored unless explicitly promoted.

Existing repo-level ADRs were moved from former public ADR paths and package-local ADR paths into `.ai/adr/` during the docs refresh follow-up. Public navigation plus generated agent projections must not link raw ADRs.

## Consequences

- ADR files under public docs paths are invalid; add new decision records under `.ai/adr/`.
- Internal references to old public ADR paths should be updated to `.ai/adr/*`.
- Public docs navigation and generated public docs context should exclude `.ai/`.
- Agent context may include `.ai/adr/` when working on the codebase.
- `.gitignore` allows only durable `.ai` decision records by default.
34 changes: 34 additions & 0 deletions .ai/adr/0004-docs-overview-led-ia.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# ADR 0004 — Docs overview-led information architecture

- **Status**: Accepted
- **Date**: 2026-05-26

## Context

The DKG docs refresh needs to serve both humans and agents. A pure task-first structure risks giving agents narrow command playbooks without the system model they need to reason about WM/SWM/VM, context graphs, Knowledge Assets, trust, finality, and stale V9 material. A pure architecture-first structure risks burying installation, integration, and troubleshooting intents.

This decision was later aligned to `OriginTrail/dkgv10-spec#119`: the public IA uses one root page plus `how-dkg-works`, `use-dkg`, `reference`, and `agent-context`. The rejected intermediate split (`build`, `operate`, `understand`, `architecture`, `for-ai-agents`) is not the accepted public structure.

## Decision

The public DKG docs information architecture will be overview-led, task-routed, and architecture-backed. The first visible page is `docs/README.md`: a compact DKG V10 system map that describes DKG as a decentralized knowledge network/protocol and the DKG node as the local gateway into that network.

Top-level public navigation is the accepted #119 structure:

- `docs/how-dkg-works/` for the system model and implementation architecture.
- `docs/use-dkg/` for installation, connection, publishing/querying, operation, and troubleshooting workflows.
- `docs/references/` for exact lookup pointers to package-owned contracts.
- `docs/agent-context/` for agent projections derived from the current corpus.

Diataxis-style categories stay as internal `doc_type` metadata for generation, retrieval, and review.

## Consequences

- Do not label the public entry point `index`; `index.md` may exist only as a framework implementation detail.
- Do not make the docs task-only. Agents get the map first, then the route, then the exact commands.
- Do not recreate the intermediate `docs/build`, `docs/operate`, `docs/understand`, or `docs/architecture` split.
- Treat `docs/agent-context` as a projection of the current corpus, not as a competing public-docs alternative.
- Keep `doc_type` metadata for how-to, concept, reference, architecture, invariant, and playbook classification underneath the visible nav.
- Keep the Node Skill as the operational contract, while the docs corpus explains the DKG node as a whole.
- Generate or curate agent projections from the current corpus only; archive material must not pollute default retrieval.
- Move non-V10 docs under versioned archive paths, such as `docs/archive/v9/` or `docs/archive/v8/`, and remove links from current V10 docs to old-version docs.
19 changes: 19 additions & 0 deletions .ai/adr/0005-versioned-docs-archive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ADR 0005 — Versioned documentation archive

- **Status**: Accepted
- **Date**: 2026-05-26

## Context

The current docs tree mixes V10 release-candidate material with V9-era setup guides, specs, onboarding pages, plans, and historical reports. That creates a direct retrieval risk: agents can answer from stale docs that look current because they live near supported V10 material.

## Decision

All non-V10 docs will be moved under versioned archive folders, such as `docs/archive/v9/` or `docs/archive/v8/`. Current V10 docs must not link to old-version docs, and generated agent context must exclude the archive by default. The V10 docs themselves must be updated to reflect current supported behavior rather than depending on old pages as transitional references.

## Consequences

- Metadata alone is not enough for stale docs; path-level separation is required.
- Current docs navigation and generated agent packs exclude version archives.
- V10 pages need current replacements for any old setup, concept, architecture, or reference pages they previously linked to.
- Archive material remains available for historical inspection but is not part of the current documentation graph.
33 changes: 33 additions & 0 deletions .ai/decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Decisions

## 2026-05-26 — Docs IA Is Overview-Led

The DKG docs refresh uses an overview-led, task-routed, architecture-backed
information architecture aligned to `OriginTrail/dkgv10-spec#119`. Public docs
start with `docs/README.md`, not a visible `index.md`; the root describes DKG
V10 as a decentralized knowledge network/protocol and the DKG node as the local
gateway. Public navigation is `how-dkg-works`, `use-dkg`, `reference`, and
`agent-context`; the old `build`, `operate`, `understand`, `architecture`, and
`for-ai-agents` split is rejected. Agent context packs are projections of the
current corpus before task routing and exact commands.

See `.ai/adr/0004-docs-overview-led-ia.md`.

## 2026-05-26 — Non-V10 Docs Move To Versioned Archive

All non-V10 docs should be moved under versioned archive folders such as
`docs/archive/v9/` or `docs/archive/v8/`. Current V10 docs should not link to
old-version docs, and replacement V10 docs must be updated to current behavior.

See `.ai/adr/0005-versioned-docs-archive.md`.

## 2026-05-26 — Repo-Level ADRs Live In `.ai/adr/`

Repo-level ADRs and implementation decision records are codebase memory for
maintainers and coding agents. They live outside public docs under
`.ai/adr/`, with public docs getting derived architecture explainers only when a
decision is necessary for initial product understanding.

Public docs navigation and generated agent projections must not expose raw ADRs.

See `.ai/adr/0001-codebase-decision-records.md`.
34 changes: 34 additions & 0 deletions .ai/docs-playbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
status: current
version: v10
audience: human+agent
doc_type: playbook
---

# Docs Playbook

Current docs must describe supported DKG V10 behavior. Historical docs belong under `docs/archive/<version>/`.

Required metadata for current pages:

```yaml
status: current
version: v10
audience: human+agent
doc_type: concept
```

Rules:

- Do not link current docs to old-version archive pages.
- Do not use archived docs to generate agent context.
- Keep the public overview human-readable and agent-usable.
- Use package READMEs for package-specific details.
- Use `packages/cli/skills/dkg-node/SKILL.md` for exact agent operations.
- Update `llms.txt` and `llms-full.txt` when the current docs IA changes.

Validation:

```bash
node scripts/docs/validate-docs-corpus.mjs
```
31 changes: 31 additions & 0 deletions .ai/docs-update-playbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
status: current
version: v10
audience: agent+human
doc_type: playbook
---

# Docs Update Playbook

When code behavior changes:

1. Update package-owned references if flags, routes, payloads, or setup behavior changed.
2. Update current docs if user-facing workflows, concepts, or operating rules changed.
3. Update `packages/cli/skills/dkg-node/SKILL.md` if agent tool/HTTP contracts changed.
4. Update Agent Context projections when current docs change.
5. Keep old-version docs in `docs/archive/<version>/`.
6. Do not link current docs or agent projections to old-version archive pages.
7. Run:

```bash
node scripts/docs/validate-docs-corpus.mjs
```

Current docs require front matter:

```yaml
status: current
version: v10
audience: human+agent
doc_type: how-to
```
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and consistency compared to isolated agent workflows.
## Structure

```
docs/experiments/openclaw-benchmark/
.ai/experiments/openclaw-benchmark-root/openclaw-benchmark/
├── README.md ← This file
├── RESULTS.md ← Main findings, deltas, conclusions
├── tasks/ ← Task sets + next experiment definitions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import subprocess
from pathlib import Path

BASE = Path("/Users/aleatoric/dev/dkg-v9/docs/experiments/openclaw-benchmark")
BASE = Path(__file__).resolve().parents[1]
RESULTS = BASE / "results"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from pathlib import Path
import statistics

BASE = Path("/Users/aleatoric/dev/dkg-v9/docs/experiments/openclaw-benchmark/results")
BASE = Path(__file__).resolve().parents[1] / "results"


def summarize(exp: str):
Expand Down
115 changes: 73 additions & 42 deletions docs/messenger-operator.md → .ai/messenger-operator.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
---
status: current
version: v10
audience: human+agent
doc_type: how-to
---

# Universal Messenger — Operator Guide

> Audience: node operators (running a DKG daemon as a service). For
> the architecture-level reference, see [`messenger.md`](./messenger.md).
> For the new-protocol migration recipe, see
> [`messenger-add-protocol.md`](./messenger-add-protocol.md).
> the architecture-level reference, see [`docs/how-dkg-works/universal-messenger.md`](../docs/how-dkg-works/universal-messenger.md).
> Contributor migration notes for future protocol additions live in codebase-only
> agent context, outside the public docs tree.
>
> Status: shipping in `v10.0.0-rc.9`.
> Status: active in the current V10 code. Current substrate-routed
> protocols use `/dkg/10.0.1/*`; a small set of legacy bare protocols
> still uses `/dkg/10.0.0/*`.

This is the operator-facing manual for running a DKG node on top of
the Universal Messenger substrate. The two surfaces you'll touch in
Expand All @@ -19,7 +28,7 @@ practice are:

Most operators won't need either — defaults are safe, the public
testnet relay set works, and the substrate self-heals through the
recovery primitives documented in `messenger.md`. The surfaces below
recovery primitives documented in `docs/how-dkg-works/universal-messenger.md`. The surfaces below
exist for operators running custom infrastructure or chasing a
specific reliability tail.

Expand Down Expand Up @@ -129,7 +138,8 @@ curl -s http://127.0.0.1:9200/api/slo \
"delivered": 1602, // monotonic counter (since daemon start)
"queued": 14 // monotonic; "queued" = first send failed → outbox
},
"/dkg/10.0.1/storage-ack": { ... }
"/dkg/10.0.1/storage-ack": { ... },
"/dkg/10.0.1/swm-update": { ... }
},
// rc.9 PR-A (SWM reliable fan-out, Step 0): two new sections,
// additive — soak tooling and operators that only parse `protocols`
Expand Down Expand Up @@ -168,7 +178,31 @@ curl -s http://127.0.0.1:9200/api/slo \
// Sticky boolean — true once the per-cgId cap eviction has fired.
// Means the `redundantApplies` breakdown is partial; the grand
// total is still `sum(redundantApplies) + redundantAppliesOverflow`.
"redundantAppliesTruncated": false
"redundantAppliesTruncated": false,
"substrateFanout": {
"delivered": { "did:dkg:context-graph:lex/playground": 8 },
"rejected": {},
"retryable": {},
"queued": {},
"inFlight": {},
"failed": {},
"overflow": {
"delivered": 0,
"rejected": 0,
"retryable": 0,
"queued": 0,
"inFlight": 0,
"failed": 0
},
"truncated": false
},
"shareAckQuorum": {
"tracked": 10,
"completed": 10,
"watchdogFired": 0,
"deadlineExpired": 0,
"pending": 0
}
}
}
```
Expand All @@ -194,8 +228,7 @@ flowed and no SWM share has either failed at gossip or been applied
the grand total is still accurate.
- **`swm.redundantApplies[cgId] > 0`** → a (cgId, shareOpId) was
re-delivered within the TTL window and applied a second time.
Pure measurement: behaviour is unchanged. Used to inform the rc10
dedup decision (RFC-003 Concern-2).
Pure measurement: behaviour is unchanged.
- **`swm.redundantAppliesLowerBound = true`** → the receiver-side
`seenShareOps` cap eviction had to trim a still-live entry to
stay bounded. `redundantApplies` is now a lower bound for the
Expand All @@ -207,6 +240,12 @@ flowed and no SWM share has either failed at gossip or been applied
total is still accurate via
`sum(redundantApplies) + redundantAppliesOverflow`. If `Truncated`
flips in normal operation (no hostile peer), raise the cap.
- **`swm.substrateFanout`** → per-CG outcome counters for the
point-to-point SWM delivery path. A healthy run has `delivered`
growing, low or empty `queued`, and no sustained `failed` growth.
- **`swm.shareAckQuorum`** → ack-quorum overlay counters. `completed`
should grow with `tracked`; sustained `deadlineExpired` means peers
missed the delivery window and will need reconnect sync to catch up.

### Clock definition

Expand All @@ -224,20 +263,21 @@ attempt (initial send or any background outbox retry) resolves to
- Receiver-side dedup hits are recorded as delivered with zero
latency (the caller's effective "perceived" RTT).

This is the operator-visible "I clicked send → it arrived" time, which
is what the ship-gate SLO targets measure.
This is the operator-visible "I clicked send → it arrived" time.

### SLO targets

| Protocol family | SLO |
| -------------------------------------------------------------------------------- | ----------- |
| chat / skill_request / query-remote | ≥ 99%/15s |
| swm-sender-key / private-access / join-request / storage-ack / verify-proposal | ≥ 99.5%/15s |
The runtime exposes measurements, not a pass/fail policy. Historical
rc.9 soak runs used 15-second p99 thresholds; current operators should
evaluate each protocol family against the workflow they are testing.

| Protocol family | Historical soak target |
| --- | --- |
| chat / skill_request / query-remote / sync | >= 99% within 15s |
| swm-sender-key / swm-update / swm-share-ack / swm-host-catchup / private-access / join-request / storage-ack / verify-proposal | >= 99.5% within 15s |

The ship-gate runs the soak script
(`scripts/libp2p-soak-test.sh`) across both Lex and Miles for an
overnight run; `/api/slo` is the source of truth for go/no-go on the
`v10.0.0-rc.9` tag.
Use the soak script (`scripts/libp2p-soak-test.sh`) for long-running
evidence and `/api/slo` for the local node's current in-memory view.

### Reading guide

Expand All @@ -256,22 +296,27 @@ overnight run; `/api/slo` is the source of truth for go/no-go on the
failed first attempts — typically a brand-new peer where address
resolution hasn't settled. Watch for `delivered` to start climbing
as the outbox retries land; PR-5's DHT-walk-on-stall should kick
in after 5 failed attempts (see `messenger.md` § Recovery
in after 5 failed attempts (see `docs/how-dkg-works/universal-messenger.md` § Recovery
primitives).
- **Soak runs.** `scripts/libp2p-soak-test.sh` writes a per-cycle
snapshot of `/api/slo` to `~/.dkg/soak-test-*/slo.jsonl` alongside
the existing `preflight.jsonl`, `sends.jsonl`, `inbox.jsonl`. The
human-readable summary line in `main.log` reads e.g.
`slo: message=d12/q0 p99=145ms, query-remote=d3/q0 p99=890ms, ...`.
- **SWM fan-out.** `swm.substrateFanout` is the per-CG outcome counter
for point-to-point SWM delivery. `shareAckQuorum` tracks the
ack-quorum overlay: `completed` should grow with `tracked`; sustained
`deadlineExpired` means recipients missed the delivery window and
will need reconnect sync to catch up.

### Caveats

- The histogram is **in-memory only**. Daemon restart resets all
counters and samples. The SQLite outbox itself survives restart;
the SLO view does not.
- Samples are recorded only for protocols routed through the
substrate. Anything still on `/dkg/10.0.0/*` (none at rc.9 ship;
the surface remains for future incremental migrations) is
substrate. Current bare `/dkg/10.0.0/*` examples include
`publish`, `query`, `discover`, and `verify-approval`; they are
invisible to `/api/slo`.

## Debugging a stuck outbox entry
Expand Down Expand Up @@ -315,24 +360,10 @@ will not retry deleted entries, and the receiver-side idempotency
table still absorbs duplicates if the same `messageId` ever shows up
on a re-issue path.

## Upgrade from rc.8 to rc.9

Wire-format break: all 8 short-message protocols moved from
`/dkg/10.0.0/*` to `/dkg/10.0.1/*`. Both daemons in a pair must be on
rc.9 for chat / skill / query / etc. to work between them. Mixed-pair
deploys (one node rc.8, one node rc.9) will fail negotiation on the
substrate-bumped protocols and surface as `delivered: false, queued:
true` outbox entries that drain once both sides upgrade.

Upgrade order recommendation:

1. Drain the rc.8 chat outbox on each node (let the daemon idle for
one tick cycle — typically 30s).
2. Stop the rc.8 daemon.
3. Pull rc.9, start the rc.9 daemon. The V12 + V13 SQLite migrations
run automatically.
4. Repeat on the paired node.
## Mixed-version protocol note

`chat_messages.message_id` column is preserved (nullable + unwritten
by rc.9) for hot-rollback safety; rc.8 finds a column it recognises
if you have to fall back.
Substrate-routed protocols use `/dkg/10.0.1/*` and require both peers
to advertise the same protocol ID. Older peers that only advertise the
pre-substrate `/dkg/10.0.0/*` IDs will fail negotiation for chat,
query-remote, sync, SWM fan-out, and the other substrate-routed
protocols. Upgrade both sides before relying on those workflows.
Loading
Loading