一键导入
ax-provider-audit
Use when modifying audit logging providers — database-backed audit logs or audit entry structure in src/providers/audit/
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when modifying audit logging providers — database-backed audit logs or audit entry structure in src/providers/audit/
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when modifying logging, error handling, or diagnostic messages — logger setup, transports, error diagnosis patterns in src/logger.ts and src/errors.ts
Use when modifying the trusted host process — server orchestration, message routing, IPC handler, request lifecycle, event streaming, file handling, plugin loading, or agent delegation in src/host/
Use when modifying the sandboxed agent process — runner, IPC client, local/IPC tools, tool catalog, prompt building, or identity loading in src/agent/
Use when modifying agent sandbox isolation -- Docker, Apple Container (macOS), or k8s providers in src/providers/sandbox/
Use when modifying IPC protocol between host and agent — schemas, actions, length-prefix framing, or Zod validation in ipc-schemas.ts and ipc-server.ts
AX project architecture and coding skills - use sub-skills for specific subsystems (agent, host, cli, providers, etc.)
| name | ax-provider-audit |
| description | Use when modifying audit logging providers — database-backed audit logs or audit entry structure in src/providers/audit/ |
The audit provider records every IPC action, LLM call, and security event. Two implementations: append-only JSONL for simplicity, database-backed (SQLite/PostgreSQL via shared DatabaseProvider) for indexed queries. The IPC dispatch wrapper calls audit.log() automatically after every handler.
| Field | Type | Required | Notes |
|---|---|---|---|
timestamp | Date | yes | When the action occurred |
sessionId | string | yes | Originating session |
action | string | yes | IPC action name |
args | Record<string, unknown> | yes | Action parameters |
result | 'success' | 'blocked' | 'error' | yes | Outcome |
taint | TaintTag | no | Taint tag if content was tainted |
durationMs | number | yes | Execution time in milliseconds |
tokenUsage | { input, output } | no | LLM token counts |
| Field | Type | Notes |
|---|---|---|
action | string | Filter by action name |
sessionId | string | Filter by session |
since | Date | Inclusive lower bound on timestamp |
until | Date | Inclusive upper bound on timestamp |
limit | number | Return last N matching entries |
| Method | Description |
|---|---|
log(entry) | Append a partial AuditEntry (timestamp auto-filled) |
query(filter) | Return entries matching AuditFilter |
| Provider | File | Storage | Queryable | Notes |
|---|---|---|---|---|
file | file.ts | JSONL append | yes (scan) | Reads entire file for queries |
database | database.ts | Shared DatabaseProvider (SQLite/PostgreSQL) | yes (SQL) | Uses injected DatabaseProvider; indexed on session_id and action |
dataFile('audit', 'audit.jsonl') via appendFileSync.ENOENT.query() reads and parses all lines, then filters in-memory. Not efficient for large logs.DatabaseProvider via create(config, name, { database }) — no standalone DB connection.audit_log table with id, timestamp, session_id, action, args (JSON), result, taint (JSON), duration_ms, token_input, token_output.idx_audit_session (session_id, timestamp), idx_audit_action (action, timestamp).migrations.ts — applied by the database provider during startup.limit returns the last N entries (most recent), re-sorted ascending.AuditEntry type, add column via migration in migrations.ts, add to JSONL serialization, update rowToEntry() mapping.AuditFilter, add SQL WHERE clause in database.ts, add in-memory filter in file.ts.query({ action: 'your_action', limit: 10 }).audit.log() with empty args after the handler runs. When testing handler-specific audit entries, mock audit.log to push to an array and use .find() to locate the correct entry.query() on the file provider parses every line on every call. For large deployments, prefer SQLite.limit uses a nested subquery to get the last N rows, then re-sorts ascending. Adding new filter logic must account for this wrapping.