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:
@@ -58,3 +58,12 @@ or old harness during a heterogeneous rollout. See
|
|||||||
machine; budget WARN trips correctly on a synthetic over-budget value.
|
machine; budget WARN trips correctly on a synthetic over-budget value.
|
||||||
- Also reconciled the remaining "GrepAI first" docs (standard + CODING_GUIDELINES) with the
|
- Also reconciled the remaining "GrepAI first" docs (standard + CODING_GUIDELINES) with the
|
||||||
wiki-first recall hierarchy (started in CLAUDE_EXTENDED).
|
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.
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.4.1
|
1.4.2
|
||||||
|
|||||||
@@ -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. |
|
| **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. |
|
| **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`. |
|
| **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). |
|
| **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). |
|
| **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 —
|
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.
|
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)
|
## Fleet self-remediation loop (machines fix themselves)
|
||||||
|
|
||||||
We never fix a remote machine. The flow is:
|
We never fix a remote machine. The flow is:
|
||||||
|
|||||||
@@ -18,6 +18,16 @@
|
|||||||
"guard_wired_in": ".claude/scripts/sync.sh"
|
"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": [
|
"required_tools": [
|
||||||
{ "name": "bash", "why": "hooks, scripts, sync, vault wrapper" },
|
{ "name": "bash", "why": "hooks, scripts, sync, vault wrapper" },
|
||||||
{ "name": "git", "why": "repo + submodules + Gitea sync" },
|
{ "name": "git", "why": "repo + submodules + Gitea sync" },
|
||||||
|
|||||||
@@ -661,6 +661,36 @@ check_harness_smoke() {
|
|||||||
fi
|
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
|
# Build the census JSON from accumulated results
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
@@ -846,6 +876,7 @@ check_skills_commands
|
|||||||
check_duplicates
|
check_duplicates
|
||||||
check_memory
|
check_memory
|
||||||
check_harness_smoke
|
check_harness_smoke
|
||||||
|
check_command_standard
|
||||||
check_vault
|
check_vault
|
||||||
check_connectivity
|
check_connectivity
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user