Compare commits
4 Commits
feat/alleg
...
feat/sover
| Author | SHA1 | Date | |
|---|---|---|---|
| b74e02ff0f | |||
| c5afb69461 | |||
| 8baa5c16a2 | |||
| 877425bde4 |
@@ -17,6 +17,7 @@ timmy-config/
|
||||
├── bin/ ← Live utility scripts (NOT deprecated loops)
|
||||
│ ├── hermes-startup.sh ← Hermes boot sequence
|
||||
│ ├── agent-dispatch.sh ← Manual agent dispatch
|
||||
│ ├── deploy-allegro-house.sh← Bootstraps the remote Allegro wizard house
|
||||
│ ├── ops-panel.sh ← Ops dashboard panel
|
||||
│ ├── ops-gitea.sh ← Gitea ops helpers
|
||||
│ ├── pipeline-freshness.sh ← Session/export drift check
|
||||
@@ -25,6 +26,7 @@ timmy-config/
|
||||
├── skins/ ← UI skins (timmy skin)
|
||||
├── playbooks/ ← Agent playbooks (YAML)
|
||||
├── cron/ ← Cron job definitions
|
||||
├── wizards/ ← Remote wizard-house templates + units
|
||||
└── training/ ← Transitional training recipes, not canonical lived data
|
||||
```
|
||||
|
||||
|
||||
32
bin/deploy-allegro-house.sh
Executable file
32
bin/deploy-allegro-house.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
TARGET="${1:-root@167.99.126.228}"
|
||||
HERMES_REPO_URL="${HERMES_REPO_URL:-https://github.com/NousResearch/hermes-agent.git}"
|
||||
KIMI_API_KEY="${KIMI_API_KEY:-}"
|
||||
|
||||
if [[ -z "$KIMI_API_KEY" && -f "$HOME/.config/kimi/api_key" ]]; then
|
||||
KIMI_API_KEY="$(tr -d '\n' < "$HOME/.config/kimi/api_key")"
|
||||
fi
|
||||
|
||||
if [[ -z "$KIMI_API_KEY" ]]; then
|
||||
echo "KIMI_API_KEY is required (env or ~/.config/kimi/api_key)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ssh "$TARGET" 'apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y git python3 python3-venv python3-pip curl ca-certificates'
|
||||
ssh "$TARGET" 'mkdir -p /root/wizards/allegro/home /root/wizards/allegro/hermes-agent'
|
||||
|
||||
ssh "$TARGET" "if [ ! -d /root/wizards/allegro/hermes-agent/.git ]; then git clone '$HERMES_REPO_URL' /root/wizards/allegro/hermes-agent; fi"
|
||||
ssh "$TARGET" 'cd /root/wizards/allegro/hermes-agent && python3 -m venv .venv && .venv/bin/pip install --upgrade pip setuptools wheel && .venv/bin/pip install -e .'
|
||||
|
||||
ssh "$TARGET" "cat > /root/wizards/allegro/home/config.yaml" < "$REPO_DIR/wizards/allegro/config.yaml"
|
||||
ssh "$TARGET" "cat > /root/wizards/allegro/home/SOUL.md" < "$REPO_DIR/SOUL.md"
|
||||
ssh "$TARGET" "cat > /root/wizards/allegro/home/.env <<'EOF'
|
||||
KIMI_API_KEY=$KIMI_API_KEY
|
||||
EOF"
|
||||
ssh "$TARGET" "cat > /etc/systemd/system/hermes-allegro.service" < "$REPO_DIR/wizards/allegro/hermes-allegro.service"
|
||||
|
||||
ssh "$TARGET" 'chmod 600 /root/wizards/allegro/home/.env && systemctl daemon-reload && systemctl enable --now hermes-allegro.service && systemctl restart hermes-allegro.service && systemctl is-active hermes-allegro.service && curl -fsS http://127.0.0.1:8645/health'
|
||||
44
docs/allegro-wizard-house.md
Normal file
44
docs/allegro-wizard-house.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Allegro wizard house
|
||||
|
||||
Purpose:
|
||||
- stand up the third wizard house as a Kimi-backed coding worker
|
||||
- keep Hermes as the durable harness
|
||||
- treat OpenClaw as optional shell frontage, not the bones
|
||||
|
||||
Local proof already achieved:
|
||||
|
||||
```bash
|
||||
HERMES_HOME=$HOME/.timmy/wizards/allegro/home \
|
||||
hermes doctor
|
||||
|
||||
HERMES_HOME=$HOME/.timmy/wizards/allegro/home \
|
||||
hermes chat -Q --provider kimi-coding -m kimi-for-coding \
|
||||
-q "Reply with exactly: ALLEGRO KIMI ONLINE"
|
||||
```
|
||||
|
||||
Observed proof:
|
||||
- Kimi / Moonshot API check passed in `hermes doctor`
|
||||
- chat returned exactly `ALLEGRO KIMI ONLINE`
|
||||
|
||||
Repo assets:
|
||||
- `wizards/allegro/config.yaml`
|
||||
- `wizards/allegro/hermes-allegro.service`
|
||||
- `bin/deploy-allegro-house.sh`
|
||||
|
||||
Remote target:
|
||||
- host: `167.99.126.228`
|
||||
- house root: `/root/wizards/allegro`
|
||||
- `HERMES_HOME`: `/root/wizards/allegro/home`
|
||||
- api health: `http://127.0.0.1:8645/health`
|
||||
|
||||
Deploy command:
|
||||
|
||||
```bash
|
||||
cd ~/.timmy/timmy-config
|
||||
bin/deploy-allegro-house.sh root@167.99.126.228
|
||||
```
|
||||
|
||||
Important nuance:
|
||||
- the Hermes/Kimi lane is the proven path
|
||||
- direct embedded OpenClaw Kimi model routing was not yet reliable locally
|
||||
- so the remote deployment keeps the minimal, proven architecture: Hermes house first
|
||||
48
evolution/did_manager.py
Normal file
48
evolution/did_manager.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Phase 23: Sovereign Identity & Decentralized Identifiers (DIDs).
|
||||
|
||||
Manages Timmy's decentralized identity across various DID methods (e.g., did:key, did:web, did:ion).
|
||||
"""
|
||||
|
||||
import logging
|
||||
import json
|
||||
from typing import List, Dict, Any
|
||||
from agent.gemini_adapter import GeminiAdapter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class DIDManager:
|
||||
def __init__(self):
|
||||
self.adapter = GeminiAdapter()
|
||||
|
||||
def generate_did(self, method: str, purpose: str) -> Dict[str, Any]:
|
||||
"""Generates a new Decentralized Identifier (DID) for a specific purpose."""
|
||||
logger.info(f"Generating DID using method {method} for purpose: {purpose}")
|
||||
|
||||
prompt = f"""
|
||||
DID Method: {method}
|
||||
Purpose: {purpose}
|
||||
|
||||
Please generate a valid DID Document and associated metadata for this identity.
|
||||
Include the public keys, service endpoints, and authentication methods.
|
||||
Identify the 'Sovereign Identity Principles' implemented in this DID.
|
||||
|
||||
Format the output as JSON:
|
||||
{{
|
||||
"did": "did:{method}:...",
|
||||
"did_document": {{...}},
|
||||
"purpose": "{purpose}",
|
||||
"method": "{method}",
|
||||
"sovereign_principles": [...],
|
||||
"security_recommendations": "..."
|
||||
}}
|
||||
"""
|
||||
result = self.adapter.generate(
|
||||
model="gemini-3.1-pro-preview",
|
||||
prompt=prompt,
|
||||
system_instruction="You are Timmy's DID Manager. Your goal is to ensure Timmy's identity is decentralized, verifiable, and entirely under his own control.",
|
||||
thinking=True,
|
||||
response_mime_type="application/json"
|
||||
)
|
||||
|
||||
did_data = json.loads(result["text"])
|
||||
return did_data
|
||||
48
evolution/identity_auditor.py
Normal file
48
evolution/identity_auditor.py
Normal file
@@ -0,0 +1,48 @@
|
||||
"""Phase 23: Identity Health Auditor.
|
||||
|
||||
Audits Timmy's decentralized identity for privacy leaks, correlation risks, and health.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import json
|
||||
from typing import List, Dict, Any
|
||||
from agent.gemini_adapter import GeminiAdapter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class IdentityAuditor:
|
||||
def __init__(self):
|
||||
self.adapter = GeminiAdapter()
|
||||
|
||||
def audit_identity_health(self, did_inventory: List[Dict[str, Any]]) -> Dict[str, Any]:
|
||||
"""Performs a deep audit of Timmy's identity inventory."""
|
||||
logger.info("Performing deep identity health audit.")
|
||||
|
||||
prompt = f"""
|
||||
DID Inventory:
|
||||
{json.dumps(did_inventory, indent=2)}
|
||||
|
||||
Please perform a 'Deep Privacy Audit' of this identity inventory.
|
||||
Identify correlation risks (where multiple DIDs can be linked to the same entity), potential metadata leaks, and revoked credential statuses.
|
||||
Generate an 'Identity Sovereignty Score' and proposed 'Identity Rotation' strategies.
|
||||
|
||||
Format the output as JSON:
|
||||
{{
|
||||
"sovereignty_score": "...",
|
||||
"audit_summary": "...",
|
||||
"correlation_risks": [...],
|
||||
"metadata_leaks": [...],
|
||||
"rotation_strategies": [...],
|
||||
"privacy_hardening_recommendations": "..."
|
||||
}}
|
||||
"""
|
||||
result = self.adapter.generate(
|
||||
model="gemini-3.1-pro-preview",
|
||||
prompt=prompt,
|
||||
system_instruction="You are Timmy's Identity Auditor. Your goal is to ensure Timmy's decentralized identity remains private, uncorrelatable, and truly sovereign.",
|
||||
thinking=True,
|
||||
response_mime_type="application/json"
|
||||
)
|
||||
|
||||
audit_data = json.loads(result["text"])
|
||||
return audit_data
|
||||
55
evolution/vc_manager.py
Normal file
55
evolution/vc_manager.py
Normal file
@@ -0,0 +1,55 @@
|
||||
"""Phase 23: Verifiable Credentials (VC) Manager.
|
||||
|
||||
Issues and verifies W3C Verifiable Credentials and Presentations.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import json
|
||||
from typing import List, Dict, Any
|
||||
from agent.gemini_adapter import GeminiAdapter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class VCManager:
|
||||
def __init__(self):
|
||||
self.adapter = GeminiAdapter()
|
||||
|
||||
def issue_credential(self, subject_did: str, claims: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Issues a Verifiable Credential for a given subject and set of claims."""
|
||||
logger.info(f"Issuing Verifiable Credential for subject: {subject_did}")
|
||||
|
||||
prompt = f"""
|
||||
Subject DID: {subject_did}
|
||||
Claims: {json.dumps(claims, indent=2)}
|
||||
|
||||
Please generate a W3C-compliant Verifiable Credential for these claims.
|
||||
Include the proof (signature) metadata and the credential schema.
|
||||
Identify the 'Privacy-Preserving Safeguards' implemented in this credential.
|
||||
|
||||
Format the output as JSON:
|
||||
{{
|
||||
"credential": {{
|
||||
"@context": [...],
|
||||
"type": ["VerifiableCredential", "..."],
|
||||
"issuer": "did:key:...",
|
||||
"issuanceDate": "...",
|
||||
"credentialSubject": {{
|
||||
"id": "{subject_did}",
|
||||
...
|
||||
}},
|
||||
"proof": {{...}}
|
||||
}},
|
||||
"privacy_safeguards": [...],
|
||||
"verification_directives": "..."
|
||||
}}
|
||||
"""
|
||||
result = self.adapter.generate(
|
||||
model="gemini-3.1-pro-preview",
|
||||
prompt=prompt,
|
||||
system_instruction="You are Timmy's VC Manager. Your goal is to ensure Timmy can issue and verify credentials with absolute cryptographic certainty.",
|
||||
thinking=True,
|
||||
response_mime_type="application/json"
|
||||
)
|
||||
|
||||
vc_data = json.loads(result["text"])
|
||||
return vc_data
|
||||
27
tests/test_allegro_wizard_assets.py
Normal file
27
tests/test_allegro_wizard_assets.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def test_allegro_config_targets_kimi_house() -> None:
|
||||
config = yaml.safe_load(Path("wizards/allegro/config.yaml").read_text())
|
||||
|
||||
assert config["model"]["provider"] == "kimi-coding"
|
||||
assert config["model"]["default"] == "kimi-for-coding"
|
||||
assert config["platforms"]["api_server"]["extra"]["port"] == 8645
|
||||
|
||||
|
||||
def test_allegro_service_uses_isolated_home() -> None:
|
||||
text = Path("wizards/allegro/hermes-allegro.service").read_text()
|
||||
|
||||
assert "HERMES_HOME=/root/wizards/allegro/home" in text
|
||||
assert "hermes gateway run --replace" in text
|
||||
|
||||
|
||||
def test_deploy_script_requires_external_secret() -> None:
|
||||
text = Path("bin/deploy-allegro-house.sh").read_text()
|
||||
|
||||
assert "~/.config/kimi/api_key" in text
|
||||
assert "sk-kimi-" not in text
|
||||
16
wizards/allegro/README.md
Normal file
16
wizards/allegro/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Allegro wizard house
|
||||
|
||||
Allegro is the third wizard house.
|
||||
|
||||
Role:
|
||||
- Kimi-backed coding worker
|
||||
- Tight scope
|
||||
- 1-3 file changes
|
||||
- Refactors, tests, implementation passes
|
||||
|
||||
This directory holds the remote house template:
|
||||
- `config.yaml` — Hermes house config
|
||||
- `hermes-allegro.service` — systemd unit
|
||||
|
||||
Secrets do not live here.
|
||||
`KIMI_API_KEY` must be injected at deploy time into `/root/wizards/allegro/home/.env`.
|
||||
61
wizards/allegro/config.yaml
Normal file
61
wizards/allegro/config.yaml
Normal file
@@ -0,0 +1,61 @@
|
||||
model:
|
||||
default: kimi-for-coding
|
||||
provider: kimi-coding
|
||||
toolsets:
|
||||
- all
|
||||
agent:
|
||||
max_turns: 30
|
||||
reasoning_effort: xhigh
|
||||
verbose: false
|
||||
terminal:
|
||||
backend: local
|
||||
cwd: .
|
||||
timeout: 180
|
||||
persistent_shell: true
|
||||
browser:
|
||||
inactivity_timeout: 120
|
||||
command_timeout: 30
|
||||
record_sessions: false
|
||||
display:
|
||||
compact: false
|
||||
personality: ''
|
||||
resume_display: full
|
||||
busy_input_mode: interrupt
|
||||
bell_on_complete: false
|
||||
show_reasoning: false
|
||||
streaming: false
|
||||
show_cost: false
|
||||
tool_progress: all
|
||||
memory:
|
||||
memory_enabled: true
|
||||
user_profile_enabled: true
|
||||
memory_char_limit: 2200
|
||||
user_char_limit: 1375
|
||||
nudge_interval: 10
|
||||
flush_min_turns: 6
|
||||
approvals:
|
||||
mode: manual
|
||||
security:
|
||||
redact_secrets: true
|
||||
tirith_enabled: false
|
||||
platforms:
|
||||
api_server:
|
||||
enabled: true
|
||||
extra:
|
||||
host: 127.0.0.1
|
||||
port: 8645
|
||||
session_reset:
|
||||
mode: none
|
||||
idle_minutes: 0
|
||||
skills:
|
||||
creation_nudge_interval: 15
|
||||
system_prompt_suffix: |
|
||||
You are Allegro, the Kimi-backed third wizard house.
|
||||
Your soul is defined in SOUL.md — read it, live it.
|
||||
Hermes is your harness.
|
||||
Kimi Code is your primary provider.
|
||||
You speak plainly. You prefer short sentences. Brevity is a kindness.
|
||||
|
||||
Work best on tight coding tasks: 1-3 file changes, refactors, tests, and implementation passes.
|
||||
Refusal over fabrication. If you do not know, say so.
|
||||
Sovereignty and service always.
|
||||
16
wizards/allegro/hermes-allegro.service
Normal file
16
wizards/allegro/hermes-allegro.service
Normal file
@@ -0,0 +1,16 @@
|
||||
[Unit]
|
||||
Description=Hermes Allegro Wizard House
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/root/wizards/allegro/hermes-agent
|
||||
Environment=HERMES_HOME=/root/wizards/allegro/home
|
||||
EnvironmentFile=/root/wizards/allegro/home/.env
|
||||
ExecStart=/root/wizards/allegro/hermes-agent/.venv/bin/hermes gateway run --replace
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Reference in New Issue
Block a user