evidenceops
通过监管链进行法医媒体分类。在接收需要证据级处理、完整性验证和审计跟踪的图像、视频、音频、PDF 或文档时使用。
安装 / 下载方式
TotalClaw CLI推荐
totalclaw install totalclaw:totalclaw~msrovani-skill-evidenceopscURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~msrovani-skill-evidenceops/file -o msrovani-skill-evidenceops.md## 概述(中文)
通过监管链进行法医媒体分类。在接收需要证据级处理、完整性验证和审计跟踪的图像、视频、音频、PDF 或文档时使用。
## 原文
# EvidenceOps - Forensic Media Triage
## What It Does
EvidenceOps provides forensic-grade handling of media files with complete chain of custody:
1. **Media Intake** - Accept images, videos, audio, PDFs, and documents from any channel
2. **Immutable Storage** - Store originals in append-only vault with cryptographic hashes
3. **Metadata Extraction** - Extract EXIF, file properties, and media information without altering originals
4. **Derivative Generation** - Create thumbnails, transcripts, previews in separate folders
5. **Chain of Custody** - Maintain tamper-evident audit trail with hash chain
6. **Integrity Verification** - Verify evidence hasn't been modified post-ingest
7. **Audit Trail** - Complete JSONL audit log for compliance
## What It NEVER Does
- **NEVER** modifies original evidence files after ingest
- **NEVER** stores secrets, API keys, or credentials in manifests or logs
- **NEVER** accepts unsanitized paths from user input
- **NEVER** executes untrusted code or downloads remote scripts
- **NEVER** exfiltrates data to external services without explicit configuration
- **NEVER** bypasses channel allowlists or pairing requirements
- **NEVER** stores real personal data in example files
## Prerequisites
Before using this skill, ensure:
1. Plugin `@openclaw/evidence-vault` is installed and initialized
2. Vault storage directory is configured with appropriate permissions
3. Channel allowlist is configured for trusted sources only
4. Retention policies comply with your legal requirements
## Workflow
### Step 1: Receive Media
When media is received via any channel:
```
User sends: [image/video/document]
```
**Required Information:**
- File content (from attachment)
- Original filename
- Source channel (whatsapp, telegram, email, etc.)
- Sender identifier
- Message ID (if available)
### Step 2: Create or Select Case
```
IF user specifies existing caseId:
USE that caseId
ELSE IF user requests new case:
CREATE case with format: case-{YYYY}-{NNN}
EXAMPLE: case-2026-001
ELSE:
ASK user: "Should I create a new case or add to existing case [case-2026-XXX]?"
```
**Case ID Format:** `case-{year}-{sequence}`
- Must match pattern: `^case-[a-zA-Z0-9_-]+$`
- Examples: `case-2026-001`, `case-incident-alpha`, `case-legal-2026-q1`
### Step 3: Stage Original (Read-Only)
Before ingest:
1. **Save received file to temporary staging area**
2. **Calculate SHA-256 hash immediately**
3. **Record file size and MIME type**
4. **DO NOT modify the file**
```
# Staging directory structure
/tmp/evidence-staging/
├── {caseId}/
│ └── {timestamp}-{filename}
```
### Step 4: Extract Metadata
Extract metadata WITHOUT modifying original:
**For Images:**
- EXIF data (camera, GPS, timestamps)
- Dimensions
- Color profile
**For Videos:**
- Duration
- Codec information
- Resolution
**For Audio:**
- Duration
- Sample rate
- Codec
**For PDFs:**
- Page count
- Author (if embedded)
- Creation date
```
# Use Read tool or appropriate extraction commands
# NEVER write back to original file
```
### Step 5: Generate Derivatives (Optional)
Create derivative artifacts in SEPARATE folder:
```
derivatives/
├── thumbnails/
│ └── {evidenceId}-thumb.jpg
├── transcripts/
│ └── {evidenceId}-transcript.txt
└── previews/
└── {evidenceId}-preview.pdf
```
**Derivative Types:**
- `thumbnail` - Reduced resolution image/video preview
- `transcript` - Speech-to-text for audio/video
- `preview` - PDF or text representation
- `ocr` - Extracted text from images
### Step 6: Ingest to Vault
Call the evidence.ingest tool:
```json
{
"filePath": "/path/to/staged/file",
"filename": "original-filename.jpg",
"caseId": "case-2026-001",
"channel": "whatsapp",
"sender": "user@example.com",
"messageId": "msg-abc123",
"retentionDays": 2555,
"metadata": {
"exif": { ... },
"extracted": { ... }
}
}
```
**Response:**
```json
{
"success": true,
"evidenceId": "ev-abc123...",
"sha256": "a1b2c3...",
"vaultUrl": "file:///vault/cases/case-2026-001/originals/ev-abc123.jpg",
"timestamp": "2026-02-17T10:30:00.000Z"
}
```
### Step 7: Update Manifest
The manifest is automatically updated by the ingest operation.
**Manifest Location:** `{vault}/cases/{caseId}/manifest.json`
**Manifest Contents:**
- Case metadata
- Evidence items with hashes
- Derivatives
- Chain of custody entries
- Retention policy
### Step 8: Return Receipt
Provide user with evidence receipt:
```
📋 EVIDENCE RECEIPT
Case ID: case-2026-001
Evidence ID: ev-abc123...
File: original-filename.jpg
SHA-256: a1b2c3d4e5f6...
Size: 1.2 MB
Received: 2026-02-17 10:30:00 UTC
Vault: file:///vault/cases/case-2026-001/originals/ev-abc123.jpg
✅ Chain of custody established
✅ Original preserved immutably
✅ Audit trail active
```
## Tool Reference
### evidence.ingest
Ingest a file into the evidence vault.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| filePath | string | Yes | Path to the staged file |
| filename | string | Yes | Original filename |
| caseId | string | Yes | Case identifier |
| channel | string | No | Source channel |
| sender | string | No | Sender identifier |
| messageId | string | No | Message ID from source |
| retentionDays | number | No | Retention period |
| metadata | object | No | Additional metadata |
**Returns:** `{ evidenceId, sha256, vaultUrl, timestamp }`
### evidence.verify
Verify evidence integrity.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| evidenceId | string | Yes | Evidence to verify |
| caseId | string | No | Limit search to case |
**Returns:** `{ verified, details: { originalIntact, hashMatch, lastVerifiedAt } }`
### evidence.manifest
Get case manifest.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| caseId | string | Yes | Case identifier |
**Returns:** Complete case manifest with all items
### evidence.export
Export case as archive.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| caseId | string | Yes | Case identifier |
| format | string | No | 'zip' or 'tar' (default: zip) |
**Returns:** `{ exportPath, sha256, size, itemCount }`
### evidence.access_log
Get audit trail.
**Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| caseId | string | Yes | Case identifier |
| limit | number | No | Max events (default: 100) |
**Returns:** `{ events: [ ... ], count }`
## SECURITY POSTURE
### Channel Allowlist Configuration
Configure which channels can submit evidence:
```yaml
# ~/.openclaw/openclaw.json
{
"plugins": {
"evidence-vault": {
"channelAllowlist": ["whatsapp", "telegram", "email"],
"channelDenylist": ["public-discord"],
"requirePairing": true
}
}
}
```
### Pairing Requirements
For Direct Messages (DMs):
- **REQUIRE** pairing before accepting evidence
- **BLOCK** unpaired DMs by default
- **LOG** rejected ingestion attempts
For Group Channels:
- **VERIFY** channel is in allowlist
- **REJECT** evidence from untrusted channels
- **NEVER** auto-ingest from public channels
### Path Sanitization Rules
ALL paths are validated:
1. **No path traversal** - `../` sequences rejected
2. **No null bytes** - `\0` rejected
3. **No home directory** - `~/` rejected
4. **Canonicalization** - Paths resolved before validation
5. **Base path check** - Must be within vault directory
**Violations result in:** `E_PATH_TRAVERSAL` error + audit log entry
### Destructive Action Confirmation
Before any potentially destructive operation:
1. **EXPORT** - Confirm export destination
2. **RETENTION DELETE** - Require explicit confirmation (if enabled)
3. **LEGAL HOLD RELEASE** - Require explicit confirmation
**Confirmation format:**
```
⚠️ DE