feat(self-check): command-restates-standard lint (consistency category, VERSION 1.4.2)

Task 3 leftover. Adds a 'consistency' category to /self-check that catches a standard
drifting back into restating/contradicting the command that owns the rule -- the Syncro
timers failure mode (standard said 'always timer' while /syncro said 'outlier only').

Deterministic half: each manifest.command_standard_links pair's standard must still carry
its defer-to-SSOT pointer (must_reference regex). Lost pointer = WARN. Seeded with
syncro-billing (time-entry-protocol.md -> /syncro). Semantic contradiction pass delegated
to the model in SKILL.md, mirroring check_memory. Verified PASS; negative-tested.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-08 08:29:58 -07:00
parent edcbc5f7ea
commit e180a463e2
5 changed files with 72 additions and 1 deletions

View File

@@ -58,3 +58,12 @@ or old harness during a heterogeneous rollout. See
machine; budget WARN trips correctly on a synthetic over-budget value.
- Also reconciled the remaining "GrepAI first" docs (standard + CODING_GUIDELINES) with the
wiki-first recall hierarchy (started in CLAUDE_EXTENDED).
## 1.4.2 — 2026-06-08 (Task 3 leftover: command-restates-standard lint)
- /self-check gained a `consistency` category — the command-restates-standard lint. Deterministic
half: for each manifest.command_standard_links pair, the standard must still carry its
defer-to-SSOT pointer to the owning command; a lost pointer WARNs (the standard likely drifted
back into restating the command — the Syncro-timers failure mode). Seeded with the syncro-billing
link (time-entry-protocol.md -> /syncro). Semantic contradiction pass (read both, judge actual
conflict) delegated to the model in SKILL.md, mirroring the memory pass. Verified PASS; negative-
tested (WARN fires when the pointer is removed). New pairs: add to manifest.command_standard_links.

View File

@@ -1 +1 @@
1.4.1
1.4.2

View File

@@ -82,6 +82,7 @@ SELFCHECK_TS="$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
| **duplicates** | command/skill names present in BOTH the repo and `~/.claude`. Divergent content = WARN (the "same `/cmd`, different behaviour on the Mac" bug); identical = INFO (redundant, will drift). CRLF-only differences are ignored. |
| **memory** | `MEMORY.md` index exists; no orphaned memory files; manifest-declared contradiction patterns (see semantic pass below). Never FAILs the grade. |
| **harness** | the 1.4.0 invariants (read-only): VERSION marker present + not older than `manifest.harness.min_version`; **skill-registry description budget** (sum of all SKILL.md `description:` fields under `registry_desc_budget_chars` — WARN on regrowth); global deploy targets `~/.claude/skills` + `~/.claude/commands` populated (the "Mac wiped global skills" failure); `harness-guard.sh` present + wired into `sync.sh`; core scripts parse (`bash -n` on sync/guard/now-phoenix); `now-phoenix.sh --date` emits a valid date. Budget/min-version/script-list are tunable in `manifest.harness`. |
| **consistency** | the **command-restates-standard** lint (deterministic half): for each `manifest.command_standard_links` pair, the standard must still contain its defer-to-SSOT pointer to the owning command. A lost pointer = WARN (the standard likely drifted back into restating the command — the Syncro-timers failure mode). The semantic contradiction judgement is delegated to the model (see below). |
| **vault** | vault repo exists; sops+age present; `vault.sh list` succeeds (decrypt wired). |
| **connectivity** | coord API (required), main API + internal Gitea (advisory; off-network is OK). |
@@ -110,6 +111,26 @@ Ollama Tier-0 per the house rules; Claude reviews the result):
Genuinely machine-specific guidance in a *shared* memory is the usual culprit —
the fix is to scope it ("on Windows…") or split it, not to globally flip it.
### Semantic pass 2 — command vs standard contradiction
The `consistency` category only checks that the defer-to-SSOT *pointer* is present.
Whether a command and its standard actually **say contradictory things** is a
judgement task — do it the same way (Ollama Tier-0 for the read/classify, Claude
reviews):
1. For each `manifest.command_standard_links` pair, read BOTH the standard and the
owning command it points to.
2. Flag any rule the standard states that **conflicts** with the command (e.g. the
standard mandates a timer for routine billing while `/syncro` says line-item is
normal and timers are outlier-only — the original drift this lint exists to catch).
3. Report: the topic, the conflicting claims (quote both sides), and which one is the
SSOT. **Do not edit** — surface for the operator; the SSOT (the command) wins, so
the fix is almost always to correct the standard, not the command.
New links are cheap to add — drop another `{topic, standard, must_reference, why}`
into `manifest.command_standard_links` whenever a command and a standard speak to the
same rule.
## Fleet self-remediation loop (machines fix themselves)
We never fix a remote machine. The flow is:

