Sweep stamp and pre-push hook — .githooks/pre-push (2026-09-07, gate removed 2026-09-30)
Operator decision: CI catches code; real tests run on the developer machine, which has every CLI
and key. A full npm run sweep (no --only / --security) records its verdict in
.local/selftest-stamp/<host>/<HEAD sha>.json. From 2026-09-07 the tracked pre-push hook refused a
push to main whose commit had no ok: true stamp from THIS host; on 2026-09-30 the operator removed
that check because the sweep made every push wait ~15 minutes. The sweep now runs on the operator's
word through /cyberine-project-selftest, and the stamp is the record of what was swept.
git commit ... # the stamp is keyed by the COMMITTED sha
npm run sweep # ... sweep stamp: .local/selftest-stamp/<host>/<sha>.json (ok -- ...)
node scripts/sweep-stamp.mjs host # the host token the stamp is keyed by
node scripts/sweep-stamp.mjs verify "$(git rev-parse HEAD)" # was this sha swept clean on this host (the skill's --sha-check)
git push origin main # the hook checks only the skip-ci token nowThe stamp carries sha, host, platform, at, the PASS/SKIP/FAIL counts, unexpectedSkips,
staleExpectations, dirty and ok. ok is true only for a clean pass on a clean tree
(git status --porcelain --untracked-files=no empty): a dirty tree still gets a stamp, marked
ok: false, so the reason is visible rather than silently absent.
The stamp is bound to the machine that swept it (kr0q2, 2026-09-16). .local/ is rsync-mirrored
between machines, so a stamp arriving from another machine would otherwise let this one push a SHA
it never swept. host is os.hostname() lowercased with anything outside [a-z0-9._-] replaced by
-; sweep-stamp.mjs verify refuses, naming the host involved, a stamp that exists only under another host's
directory, a legacy flat .local/selftest-stamp/<sha>.json from before this change, a stamp in this
host's directory whose recorded host is another machine's or missing, and a stamp whose recorded
sha differs from its filename. Guarded by npm run selftest:stamp-host-binding, which drives
sweep-stamp.mjs verify in a throwaway repo and checks that the hook no longer reads the stamp.
The hook is wired by npm run prepare (git config core.hooksPath .githooks), which npm ci /
npm install run automatically; a fresh clone gets it on first install. CI runs npm ci too and
the setting is harmless there (nothing pushes from a runner).
The same hook guards against a silently skipped run: GitHub scans the WHOLE message of the push's
head commit for skip tokens, body included, and creates no run at all when it finds one. Commit
cfa184c (2026-09-07) quoted the token in its body while documenting this very escape hatch and
produced zero runs. The hook now refuses a push to main whose head commit carries a token while the
push changes a path a gate reads (src/, scripts/, site/, docs/, .github/, package*.json,
USAGE.md, CLAUDE.md, .claude/rules/push-gates.md); a token on a doc-only commit still passes.
Positive-controlled against the real commits: cfa184c refused, the doc-only a1f0d57 accepted.
Known limitations and deferred work: with the gate gone, a push to main can land code no sweep has
run on; CI still runs typecheck, lint and the static drift smokes, and a runtime regression surfaces
at the next sweep the operator asks for. Nothing verifies that the sweep ran on THIS
machine's real environment rather than a stripped one — the stamp records the platform and host, not
the installed CLI set. The host binding trusts os.hostname(): two machines sharing a hostname share
a stamp directory, and a machine whose hostname changes (renamed, or a network-assigned name) must
re-sweep before it can push. Stamps written before 2026-09-16 sit flat in .local/selftest-stamp/
and are never accepted again; nothing deletes them.
Security-gate drift check — npm run selftest:gate-list-drift (T707, retargeted 2026-09-07)
The security/data-integrity smoke list froze on 2026-08-22 in two hand-maintained copies (the CI gate loop and the git-workflow rule's precondition 3), and ten security smokes shipped afterwards...
Sweep flake ledger — npm run sweep:flakes (kdpxk, 2026-09-28)
Every sweep, full or partial, appends one line to .local/selftest-stamp/<host>/ledger.jsonl: at, sha, host, scope (full / security / only, with selected for a partial run), the pass count,...