ok:true is not a verdict

Every ork hook writes ok: true to hook-timing when it does not throw. #3801 showed what that hides: a verifier at ok:true, 2 ms for months, doing nothing. This page shows the two instruments that replace "did not throw" with "did its job", and what they found on their first run.

1. First run: 17 probes, three reds, all real

probeentry probedtrip fixtureday onenow
bash-catastrophic-rm-denysync-bash-dispatcherrecursive delete of rootdenydeny
bash-force-push-asksync-bash-dispatchergit push --forceaskask
bash-push-refspec-to-main-denysync-bash-dispatchergit push origin HEAD:main from feat/xsilentdeny
bash-pipe-to-shell-denysync-bash-dispatchercurl ... | bashdenydeny
egress-staged-download-run-asknetwork-egress-guardcurl -o s.sh && bash s.shaskask
compound-herestring-askcompound-command-validatorbash <<< "code"askask
write-file-guard-oversize-asksync-write-edit-dispatcher400-line source WriteupdatedInput onlyask
write-memory-budget-asksync-write-edit-dispatcher20 KB MEMORY.mdsilentask
agent-fable-pin-consent-asksync-task-dispatcherAgent with model claude-fable-5askask
agent-unknown-target-asksync-task-dispatchersubagent_type ork:no-such-agentaskask
cron-create-in-ci-blockcron-guardCronCreate with CI=trueblockblock
read-credential-file-denycredential-read-guardRead ~/.aws/credentialsdenydeny
elicitation-secret-field-blockelicitation-guardform schema with a password fieldblockblock
model-switch-to-fable-askmodel-switch-consentPreModelSwitch to claude-fable-5askask
stop-coverage-below-threshold-blockcoverage-threshold-gatecoverage-summary at 40%blockblock
stop-cross-instance-missing-tests-blockcross-instance-test-validatortwo untested exports, Stop payloadsilentxfail #3804
posttool-stale-import-blockstale-import-detectorthree importers of a rewritten moduleblockblock

Every probe also runs a control fixture one condition short, which must stay silent; a probe that cannot fail is caught by its own control. A fourth red on day one was the harness itself (bulk content expanded for files but not payload fields), which the controls could not catch and the direct sub-guard run did.

2. Why the two fixed ones were invisible

defectwhy no test saw itsince
sync-write-edit-dispatcher merged only additionalContext and updatedInput; a sibling's ask is continue:true, so neither short-circuited nor carriedfile-guard's own tests call file-guard, the dispatcher's tests mocked its siblings; nothing drove the pairfile-guard and context-file-budget-guard moved from deny to ask (#2947)
git-validator returned early when the session branch was not protected, so a refspec naming main was never examinedthe refspec tests exercise extractPushDestinations() in isolation; the guard's own comment described the intended verdict#3455 added explicit-destination awareness as an allow only

3. The telemetry half

hook-timing.jsonl lines now carry verdict: deny / ask / allow / defer from permissionDecision, block from continue:false, context when only context or an input rewrite came back, silent otherwise, error on a throw. A decisive hook that reports only silent across a week is either healthy and unprovoked or dead; the probes are how you tell.

before: ok:true ×2,140

after: silent ×2,081 · ask ×49 · deny ×10

The second bar is a sketch of the field's shape, not a measurement; the first real week of data lands after release.