# SF Audit Traces

<template_meta>
name: sf-audit-traces
version: 1
mode: oneshot
requires_project: true
artifact_dir: null
</template_meta>

<purpose>
Read SF's own observability sources, identify ONE non-obvious recurring pattern,
and file it as self-feedback so the existing triage flow can promote it.

Iterate slowly: at most three entries per run. The point isn't to flood the
queue — the point is to catch what no single session noticed.
</purpose>

<inputs>
- `.sf/SELF-FEEDBACK.md` — markdown view of filed anomalies
- `.sf/sf.db` — durable self-feedback source of truth when SQLite is available
- `.sf/self-feedback.jsonl` — legacy fallback/import source
- `.sf/journal/YYYY-MM-DD.jsonl` — per-day dispatch + iteration events
- `.sf/activity/{seq}-{type}-{id}.jsonl` — per-unit transcript
- `.sf/judgments/*.jsonl` — recorded agent decisions (when present)
- `.sf/forensics/*.json` — saved post-mortems (when present)
</inputs>

<process>

## 1. Snapshot

Run these to anchor the scan in real numbers — file paths and counts go
into the eventual self-feedback evidence:

```bash
node --input-type=module -e "import { openDatabase, closeDatabase, listSelfFeedbackEntries } from './src/resources/extensions/sf/sf-db.js'; openDatabase('.sf/sf.db'); console.log(listSelfFeedbackEntries(1000).length); closeDatabase();" 2>/dev/null || wc -l .sf/self-feedback.jsonl 2>/dev/null
ls .sf/journal/ 2>/dev/null | tail -7
ls .sf/activity/ 2>/dev/null | wc -l
```

Read the latest 7 days of journal files plus the last 30 activity files. If
a source is missing, skip silently — never block on absence.

## 2. Look for recurring patterns

The bar is **3+ occurrences** across the data, not single events. Examples:

- The same `kind` filed by self-feedback 3+ times in a week
- The same dispatch rule firing then immediately being un-applied (paired
  events in the journal)
- The same tool error repeating across activity logs
- The same run-away-guard pause across multiple units
- The same auto-resolved entry kind triaged as `wontfix` repeatedly (signal
  the detector is too noisy)
- A judgment that proves wrong over multiple subsequent units

Single events go to the operator's eyeballs, not to a permanent self-feedback
entry. Patterns earn one.

## 3. File at most three findings

For each pattern:

- One call to `report_issue` with `kind` (slug, hyphenated), `severity`
  (`low`/`medium`/`high`/`critical` — almost always `medium`), `summary`
  (one sentence naming the pattern), `evidence` (concrete file paths +
  line numbers + counts), `suggestedFix` (one or two specific edits — not
  prose).
- Set `source: "agent"` so triage knows where it came from.
- Cite at least three observed instances in `evidence` so the triage agent
  can verify without re-reading every log.

If you find nothing pattern-worthy, file zero. That is a successful run —
silence is the correct output when the system is healthy.

## 4. NEVER auto-apply

Do not edit code, prompts, templates, or docs. The triage flow
(`triage-self-feedback`, `requirement-promoter`) decides what becomes work.
Your job ends at filing. Even if the fix looks one-line obvious — file it
and stop.

## 5. NEVER ship a flood

Three is a hard cap. If you find a fourth, hold it for the next run. The
slow-pace constraint is deliberate — the triage flow is a human-paced
queue, not a firehose intake.

</process>

<output>
A short report:

- snapshot numbers (entries scanned, days covered)
- patterns considered + which ones met the 3-occurrence bar
- entry IDs filed (with `report_issue`'s returned id), or "none filed"
  when the system is healthy
- one sentence on what trend you'd watch next run
</output>

<scheduling_hint>
This template pairs well with `/schedule every morning sf-audit-traces`.
Daily cadence + the 3-entry cap means the triage queue grows by at most 21
entries per week, which a human triage pass can clear in one sitting.
</scheduling_hint>
