Skip to content
Merged
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Read these in order:
5. [`platform/docs/ARCHITECTURE.md`](platform/docs/ARCHITECTURE.md)
6. [`platform/docs/PRODUCTION_READINESS_CHECKLIST.md`](platform/docs/PRODUCTION_READINESS_CHECKLIST.md)
7. [`platform/docs/DEVFLOW.md`](platform/docs/DEVFLOW.md)
8. [`platform/docs/PLUGIN_INVENTORY.md`](platform/docs/PLUGIN_INVENTORY.md)
9. [`platform/docs/DEGRADATION.md`](platform/docs/DEGRADATION.md)

## Repository map

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"enabled": true,
"config": {
"command": [
"__PYTHON_EXECUTABLE__",
"-m",
"clawops"
],
"configPath": "__HYPERMEMORY_SQLITE_CONFIG_PATH__",
Expand Down
2 changes: 2 additions & 0 deletions platform/configs/openclaw/77-hypermemory.example.json5
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"enabled": true,
"config": {
"command": [
"__PYTHON_EXECUTABLE__",
"-m",
"clawops"
],
"configPath": "__HYPERMEMORY_CONFIG_PATH__",
Expand Down
13 changes: 13 additions & 0 deletions platform/docs/BACKUP_AND_RECOVERY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@
- `clawops recovery prune-retention`
- `clawops recovery rotate-secrets`

## Scheduled maintenance

StrongClaw host service activation now installs a daily maintenance schedule at `04:00` local time:

- systemd: `openclaw-maintenance.timer` -> `openclaw-maintenance.service`
- launchd: `ai.openclaw.maintenance`

The scheduled command is:

- `clawops recovery --home-dir <home> prune-retention`

This maintenance path is idempotent and retention-only. It prunes expired StrongClaw recovery artifacts and does not mutate upstream OpenClaw internals.

## Development-mode repo-local compose state

If you keep compose state under `platform/compose/state` during development, use the explicit dev wrappers instead of relying on implicit leftover mounts:
Expand Down
2 changes: 2 additions & 0 deletions platform/docs/CI_AND_SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,5 @@ hypermemory Qdrant checks against the official pinned Qdrant GHCR image instead
compile-checks the repo, runs targeted devflow tests, and validates `clawops devflow plan --goal "contract smoke"` without live ACP providers.
- Operators can verify published provenance with GitHub's attestation tooling
after a tagged release lands.

Canonical plugin support status lives in [Plugin Inventory](./PLUGIN_INVENTORY.md).
37 changes: 37 additions & 0 deletions platform/docs/DEGRADATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Degradation Contract

This document defines how dependency health maps to StrongClaw runtime impact.

## Sidecar Dependency Matrix

| Dependency | Used by | Required for `clawops ops sidecars up` success | Impact when unavailable |
| --- | --- | --- | --- |
| Postgres | runtime metadata/session state | Yes | **fatal**: sidecar bring-up fails |
| LiteLLM | loopback model routing | Yes | **fatal**: sidecar bring-up fails |
| Qdrant | dense/sparse retrieval (`openclaw-qmd`, `hypermemory`) | Required when the active profile uses QMD or hypermemory retrieval | **degraded**: retrieval lanes depending on Qdrant are unavailable |
| Neo4j | graph expansion for `hypermemory` context | Required when the active profile uses hypermemory graph expansion | **degraded**: graph expansion is unavailable |
| OTel Collector | telemetry export | No | **observational**: tracing/metrics export unavailable, runtime behavior unaffected |

## Operator Output Contract

- `clawops ops status` reports dependency health under `readiness.required` and `readiness.optional`.
- Each readiness entry includes:
- `service`
- `required`
- `impact` (`fatal`, `degraded`, or `observational`)
- `reason`
- `ready`
- expected vs observed state/health fields
- `ok` and `readiness.requiredReady` are `true` only when every required dependency is ready.

## Plugin Startup Contract

- `strongclaw-hypermemory` runs startup preflight (`clawops hypermemory verify --json`) before serving memory tools.
- If preflight fails, tool responses return a disabled/unavailable payload instead of silent fallback.
- Existing configs that only define `timeoutMs` remain valid; startup/tool timeout split is optional via `startupTimeoutMs` and `toolTimeoutMs`.

## Related Docs

- [Plugin Inventory](./PLUGIN_INVENTORY.md)
- [Observability](./OBSERVABILITY.md)
- [Hypermemory](./HYPERMEMORY.md)
5 changes: 5 additions & 0 deletions platform/docs/HYPERMEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

The built-in OpenClaw fallback remains available as `openclaw-default`, and the explicit built-ins-plus-QMD fallback remains available as `openclaw-qmd`.

Canonical support/degradation references:

- [Plugin Inventory](./PLUGIN_INVENTORY.md)
- [Degradation Contract](./DEGRADATION.md)

## Design goals

- preserve OpenClaw-compatible `memory_search` and `memory_get`
Expand Down
26 changes: 26 additions & 0 deletions platform/docs/OBSERVABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,29 @@ Collector-side redaction is mandatory before broader trace export. Do not assume
- vector sync runs and sync failures

Those signals reuse the shared ClawOps telemetry path instead of adding a separate exporter or collector.

## Runtime Bring-Up Events

`clawops ops` now emits structured readiness events:

- `clawops.ops.sidecars.wait.start`
- `clawops.ops.sidecars.wait.ready`
- `clawops.ops.sidecars.wait.timeout`
- `clawops.ops.sidecars.ready`
- `clawops.ops.sidecars.status`

Wait-timeout events include `service`, `target`, `observed`, and `timeout_seconds` so failed dependencies can be diagnosed without replaying the command interactively.

## Host Service Activation Events

`clawops services install --activate` now emits:

- `clawops.services.activate` with `service_manager=launchd` and `step` values:
- `sidecars_bootstrap`
- `gateway_bootstrap`
- `maintenance_bootstrap`
- `clawops.services.activate` with `service_manager=systemd` and `step` values:
- `daemon_reload`
- `enable_now` (`unit` included per activation)

These events are intentionally coarse-grained to avoid high-volume per-poll logging.
22 changes: 22 additions & 0 deletions platform/docs/PLUGIN_INVENTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Plugin Inventory

This page is the canonical StrongClaw plugin support matrix.

## Shipped Plugins

| Plugin | Purpose | Default status | Build/runtime expectation | CI coverage | Support level |
| --- | --- | --- | --- | --- | --- |
| `strongclaw-hypermemory` | StrongClaw-owned memory plugin that proxies `clawops hypermemory` and preserves OpenClaw memory tool names. | Enabled by default in the `hypermemory` profile; opt-in via standalone overlay `75-strongclaw-hypermemory.example.json5`. | Requires a valid rendered `configPath` plus a callable StrongClaw command (`python -m clawops` in managed overlays). Startup preflight runs `clawops hypermemory verify --json` before serving tools. | `tests/suites/integration/clawops/hypermemory/test_plugin.py` and `platform/plugins/strongclaw-hypermemory/test/openclaw-host-functional.mjs` in CI. | **Supported (StrongClaw-owned)** |
| `memory-lancedb-pro` (vendored) | Vendored upstream memory plugin for migration bridge and compatibility use cases. | Not default; enabled through `memory-lancedb-pro` profile. | Vendored bundle under `platform/plugins/memory-lancedb-pro`, rendered via managed profile overlays. | `tests/suites/unit/ci/test_memory_plugin_verification.py` and `.github/workflows/memory-plugin-verification.yml`. | **Supported (vendored bridge path)** |

## Support Policy

- Support labels in this table must match real CI evidence and workflow coverage.
- New plugin entries must update this table and `platform/docs/CI_AND_SECURITY.md` in the same change.
- If a plugin is experimental or unavailable by default, that status must be explicit in this table and in any setup docs that mention it.

## Related Docs

- [Hypermemory](./HYPERMEMORY.md)
- [CI and Security](./CI_AND_SECURITY.md)
- [Degradation Contract](./DEGRADATION.md)
55 changes: 55 additions & 0 deletions platform/launchd/ai.openclaw.maintenance.plist.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>ai.openclaw.maintenance</string>
<key>ProgramArguments</key>
<array>
<string>__PYTHON_EXECUTABLE__</string>
<string>-m</string>
<string>clawops</string>
<string>recovery</string>
<string>--home-dir</string>
<string>__HOME_DIR__</string>
<string>prune-retention</string>
</array>
<key>WorkingDirectory</key>
<string>__REPO_ROOT__</string>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key>
<string>__HOME_DIR__</string>
<key>XDG_CONFIG_HOME</key>
<string>__HOME_DIR__/.config</string>
<key>OPENCLAW_HOME</key>
<string>__OPENCLAW_HOME__</string>
<key>OPENCLAW_STATE_DIR</key>
<string>__STATE_DIR__</string>
<key>OPENCLAW_CONFIG_PATH</key>
<string>__OPENCLAW_CONFIG_PATH__</string>
<key>OPENCLAW_CONFIG</key>
<string>__OPENCLAW_CONFIG__</string>
<key>OPENCLAW_PROFILE</key>
<string>__OPENCLAW_PROFILE__</string>
<key>STRONGCLAW_RUNTIME_ROOT</key>
<string>__STRONGCLAW_RUNTIME_ROOT__</string>
<key>PATH</key>
<string>__HOME_DIR__/.config/varlock/bin:__HOME_DIR__/.local/bin:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
__LAUNCHD_EXTRA_ENV__
</dict>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>4</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>__STATE_DIR__/logs/launchd-maintenance.out.log</string>
<key>StandardErrorPath</key>
<string>__STATE_DIR__/logs/launchd-maintenance.err.log</string>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
Loading
Loading