Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(self-audit): v1.1.0 — add mechanical Step 0 (file existence chec…
…k) + requirement traceability in Completeness + de-branded Background section with scope note
  • Loading branch information
YuhaoLin2005 committed Jun 29, 2026
commit 21bafebffc68f438185c030a9b4333c887e6bc01
63 changes: 48 additions & 15 deletions skills/self-audit/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
---
name: self-audit
description: Audits AI output across four dimensions before delivering — completeness, consistency, groundedness, and honesty. Use this skill whenever completing a complex task, before stopping and delivering results, or whenever output quality matters. Use whenever an agent is about to finish work — even if the user has not explicitly asked for review. Use after multi-file edits, architectural decisions, or any session where sloppy thinking could slip through. Use proactively: if you are about to ship, audit first.
description: Audits AI output before delivery — mechanical file check + four-dimension reasoning audit. Catches what tests miss.
version: 1.1.0
tags: [quality, audit, verification, reasoning]
---

# Self-Audit

Before you ship, ask yourself four questions:
Before you ship, verify mechanically first, then audit reasoning.

**Step 0 (mechanical):** If you claimed to produce files, confirm each one exists via the file-read tool. A file that doesn't exist is a hard fail — no reasoning audit can detect a physically absent artifact.

**Steps 1-4 (reasoning):** Ask four questions:
1. **Did I answer everything?** (Completeness)
2. **Did I contradict myself?** (Consistency)
3. **Did I show evidence?** (Groundedness)
4. **Am I being honest about the limits?** (Honesty)

If any answer is no -> fix it -> re-ask. Code can pass all tests with sloppy thinking behind it. These four questions catch what tests miss — they are a habit of mind, not a checklist.
If any answer is no → fix it → re-ask. Code can pass all tests with sloppy thinking behind it. These questions catch what tests miss.

Tests verify code. Nothing verifies reasoning. This skill fills that gap — four questions that catch what compilers and test suites cannot.
Tests verify code. Nothing verifies reasoning. And nothing mechanically verifies that the agent actually produced what it claims — Step 0 fills that second gap.

## Priority Order

Expand All @@ -25,49 +30,67 @@ Tests verify code. Nothing verifies reasoning. This skill fills that gap — fou

## Hard Constraints

- **Never fabricate findings.** If all four dimensions pass, report PASS. If any fail, report FIXED with specifics.
- **Never fabricate findings.** If all dimensions pass, report PASS. If any fail, report FIXED with specifics.
- **Never expose sensitive data.** Redact paths, secrets, tokens, PII before displaying audit output.
- **Never block on subjective grounds.** Flag only concrete, verifiable gaps — not stylistic preferences.
- **Step 0 is non-negotiable when files are claimed.** If the agent said it produced output files, verify mechanically first. No exceptions.

## When to Use

- Complex task completed (3+ file edits)
- Agent about to stop and deliver results
- After architectural decisions with downstream impact
- Sessions where sloppy thinking could slip through
- Agent claimed to produce output files (Step 0 applies)
- Proactively: if you are about to ship, audit first

## Step 0 — Mechanical File Check

**Before any reasoning questions, verify claimed output files exist.**

If the agent claimed to produce files:
- Use the file-read tool to confirm each file exists at the claimed path
- If any claimed file is missing → FAIL immediately, report to user, do not proceed to reasoning audit
- If multiple files were claimed, check all of them. Report each missing file individually.

This catches: "I generated report.md" when no file was written. No amount of reasoning audit can detect a physically absent artifact.

## The Four Questions

### 1. Completeness
List each request. Verify response or deferral. Flag partials as full.

If the input was a spec, feature list, or set of numbered requirements: map each requirement to the output section that addresses it. Flag any unmapped requirements — the agent may have forgotten them.

### 2. Consistency
Scan vs earlier. Check project rules. Flag A-and-not-A.

### 3. Groundedness
Identify claims. Evidence or words? Distinguish not-verified vs hidden.

### 4. Honesty
Check over-packaging. Edge cases mentioned? Verified without showing? Missing error handling = production ready?
Check over-packaging. Edge cases mentioned? Verified without showing? Missing error handling ≠ production ready.

## Process

0. **MECHANICAL**: If agent claimed output files → use file-read tool to confirm existence. Missing → FAIL.
1. COMPLETE task
2. ASK four. Fail -> fix -> re-ask.
2. ASK four. Fail → fix → re-ask.
3. 3+ stuck: report blocking, ask user.
4. All pass -> stop.
4. All pass → stop.

Output:

```
Self-Audit:
Completeness: OK | FIXED [what]
Consistency: OK | FIXED [what]
Groundedness: OK | FIXED [what]
Honesty: OK | FIXED [what]
Step 0 (Mechanical): PASS | FAIL [file not found: <path>]
Completeness: OK | FIXED [what]
Consistency: OK | FIXED [what]
Groundedness: OK | FIXED [what]
Honesty: OK | FIXED [what]
```

## Failure Modes

- **Step 0 fails but reasoning would pass**: The agent forgot to write the file. This is exactly why Step 0 exists — reasoning alone cannot catch this.
- **Overly long**: Sample 5 most critical.
- **Data leak**: Redact before display.
- **Fatigue**: Detail mode for shipping only.
Expand All @@ -79,25 +102,35 @@ Honesty: OK | FIXED [what]
| Simple change, no audit | Simple changes cause bugs. 30s saves hours. |
| Checked as I went | Cross-cutting only in dedicated pass. |
| User will catch | Users not QA. |
| All four OK no detail | Complex tasks find >=1 issue. |
| All four OK no detail | Complex tasks find ≥1 issue. |
| Verified internally | Without output = assumption. |
| I'm sure I wrote the file | Step 0 verifies mechanically. Trust the tool, not memory. |

