Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1be8d73
feat(agent-registry): register PMOVES-MiniMax-MCP as the MiniMax mode…
Aug 19, 2026
90fb730
feat(cgp): add pmoves-minimax-mcp + minimax service block to bootstra…
Aug 19, 2026
674d91f
docs(verifier): add PROVIDER_VERIFIER_GATE.md — how to run the confor…
Aug 19, 2026
13a2297
docs(cli): add MMX_CLI_SURFACE.md — catalog the mmx-cli surface
Aug 19, 2026
ccbfda2
docs(skills): add PMOVES_SKILLS_REVIEW.md — review the find-skills me…
Aug 19, 2026
890d0c5
docs(agents-md): add AGENTS_MD_FORMAT_REVIEW.md — review the open for…
Aug 19, 2026
1b07302
docs(cipher): store cipher skill context — what's encrypted, where, C…
Aug 19, 2026
c6c4628
docs(hirag): store HiRAG context — submodule state, what's wired, wha…
Aug 19, 2026
2fcc651
feat(registry): wire find-skills meta-skill into cli_tools + skill-pa…
Aug 19, 2026
4f6dac3
test(wireup): add 13 drift-detector tests for the model-cascade wire-up
Aug 19, 2026
c5c4457
agnote: CLAIM+RELEASE the mcpcli-wireup slice (Mavis::MCPCLI-WIREUP-C…
Aug 19, 2026
6dfbe1d
learnings: add mcpcli_wireup_LEARNINGS.md — capture the 5 patterns fr…
Aug 19, 2026
0561581
fix(cgp): add minimax to v1.schema.json services whitelist
Aug 19, 2026
1686e95
fix(mcp): pin minimax-mcp to the audited submodule version
POWERFULMOVES Aug 19, 2026
66d44ac
test(mcpcli): assert the minimax pin, not just the package name
POWERFULMOVES Aug 19, 2026
3c846c2
fix(rooms): point pmoves_minimax_mcp at real rooms (not a fabricated …
Aug 19, 2026
1971472
feat(gate): add pmoves/tools/provider_verifier_gate.py — the static C…
Aug 19, 2026
5d6ec6a
test(gate): add 22 tests for provider_verifier_gate (6 checks + aggre…
Aug 19, 2026
64523ae
feat(ci): add .github/workflows/provider-verifier.yml — the static gate
Aug 19, 2026
00a3903
refactor(gate): take verifier_submodule as a parameter, not a module …
Aug 19, 2026
b91ea89
docs(verifier): update PROVIDER_VERIFIER_GATE.md — Gate in CI is now …
Aug 19, 2026
397759c
feat(merge-gate): wire verifier-gate into the merge-decision + skippe…
Aug 19, 2026
9bdcfc6
fix(workflow): add issues:write to static-gate job for the PR-comment…
Aug 19, 2026
5b1c33d
agnote: CLAIM+RELEASE the provider-verifier-ci-gate slice
Aug 19, 2026
03fdaa7
learnings: add provider_verifier_ci_gate_LEARNINGS.md — capture the 5…
Aug 19, 2026
cee6ff2
docs(bootstrap): add provider-verifier to the Known Roads table
Aug 19, 2026
feeac5c
test(install): pin the operator's full-conformance run path
Aug 19, 2026
836d452
fix(ci): repair three defects that would have blocked every PR in the…
POWERFULMOVES Aug 19, 2026
fdaf7fb
fix(ci): two more fabricated pins — caught by the gate #2622 just landed
POWERFULMOVES Aug 19, 2026
7ddddb8
test(provider-verifier): the tests asserted the defects, so fix them too
POWERFULMOVES Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .claude/BOOTSTRAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Missing items are not failures — they are operational facts. Disclose them. Ne
| Fleet view | `make -C pmoves fleet-status` (never raw `tailscale status` for public IPs) |
| CHIT-sign provenance | `make -C pmoves sign-trail SUMMARY=... AGENT=...` |
| Refresh living docs | `make -C pmoves docs-reconcile` |
| Run the provider-verifier static gate | `py pmoves/tools/provider_verifier_gate.py` (no API calls; 6 checks; FAIL blocks merge via merge-gate) |
| Run the provider-verifier full conformance | `cd Pmoves-MiniMax-Provider-Verifier && python verify.py --providers <file> --output-dir /tmp/run` (operator-only, requires real API keys from `env.shared`) |

Full Known Roads catalog lives in `.claude/PATTERNS.md § Known Roads`. When the damage-control hook converts a raw `docker` / `netsh` / `gh workflow run` command to an `ask` prompt, that means a Make target already exists — use it.

Expand All @@ -35,6 +37,7 @@ Full Known Roads catalog lives in `.claude/PATTERNS.md § Known Roads`. When the
| Server | Transport | Purpose |
|--------|-----------|---------|
| `pmoves-cipher` | SSE `http://localhost:8105/mcp/sse` | Persistent agent memory lookups + writes |
| `pmoves-minimax-mcp` | stdio `uvx minimax-mcp` | MiniMax model surface (text/image/video/TTS/voice-clone); submodule PMOVES-MiniMax-MCP |
| `docker` | `mcp/docker` | Container inspection via local Docker socket |
| `hostinger-mcp` | stdio | Hostinger VPS API via `HOSTINGER_API_KEY` |
| `tailscale` | stdio | Tailnet inventory, stale-node cleanup, ACL operations |
Expand Down
87 changes: 87 additions & 0 deletions .claude/context/cipher.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Cipher context

**Submodule:** [Pmoves-cipher/](https://github.com/POWERFULMOVES/Pmoves-cipher) + [pmoves-cipher-mcp/](https://github.com/POWERFULMOVES/pmoves-cipher-mcp)
**MCP server name:** `pmoves-cipher`
**Transport:** SSE at `http://localhost:8105/mcp/sse`
**Bearer auth:** `Authorization: Bearer ${CIPHER_API_TOKEN}` (header expands empty without the env var → 401, expected)
**Discovery entry:** `pmoves/config/agent_registry.yaml` → `mcp_servers.pmoves_cipher_mcp`

Cipher is the PMOVES memory layer. Every cross-session knowledge lookup, every durable plan/checkpoint/completion, every state-changing action's signed audit trail flows through it. This context captures what's encrypted, where the keys live, the NATS custody chain, and how a Mavis-class agent should use it.

## What cipher is for

Three distinct things, all served by the same MCP server:

1. **Persistent agent memory** — durable storage of plans, checkpoints, and completions across agent sessions. An agent that gets a cold start can re-read its prior plan, see what it tried, and pick up.
2. **Reasoning trace storage** — the long-form chain-of-thought or decision rationale. Not the same as the plan; the trace is the working memory, the plan is the durable artifact.
3. **CHIT custody chain** — the signed audit trail for state-changing actions. The CHIT signing flow (`make -C pmoves sign-trail`) reads cipher's memory of the action context, signs the payload, and writes the signed result back to cipher.

These three together make cipher the "long now" for PMOVES agents. Without cipher, every session starts from zero; with cipher, the agent inherits the prior context.

## What's encrypted

Cipher encrypts the **memory body** (the actual stored payload — plans, traces, completions) using the node's CHIT key. The **memory index** (titles, timestamps, category, search hits) is stored unencrypted so the MCP server can answer search queries without decrypting every record.

Encryption key: `$CHIT_PASSPHRASE` (per the `B850-CLAUDE::SECRETS-LANE-L4-L5` AGNOTE entry 2026-08-18, the container-side name is `CHIT_PASSPHRASE`; the host-side label that the secrets pipeline writes is also `CHIT_PASSPHRASE` after the sync-secrets-local.yml fix in PR #2605). The key is loaded at container start; without it, the cipher container refuses to decrypt anything.

Encryption scheme: HMAC-SHA256 + AES-256-GCM, per the cipher spec at `pmoves/docs/security/CHIT/` (the CHIT signing spec). The HMAC is the CHIT trail; the AES key is derived from the passphrase via PBKDF2.

## Where the keys live

| Key | Lives in | Used by | Notes |
|-----|----------|---------|-------|
| `$CHIT_PASSPHRASE` (host-side) | `pmoves/env.shared` (per node) | `secrets-funnel` pipeline; cipher container reads it via the env interpolation in compose | Per-node, never shared. The pipeline writes a different value per node, so a stolen value only exposes one node's memory. |
| `$CHIT_PASSPHRASE` (container-side) | `docker-compose.<overlay>.yml` env section | `pmoves-cipher-api-1` reads it at container start | Same value as the host side, just propagated via the env interpolation. |
| HMAC kid (the public identifier) | `pmoves/contracts/chit/manifest.json` | CHIT signing + verification | Public; identifies the signing key, not the key itself. |
| HMAC secret (the actual signing key) | `$CHIT_PASSPHRASE` derived | `make -C pmoves sign-trail` | Used at signing time; never written to disk. |

The CHIT trail unsigned-local fallback (no `$CHIT_PASSPHRASE` set) is acceptable in dev per the AGNOTE rules, but the trail is still recorded — just unsigned. A signed trail is the only kind that gates merge in production; an unsigned trail is informational.

## NATS custody chain

Cipher publishes three subjects that the wider PMOVES ecosystem subscribes to (per `.claude/context/nats-subjects.md`):

| Subject | Direction | Purpose |
|---------|-----------|---------|
| `cipher.memory.stored.v1` | cipher-api → monitoring | Notify that a memory was stored |
| `cipher.memory.searched.v1` | cipher-api → monitoring | Notify that a memory search was performed |
| `cipher.reasoning.stored.v1` | cipher-api → monitoring | Notify that a reasoning trace was stored |

Cipher does NOT publish to `chit.signed.v1` directly. The CHIT signing flow is:
1. An agent decides to take a state-changing action.
2. The agent calls `make -C pmoves sign-trail SUMMARY=... AGENT=...`.
3. `sign-trail` reads the agent's context (often from cipher itself), composes a CHIT payload, signs it with the HMAC key derived from `$CHIT_PASSPHRASE`, and writes the signed payload to cipher.
4. `sign-trail` then publishes the signed event to `chit.signed.v1` on NATS.
5. Subscribers (AGNOTE trail writers, monitoring, downstream consumers) react to the signed event.

The HMAC signature is the custody mechanism. A signed trail can be verified offline against the public kid + the secret; a forged trail fails verification. This is what makes the AGNOTE append-only discipline work — the prior entry's signature is the trust anchor for the next entry.

## How a Mavis-class agent should use it

Three patterns, in priority order:

1. **Read on cold start.** Before doing work, search cipher for prior plans, recent completions, and AGNOTE entries tagged with your role. The `.claude/mcp.json` `pmoves-cipher` server exposes `cipher_search(query, category, limit)` and `cipher_read(record_id)` for this. Use the `category` filter to narrow (e.g. `category=agent_checkpoint` for the prior plan; `category=agent_completion` for what was tried).

2. **Write on phase boundaries.** Every BPM phase transition (define → assign → execute → review → close, per the harness v0 NATS subjects) should write a cipher record. The `cipher_store(record_type, payload, chit_signature?)` MCP method is the entry point. The record_type enum is `agent_plan | agent_checkpoint | agent_completion | reasoning_trace | chit_signed_event`.

3. **Sign before any state-changing action.** `make -C pmoves sign-trail` is the canonical entry point; raw HMAC calls bypass the audit chain. The damage-control hook redirects raw `hmac` / `openssl dgst -hmac` calls to an `ask` prompt, same as it does for raw `docker`. Don't bypass.

## What cipher is NOT

- Not a search engine. Cipher is a memory store; if the memory wasn't written, it can't be found. If a prior agent didn't record a decision, that decision is lost.
- Not a database. Cipher's search is best-effort text match over encrypted records; it's not a SQL query. For structured data (agent registry, model configs, NATS subjects), use the appropriate PMOVES subsystem.
- Not a key-value store. Cipher records have a schema (the four `agent_*` / `reasoning_trace` types plus the chit_signed_event type); the payload must conform.
- Not a real-time channel. Cipher's NATS subjects are for monitoring, not for inter-agent messaging. For that, use the NATS subjects registered in `pmoves/contracts/schemas/` directly (e.g. `pmoves.agent.task.v1`).

## Reference

- MCP server source: `pmoves-cipher-mcp/` (PMOVES fork of the cipher MCP)
- Memory source: `Pmoves-cipher/` (the cipher storage engine)
- MCP config: `.claude/mcp.json` → `pmoves-cipher` server
- Agent registry: `pmoves/config/agent_registry.yaml` → `mcp_servers.pmoves_cipher_mcp`
- NATS subjects: `.claude/context/nats-subjects.md` (search for `cipher.*`)
- AGNOTE body: `.claude/agents/memory-agent.md` (the Three-Body Memory Body)
- CHIT signing spec: `pmoves/docs/security/CHIT/` (CHIT trail signing reference)
- Signing entry point: `make -C pmoves sign-trail` (per `pmoves/Makefile`)
- Secrets pipeline: `pmoves/mk/codex.mk` → `secrets-funnel` target (the canonical funnel)
- Path verification: `.claude/mcp.json` `_note` on `pmoves-cipher` — `/mcp/sse` returns 200, `/api/mcp/sse` and `/sse` return 404 (PATH VERIFIED 2026-08-12)
66 changes: 66 additions & 0 deletions .claude/context/hirag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# HiRAG context

**Submodules:** [PMOVES-HiRAG/](https://github.com/POWERFULMOVES/PMOVES-HiRAG) (the algorithm/research work) + [pmoves-hirag-mcp/](https://github.com/POWERFULMOVES/pmoves-hirag-mcp) (the MCP server)
**Submodule pins:** PMOVES-HiRAG `e904b12a477ad670d5036e059912c2889c308926` (tracks `PMOVES.AI-Edition-Hardened`), pmoves-hirag-mcp `0ec18d886643bf16a9b415873b4898409421c024` (main)
**Compose services:** `hi-rag-gateway` (CPU, port 8089→8086, legacy profile) and `hi-rag-gateway-gpu` (GPU, port 8090→8086, gpu + legacy profile)
**MCP server name:** `pmoves-hirag-mcp`
**MCP transport:** SSE (declared in agent registry; not yet in `.claude/mcp.json` — wiring is a follow-up)
**Discovery entry:** `pmoves/config/agent_registry.yaml` → `mcp_servers.pmoves_hirag_mcp`
**Grounding source:** `true` (per the registry: "a discovering agent fetches startup grounding here")

HiRAG is PMOVES's hybrid retrieval layer — vector + graph + full-text, combined under a single query interface. It's the second of the two `grounding_source: true` MCP servers in the registry (cipher is the other). This context captures what it is, what's wired, what's pending, and how a Mavis-class agent should use it.

## What HiRAG is

The "hybrid" in HiRAG is a three-way retrieval: dense vector (Qdrant), graph traversal (Neo4j), and full-text search (MeiliSearch). A single query fans out to all three, the results are merged and reranked, and a unified top-K comes back. The legacy gateway (`hi-rag-gateway`) and v2 gateway (`hi-rag-gateway-v2`) are the two HTTP surfaces; the MCP server is the discovery-friendly entry point.

The research/algorithm substrate is in PMOVES-HiRAG, which tracks the hardened branch. The companion paper "Latent Geometry as a Control Knob" (in `pmoves/docs/context/Latent_Geometry_Is_a_Control_Knob/`) is the theoretical motivation — the claim is that the latent geometry of the vector space encodes the relationship structure that a graph would otherwise have to be told about, and that hybrid retrieval is a way to combine the geometry's implicit structure with explicit graph structure. The HiRAG v2 gateway is the implementation of that thesis.

## What's wired

Three things, in priority order:

1. **MCP server entry in agent registry** — `pmoves_hirag_mcp` is declared in `pmoves/config/agent_registry.yaml` line 3032 with `transport: "sse"`, `endpoint: ${PMOVES_HIRAG_MCP_ENDPOINT:-http://pmoves-hirag-mcp:8080/sse}`, `action_namespace: "mcp.v1.hirag"`, `capabilities: ["retrieve", "graph", "search", "notebook"]`, `rooms: ["4090-field.room.control", "hermes-agent.room.control"]`, `grounding_source: true`, `status: "planned"`. The entry exists; the MCP server itself runs as a Docker service in compose.

2. **Legacy hi-rag-gateway in compose** — both the CPU and GPU variants are in the compose overlay system. The CPU service is `hi-rag-gateway` on port `8089→8086`; the GPU service is `hi-rag-gateway-gpu` on port `8090→8086`. Both are gated on the `legacy` profile; the GPU service also needs the `gpu` profile. Both depend on Qdrant and Neo4j.

3. **Smoke test path** — `docker compose --profile legacy up -d qdrant neo4j hi-rag-gateway` brings up the legacy stack, then `curl -sS http://localhost:8089/hirag/query -H 'content-type: application/json' -d '{"query":"hello","namespace":"pmoves","k":3}'` exercises the query interface. The README notes that `make bootstrap-data` is the right way to populate the demo data before running smokes.

## What's pending

Three things, in priority order:

1. **`.claude/mcp.json` registration** — unlike cipher (which has both a registry entry AND a `.claude/mcp.json` server), HiRAG is in the registry only. A future PMOVES-aware agent that tries to consume the MCP server directly from `.claude/mcp.json` will not find it. The fix is a one-block addition to `.claude/mcp.json` mirroring the `pmoves-cipher` pattern (SSE transport, URL from the same env var the registry references). Recommendation: do this when HiRAG becomes a real cold-start surface, not in the wire-up PR (the MCP server is `status: "planned"`, not `"active"`).

2. **v2 gateway promotion** — the v2 README explicitly says "v2 remains the preferred path for advanced features and UI" but the legacy stack is what's actually wired in compose. The v2 is documented but not deployed. The risk is that a new agent is built against the legacy gateway and the v2 stays second-class. Recommendation: a follow-up slice that promotes v2 to the default and demotes the legacy stack to "compatibility only."

3. **PMOVES-HiRAG submodule freshness** — the submodule tracks `PMOVES.AI-Edition-Hardened`, not `main`. The most recent commit is `e904b12a` from August 2026; the upstream research is presumably still landing there. The risk is the algorithm substrate drifts from the v2 gateway implementation. Recommendation: a `submodule-integrity` check on every PR that touches either the submodule or the gateway; the existing `.github/scripts/validate_submodule_gitlinks.sh` covers the gitlink but not the freshness-vs-main check.

## How a Mavis-class agent should use it

Three patterns, in priority order:

1. **Read on cold start for grounding.** The `grounding_source: true` flag in the registry entry means a discovering agent fetches startup grounding here. Concretely: when Mavis first loads, it should issue a `retrieve(query="<lane context>", namespace="pmoves", k=5)` call against HiRAG to surface the most relevant prior work, plans, and CHIT trail entries for the lane it's about to work in. The cipher MCP complements this (cipher is the durable memory; HiRAG is the relevant-now retrieval over that memory).

2. **Issue hybrid queries for cross-cutting context.** A single HiRAG query covers the vector + graph + full-text space. The common case: "what did we decide about X last time it came up?" — a vector match on the topic, a graph match on related people/decisions, and a full-text match on the literal phrase. The merged top-K is the right context window for a planning step.

3. **Fall back to scoped search for narrow questions.** If the question is highly specific (a function name, a commit SHA, a person), full-text search via Meili is faster than HiRAG. The MCP server's `search` capability is the right entry point; reserve the broader `retrieve` for open-ended questions.

## What HiRAG is NOT

- Not a primary database. The durable source of truth is Supabase (Postgres) for structured data, Neo4j for the graph, and Qdrant for vectors. HiRAG is the read-side.
- Not a real-time index. HiRAG's indices are populated by the bootstrap-data make target, not by event-driven writes. If you write to Qdrant/Neo4j/Meili directly, HiRAG will see it on its next query; if you need a guaranteed-fresh view, query the underlying store.
- Not a replacement for cipher. Cipher is the durable memory; HiRAG is the retrieval over it. A write goes to cipher; a read goes to HiRAG.
- Not a search engine. HiRAG searches PMOVES-side data (the seeded corpus). For web search, use the `mmx search web` CLI or a web-search MCP.

## Reference

- Submodule (algorithm substrate): `PMOVES-HiRAG/` (PMOVES fork of HiRAG research; tracks `PMOVES.AI-Edition-Hardened`)
- Submodule (MCP server): `pmoves-hirag-mcp/`
- Compose services: `hi-rag-gateway` (CPU, legacy profile) and `hi-rag-gateway-gpu` (GPU, gpu+legacy profile)
- Service docs: `pmoves/docs/services/hi-rag-gateway/README.md` and `pmoves/docs/services/hi-rag-gateway-v2/README.md`
- Agent registry: `pmoves/config/agent_registry.yaml` → `mcp_servers.pmoves_hirag_mcp`
- Theory paper: `pmoves/docs/context/Latent_Geometry_Is_a_Control_Knob/`
- v2 design notes: see `hi-rag-gateway-v2/README.md` and the LATEST_ENTRY notes in the submodule
- Hybrid search: Qdrant (vector) + Neo4j (graph) + MeiliSearch (full-text), merged at the gateway
- Discovery rooms: `4090-field.room.control`, `hermes-agent.room.control`
14 changes: 13 additions & 1 deletion .claude/mcp.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_pinned_versions_note": "Dependencies pinned to exact versions on 2026-05-14 to prevent supply chain attacks (F-07). Re-pin after auditing new releases before upgrading. hostinger-api-mcp=POWERFULMOVES fork @094e38c (v1.35.7; replaced the npm 0.2.1 pin), tailscale-mcp=2026.4.10-1, @supabase/mcp-server-postgrest=0.1.1, postgres-mcp=0.3.0",
"_pinned_versions_note": "Dependencies pinned to exact versions on 2026-05-14 to prevent supply chain attacks (F-07). Re-pin after auditing new releases before upgrading. hostinger-api-mcp=POWERFULMOVES fork @094e38c (v1.35.7; replaced the npm 0.2.1 pin), tailscale-mcp=2026.4.10-1, @supabase/mcp-server-postgrest=0.1.1, postgres-mcp=0.3.0, minimax-mcp=0.0.18 (matches the audited PMOVES-MiniMax-MCP gitlink f4d6a61b, whose pyproject.toml declares version 0.0.18)",
"mcpServers": {
"pmoves-cipher": {
"_note": "Cipher SSE requires bearer auth when the API token is set (hardened container, post-#2005 recreate). The claude-pmoves launcher injects the token env var; without it the header expands empty and cipher returns 401 (same as before this header existed - no regression). PATH VERIFIED 2026-08-12 against a freshly built pmoves-cipher-api-1 (node dist/pmoves/rest-server.js --port 8105, published 127.0.0.1:8105->8105): /mcp/sse answers 200; /api/mcp/sse and /sse both 404. Same result as an independent 2026-08-04 probe of a different build, so the path is a property of the server, not of one container.",
Expand Down Expand Up @@ -147,6 +147,18 @@
"env": {
"DATABASE_URI": "${SUPABASE_DB_URI}"
}
},
"pmoves-minimax-mcp": {
"_purpose": "PMOVES-MiniMax-MCP — MiniMax model surface (text/image/video/TTS/voice-clone) over MCP stdio. Submodule POWERFULMOVES/PMOVES-MiniMax-MCP (f4d6a61b) at PMOVES-MiniMax-MCP/; entry point `uvx minimax-mcp` per the submodule's pyproject.toml. Mavis harness v0 follow-ups (PR #2568) consume this for model access; the sidecar lane (Pinokio on operator devices) calls the same surface via Pmoves-minimax-cli. Requires MINIMAX_API_KEY.",
"command": "uvx",
"args": [
"minimax-mcp==0.0.18"
],
"env": {
"MINIMAX_API_KEY": "${MINIMAX_API_KEY}",
"MINIMAX_API_HOST": "${MINIMAX_API_HOST:-https://api.minimax.chat}",
"MINIMAX_API_RESOURCE_MODE": "${MINIMAX_API_RESOURCE_MODE:-url}"
}
}
}
}
Loading
Loading