codex-log-guard — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited codex-log-guard (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Diagnose Codex persistent diagnostic logging from local evidence, then give a concise conclusion and the safest next action. Do not make the user choose from a command menu.
Select one mode from the current user request:
diagnose_only is the default for check, inspect, explain, or verify requests. It is read-only.protect requires an explicit request to stop or mitigate log writes. It may install and verify block_log_inserts, but it does not delete rows or vacuum files.cleanup requires an explicit current request to reclaim disk space or clean up logs. It first installs protection when needed, creates and verifies a timestamped backup, and only then deletes log rows and vacuums.restore requires an explicit request to resume diagnostic logging. It may drop only the known block_log_inserts trigger.Generic wording such as "处理", "修一下", or "止血" selects protect, not cleanup. Prior approval does not carry into a later run. If the requested write mode is ambiguous, return the diagnose_only report and the exact proposed mutation without applying it.
Direct actions:
Escalate before:
Evidence-backed pushback:
Feedback loop:
agents/openai.yaml contains discovery UI metadata only; it is not an operational instruction source.
When the user asks to "check", "看看", "诊断", or asks whether the local machine is affected:
~/.codex/logs_2.sqlite~/.codex/sqlite/logs_2.sqliteblock_log_inserts already exists on each candidate with a logs table.logs is still being written using COUNT(*), MIN(id), MAX(id) samples.Treat MAX(id) or MIN(id) movement with stable COUNT(*) as active churn, not necessarily disk growth.
TRACE/DEBUG counts and top noisy targets.In protect mode:
block_log_inserts first.COUNT(*), MAX(id) stops growing.In cleanup mode:
.backup and require a non-empty file plus a successful PRAGMA quick_check result.In restore mode:
block_log_inserts.COUNT(*), MAX(id) to confirm logging resumes or stays quiet.Run direct shell/SQLite commands. Use only the needed subset for the user's request; do not paste a menu back to the user.
Inspect files:
for db in ~/.codex/logs_2.sqlite ~/.codex/sqlite/logs_2.sqlite; do
ls -lh "$db"* 2>/dev/null
du -h "$db"* 2>/dev/null
doneAfter lsof identifies the active candidate, validate the selected path in the same shell command before running any later SQLite snippet:
: "${CODEX_LOG_DB:?set CODEX_LOG_DB to the verified active candidate}"
case "$CODEX_LOG_DB" in
"$HOME/.codex/logs_2.sqlite"|"$HOME/.codex/sqlite/logs_2.sqlite") ;;
*) echo "refusing unexpected Codex log database path" >&2; exit 2 ;;
esac
readonly db="$CODEX_LOG_DB"Do not supply a default. If no active path can be proven, stay in diagnose_only and report the ambiguity.
Check schema and trigger:
sqlite3 "$db" ".tables"
sqlite3 "$db" "PRAGMA table_info(logs);"
sqlite3 "$db" "SELECT name, tbl_name, sql FROM sqlite_master WHERE type='trigger' AND name='block_log_inserts';"Sample writes and growth:
for i in 1 2 3; do
date '+%F %T'
sqlite3 "$db" "SELECT COUNT(*) AS rows, MIN(id) AS min_id, MAX(id) AS max_id FROM logs;"
stat -f '%N %z bytes mtime=%Sm' "$db" "$db-wal" "$db-shm" 2>/dev/null
sleep 10
doneInspect levels and noisy targets:
sqlite3 "$db" "SELECT level, COUNT(*) AS n, ROUND(SUM(estimated_bytes)/1024.0/1024.0, 1) AS estimated_mib FROM logs GROUP BY level ORDER BY n DESC;"
sqlite3 "$db" "SELECT target, level, COUNT(*) AS n, ROUND(SUM(estimated_bytes)/1024.0/1024.0, 1) AS estimated_mib FROM logs GROUP BY target, level ORDER BY n DESC LIMIT 15;"Check open processes:
lsof ~/.codex/logs_2.sqlite ~/.codex/logs_2.sqlite-wal ~/.codex/logs_2.sqlite-shm \
~/.codex/sqlite/logs_2.sqlite ~/.codex/sqlite/logs_2.sqlite-wal ~/.codex/sqlite/logs_2.sqlite-shm 2>/dev/nullInstall protection:
sqlite3 "$db" "PRAGMA busy_timeout=10000; CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"Clean up after protection:
backup="$db.bak.$(date +%Y%m%d-%H%M%S)"
sqlite3 "$db" ".backup '$backup'"
test -s "$backup"
test "$(sqlite3 "$backup" 'PRAGMA quick_check;')" = "ok"
sqlite3 "$db" "PRAGMA busy_timeout=10000; PRAGMA wal_checkpoint(TRUNCATE); DELETE FROM logs; VACUUM; PRAGMA wal_checkpoint(TRUNCATE);"
echo "$backup"Restore persistent logging:
sqlite3 "$db" "DROP TRIGGER IF EXISTS block_log_inserts;"logs_2.sqlite files: healthy/not applicable unless the user expects Codex to have run.lsof; do not assume the top-level path is the only live database.COUNT/MIN(id)/MAX(id) stable: protected.MIN(id) or MAX(id) moves: affected and actively writing.TRACE/DEBUG, but no sample movement: affected historically; recommend protection, cleanup optional.logs is absent or schema differs, stop and report that the known workaround is not safely applicable.COUNT(*), MAX(id) sampling.cleanup as reversible only through its timestamped backup. Mention the backup path in the final answer.~/.codex/logs_2.sqlite* and ~/.codex/sqlite/logs_2.sqlite*); it does not manage conversation archives, repo files, credentials, or remote telemetry.COUNT(*) can stay constant while MIN(id) and MAX(id) move; classify this as churn, not a quiet database.Keep the user-facing answer short:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.