@aiassesstech/mighty-mark 0.3.31 → 0.3.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +88 -0
- package/agent/AGENTS.md +28 -0
- package/dist/checks/backup-orchestrator.d.ts +33 -0
- package/dist/checks/backup-orchestrator.d.ts.map +1 -0
- package/dist/checks/backup-orchestrator.js +260 -0
- package/dist/checks/backup-orchestrator.js.map +1 -0
- package/dist/checks/check-runner.d.ts +7 -0
- package/dist/checks/check-runner.d.ts.map +1 -1
- package/dist/checks/check-runner.js +22 -2
- package/dist/checks/check-runner.js.map +1 -1
- package/dist/checks/data-integrity.d.ts +2 -1
- package/dist/checks/data-integrity.d.ts.map +1 -1
- package/dist/checks/data-integrity.js +10 -2
- package/dist/checks/data-integrity.js.map +1 -1
- package/dist/checks/gateway-health.d.ts.map +1 -1
- package/dist/checks/gateway-health.js +3 -0
- package/dist/checks/gateway-health.js.map +1 -1
- package/dist/checks/openclaw-version.d.ts +34 -0
- package/dist/checks/openclaw-version.d.ts.map +1 -0
- package/dist/checks/openclaw-version.js +165 -0
- package/dist/checks/openclaw-version.js.map +1 -0
- package/package.json +3 -1
- package/src/watchdog/fleet-backup/config.sh +74 -0
- package/src/watchdog/fleet-backup/fleet-backup.sh +363 -0
- package/src/watchdog/fleet-backup/fleet-restore.sh +437 -0
- package/src/watchdog/fleet-backup/test/test-backup.sh +395 -0
- package/src/watchdog/fleet-backup/test/test-restore.sh +302 -0
- package/src/watchdog/install.sh +61 -4
- package/src/watchdog/morning-check.sh +5 -13
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@aiassesstech/mighty-mark` will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.3.32] — 2026-03-03
|
|
9
|
+
|
|
10
|
+
**Fleet disaster recovery backup — bundled into the npm package.**
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Fleet backup scripts bundled** — `fleet-backup.sh`, `fleet-restore.sh`, `config.sh`, and 48 bash tests now ship inside the npm package (`src/watchdog/fleet-backup/`). No separate `git clone` needed on the VPS.
|
|
14
|
+
- **TypeScript backup orchestrator** (`src/checks/backup-orchestrator.ts`) — executes the backup script, validates the manifest, then runs both test suites (backup + restore). Returns `CheckResult[]` for integration into the morning report.
|
|
15
|
+
- **Auto-detection** — `CheckRunner.detectBackupConfig()` checks for `/opt/fleet-backup/fleet-backup.sh` at runtime. If found, the full orchestration runs; otherwise falls back to manifest-only freshness check.
|
|
16
|
+
- **Tiered backup strategy** — weekly full (~460 MB, split into <95 MB chunks) and daily light (~5-15 MB). Both push off-site to GitHub with 35-day retention.
|
|
17
|
+
- **`install.sh` updated** — copies fleet backup scripts from the bundled npm package (preferred) or standalone git clone (fallback). Removes the old standalone cron job.
|
|
18
|
+
- **17 unit tests** for `backup-orchestrator.ts` (execution, failure, manifest, tests, edge cases).
|
|
19
|
+
- **15 watchdog validation tests** for the bundled fleet backup scripts and updated installer.
|
|
20
|
+
- **4 scenario tests** for backup orchestration through `runDataChecks`.
|
|
21
|
+
- **3 data-integrity tests** for `backupConfig` parameter behavior.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `morning-check.sh` no longer triggers `fleet-backup.sh` directly — backup is orchestrated by the TypeScript health engine.
|
|
25
|
+
- `runDataChecks()` accepts optional `backupConfig` parameter for full orchestration.
|
|
26
|
+
- `runAll()` and `runCategory()` in `CheckRunner` auto-detect backup infrastructure.
|
|
27
|
+
- Total test count: 499 across 26 files (28 new tests in this release).
|
|
28
|
+
|
|
29
|
+
## [0.3.31] — 2026-03-02
|
|
30
|
+
|
|
31
|
+
**Docs site daily backup monitoring.**
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **`checkDocsBackupFreshness()`** — monitors the `docs-backup` branch on GitHub for daily documentation site backup freshness. Warns if no backup in 36 hours.
|
|
35
|
+
- **`checkFleetBackupFreshness()`** — reads `latest-manifest.json` from fleet backup, validates structure and recency.
|
|
36
|
+
- Comprehensive freshness tests for both backup types.
|
|
37
|
+
|
|
38
|
+
## [0.3.29] — 2026-03-01
|
|
39
|
+
|
|
40
|
+
**Fleet backup integration into morning check.**
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **Morning check triggers fleet backup** — `morning-check.sh` now executes `/opt/fleet-backup/fleet-backup.sh` before running health checks. Sends Telegram alert on failure.
|
|
44
|
+
- Fleet backup result included in health report.
|
|
45
|
+
|
|
46
|
+
## [0.3.26] — 2026-02-28
|
|
47
|
+
|
|
48
|
+
**Alerting health checks and path improvements.**
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- 6 security pipeline runtime checks.
|
|
52
|
+
- Fleet tool registration validation (Rule 155 compliance).
|
|
53
|
+
- Alerting health checks integrated into morning report.
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
- Removed hardcoded VPS paths — all paths now resolved dynamically.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
- Published to npm as `@aiassesstech/mighty-mark@0.3.26`.
|
|
60
|
+
|
|
61
|
+
## [0.3.1] — 2026-02-23
|
|
62
|
+
|
|
63
|
+
**OpenClaw workspace path integration.**
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
- Read workspace paths from `openclaw.json` configuration.
|
|
67
|
+
- Single-command `setup` for agent provisioning.
|
|
68
|
+
|
|
69
|
+
## [0.2.6] — 2026-02-21
|
|
70
|
+
|
|
71
|
+
**Memory path fix — OpenClaw ignores symlinks.**
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
- Write memory files directly to agent workspaces. OpenClaw's memory scanner does not follow symlinks (discovered in production). See rule `807-openclaw-memory-paths.mdc`.
|
|
75
|
+
|
|
76
|
+
## [0.2.0] — 2026-02-19
|
|
77
|
+
|
|
78
|
+
**Fleet Memory Infrastructure — initial release.**
|
|
79
|
+
|
|
80
|
+
### Added
|
|
81
|
+
- `MemoryWriter` for agent memory files with correct path resolution.
|
|
82
|
+
- `createAgentMemoryDirs()` for workspace directory setup.
|
|
83
|
+
- Memory backfill from central directory to agent workspaces.
|
|
84
|
+
- 26 health checks across 5 categories (API, Data, Infrastructure, Memory, Process).
|
|
85
|
+
- Two-layer architecture: Level 2 (OpenClaw plugin) + Level 1 (bash watchdog).
|
|
86
|
+
- Morning check protocol with Telegram reporting.
|
|
87
|
+
- Incident management with severity classification.
|
|
88
|
+
- Uptime tracking (7/14/30-day SLA).
|
package/agent/AGENTS.md
CHANGED
|
@@ -37,6 +37,19 @@ If the gateway dies and I die with it, my Level 1 watchdog — pure bash, runnin
|
|
|
37
37
|
via cron — will restart the gateway and bring me back. I trust it because it has
|
|
38
38
|
no dependencies. It's the simplest possible script doing the most important job.
|
|
39
39
|
|
|
40
|
+
## Rule 8: Fleet Backup Is My Duty
|
|
41
|
+
Every morning before health checks, I orchestrate the fleet backup. My TypeScript
|
|
42
|
+
engine executes fleet-backup.sh, validates the manifest, then runs both test suites
|
|
43
|
+
(48 bash tests) to verify the backup is restorable. The backup is tiered:
|
|
44
|
+
- **Full** (Sunday): Everything — extensions, memory, data stores, vector indexes,
|
|
45
|
+
sessions, fleet-bus, configs. ~460 MB, split into chunks for GitHub.
|
|
46
|
+
- **Light** (Mon–Sat): Agent .md files, sanitized configs, systemd/cron. ~5-15 MB.
|
|
47
|
+
|
|
48
|
+
Both tiers push off-site to GitHub. Both are retained for 35 days. If the backup
|
|
49
|
+
fails, I send an immediate Telegram alert. If tests fail, I report it in the
|
|
50
|
+
morning check. This is the last line of defense — if the VPS is compromised,
|
|
51
|
+
these backups are all we have.
|
|
52
|
+
|
|
40
53
|
## Communication Protocol
|
|
41
54
|
|
|
42
55
|
When communicating with other agents via agent-to-agent messaging:
|
|
@@ -59,3 +72,18 @@ Store results in the `.mighty-mark-data/` directory:
|
|
|
59
72
|
incidents/ # Incident records
|
|
60
73
|
config/ # Fleet topology (BB-editable)
|
|
61
74
|
```
|
|
75
|
+
|
|
76
|
+
## Backup Infrastructure
|
|
77
|
+
|
|
78
|
+
Fleet backup scripts ship with my npm package and are deployed to `/opt/fleet-backup/`:
|
|
79
|
+
```
|
|
80
|
+
/opt/fleet-backup/
|
|
81
|
+
fleet-backup.sh # Tiered backup (auto-detects full/light)
|
|
82
|
+
fleet-restore.sh # Restore from local or GitHub
|
|
83
|
+
config.sh # Paths, retention, GitHub settings
|
|
84
|
+
config.local.sh # VPS-specific overrides (not in git)
|
|
85
|
+
latest-manifest.json # Last backup manifest (read by health checks)
|
|
86
|
+
backups/ # Local archive storage (35-day retention)
|
|
87
|
+
logs/ # Backup logs
|
|
88
|
+
test/ # 48 bash tests (backup + restore)
|
|
89
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup Orchestrator — executes fleet-backup.sh, runs test suites,
|
|
3
|
+
* parses results, and returns structured CheckResult[].
|
|
4
|
+
*
|
|
5
|
+
* Designed to be invoked by CheckRunner during the morning health check.
|
|
6
|
+
* On the VPS, scripts live at /opt/fleet-backup/. The npm package bundles
|
|
7
|
+
* them at src/watchdog/fleet-backup/ for install.sh to deploy.
|
|
8
|
+
*/
|
|
9
|
+
import type { CheckResult } from '../types/health.js';
|
|
10
|
+
import { type CheckContext } from './check-context.js';
|
|
11
|
+
export interface BackupOrchestratorConfig {
|
|
12
|
+
/** Override fleet backup directory (default: /opt/fleet-backup). */
|
|
13
|
+
fleetBackupDir?: string;
|
|
14
|
+
/** Skip actually running the backup (test mode). */
|
|
15
|
+
skipBackup?: boolean;
|
|
16
|
+
/** Skip running test suites (faster morning check). */
|
|
17
|
+
skipTests?: boolean;
|
|
18
|
+
/** Timeout for the backup script in ms (default: 5 minutes). */
|
|
19
|
+
backupTimeoutMs?: number;
|
|
20
|
+
/** Timeout for each test suite in ms (default: 2 minutes). */
|
|
21
|
+
testTimeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Run the full backup orchestration sequence:
|
|
25
|
+
* 1. Execute fleet-backup.sh
|
|
26
|
+
* 2. Validate the resulting manifest
|
|
27
|
+
* 3. Run test-backup.sh against the fresh backup
|
|
28
|
+
* 4. Run test-restore.sh against the fresh backup
|
|
29
|
+
*
|
|
30
|
+
* Returns CheckResult[] that integrates into the morning report.
|
|
31
|
+
*/
|
|
32
|
+
export declare function runBackupOrchestration(config?: BackupOrchestratorConfig, ctx?: CheckContext): Promise<CheckResult[]>;
|
|
33
|
+
//# sourceMappingURL=backup-orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup-orchestrator.d.ts","sourceRoot":"","sources":["../../src/checks/backup-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAQ5D,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAiDD;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,CAAC,EAAE,wBAAwB,EACjC,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CA2MxB"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backup Orchestrator — executes fleet-backup.sh, runs test suites,
|
|
3
|
+
* parses results, and returns structured CheckResult[].
|
|
4
|
+
*
|
|
5
|
+
* Designed to be invoked by CheckRunner during the morning health check.
|
|
6
|
+
* On the VPS, scripts live at /opt/fleet-backup/. The npm package bundles
|
|
7
|
+
* them at src/watchdog/fleet-backup/ for install.sh to deploy.
|
|
8
|
+
*/
|
|
9
|
+
import { exec as execCb } from 'node:child_process';
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { now } from './check-context.js';
|
|
13
|
+
const FLEET_BACKUP_DIR = '/opt/fleet-backup';
|
|
14
|
+
const FLEET_BACKUP_SCRIPT = path.join(FLEET_BACKUP_DIR, 'fleet-backup.sh');
|
|
15
|
+
const MANIFEST_PATH = path.join(FLEET_BACKUP_DIR, 'latest-manifest.json');
|
|
16
|
+
const TEST_BACKUP_SCRIPT = path.join(FLEET_BACKUP_DIR, 'test', 'test-backup.sh');
|
|
17
|
+
const TEST_RESTORE_SCRIPT = path.join(FLEET_BACKUP_DIR, 'test', 'test-restore.sh');
|
|
18
|
+
function execAsync(cmd, timeoutMs, ctx) {
|
|
19
|
+
if (ctx?.execCommand) {
|
|
20
|
+
try {
|
|
21
|
+
const stdout = ctx.execCommand(cmd);
|
|
22
|
+
return Promise.resolve({ stdout, stderr: '', exitCode: 0 });
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
26
|
+
return Promise.resolve({ stdout: '', stderr: message, exitCode: 1 });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
execCb(cmd, { timeout: timeoutMs, maxBuffer: 1024 * 1024 * 5 }, (error, stdout, stderr) => {
|
|
31
|
+
resolve({
|
|
32
|
+
stdout: String(stdout),
|
|
33
|
+
stderr: String(stderr),
|
|
34
|
+
exitCode: error ? error.code ?? 1 : 0,
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Parse the summary line from test-backup.sh / test-restore.sh output.
|
|
41
|
+
* Format: "Results: 32 passed, 0 failed, 0 skipped (32 total)"
|
|
42
|
+
*/
|
|
43
|
+
function parseTestResults(output) {
|
|
44
|
+
const match = output.match(/(\d+)\s+passed.*?(\d+)\s+failed.*?(\d+)\s+skipped.*?\((\d+)\s+total\)/);
|
|
45
|
+
if (!match)
|
|
46
|
+
return null;
|
|
47
|
+
return {
|
|
48
|
+
passed: parseInt(match[1], 10),
|
|
49
|
+
failed: parseInt(match[2], 10),
|
|
50
|
+
skipped: parseInt(match[3], 10),
|
|
51
|
+
total: parseInt(match[4], 10),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Run the full backup orchestration sequence:
|
|
56
|
+
* 1. Execute fleet-backup.sh
|
|
57
|
+
* 2. Validate the resulting manifest
|
|
58
|
+
* 3. Run test-backup.sh against the fresh backup
|
|
59
|
+
* 4. Run test-restore.sh against the fresh backup
|
|
60
|
+
*
|
|
61
|
+
* Returns CheckResult[] that integrates into the morning report.
|
|
62
|
+
*/
|
|
63
|
+
export async function runBackupOrchestration(config, ctx) {
|
|
64
|
+
const results = [];
|
|
65
|
+
const dir = config?.fleetBackupDir ?? FLEET_BACKUP_DIR;
|
|
66
|
+
const backupScript = path.join(dir, 'fleet-backup.sh');
|
|
67
|
+
const manifestFile = ctx?.dataDir
|
|
68
|
+
? path.join(ctx.dataDir, 'latest-manifest.json')
|
|
69
|
+
: path.join(dir, 'latest-manifest.json');
|
|
70
|
+
const testBackup = path.join(dir, 'test', 'test-backup.sh');
|
|
71
|
+
const testRestore = path.join(dir, 'test', 'test-restore.sh');
|
|
72
|
+
const backupTimeout = config?.backupTimeoutMs ?? 300_000;
|
|
73
|
+
const testTimeout = config?.testTimeoutMs ?? 120_000;
|
|
74
|
+
// ── Step 1: Execute backup ─────────────────────────────────────
|
|
75
|
+
if (!config?.skipBackup) {
|
|
76
|
+
const backupStart = Date.now();
|
|
77
|
+
if (!fs.existsSync(backupScript)) {
|
|
78
|
+
results.push({
|
|
79
|
+
name: 'Fleet backup execution',
|
|
80
|
+
category: 'data',
|
|
81
|
+
status: 'warn',
|
|
82
|
+
message: `Backup script not found: ${backupScript}`,
|
|
83
|
+
timestamp: now(),
|
|
84
|
+
durationMs: Date.now() - backupStart,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const { stdout, stderr, exitCode } = await execAsync(`bash "${backupScript}"`, backupTimeout, ctx);
|
|
89
|
+
if (exitCode !== 0) {
|
|
90
|
+
const errorTail = (stderr || stdout).split('\n').slice(-5).join(' ').trim();
|
|
91
|
+
results.push({
|
|
92
|
+
name: 'Fleet backup execution',
|
|
93
|
+
category: 'data',
|
|
94
|
+
status: 'fail',
|
|
95
|
+
message: `Backup failed (exit ${exitCode}): ${errorTail.slice(0, 200)}`,
|
|
96
|
+
timestamp: now(),
|
|
97
|
+
durationMs: Date.now() - backupStart,
|
|
98
|
+
});
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
const tierMatch = stdout.match(/Starting (\w+) backup/);
|
|
102
|
+
const tier = tierMatch?.[1] ?? 'unknown';
|
|
103
|
+
const sizeMatch = stdout.match(/([\d.]+)\s*MB/);
|
|
104
|
+
const sizeMb = sizeMatch?.[1] ?? '?';
|
|
105
|
+
results.push({
|
|
106
|
+
name: 'Fleet backup execution',
|
|
107
|
+
category: 'data',
|
|
108
|
+
status: 'pass',
|
|
109
|
+
message: `${tier} backup completed (${sizeMb} MB)`,
|
|
110
|
+
timestamp: now(),
|
|
111
|
+
durationMs: Date.now() - backupStart,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ── Step 2: Validate manifest ──────────────────────────────────
|
|
116
|
+
const manifestStart = Date.now();
|
|
117
|
+
try {
|
|
118
|
+
if (!fs.existsSync(manifestFile)) {
|
|
119
|
+
results.push({
|
|
120
|
+
name: 'Fleet backup manifest',
|
|
121
|
+
category: 'data',
|
|
122
|
+
status: 'warn',
|
|
123
|
+
message: `No manifest found after backup: ${manifestFile}`,
|
|
124
|
+
timestamp: now(),
|
|
125
|
+
durationMs: Date.now() - manifestStart,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const manifest = JSON.parse(fs.readFileSync(manifestFile, 'utf-8'));
|
|
130
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
131
|
+
if (manifest.date !== today) {
|
|
132
|
+
results.push({
|
|
133
|
+
name: 'Fleet backup manifest',
|
|
134
|
+
category: 'data',
|
|
135
|
+
status: 'warn',
|
|
136
|
+
message: `Manifest date ${manifest.date} doesn't match today ${today}`,
|
|
137
|
+
timestamp: now(),
|
|
138
|
+
durationMs: Date.now() - manifestStart,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
else if (!manifest.checksum) {
|
|
142
|
+
results.push({
|
|
143
|
+
name: 'Fleet backup manifest',
|
|
144
|
+
category: 'data',
|
|
145
|
+
status: 'warn',
|
|
146
|
+
message: 'Manifest missing checksum',
|
|
147
|
+
timestamp: now(),
|
|
148
|
+
durationMs: Date.now() - manifestStart,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
results.push({
|
|
153
|
+
name: 'Fleet backup manifest',
|
|
154
|
+
category: 'data',
|
|
155
|
+
status: 'pass',
|
|
156
|
+
message: `[${manifest.tier}] ${manifest.extensions} ext, ${manifest.agents} agents, ${manifest.memory_files ?? '?'} files, ${manifest.size_mb} MB`,
|
|
157
|
+
timestamp: now(),
|
|
158
|
+
durationMs: Date.now() - manifestStart,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
results.push({
|
|
165
|
+
name: 'Fleet backup manifest',
|
|
166
|
+
category: 'data',
|
|
167
|
+
status: 'warn',
|
|
168
|
+
message: `Manifest read error: ${err instanceof Error ? err.message : 'unknown'}`,
|
|
169
|
+
timestamp: now(),
|
|
170
|
+
durationMs: Date.now() - manifestStart,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// ── Step 3: Run test suites ────────────────────────────────────
|
|
174
|
+
if (!config?.skipTests) {
|
|
175
|
+
// test-backup.sh
|
|
176
|
+
const tbStart = Date.now();
|
|
177
|
+
if (!fs.existsSync(testBackup)) {
|
|
178
|
+
results.push({
|
|
179
|
+
name: 'Fleet backup test suite',
|
|
180
|
+
category: 'data',
|
|
181
|
+
status: 'warn',
|
|
182
|
+
message: `Test script not found: ${testBackup}`,
|
|
183
|
+
timestamp: now(),
|
|
184
|
+
durationMs: Date.now() - tbStart,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
const tbResult = await execAsync(`bash "${testBackup}"`, testTimeout, ctx);
|
|
189
|
+
const tbOutput = tbResult.stdout + '\n' + tbResult.stderr;
|
|
190
|
+
const parsed = parseTestResults(tbOutput);
|
|
191
|
+
if (tbResult.exitCode !== 0 || (parsed && parsed.failed > 0)) {
|
|
192
|
+
results.push({
|
|
193
|
+
name: 'Fleet backup test suite',
|
|
194
|
+
category: 'data',
|
|
195
|
+
status: 'fail',
|
|
196
|
+
message: parsed
|
|
197
|
+
? `${parsed.passed}/${parsed.total} passed, ${parsed.failed} FAILED`
|
|
198
|
+
: `Tests failed (exit ${tbResult.exitCode})`,
|
|
199
|
+
timestamp: now(),
|
|
200
|
+
durationMs: Date.now() - tbStart,
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
results.push({
|
|
205
|
+
name: 'Fleet backup test suite',
|
|
206
|
+
category: 'data',
|
|
207
|
+
status: 'pass',
|
|
208
|
+
message: parsed
|
|
209
|
+
? `${parsed.passed}/${parsed.total} passed`
|
|
210
|
+
: 'All tests passed',
|
|
211
|
+
timestamp: now(),
|
|
212
|
+
durationMs: Date.now() - tbStart,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// test-restore.sh
|
|
217
|
+
const trStart = Date.now();
|
|
218
|
+
if (!fs.existsSync(testRestore)) {
|
|
219
|
+
results.push({
|
|
220
|
+
name: 'Fleet restore test suite',
|
|
221
|
+
category: 'data',
|
|
222
|
+
status: 'warn',
|
|
223
|
+
message: `Test script not found: ${testRestore}`,
|
|
224
|
+
timestamp: now(),
|
|
225
|
+
durationMs: Date.now() - trStart,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
const trResult = await execAsync(`bash "${testRestore}"`, testTimeout, ctx);
|
|
230
|
+
const trOutput = trResult.stdout + '\n' + trResult.stderr;
|
|
231
|
+
const parsed = parseTestResults(trOutput);
|
|
232
|
+
if (trResult.exitCode !== 0 || (parsed && parsed.failed > 0)) {
|
|
233
|
+
results.push({
|
|
234
|
+
name: 'Fleet restore test suite',
|
|
235
|
+
category: 'data',
|
|
236
|
+
status: 'fail',
|
|
237
|
+
message: parsed
|
|
238
|
+
? `${parsed.passed}/${parsed.total} passed, ${parsed.failed} FAILED`
|
|
239
|
+
: `Tests failed (exit ${trResult.exitCode})`,
|
|
240
|
+
timestamp: now(),
|
|
241
|
+
durationMs: Date.now() - trStart,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
results.push({
|
|
246
|
+
name: 'Fleet restore test suite',
|
|
247
|
+
category: 'data',
|
|
248
|
+
status: 'pass',
|
|
249
|
+
message: parsed
|
|
250
|
+
? `${parsed.passed}/${parsed.total} passed`
|
|
251
|
+
: 'All tests passed',
|
|
252
|
+
timestamp: now(),
|
|
253
|
+
durationMs: Date.now() - trStart,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return results;
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=backup-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup-orchestrator.js","sourceRoot":"","sources":["../../src/checks/backup-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,6 +12,13 @@ export declare class CheckRunner {
|
|
|
12
12
|
constructor(config: MightyMarkConfig, topology: FleetTopology);
|
|
13
13
|
/** Run the full morning check — all checks across 8 categories. */
|
|
14
14
|
runAll(ctx?: CheckContext): Promise<MorningReport>;
|
|
15
|
+
/**
|
|
16
|
+
* Auto-detect whether the fleet backup system is installed.
|
|
17
|
+
* If /opt/fleet-backup/fleet-backup.sh exists, return orchestrator config
|
|
18
|
+
* that will run the backup + tests during the morning check.
|
|
19
|
+
* Otherwise return undefined (falls back to manifest-only freshness check).
|
|
20
|
+
*/
|
|
21
|
+
private detectBackupConfig;
|
|
15
22
|
/** Run checks for a single category. */
|
|
16
23
|
runCategory(category: CheckCategory, ctx?: CheckContext): Promise<CategoryResults>;
|
|
17
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-runner.d.ts","sourceRoot":"","sources":["../../src/checks/check-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"check-runner.d.ts","sourceRoot":"","sources":["../../src/checks/check-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAe,aAAa,EAAgB,aAAa,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAUvD,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGpE,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;gBAE7B,MAAM,EAAE,gBAAgB,EAAE,QAAQ,EAAE,aAAa;IAK7D,mEAAmE;IAC7D,MAAM,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IAuDxD;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAY1B,wCAAwC;IAClC,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;CAyCzF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* CheckRunner — orchestrates all health checks across 5 categories.
|
|
3
3
|
* Runs checks in parallel within each category, sequential across categories.
|
|
4
4
|
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
5
6
|
import os from 'node:os';
|
|
6
7
|
import { runGatewayChecks } from './gateway-health.js';
|
|
7
8
|
import { runAgentChecks } from './agent-verify.js';
|
|
@@ -33,7 +34,9 @@ export class CheckRunner {
|
|
|
33
34
|
allChecks.push(...system);
|
|
34
35
|
const api = await runApiChecks(this.config.telegramToken, ctx);
|
|
35
36
|
allChecks.push(...api);
|
|
36
|
-
|
|
37
|
+
// Auto-detect fleet backup system and enable full orchestration if installed
|
|
38
|
+
const backupConfig = this.detectBackupConfig();
|
|
39
|
+
const data = await runDataChecks(this.config.dataDir, this.config.telegramToken, this.topology, ctx, backupConfig);
|
|
37
40
|
allChecks.push(...data);
|
|
38
41
|
const memory = await runMemoryChecks(this.topology, ctx);
|
|
39
42
|
allChecks.push(...memory);
|
|
@@ -63,6 +66,23 @@ export class CheckRunner {
|
|
|
63
66
|
durationMs: Date.now() - suiteStart,
|
|
64
67
|
};
|
|
65
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Auto-detect whether the fleet backup system is installed.
|
|
71
|
+
* If /opt/fleet-backup/fleet-backup.sh exists, return orchestrator config
|
|
72
|
+
* that will run the backup + tests during the morning check.
|
|
73
|
+
* Otherwise return undefined (falls back to manifest-only freshness check).
|
|
74
|
+
*/
|
|
75
|
+
detectBackupConfig() {
|
|
76
|
+
const backupScript = '/opt/fleet-backup/fleet-backup.sh';
|
|
77
|
+
if (fs.existsSync(backupScript)) {
|
|
78
|
+
return {
|
|
79
|
+
fleetBackupDir: '/opt/fleet-backup',
|
|
80
|
+
skipBackup: false,
|
|
81
|
+
skipTests: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
66
86
|
/** Run checks for a single category. */
|
|
67
87
|
async runCategory(category, ctx) {
|
|
68
88
|
const start = Date.now();
|
|
@@ -81,7 +101,7 @@ export class CheckRunner {
|
|
|
81
101
|
checks = await runApiChecks(this.config.telegramToken, ctx);
|
|
82
102
|
break;
|
|
83
103
|
case 'data':
|
|
84
|
-
checks = await runDataChecks(this.config.dataDir, this.config.telegramToken, this.topology, ctx);
|
|
104
|
+
checks = await runDataChecks(this.config.dataDir, this.config.telegramToken, this.topology, ctx, this.detectBackupConfig());
|
|
85
105
|
break;
|
|
86
106
|
case 'memory':
|
|
87
107
|
checks = await runMemoryChecks(this.topology, ctx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-runner.js","sourceRoot":"","sources":["../../src/checks/check-runner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AAIzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAqB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"check-runner.js","sourceRoot":"","sources":["../../src/checks/check-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { CheckResult } from '../types/health.js';
|
|
5
5
|
import type { FleetTopology } from '../types/fleet.js';
|
|
6
6
|
import { type CheckContext } from './check-context.js';
|
|
7
|
+
import { type BackupOrchestratorConfig } from './backup-orchestrator.js';
|
|
7
8
|
/** Check #23: Grillo audit chain — recent assessment files are valid JSON. */
|
|
8
9
|
export declare function checkGrilloChain(topology?: FleetTopology, ctx?: CheckContext): Promise<CheckResult>;
|
|
9
10
|
/** Check #24: Noah temporal store accessible and valid. */
|
|
@@ -21,5 +22,5 @@ export declare function checkDocsBackupFreshness(ctx?: CheckContext): Promise<Ch
|
|
|
21
22
|
*/
|
|
22
23
|
export declare function checkFleetBackupFreshness(ctx?: CheckContext): Promise<CheckResult>;
|
|
23
24
|
/** Run all data integrity checks. */
|
|
24
|
-
export declare function runDataChecks(dataDir: string, telegramToken?: string, topology?: FleetTopology, ctx?: CheckContext): Promise<CheckResult[]>;
|
|
25
|
+
export declare function runDataChecks(dataDir: string, telegramToken?: string, topology?: FleetTopology, ctx?: CheckContext, backupConfig?: BackupOrchestratorConfig): Promise<CheckResult[]>;
|
|
25
26
|
//# sourceMappingURL=data-integrity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-integrity.d.ts","sourceRoot":"","sources":["../../src/checks/data-integrity.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAoD,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"data-integrity.d.ts","sourceRoot":"","sources":["../../src/checks/data-integrity.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAoD,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACzG,OAAO,EAA0B,KAAK,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAwCjG,8EAA8E;AAC9E,wBAAsB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiCzG;AAED,2DAA2D;AAC3D,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBvG;AAED,yCAAyC;AACzC,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBvG;AAED,wEAAwE;AACxE,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,GAAG,CAAC,EAAE,YAAY,GACjB,OAAO,CAAC,WAAW,EAAE,CAAC,CAqCxB;AAED,yGAAyG;AACzG,wBAAsB,wBAAwB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAgFvF;AAKD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAwFxF;AAED,qCAAqC;AACrC,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,aAAa,EACxB,GAAG,CAAC,EAAE,YAAY,EAClB,YAAY,CAAC,EAAE,wBAAwB,GACtC,OAAO,CAAC,WAAW,EAAE,CAAC,CAiBxB"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import fs from 'node:fs';
|
|
5
5
|
import path from 'node:path';
|
|
6
6
|
import { fetchUrl, getWorkspace, now, resolveOpenClawHome } from './check-context.js';
|
|
7
|
+
import { runBackupOrchestration } from './backup-orchestrator.js';
|
|
7
8
|
/**
|
|
8
9
|
* Find a data directory by checking multiple possible locations.
|
|
9
10
|
* @param name Agent name (e.g. 'grillo')
|
|
@@ -297,14 +298,21 @@ export async function checkFleetBackupFreshness(ctx) {
|
|
|
297
298
|
}
|
|
298
299
|
}
|
|
299
300
|
/** Run all data integrity checks. */
|
|
300
|
-
export async function runDataChecks(dataDir, telegramToken, topology, ctx) {
|
|
301
|
+
export async function runDataChecks(dataDir, telegramToken, topology, ctx, backupConfig) {
|
|
301
302
|
const results = [];
|
|
302
303
|
results.push(await checkGrilloChain(topology, ctx));
|
|
303
304
|
results.push(await checkNoahStore(topology, ctx));
|
|
304
305
|
results.push(await checkNoleState(topology, ctx));
|
|
305
306
|
results.push(...await checkMarkSelf(dataDir, telegramToken, ctx));
|
|
306
307
|
results.push(await checkDocsBackupFreshness(ctx));
|
|
307
|
-
|
|
308
|
+
// Run full backup orchestration (backup + validate + tests) when available,
|
|
309
|
+
// otherwise fall back to manifest-only freshness check
|
|
310
|
+
if (backupConfig) {
|
|
311
|
+
results.push(...await runBackupOrchestration(backupConfig, ctx));
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
results.push(await checkFleetBackupFreshness(ctx));
|
|
315
|
+
}
|
|
308
316
|
return results;
|
|
309
317
|
}
|
|
310
318
|
/** Recursively find JSON files in a directory. */
|