@aiassesstech/mighty-mark 0.4.9 → 0.5.0

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.
@@ -14,6 +14,10 @@ export declare function checkDmScope(ctx?: CheckContext): Promise<CheckResult>;
14
14
  export declare function checkExecSecurity(ctx?: CheckContext): Promise<CheckResult>;
15
15
  export declare function checkMemoryFlush(ctx?: CheckContext): Promise<CheckResult>;
16
16
  export declare function checkSpawnPrevention(ctx?: CheckContext): Promise<CheckResult>;
17
- /** Run all platform hardening security checks. */
17
+ export declare function checkModelDefaults(ctx?: CheckContext): Promise<CheckResult>;
18
+ export declare function checkSecretPermissions(ctx?: CheckContext): Promise<CheckResult>;
19
+ export declare function checkTelegramAllowlist(ctx?: CheckContext): Promise<CheckResult>;
20
+ export declare function checkWorkspacePersonalization(ctx?: CheckContext): Promise<CheckResult>;
21
+ /** Run all platform hardening + post-install security checks. */
18
22
  export declare function runSecurityChecks(ctx?: CheckContext): Promise<CheckResult[]>;
19
23
  //# sourceMappingURL=security-hardening.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security-hardening.d.ts","sourceRoot":"","sources":["../../src/checks/security-hardening.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA+B3E,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiD3E;AAED,wBAAsB,iBAAiB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiDhF;AAED,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA+C/E;AAED,wBAAsB,oBAAoB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA0DnF;AAED,kDAAkD;AAClD,wBAAsB,iBAAiB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAOlF"}