View File

@@ -18,6 +18,16 @@
"guard_wired_in": ".claude/scripts/sync.sh"
},
"command_standard_links": [
{
"topic": "syncro-billing",
"standard": ".claude/standards/syncro/time-entry-protocol.md",
"must_reference": "syncro\\.md|single source of truth",
"why": "the time-entry standard must DEFER to the /syncro command (one SSOT), not restate billing mechanics. A past drift had the standard say 'always timer' while the command said 'outlier only' — losing the pointer is the early warning of that re-drift."
}
],
"command_standard_links_note": "Deterministic half of the command-restates-standard lint: each linked standard must contain a defer-to-SSOT pointer (must_reference, a grep -iE regex). A WARN means the standard may have drifted back into restating/contradicting the command. The SEMANTIC contradiction judgement (read both files, decide if they actually conflict) is delegated to the model in SKILL.md, mirroring the memory contradiction pass.",
"required_tools": [
{ "name": "bash", "why": "hooks, scripts, sync, vault wrapper" },
{ "name": "git", "why": "repo + submodules + Gitea sync" },

View File

@@ -661,6 +661,36 @@ check_harness_smoke() {
fi
}
# ---------------------------------------------------------------------------
# CHECK: command <-> standard consistency (the "command-restates-standard" lint).
# Deterministic core only: for each manifest-declared (command, standard) link,
# verify the standard still contains its defer-to-SSOT pointer (must_reference).
# A standard that loses the pointer has likely drifted back into RESTATING the
# command's rules -- the exact failure mode behind the Syncro timers contradiction
# (standard said 'always timer' while /syncro said 'outlier only'). The SEMANTIC
# pass (read both, judge actual contradiction) is delegated to the model in
# SKILL.md, mirroring check_memory.
# ---------------------------------------------------------------------------
check_command_standard() {
local has; has="$(jq -r '(.command_standard_links // []) | length' "$MANIFEST" 2>/dev/null)"
[ "${has:-0}" -gt 0 ] 2>/dev/null || return
local topic stdf ref why p
while IFS=$'\t' read -r topic stdf ref why; do
[ -n "$topic" ] || continue
p="$REPO_ROOT/$stdf"
if [ ! -f "$p" ]; then
emit "consistency.$topic" consistency WARN "standard missing for '$topic': $stdf" \
"Restore via /sync, or remove the link from manifest.command_standard_links"
elif grep -qiE "$ref" "$p" 2>/dev/null; then
emit "consistency.$topic" consistency PASS "'$topic' standard defers to the owning command (SSOT pointer present)"
else
emit "consistency.$topic" consistency WARN \
"'$topic' standard ($stdf) lost its defer-to-SSOT pointer ($why)" \
"Re-add the pointer to the owning command, and confirm the standard does NOT restate or contradict it"
fi
done < <(jq -r '(.command_standard_links // [])[] | [.topic, .standard, .must_reference, .why] | @tsv' "$MANIFEST")
}
# ---------------------------------------------------------------------------
# Build the census JSON from accumulated results
# ---------------------------------------------------------------------------
@@ -846,6 +876,7 @@ check_skills_commands
check_duplicates
check_memory
check_harness_smoke
check_command_standard
check_vault
check_connectivity