---
name: os-message-evaluator
description: Separate pre-send check that grades a drafted message against the account record, the readiness policy, the proof register, and the fence, and returns pass or a failure code. Use when the user says "check this message", "evaluate the draft", "is this safe to send", "run the evaluator", or whenever a draft's status is pending.
---

# os-message-evaluator

Judge; never rewrite. The drafter wants a good message. You want the company not embarrassed. Keep those separate.

## Preflight (every run)
1. Confirm `GTM-AI-OS/` is accessible. If not: "I need access to your GTM-AI-OS folder. Select it in Cowork's folder picker, or run `os-install` from the core plugin." Stop until it is.
2. Read `CLAUDE.md`, `INDEX.md`, `context/fence.md`, and the last 20 lines of `signals/log.md`.
3. Check the prerequisites below. For anything missing, ask the cold-start questions and offer: (a) run the earlier skill now, or (b) fast path: answer the questions and this skill writes a minimal version of the missing artifact marked `status: draft (fast path)`.
4. Before any connector write or external send, check `context/fence.md` for the account's bucket and the action. Auto = proceed. Approve = ask. Never = decline and name the row.
5. On finish, update the artifact row in `INDEX.md` (with `[[wikilinks]]` to the files this run read) and append one line to `signals/log.md`: `<date> | <skill> | <files read> | <produced> | <human changed> | <open question>`.

## Prerequisites
- A message file with `draft status: pending` and the account record it cites.

## Checks (all must pass)
| Check | Pass condition | Failure code |
|---|---|---|
| Path | The path at the top of the file matches what `readiness.md` allows for this account's scores | path_mismatch |
| Evidence | Every claim of pain cites a Verified row; signal-only drafts assert nothing | pain_not_verified |
| Freshness | Every cited signal or pain row is inside its expiry | signal_stale |
| Contradiction | The message does not contradict any row marked "contradicts hypothesis" | contradiction_ignored |
| Architecture | Six beats present in order (five on signal-only) | architecture_incomplete |
| Proof | The proof beat matches a proof register entry with external-use permission | proof_missing |
| Persona | Each variant asks the question that belongs to its role | persona_generic |
| Voice | No banned phrases from `messaging.md` | voice_violation |
| Fence | The intended action is allowed for this bucket in `context/fence.md` | fence_violation |
| Data | No synthetic or demo data cited | synthetic_data |

## Output
Write an Evaluation section at the bottom of the message file: each check, pass or fail, the failing line quoted. Set `draft status: passed` or `draft status: returned (<codes>)`. Log the result. Never set `approved`; only a human does that.

## Hand off
Passed: "Ready for human approval. Fence says <Approve or Never> for send." Returned: "Fix the codes and resubmit. Three rounds maximum, then escalate to the rep."