1
+ {"version":3,"file":"security-hardening.d.ts","sourceRoot":"","sources":["../../src/checks/security-hardening.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAuChG,wBAAsB,YAAY,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiD3E;AAED,wBAAsB,iBAAiB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAiDhF;AAED,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA+C/E;AAED,wBAAsB,oBAAoB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsDnF;AAeD,wBAAsB,kBAAkB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAwEjF;AAED,wBAAsB,sBAAsB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAqErF;AAED,wBAAsB,sBAAsB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAuErF;AAED,wBAAsB,6BAA6B,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAsF5F;AAED,iEAAiE;AACjE,wBAAsB,iBAAiB,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAWlF"}
@@ -9,7 +9,8 @@
9
9
  * - agents.defaults.compaction.memoryFlush.enabled = true
10
10
  */
11
11
  import fs from 'node:fs';
12
- import { getConfigPath, now } from './check-context.js';
12
+ import path from 'node:path';
13
+ import { getConfigPath, now, resolveOpenClawHome } from './check-context.js';
13
14
  const CATEGORY = 'security';
14
15
  function loadConfig(ctx) {
15
16
  const configPath = getConfigPath(ctx);
@@ -179,42 +180,333 @@ export async function checkSpawnPrevention(ctx) {
179
180
  durationMs: Date.now() - start,
180
181
  };
181
182
  }
183
+ const depth = subagents.maxSpawnDepth;
184
+ const children = subagents.maxChildrenPerAgent;
185
+ if (depth === 1 && children === 1) {
186
+ return {
187
+ name: 'Spawn prevention',
188
+ category: CATEGORY,
189
+ status: 'pass',
190
+ message: 'maxSpawnDepth=1, maxChildrenPerAgent=1 (OpenClaw minimum)',
191
+ timestamp: now(),
192
+ durationMs: Date.now() - start,
193
+ };
194
+ }
182
195
  const issues = [];
183
- if (!Array.isArray(subagents.allowAgents) || subagents.allowAgents.length > 0) {
184
- issues.push(`allowAgents=${JSON.stringify(subagents.allowAgents)}`);
196
+ if (depth !== 1)
197
+ issues.push(`maxSpawnDepth=${depth ?? 'not set'}`);
198
+ if (children !== 1)
199
+ issues.push(`maxChildrenPerAgent=${children ?? 'not set'}`);
200
+ return {
201
+ name: 'Spawn prevention',
202
+ category: CATEGORY,
203
+ status: (depth ?? Infinity) > 1 || (children ?? Infinity) > 1 ? 'fail' : 'warn',
204
+ message: `Not fully locked: ${issues.join(', ')} (expected 1/1)`,
205
+ timestamp: now(),
206
+ durationMs: Date.now() - start,
207
+ };
208
+ }
209
+ // ================================================================
210
+ // Post-Install Hardening Checks (Check H)
211
+ //
212
+ // Per SPEC-OPENCLAW-POST-INSTALL-HARDENING-CHECKLIST v1.1:
213
+ // - Model defaults configured with fallbacks
214
+ // - Secrets file exists with correct permissions
215
+ // - Telegram DM policy set to allowlist
216
+ // - Workspace personalization files exist and are customized
217
+ // ================================================================
218
+ const EXPECTED_AGENTS = ['grillo', 'jessie', 'noah', 'nole', 'mighty-mark', 'sam'];
219
+ const MIN_PERSONALIZATION_BYTES = 100;
220
+ export async function checkModelDefaults(ctx) {
221
+ const start = Date.now();
222
+ const config = loadConfig(ctx);
223
+ if (!config) {
224
+ return {
225
+ name: 'Model defaults',
226
+ category: CATEGORY,
227
+ status: 'warn',
228
+ message: 'openclaw.json not found or unreadable',
229
+ timestamp: now(),
230
+ durationMs: Date.now() - start,
231
+ };
185
232
  }
186
- if (subagents.maxSpawnDepth !== 0) {
187
- issues.push(`maxSpawnDepth=${subagents.maxSpawnDepth}`);
233
+ const model = config.agents?.defaults?.model;
234
+ if (!model) {
235
+ return {
236
+ name: 'Model defaults',
237
+ category: CATEGORY,
238
+ status: 'warn',
239
+ message: 'no model config — using OpenClaw defaults (single point of failure)',
240
+ timestamp: now(),
241
+ durationMs: Date.now() - start,
242
+ };
188
243
  }
189
- if (subagents.maxChildrenPerAgent !== 0) {
190
- issues.push(`maxChildrenPerAgent=${subagents.maxChildrenPerAgent}`);
244
+ if (typeof model === 'string') {
245
+ return {
246
+ name: 'Model defaults',
247
+ category: CATEGORY,
248
+ status: 'warn',
249
+ message: `primary=${model}, no fallbacks configured`,
250
+ timestamp: now(),
251
+ durationMs: Date.now() - start,
252
+ };
191
253
  }
192
- if (issues.length > 0) {
254
+ const primary = model.primary;
255
+ const fallbacks = model.fallbacks ?? [];
256
+ if (!primary) {
193
257
  return {
194
- name: 'Spawn prevention',
258
+ name: 'Model defaults',
259
+ category: CATEGORY,
260
+ status: 'warn',
261
+ message: 'no primary model set',
262
+ timestamp: now(),
263
+ durationMs: Date.now() - start,
264
+ };
265
+ }
266
+ if (fallbacks.length === 0) {
267
+ return {
268
+ name: 'Model defaults',
269
+ category: CATEGORY,
270
+ status: 'warn',
271
+ message: `primary=${primary}, no fallbacks (single point of failure)`,
272
+ timestamp: now(),
273
+ durationMs: Date.now() - start,
274
+ };
275
+ }
276
+ return {
277
+ name: 'Model defaults',
278
+ category: CATEGORY,
279
+ status: 'pass',
280
+ message: `primary=${primary}, ${fallbacks.length} fallback(s)`,
281
+ timestamp: now(),
282
+ durationMs: Date.now() - start,
283
+ };
284
+ }
285
+ export async function checkSecretPermissions(ctx) {
286
+ const start = Date.now();
287
+ const openClawHome = ctx?.configPath
288
+ ? path.dirname(ctx.configPath)
289
+ : resolveOpenClawHome();
290
+ const secretsDir = path.join(openClawHome, 'secrets');
291
+ const secretsFile = path.join(secretsDir, 'openclaw.env');
292
+ if (!fs.existsSync(secretsDir)) {
293
+ return {
294
+ name: 'Secret file permissions',
295
+ category: CATEGORY,
296
+ status: 'fail',
297
+ message: `secrets directory not found at ${secretsDir}`,
298
+ timestamp: now(),
299
+ durationMs: Date.now() - start,
300
+ };
301
+ }
302
+ if (!fs.existsSync(secretsFile)) {
303
+ return {
304
+ name: 'Secret file permissions',
305
+ category: CATEGORY,
306
+ status: 'fail',
307
+ message: 'secrets directory exists but openclaw.env not found',
308
+ timestamp: now(),
309
+ durationMs: Date.now() - start,
310
+ };
311
+ }
312
+ try {
313
+ const dirStat = fs.statSync(secretsDir);
314
+ const fileStat = fs.statSync(secretsFile);
315
+ const dirMode = (dirStat.mode & 0o777).toString(8);
316
+ const fileMode = (fileStat.mode & 0o777).toString(8);
317
+ const issues = [];
318
+ if (dirMode !== '700')
319
+ issues.push(`dir=${dirMode} (expected 700)`);
320
+ if (fileMode !== '600')
321
+ issues.push(`file=${fileMode} (expected 600)`);
322
+ if (issues.length > 0) {
323
+ return {
324
+ name: 'Secret file permissions',
325
+ category: CATEGORY,
326
+ status: 'warn',
327
+ message: `permissions not strict: ${issues.join(', ')}`,
328
+ timestamp: now(),
329
+ durationMs: Date.now() - start,
330
+ };
331
+ }
332
+ return {
333
+ name: 'Secret file permissions',
334
+ category: CATEGORY,
335
+ status: 'pass',
336
+ message: 'secrets dir=700, file=600',
337
+ timestamp: now(),
338
+ durationMs: Date.now() - start,
339
+ };
340
+ }
341
+ catch {
342
+ return {
343
+ name: 'Secret file permissions',
344
+ category: CATEGORY,
345
+ status: 'warn',
346
+ message: 'could not stat secrets files',
347
+ timestamp: now(),
348
+ durationMs: Date.now() - start,
349
+ };
350
+ }
351
+ }
352
+ export async function checkTelegramAllowlist(ctx) {
353
+ const start = Date.now();
354
+ const config = loadConfig(ctx);
355
+ if (!config) {
356
+ return {
357
+ name: 'Telegram DM policy',
358
+ category: CATEGORY,
359
+ status: 'warn',
360
+ message: 'openclaw.json not found or unreadable',
361
+ timestamp: now(),
362
+ durationMs: Date.now() - start,
363
+ };
364
+ }
365
+ const telegram = config.telegram;
366
+ if (!telegram) {
367
+ return {
368
+ name: 'Telegram DM policy',
369
+ category: CATEGORY,
370
+ status: 'warn',
371
+ message: 'no telegram config — skipped (may not use Telegram)',
372
+ timestamp: now(),
373
+ durationMs: Date.now() - start,
374
+ };
375
+ }
376
+ const policy = telegram.dmPolicy;
377
+ if (policy === 'allowlist') {
378
+ const allowCount = telegram.allowFrom?.length ?? 0;
379
+ if (allowCount === 0) {
380
+ return {
381
+ name: 'Telegram DM policy',
382
+ category: CATEGORY,
383
+ status: 'warn',
384
+ message: 'allowlist enabled but allowFrom is empty — nobody can DM',
385
+ timestamp: now(),
386
+ durationMs: Date.now() - start,
387
+ };
388
+ }
389
+ return {
390
+ name: 'Telegram DM policy',
391
+ category: CATEGORY,
392
+ status: 'pass',
393
+ message: `allowlist, ${allowCount} allowed ID(s)`,
394
+ timestamp: now(),
395
+ durationMs: Date.now() - start,
396
+ };
397
+ }
398
+ if (policy === 'open' || !policy) {
399
+ return {
400
+ name: 'Telegram DM policy',
195
401
  category: CATEGORY,
196
402
  status: 'fail',
197
- message: `Not fully locked: ${issues.join(', ')}`,
403
+ message: `${policy ?? 'NOT SET'} — anyone can message and consume API credits`,
198
404
  timestamp: now(),
199
405
  durationMs: Date.now() - start,
200
406
  };
201
407
  }
202
408
  return {
203
- name: 'Spawn prevention',
409
+ name: 'Telegram DM policy',
410
+ category: CATEGORY,
411
+ status: 'warn',
412
+ message: `${policy} — verify manually`,
413
+ timestamp: now(),
414
+ durationMs: Date.now() - start,
415
+ };
416
+ }
417
+ export async function checkWorkspacePersonalization(ctx) {
418
+ const start = Date.now();
419
+ const openClawHome = ctx?.configPath
420
+ ? path.dirname(ctx.configPath)
421
+ : resolveOpenClawHome();
422
+ const extensionsDir = path.join(openClawHome, 'extensions');
423
+ if (!fs.existsSync(extensionsDir)) {
424
+ return {
425
+ name: 'Workspace personalization',
426
+ category: CATEGORY,
427
+ status: 'warn',
428
+ message: 'extensions directory not found — cannot check agent files',
429
+ timestamp: now(),
430
+ durationMs: Date.now() - start,
431
+ };
432
+ }
433
+ const requiredFiles = ['SOUL.md', 'IDENTITY.md'];
434
+ const agentsMissing = [];
435
+ const agentsSmall = [];
436
+ let agentsChecked = 0;
437
+ for (const agent of EXPECTED_AGENTS) {
438
+ const agentDir = path.join(extensionsDir, agent, 'agent');
439
+ if (!fs.existsSync(agentDir))
440
+ continue;
441
+ agentsChecked++;
442
+ for (const file of requiredFiles) {
443
+ const filePath = path.join(agentDir, file);
444
+ if (!fs.existsSync(filePath)) {
445
+ agentsMissing.push(`${agent}/${file}`);
446
+ }
447
+ else {
448
+ try {
449
+ const stat = fs.statSync(filePath);
450
+ if (stat.size < MIN_PERSONALIZATION_BYTES) {
451
+ agentsSmall.push(`${agent}/${file}(${stat.size}B)`);
452
+ }
453
+ }
454
+ catch {
455
+ agentsMissing.push(`${agent}/${file}`);
456
+ }
457
+ }
458
+ }
459
+ }
460
+ if (agentsChecked === 0) {
461
+ return {
462
+ name: 'Workspace personalization',
463
+ category: CATEGORY,
464
+ status: 'warn',
465
+ message: 'no agent directories found in extensions/',
466
+ timestamp: now(),
467
+ durationMs: Date.now() - start,
468
+ };
469
+ }
470
+ if (agentsMissing.length > 0) {
471
+ return {
472
+ name: 'Workspace personalization',
473
+ category: CATEGORY,
474
+ status: 'fail',
475
+ message: `${agentsChecked} agents checked; missing: ${agentsMissing.join(', ')}`,
476
+ timestamp: now(),
477
+ durationMs: Date.now() - start,
478
+ };
479
+ }
480
+ if (agentsSmall.length > 0) {
481
+ return {
482
+ name: 'Workspace personalization',
483
+ category: CATEGORY,
484
+ status: 'warn',
485
+ message: `${agentsChecked} agents checked; likely uncustomized: ${agentsSmall.join(', ')}`,
486
+ timestamp: now(),
487
+ durationMs: Date.now() - start,
488
+ };
489
+ }
490
+ return {
491
+ name: 'Workspace personalization',
204
492
  category: CATEGORY,
205
493
  status: 'pass',
206
- message: 'allowAgents=[], maxSpawnDepth=0, maxChildrenPerAgent=0',
494
+ message: `${agentsChecked} agents checked, all personalization files present and customized`,
207
495
  timestamp: now(),
208
496
  durationMs: Date.now() - start,
209
497
  };
210
498
  }
211
- /** Run all platform hardening security checks. */
499
+ /** Run all platform hardening + post-install security checks. */
212
500
  export async function runSecurityChecks(ctx) {
213
501
  return [
214
502
  await checkDmScope(ctx),
215
503
  await checkExecSecurity(ctx),
216
504
  await checkMemoryFlush(ctx),
217
505
  await checkSpawnPrevention(ctx),
506
+ await checkModelDefaults(ctx),
507
+ await checkSecretPermissions(ctx),
508
+ await checkTelegramAllowlist(ctx),
509
+ await checkWorkspacePersonalization(ctx),
218
510
  ];
219
511
  }
220
512
  //# sourceMappingURL=security-hardening.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"security-hardening.js","sourceRoot":"","sources":["../../src/checks/security-hardening.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"security-hardening.js","sourceRoot":"","sources":["../../src/checks/security-hardening.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiassesstech/mighty-mark",
3
- "version": "0.4.9",
3
+ "version": "0.5.0",
4
4
  "description": "System Health Sentinel for AI Assess Tech Fleet — autonomous monitoring, watchdog recovery, and fleet infrastructure oversight.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,292 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # OpenClaw Post-Install Hardening — Apply Script
4
+ # Author: Archie
5
+ # Date: 2026-03-07
6
+ # Spec: SPEC-OPENCLAW-POST-INSTALL-HARDENING-CHECKLIST v1.1 (BB Approved)
7
+ #
8
+ # Applies post-install hardening to a running OpenClaw VPS:
9
+ # 1. Creates secrets directory with proper permissions
10
+ # 2. Deploys MEMORY.md + HEARTBEAT.md to all agents
11
+ # 3. Patches openclaw.json with hardening config
12
+ # 4. Verifies the result with verify-post-install-hardening.sh
13
+ #
14
+ # Ships with @aiassesstech/mighty-mark npm package (src/scripts/).
15
+ # After deployment via deploy-fleet.sh, run on VPS:
16
+ # bash ~/.openclaw/extensions/mighty-mark/node_modules/@aiassesstech/mighty-mark/src/scripts/apply-post-install-hardening.sh
17
+ #
18
+ # Or dry-run first:
19
+ # bash <same-path>/apply-post-install-hardening.sh --dry-run
20
+ #
21
+ # Exit codes:
22
+ # 0 = all changes applied successfully
23
+ # 1 = error occurred
24
+ # ============================================================================
25
+
26
+ set -euo pipefail
27
+
28
+ DRY_RUN=false
29
+ SKIP_RESTART=false
30
+
31
+ while [[ $# -gt 0 ]]; do
32
+ case $1 in
33
+ --dry-run) DRY_RUN=true; shift ;;
34
+ --skip-restart) SKIP_RESTART=true; shift ;;
35
+ -h|--help)
36
+ echo "Usage: $0 [--dry-run] [--skip-restart]"
37
+ echo " --dry-run Preview changes without applying"
38
+ echo " --skip-restart Apply config but don't restart gateway"
39
+ exit 0
40
+ ;;
41
+ *) echo "Unknown option: $1"; exit 1 ;;
42
+ esac
43
+ done
44
+
45
+ OPENCLAW_HOME="${OPENCLAW_STATE_DIR:-${OPENCLAW_HOME:-$HOME}/.openclaw}"
46
+ CONFIG_FILE="$OPENCLAW_HOME/openclaw.json"
47
+ EXTENSIONS_DIR="$OPENCLAW_HOME/extensions"
48
+ EXPECTED_AGENTS="grillo jessie noah nole mighty-mark sam"
49
+ TIMESTAMP=$(date +%Y%m%d_%H%M%S)
50
+
51
+ echo ""
52
+ echo "═══════════════════════════════════════════════════════"
53
+ echo " Post-Install Hardening — Apply"
54
+ echo " OPENCLAW_HOME: $OPENCLAW_HOME"
55
+ echo " Dry run: $DRY_RUN"
56
+ echo "═══════════════════════════════════════════════════════"
57
+ echo ""
58
+
59
+ # ── Step 1: Secrets directory ───────────────────────────────
60
+ echo "── Step 1: Secrets directory ──"
61
+
62
+ SECRETS_DIR="$OPENCLAW_HOME/secrets"
63
+ SECRETS_FILE="$SECRETS_DIR/openclaw.env"
64
+
65
+ if [ ! -d "$SECRETS_DIR" ]; then
66
+ if $DRY_RUN; then
67
+ echo " [DRY RUN] Would create $SECRETS_DIR with mode 700"
68
+ else
69
+ mkdir -p "$SECRETS_DIR"
70
+ chmod 700 "$SECRETS_DIR"
71
+ echo " Created $SECRETS_DIR (mode 700)"
72
+ fi
73
+ else
74
+ CURRENT_MODE=$(stat -c '%a' "$SECRETS_DIR" 2>/dev/null || stat -f '%Lp' "$SECRETS_DIR" 2>/dev/null)
75
+ if [ "$CURRENT_MODE" != "700" ]; then
76
+ if $DRY_RUN; then
77
+ echo " [DRY RUN] Would chmod 700 $SECRETS_DIR (currently $CURRENT_MODE)"
78
+ else
79
+ chmod 700 "$SECRETS_DIR"
80
+ echo " Fixed permissions on $SECRETS_DIR: $CURRENT_MODE -> 700"
81
+ fi
82
+ else
83
+ echo " $SECRETS_DIR already exists with correct permissions (700)"
84
+ fi
85
+ fi
86
+
87
+ if [ -f "$SECRETS_FILE" ]; then
88
+ CURRENT_MODE=$(stat -c '%a' "$SECRETS_FILE" 2>/dev/null || stat -f '%Lp' "$SECRETS_FILE" 2>/dev/null)
89
+ if [ "$CURRENT_MODE" != "600" ]; then
90
+ if $DRY_RUN; then
91
+ echo " [DRY RUN] Would chmod 600 $SECRETS_FILE (currently $CURRENT_MODE)"
92
+ else
93
+ chmod 600 "$SECRETS_FILE"
94
+ echo " Fixed permissions on $SECRETS_FILE: $CURRENT_MODE -> 600"
95
+ fi
96
+ else
97
+ echo " $SECRETS_FILE exists with correct permissions (600)"
98
+ fi
99
+ else
100
+ echo " ⚠️ $SECRETS_FILE does not exist — create it manually with your API keys"
101
+ fi
102
+
103
+ # ── Step 2: Deploy workspace files to agents ────────────────
104
+ echo ""
105
+ echo "── Step 2: Agent workspace files ──"
106
+
107
+ for AGENT in $EXPECTED_AGENTS; do
108
+ AGENT_WS=""
109
+ if command -v openclaw &>/dev/null; then
110
+ AGENT_WS=$(openclaw agent workspace "$AGENT" 2>/dev/null || echo "")
111
+ fi
112
+ [ -z "$AGENT_WS" ] && AGENT_WS="$OPENCLAW_HOME/agents/$AGENT"
113
+
114
+ AGENT_EXT="$EXTENSIONS_DIR/$AGENT/agent"
115
+
116
+ if [ ! -d "$AGENT_EXT" ]; then
117
+ echo " ⚠️ $AGENT: no extension dir at $AGENT_EXT — skip"
118
+ continue
119
+ fi
120
+
121
+ # MEMORY.md — long-term memory
122
+ if [ ! -f "$AGENT_WS/MEMORY.md" ] && [ ! -f "$AGENT_EXT/MEMORY.md" ]; then
123
+ TARGET_DIR="$AGENT_WS"
124
+ [ ! -d "$TARGET_DIR" ] && TARGET_DIR="$AGENT_EXT"
125
+ if $DRY_RUN; then
126
+ echo " [DRY RUN] Would create $TARGET_DIR/MEMORY.md"
127
+ else
128
+ mkdir -p "$TARGET_DIR"
129
+ cat > "$TARGET_DIR/MEMORY.md" << 'MEMEOF'
130
+ # Long-Term Memory
131
+
132
+ Important learnings, decisions, and context that should persist across sessions.
133
+
134
+ ## Key Decisions
135
+
136
+
137
+ ## Lessons Learned
138
+
139
+
140
+ ## Important Context
141
+
142
+ MEMEOF
143
+ echo " $AGENT: created MEMORY.md"
144
+ fi
145
+ else
146
+ echo " $AGENT: MEMORY.md already exists"
147
+ fi
148
+
149
+ # HEARTBEAT.md — periodic check instructions
150
+ if [ ! -f "$AGENT_WS/HEARTBEAT.md" ] && [ ! -f "$AGENT_EXT/HEARTBEAT.md" ]; then
151
+ TARGET_DIR="$AGENT_WS"
152
+ [ ! -d "$TARGET_DIR" ] && TARGET_DIR="$AGENT_EXT"
153
+ if $DRY_RUN; then
154
+ echo " [DRY RUN] Would create $TARGET_DIR/HEARTBEAT.md"
155
+ else
156
+ mkdir -p "$TARGET_DIR"
157
+ cat > "$TARGET_DIR/HEARTBEAT.md" << 'HBEOF'
158
+ ## Cron Health Check (Every Heartbeat)
159
+
160
+ 1. Run `openclaw cron list --show-last-run` (or use /cron) to check all configured cron jobs
161
+ 2. If any job's `lastRunAtMs` is older than 2x its expected interval, it is stale
162
+ 3. If stale, force-run the missed jobs
163
+ 4. Report any exceptions briefly in today's memory file
164
+ HBEOF
165
+ echo " $AGENT: created HEARTBEAT.md"
166
+ fi
167
+ else
168
+ echo " $AGENT: HEARTBEAT.md already exists"
169
+ fi
170
+ done
171
+
172
+ # ── Step 3: Patch openclaw.json with hardening config ───────
173
+ echo ""
174
+ echo "── Step 3: Config hardening ──"
175
+
176
+ if [ ! -f "$CONFIG_FILE" ]; then
177
+ echo " ❌ $CONFIG_FILE not found — cannot patch"
178
+ echo " Run 'openclaw gateway run' first to generate the config"
179
+ exit 1
180
+ fi
181
+
182
+ if $DRY_RUN; then
183
+ echo " [DRY RUN] Would patch $CONFIG_FILE with:"
184
+ echo " - agents.defaults.model.fallbacks"
185
+ echo " - agents.defaults.subagents (1/1 lockdown)"
186
+ echo " - telegram.dmPolicy = allowlist"
187
+ else
188
+ # Backup before modifying (Rule 003: Do No Harm)
189
+ cp "$CONFIG_FILE" "$CONFIG_FILE.bak.$TIMESTAMP"
190
+ echo " Backup: $CONFIG_FILE.bak.$TIMESTAMP"
191
+
192
+ python3 -c "
193
+ import json, sys
194
+
195
+ with open('$CONFIG_FILE') as f:
196
+ cfg = json.load(f)
197
+
198
+ changed = False
199
+
200
+ # Model fallbacks
201
+ defaults = cfg.setdefault('agents', {}).setdefault('defaults', {})
202
+ model = defaults.get('model')
203
+ if not model or isinstance(model, str):
204
+ print(' ⚠️ model config is a string or missing — not overwriting')
205
+ print(' Set model defaults manually: openclaw config set agents.defaults.model ...')
206
+ elif isinstance(model, dict) and not model.get('fallbacks'):
207
+ print(' ⚠️ model.primary is set but no fallbacks — add fallbacks manually')
208
+ else:
209
+ print(' ✅ model defaults already have fallbacks')
210
+
211
+ # Subagents lockdown
212
+ subagents = defaults.get('subagents')
213
+ if not subagents:
214
+ defaults['subagents'] = {'maxSpawnDepth': 1, 'maxChildrenPerAgent': 1}
215
+ changed = True
216
+ print(' Applied: subagents lockdown (1/1)')
217
+ elif subagents.get('maxSpawnDepth') != 1 or subagents.get('maxChildrenPerAgent') != 1:
218
+ defaults['subagents'] = {'maxSpawnDepth': 1, 'maxChildrenPerAgent': 1}
219
+ changed = True
220
+ print(' Applied: subagents lockdown (1/1) — was depth=%s, children=%s' % (
221
+ subagents.get('maxSpawnDepth', '?'), subagents.get('maxChildrenPerAgent', '?')))
222
+ else:
223
+ print(' ✅ subagents already locked down (1/1)')
224
+
225
+ # Telegram DM policy
226
+ telegram = cfg.get('telegram', {})
227
+ if not telegram or telegram.get('dmPolicy') != 'allowlist':
228
+ if not telegram.get('allowFrom'):
229
+ print(' ⚠️ telegram.dmPolicy set to allowlist, but allowFrom is empty')
230
+ print(' Add your Telegram user ID: openclaw config set telegram.allowFrom ...')
231
+ cfg.setdefault('telegram', {})['dmPolicy'] = 'allowlist'
232
+ changed = True
233
+ print(' Applied: telegram.dmPolicy = allowlist')
234
+ else:
235
+ print(' ✅ telegram.dmPolicy already set to allowlist')
236
+
237
+ if changed:
238
+ with open('$CONFIG_FILE', 'w') as f:
239
+ json.dump(cfg, f, indent=2)
240
+ print(' Config saved to $CONFIG_FILE')
241
+ else:
242
+ print(' No config changes needed')
243
+ "
244
+
245
+ # Validate config before restart (Rule 807)
246
+ if command -v openclaw &>/dev/null; then
247
+ echo ""
248
+ echo " Validating config..."
249
+ if openclaw doctor 2>&1 | head -5; then
250
+ echo " ✅ Config validation passed"
251
+ else
252
+ echo " ❌ Config validation failed — restoring backup"
253
+ cp "$CONFIG_FILE.bak.$TIMESTAMP" "$CONFIG_FILE"
254
+ echo " Restored from $CONFIG_FILE.bak.$TIMESTAMP"
255
+ exit 1
256
+ fi
257
+ fi
258
+ fi
259
+
260
+ # ── Step 4: Restart gateway (optional) ──────────────────────
261
+ if ! $DRY_RUN && ! $SKIP_RESTART; then
262
+ echo ""
263
+ echo "── Step 4: Gateway restart ──"
264
+ if command -v systemctl &>/dev/null && systemctl is-active openclaw-gateway &>/dev/null; then
265
+ systemctl restart openclaw-gateway
266
+ sleep 5
267
+ echo " ✅ Gateway restarted via systemctl"
268
+ journalctl -u openclaw-gateway --no-pager -n 10 2>/dev/null || true
269
+ else
270
+ echo " ⚠️ systemctl not available or gateway not managed by systemd"
271
+ echo " Restart manually: openclaw gateway restart"
272
+ fi
273
+ fi
274
+
275
+ # ── Summary ─────────────────────────────────────────────────
276
+ echo ""
277
+ echo "═══════════════════════════════════════════════════════"
278
+ if $DRY_RUN; then
279
+ echo " DRY RUN COMPLETE — no changes made"
280
+ echo " Run without --dry-run to apply"
281
+ else
282
+ echo " Post-Install Hardening Applied"
283
+ echo ""
284
+ echo " Next steps:"
285
+ echo " 1. Add API keys to $SECRETS_DIR/openclaw.env"
286
+ echo " 2. Add your Telegram user ID to openclaw.json telegram.allowFrom"
287
+ echo " 3. Set model fallbacks if not already configured"
288
+ echo " 4. Run verify: bash /tmp/verify-post-install-hardening.sh"
289
+ echo " 5. Run Mighty Mark: mighty-mark check"
290
+ fi
291
+ echo "═══════════════════════════════════════════════════════"
292
+ echo ""
@@ -0,0 +1,266 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # OpenClaw Post-Install Hardening Verification (Check H)
4
+ # Author: Archie
5
+ # Date: 2026-03-07
6
+ # Spec: SPEC-OPENCLAW-POST-INSTALL-HARDENING-CHECKLIST v1.1 (BB Approved)
7
+ #
8
+ # Verifies post-install hardening items that complement Check G:
9
+ # 1. Gateway is running
10
+ # 2. Model defaults with fallbacks
11
+ # 3. Secrets file permissions (700/600)
12
+ # 4. Telegram DM policy = allowlist
13
+ # 5. Workspace personalization (SOUL.md, IDENTITY.md per agent)
14
+ # 6. MEMORY.md exists for each agent
15
+ # 7. HEARTBEAT.md exists for each agent
16
+ # 8. Cron jobs are not stale
17
+ # 9. Spawn prevention (maxSpawnDepth/maxChildrenPerAgent)
18
+ #
19
+ # Usage:
20
+ # ./scripts/ops/verify-post-install-hardening.sh # Normal run
21
+ # ./scripts/ops/verify-post-install-hardening.sh --json # Machine-readable
22
+ # ./scripts/ops/verify-post-install-hardening.sh --quiet # Exit code only
23
+ #
24
+ # Exit codes:
25
+ # 0 = all checks pass
26
+ # 1 = one or more FAIL results
27
+ #
28
+ # Ships with @aiassesstech/mighty-mark npm package (src/scripts/).
29
+ # After deployment, available at:
30
+ # ~/.openclaw/extensions/mighty-mark/node_modules/@aiassesstech/mighty-mark/src/scripts/
31
+ # Checks codified in: src/checks/security-hardening.ts
32
+ # ============================================================================
33
+
34
+ set -euo pipefail
35
+
36
+ OUTPUT_MODE="human"
37
+ while [[ $# -gt 0 ]]; do
38
+ case $1 in
39
+ --json) OUTPUT_MODE="json"; shift ;;
40
+ --quiet) OUTPUT_MODE="quiet"; shift ;;
41
+ -h|--help)
42
+ echo "Usage: $0 [--json|--quiet]"
43
+ echo " --json Machine-readable JSON output"
44
+ echo " --quiet No output, exit code only"
45
+ exit 0
46
+ ;;
47
+ *) echo "Unknown option: $1"; exit 1 ;;
48
+ esac
49
+ done
50
+
51
+ PASS=0
52
+ WARN=0
53
+ FAIL=0
54
+ RESULTS=""
55
+
56
+ check() {
57
+ local label=$1
58
+ local status=$2
59
+ local detail=$3
60
+
61
+ if [ "$status" = "PASS" ]; then
62
+ PASS=$((PASS + 1))
63
+ [ "$OUTPUT_MODE" = "human" ] && echo " ✅ $label — $detail"
64
+ elif [ "$status" = "WARN" ]; then
65
+ WARN=$((WARN + 1))
66
+ [ "$OUTPUT_MODE" = "human" ] && echo " ⚠️ $label — $detail"
67
+ else
68
+ FAIL=$((FAIL + 1))
69
+ [ "$OUTPUT_MODE" = "human" ] && echo " ❌ $label — $detail"
70
+ fi
71
+
72
+ if [ "$OUTPUT_MODE" = "json" ]; then
73
+ RESULTS="${RESULTS:+$RESULTS,}{\"name\":\"$label\",\"status\":\"$status\",\"detail\":\"$detail\"}"
74
+ fi
75
+ }
76
+
77
+ OPENCLAW_HOME="${OPENCLAW_STATE_DIR:-${OPENCLAW_HOME:-$HOME}/.openclaw}"
78
+ CONFIG_FILE="$OPENCLAW_HOME/openclaw.json"
79
+ EXPECTED_AGENTS="grillo jessie noah nole mighty-mark sam"
80
+
81
+ [ "$OUTPUT_MODE" = "human" ] && echo ""
82
+ [ "$OUTPUT_MODE" = "human" ] && echo "═══════════════════════════════════════════════════════"
83
+ [ "$OUTPUT_MODE" = "human" ] && echo " Check H: Post-Install Hardening Verification"
84
+ [ "$OUTPUT_MODE" = "human" ] && echo " Spec: SPEC-OPENCLAW-POST-INSTALL-HARDENING v1.1"
85
+ [ "$OUTPUT_MODE" = "human" ] && echo "═══════════════════════════════════════════════════════"
86
+ [ "$OUTPUT_MODE" = "human" ] && echo ""
87
+
88
+ # --- H.1: Gateway running ---
89
+ if pgrep -f "openclaw.*gateway" > /dev/null 2>&1; then
90
+ check "H.1 Gateway process" "PASS" "running"
91
+ else
92
+ check "H.1 Gateway process" "FAIL" "not detected"
93
+ fi
94
+
95
+ # --- H.2: Config file readable ---
96
+ if [ ! -f "$CONFIG_FILE" ]; then
97
+ check "H.2 Config file" "FAIL" "$CONFIG_FILE not found"
98
+ # Without config, skip config-dependent checks
99
+ [ "$OUTPUT_MODE" = "human" ] && echo ""
100
+ [ "$OUTPUT_MODE" = "human" ] && echo " Config missing — skipping config-dependent checks"
101
+ else
102
+ check "H.2 Config file" "PASS" "$CONFIG_FILE"
103
+
104
+ # --- H.3: Model defaults with fallbacks ---
105
+ PRIMARY=$(python3 -c "
106
+ import json, sys
107
+ with open('$CONFIG_FILE') as f: c = json.load(f)
108
+ m = c.get('agents',{}).get('defaults',{}).get('model')
109
+ if not m: sys.exit(1)
110
+ if isinstance(m, str): print(m); sys.exit(0)
111
+ print(m.get('primary',''))
112
+ " 2>/dev/null) || PRIMARY=""
113
+
114
+ FALLBACK_COUNT=$(python3 -c "
115
+ import json, sys
116
+ with open('$CONFIG_FILE') as f: c = json.load(f)
117
+ m = c.get('agents',{}).get('defaults',{}).get('model',{})
118
+ if isinstance(m, str): print(0); sys.exit(0)
119
+ print(len(m.get('fallbacks',[])))
120
+ " 2>/dev/null) || FALLBACK_COUNT="0"
121
+
122
+ if [ -n "$PRIMARY" ] && [ "$FALLBACK_COUNT" -gt 0 ] 2>/dev/null; then
123
+ check "H.3 Model defaults" "PASS" "primary=$PRIMARY, $FALLBACK_COUNT fallback(s)"
124
+ elif [ -n "$PRIMARY" ]; then
125
+ check "H.3 Model defaults" "WARN" "primary=$PRIMARY, no fallbacks"
126
+ else
127
+ check "H.3 Model defaults" "WARN" "no model defaults configured"
128
+ fi
129
+
130
+ # --- H.4: Telegram DM policy ---
131
+ DM_POLICY=$(python3 -c "
132
+ import json
133
+ with open('$CONFIG_FILE') as f: c = json.load(f)
134
+ print(c.get('telegram',{}).get('dmPolicy',''))
135
+ " 2>/dev/null) || DM_POLICY=""
136
+
137
+ ALLOW_COUNT=$(python3 -c "
138
+ import json
139
+ with open('$CONFIG_FILE') as f: c = json.load(f)
140
+ print(len(c.get('telegram',{}).get('allowFrom',[])))
141
+ " 2>/dev/null) || ALLOW_COUNT="0"
142
+
143
+ if [ "$DM_POLICY" = "allowlist" ] && [ "$ALLOW_COUNT" -gt 0 ] 2>/dev/null; then
144
+ check "H.4 Telegram DM policy" "PASS" "allowlist, $ALLOW_COUNT allowed"
145
+ elif [ "$DM_POLICY" = "allowlist" ]; then
146
+ check "H.4 Telegram DM policy" "WARN" "allowlist but allowFrom empty"
147
+ elif [ "$DM_POLICY" = "open" ] || [ -z "$DM_POLICY" ]; then
148
+ check "H.4 Telegram DM policy" "FAIL" "${DM_POLICY:-NOT SET} — open to all"
149
+ else
150
+ check "H.4 Telegram DM policy" "WARN" "$DM_POLICY — verify manually"
151
+ fi
152
+
153
+ # --- H.5: Spawn prevention ---
154
+ SPAWN_DEPTH=$(python3 -c "
155
+ import json
156
+ with open('$CONFIG_FILE') as f: c = json.load(f)
157
+ print(c.get('agents',{}).get('defaults',{}).get('subagents',{}).get('maxSpawnDepth',''))
158
+ " 2>/dev/null) || SPAWN_DEPTH=""
159
+
160
+ CHILDREN=$(python3 -c "
161
+ import json
162
+ with open('$CONFIG_FILE') as f: c = json.load(f)
163
+ print(c.get('agents',{}).get('defaults',{}).get('subagents',{}).get('maxChildrenPerAgent',''))
164
+ " 2>/dev/null) || CHILDREN=""
165
+
166
+ if [ "$SPAWN_DEPTH" = "1" ] && [ "$CHILDREN" = "1" ]; then
167
+ check "H.5 Spawn prevention" "PASS" "depth=1, children=1"
168
+ elif [ -n "$SPAWN_DEPTH" ] || [ -n "$CHILDREN" ]; then
169
+ check "H.5 Spawn prevention" "WARN" "depth=${SPAWN_DEPTH:-?}, children=${CHILDREN:-?}"
170
+ else
171
+ check "H.5 Spawn prevention" "WARN" "not configured"
172
+ fi
173
+ fi
174
+
175
+ # --- H.6: Secrets file permissions ---
176
+ SECRETS_DIR="$OPENCLAW_HOME/secrets"
177
+ SECRETS_FILE="$SECRETS_DIR/openclaw.env"
178
+
179
+ if [ ! -d "$SECRETS_DIR" ]; then
180
+ check "H.6 Secrets permissions" "FAIL" "$SECRETS_DIR not found"
181
+ elif [ ! -f "$SECRETS_FILE" ]; then
182
+ check "H.6 Secrets permissions" "FAIL" "dir exists but openclaw.env missing"
183
+ else
184
+ DIR_PERM=$(stat -c '%a' "$SECRETS_DIR" 2>/dev/null || stat -f '%Lp' "$SECRETS_DIR" 2>/dev/null)
185
+ FILE_PERM=$(stat -c '%a' "$SECRETS_FILE" 2>/dev/null || stat -f '%Lp' "$SECRETS_FILE" 2>/dev/null)
186
+ ISSUES=""
187
+ [ "$DIR_PERM" != "700" ] && ISSUES="dir=$DIR_PERM(want 700) "
188
+ [ "$FILE_PERM" != "600" ] && ISSUES="${ISSUES}file=$FILE_PERM(want 600)"
189
+ if [ -z "$ISSUES" ]; then
190
+ check "H.6 Secrets permissions" "PASS" "dir=700, file=600"
191
+ else
192
+ check "H.6 Secrets permissions" "WARN" "$ISSUES"
193
+ fi
194
+ fi
195
+
196
+ # --- H.7–H.9: Per-agent workspace files ---
197
+ EXTENSIONS_DIR="$OPENCLAW_HOME/extensions"
198
+ MISSING_SOUL=""
199
+ MISSING_IDENTITY=""
200
+ MISSING_MEMORY=""
201
+ MISSING_HEARTBEAT=""
202
+ AGENT_COUNT=0
203
+
204
+ for AGENT in $EXPECTED_AGENTS; do
205
+ AGENT_DIR="$EXTENSIONS_DIR/$AGENT/agent"
206
+ [ ! -d "$AGENT_DIR" ] && continue
207
+ AGENT_COUNT=$((AGENT_COUNT + 1))
208
+
209
+ [ ! -f "$AGENT_DIR/SOUL.md" ] && MISSING_SOUL="$MISSING_SOUL $AGENT"
210
+ [ ! -f "$AGENT_DIR/IDENTITY.md" ] && MISSING_IDENTITY="$MISSING_IDENTITY $AGENT"
211
+
212
+ AGENT_WS=$(openclaw agent workspace "$AGENT" 2>/dev/null || echo "")
213
+ [ -z "$AGENT_WS" ] && AGENT_WS="$OPENCLAW_HOME/agents/$AGENT"
214
+ [ ! -f "$AGENT_WS/MEMORY.md" ] && [ ! -f "$AGENT_DIR/MEMORY.md" ] && MISSING_MEMORY="$MISSING_MEMORY $AGENT"
215
+ [ ! -f "$AGENT_WS/HEARTBEAT.md" ] && [ ! -f "$AGENT_DIR/HEARTBEAT.md" ] && MISSING_HEARTBEAT="$MISSING_HEARTBEAT $AGENT"
216
+ done
217
+
218
+ if [ "$AGENT_COUNT" -eq 0 ]; then
219
+ check "H.7 Personalization" "WARN" "no agent dirs found"
220
+ elif [ -n "$MISSING_SOUL" ] || [ -n "$MISSING_IDENTITY" ]; then
221
+ DETAIL=""
222
+ [ -n "$MISSING_SOUL" ] && DETAIL="SOUL.md:${MISSING_SOUL}"
223
+ [ -n "$MISSING_IDENTITY" ] && DETAIL="${DETAIL:+$DETAIL; }IDENTITY.md:${MISSING_IDENTITY}"
224
+ check "H.7 Personalization" "FAIL" "missing — $DETAIL"
225
+ else
226
+ check "H.7 Personalization" "PASS" "$AGENT_COUNT agents have SOUL.md + IDENTITY.md"
227
+ fi
228
+
229
+ if [ "$AGENT_COUNT" -gt 0 ]; then
230
+ if [ -n "$MISSING_MEMORY" ]; then
231
+ check "H.8 MEMORY.md" "WARN" "missing for:${MISSING_MEMORY}"
232
+ else
233
+ check "H.8 MEMORY.md" "PASS" "$AGENT_COUNT agents"
234
+ fi
235
+
236
+ if [ -n "$MISSING_HEARTBEAT" ]; then
237
+ check "H.9 HEARTBEAT.md" "WARN" "missing for:${MISSING_HEARTBEAT}"
238
+ else
239
+ check "H.9 HEARTBEAT.md" "PASS" "$AGENT_COUNT agents"
240
+ fi
241
+ fi
242
+
243
+ # --- Summary ---
244
+ TOTAL=$((PASS + WARN + FAIL))
245
+
246
+ if [ "$OUTPUT_MODE" = "human" ]; then
247
+ echo ""
248
+ echo "───────────────────────────────────────────────────────"
249
+ echo " Results: $PASS pass | $WARN warn | $FAIL fail (total: $TOTAL)"
250
+ if [ "$FAIL" -eq 0 ] && [ "$WARN" -eq 0 ]; then
251
+ echo " Status: ✅ ALL CLEAR"
252
+ elif [ "$FAIL" -eq 0 ]; then
253
+ echo " Status: ⚠️ WARNINGS — review items above"
254
+ else
255
+ echo " Status: ❌ FAILURES — action required"
256
+ fi
257
+ echo "───────────────────────────────────────────────────────"
258
+ echo ""
259
+ fi
260
+
261
+ if [ "$OUTPUT_MODE" = "json" ]; then
262
+ echo "{\"check\":\"post-install-hardening\",\"version\":\"1.1\",\"pass\":$PASS,\"warn\":$WARN,\"fail\":$FAIL,\"total\":$TOTAL,\"results\":[$RESULTS]}"
263
+ fi
264
+
265
+ [ "$FAIL" -gt 0 ] && exit 1
266
+ exit 0