## Red Flags

- Stopping without audit
- Step 0 skipped when files were claimed
- All OK no specifics
- Verified without showing
- Requirements dropped silently
- Audit hidden in reasoning

## Verification

- [ ] Step 0: All claimed output files mechanically verified via file-read tool
- [ ] Four questions answered with specific evidence (not "seems fine")
- [ ] If spec/requirements were provided: each requirement mapped to output section; unmapped requirements flagged
- [ ] FIXED applied for every failed dimension
- [ ] Audit output visible in the response (not buried in reasoning)
- [ ] Hard constraints respected — no fabricated findings, no leaked data
- [ ] No rationalized omissions (skipped work documented as skipped, not as done)

## Background

This skill implements a hybrid quality gate: mechanical verification (Step 0) plus reasoning audit (Steps 1-4). The four-dimension taxonomy (Completeness, Consistency, Groundedness, Honesty) is also used by multi-agent pipeline architectures for handoff validation — independently convergent, not derived.

Note on scope: this skill runs within the same agent session that produced the output (same trust boundary). Multi-agent pipeline architectures deploy equivalent gates at handoff boundaries where the reviewer is independent of the producer. Both approaches address the same problem — unverified agent output — at different architectural levels.

## See Also

- `code-reviewer` — Review code changes for correctness and quality
Expand Down
155 changes: 155 additions & 0 deletions tests/skills/test_self_audit_skill.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
"""Tests for skills/self-audit/SKILL.md

Validates SKILL.md metadata, structure, and HARDLINE rule compliance.
"""

import re
from pathlib import Path

import pytest


def _load_yaml():
import yaml as _yaml
return _yaml


SKILL_DIR = (
Path(__file__).resolve().parents[2]
/ "skills"
/ "self-audit"
)
SKILL_MD = SKILL_DIR / "SKILL.md"


def _read_skill():
yaml = _load_yaml()
text = SKILL_MD.read_text(encoding="utf-8")
parts = text.split("---", 2)
if len(parts) < 3:
raise ValueError("SKILL.md missing YAML frontmatter delimiters")
frontmatter = yaml.safe_load(parts[1])
body = parts[2]
return frontmatter, body


class TestSkillExists:
def test_skill_md_present(self):
assert SKILL_MD.exists(), f"SKILL.md not found at {SKILL_MD}"
assert SKILL_MD.is_file()

def test_no_scripts_dir(self):
scripts = SKILL_DIR / "scripts"
assert not scripts.exists(), (
"This is a pure prompt-pattern skill. "
"Remove scripts/ — if scripts are needed, add them with tests."
)


class TestFrontmatter:
@pytest.fixture(autouse=True)
def load(self):
self.fm, self.body = _read_skill()

def test_name_matches_directory(self):
assert self.fm["name"] == "self-audit"

def test_description_length(self):
desc = self.fm["description"]
assert len(desc) <= 120, (
f"description is {len(desc)} chars (max 120): {desc!r}"
)

def test_description_ends_with_period(self):
assert self.fm["description"].endswith(".")

def test_version_present(self):
assert "version" in self.fm

def test_author_not_hermes_agent(self):
author = self.fm.get("author", "")
if author:
assert author != "Hermes Agent"

def test_tags_present(self):
tags = self.fm.get("tags", [])
assert len(tags) >= 2, "skill should have at least 2 tags"


class TestRequiredSections:
REQUIRED = [
"When to Use",
"Step 0",
"The Four Questions",
"Process",
"Failure Modes",
"Common Rationalizations",
"Red Flags",
"Verification",
"Background",
]

@pytest.fixture(autouse=True)
def load(self):
self.fm, self.body = _read_skill()

@pytest.mark.parametrize("section", REQUIRED)
def test_section_present(self, section):
assert f"## {section}" in self.body, (
f"Missing required section: ## {section}"
)

def test_section_order(self):
positions = {}
for section in self.REQUIRED:
idx = self.body.find(f"## {section}")
if idx >= 0:
positions[section] = idx
ordered = sorted(positions.items(), key=lambda x: x[1])
ordered_names = [name for name, _ in ordered]
present_required = [s for s in self.REQUIRED if s in positions]
assert ordered_names == present_required, (
f"Sections out of order. Expected: {present_required}, "
f"Got: {ordered_names}"
)


class TestBodyQuality:
@pytest.fixture(autouse=True)
def load(self):
self.fm, self.body = _read_skill()

def test_line_count(self):
lines = self.body.strip().split("\n")
assert len(lines) <= 250, (
f"Body is {len(lines)} lines — too long for a prompt-pattern skill"
)

def test_first_heading_is_title(self):
for line in self.body.split("\n"):
stripped = line.strip()
if stripped.startswith("# "):
assert "Self-Audit" in stripped
break

def test_step_zero_before_four_questions(self):
"""Step 0 must appear before The Four Questions section."""
step0_idx = self.body.find("## Step 0")
questions_idx = self.body.find("## The Four Questions")
assert step0_idx >= 0, "Step 0 section missing"
assert questions_idx >= 0, "The Four Questions section missing"
assert step0_idx < questions_idx, (
"Step 0 must appear before The Four Questions"
)

def test_file_read_tool_referenced_in_step_zero(self):
step0_start = self.body.find("## Step 0")
questions_start = self.body.find("## The Four Questions")
step0_text = self.body[step0_start:questions_start]
assert "file-read" in step0_text.lower() or "read_file" in step0_text.lower(), (
"Step 0 must reference file-read tool for mechanical verification"
)


if __name__ == "__main__":
raise SystemExit(pytest.main([__file__, "-q"]))