feat(dispatch): wire hypatia closed-loop contract (closes C15 estate blocker)#257
Open
hyperpolymath wants to merge 1 commit into
Open
feat(dispatch): wire hypatia closed-loop contract (closes C15 estate blocker)#257hyperpolymath wants to merge 1 commit into
hyperpolymath wants to merge 1 commit into
Conversation
…blocker)
Closes the estate-onboarding blocker C15 surfaced in the
"what stops echidna from running proof work across the estate" audit:
hypatia documents the dispatch-runner contract at
`docs/operations/dispatch-runner-contract.adoc`, but the gitbot-fleet
side that "pushes committed fixes to remotes" + reports outcomes back
was unwired. Without it, Bayesian confidence updating, auto-quarantine,
and re-scan verification all sit at :insufficient_data forever.
This wires the contract:
* New `hypatia_record_outcome` helper in `scripts/dispatch-runner.sh`
calls `mix hypatia.record_outcome --recipe --repo --file --outcome`
per the contract.
* Exit-code handling matches the contract exactly: 0 → continue,
2 → ::warning:: with optional rollback hint, anything else →
::error:: but never break the dispatch loop.
* Configured by three env vars:
HYPATIA_HOME path to the hypatia checkout
HYPATIA_OUTCOME_REPORT on (default) | off
HYPATIA_BATCH_ID when set, exit-2 surfaces a
`mix hypatia.rollback_batch` hint
* Best-effort: missing hypatia checkout, missing `mix`, empty
recipe_id all short-circuit to a silent no-op or one-line warning.
The dispatch loop never fails because of the closed-loop call.
* Existing JSONL outcome write is preserved (backwards compat for
consumers that read directly from `outcomes/YYYY-MM.jsonl`).
Outcome vocabulary mapping (shell → contract):
success → success
failure → failure
refused_license_* → false_positive (surfaces misfiring recipes to
auto-quarantine — directly
useful for the post-neurophone#99
licence-policy gate already in
this script)
anything else → skipped (no poisoning of recipe-health).
Test plan:
* `bash -n scripts/dispatch-runner.sh` clean.
* `tests/hypatia-record-outcome-smoke.sh` exercises the three
short-circuit paths (opt-out / missing $HYPATIA_HOME / empty
recipe_id) — 5/5 pass.
* End-to-end paths (exit 0/2/1 from mix) require a running hypatia
install and are covered by hypatia's own integration tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes the estate-onboarding blocker C15 from the 2026-06-03 audit: hypatia documents the dispatch-runner contract at
hypatia/docs/operations/dispatch-runner-contract.adoc, but the gitbot-fleet side that "pushes committed fixes to remotes" + reports outcomes was unwired. Without it, hypatia's Bayesian confidence updating, auto-quarantine, and re-scan verification all sit at:insufficient_dataforever — and the closed-loop verification metric from PR #309 never engages.What this wires
hypatia_record_outcomehelper inscripts/dispatch-runner.shcallsmix hypatia.record_outcome --recipe --repo --file --outcomeper the contract.0→ continue,2→::warning::with optional rollback hint, anything else →::error::but never break the dispatch loop.HYPATIA_HOME$REPOS_BASE/hypatiaHYPATIA_OUTCOME_REPORTonoffto skip mix calls (e.g. CI without Elixir)HYPATIA_BATCH_IDmix hypatia.rollback_batchhintmix, empty recipe_id all short-circuit to a silent no-op or one-line warning. The dispatch loop never fails because of the closed-loop call.outcomes/YYYY-MM.jsonl).Outcome vocabulary mapping (shell → contract)
successsuccessfailurefailurerefused_license_*false_positive— surfaces misfiring recipes to auto-quarantine, directly useful for the post-neurophone#99 licence-policy gate already in this scriptTest plan
bash -n scripts/dispatch-runner.shclean.tests/hypatia-record-outcome-smoke.shexercises the three short-circuit paths (opt-out / missing$HYPATIA_HOME/ emptyrecipe_id) — 5/5 pass.mix) require a running hypatia install and are covered by hypatia's own integration tests.Estate context
This PR is #3 of 5 in the C12/C14/C15/B7/D18 critical-blocker pass coming out of the echidna estate-scale audit.
🤖 Generated with Claude Code