Merge Orchestration · BatonEmitter (bag-of-actions mesh actuation backend)#500
Merged
Conversation
…e bag-of-actions mesh
The alternative actuation backend to merge-decisions.jsonl, built against
bag-of-actions' REAL API (read by public clone; the repo is not in this
session's MCP scope so this is hypatia-side only).
* Bag.Mesh.submit_planned(spec, budget) takes %{check_id, command, required_cap,
mutating?, risk?}; the planner routes to the cheapest capable node and GATES
mutating:true work on a verifier -- that is the independent re-verification.
* A merge is just command=[gh, pr, merge, N, --repo, R, --<method>] carrying
required_cap="secret-access" -- the capability ONLY mesh-github-runner holds
in the estate nodes.scm (the token-bearer). The brain's node lacks it, so the
Baton cannot run on the brain and migrates to the runner: the token-free-brain
invariant expressed as capability routing. No bag-of-actions changes needed.
* Hypatia.MergeOrchestration.BatonEmitter.to_spec/2 (pure) -> the submit_planned
spec, carrying lease_id + route + rationale as the trust/residue link;
emit/2 submits one Baton per ARMED Loop entry. The Bag.Mesh call is late-bound
(apply/3) + injectable, so this stays compile-decoupled from bag-of-actions and
the logic tests run without it.
74 ExUnit (was 71): +3 BatonEmitter (spec shape + gh-flag/risk mapping + emit
filters to armed only). 0 failures, mix-format-clean, scanner-clean. LEDGER
v0.10.0. Companion to the design doc in #498.
🔍 Hypatia Security ScanFindings: 42 issues detected
View findings[
{
"reason": "Repository has 5 non-main remote branch(es). Policy: single main branch only.",
"type": "GS007",
"file": ".",
"action": "delete_remote_branches",
"rule_module": "git_state",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "src/ui/gossamer/README.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "scripts/ci-tools/Cargo.toml",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "scripts/bench-tools/Cargo.toml",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "ffi/zig/README.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/reports/audit/audit-2026-04-15-post.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/github-registry.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/github-registry.adoc",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/integration/a2ml-k9.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
},
{
"reason": "Code scanning (Hypatia): hypatia/structural_drift/SD022 -- Hypatia structural_drift: SD022 -- 11 day(s) old",
"type": "CSA001",
"file": "docs/architecture/system-integration.md",
"action": "review",
"rule_module": "code_scanning_alerts",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jun 14, 2026
…:baton|:both) (#501) Finishes the live bag-of-actions wiring for the merge-orchestration runtime (the BoA follow-on tracked in `.machine_readable/merge-orchestration/LEDGER.a2ml`). ## What - `Loop.run/1` gains `:actuation` — `:manifest` (default) | `:baton` | `:both`. `:baton` submits one Baton per **armed** entry via `BatonEmitter.emit/2`, late-bound to `Bag.Mesh.submit_planned(spec, budget)` so a `:manifest`-only run never references `Bag.*` (compile-decoupled; no new dep). - Threaded through `Scheduler.cycle` and `mix hypatia.merge_orchestrate --actuation`. - **Two interop fixes in the as-merged `BatonEmitter` (#500)**, verified against bag-of-actions' real source — each would otherwise make every merge Baton fail: - `required_cap "secret-access"` → `"secret_access"` (the Zig bridge / `Bag.Planner` tag; a hyphenated tag is unprovable → routes to no node). - `to_spec` now carries a `:verifier`, so a mutating merge passes the planner's mutation gate instead of `{:rejected, :mutation_requires_verifier}`. ## Token-free brain The brain only emits/reads. `required_cap "secret_access"` is held **only** by the `mesh-github-runner` node in bag-of-actions' estate, so every merge Baton migrates off the brain to the runner — the token-free-brain invariant as capability routing. ## Tests - `+4` `Loop`/`Scheduler` `:actuation` tests; `baton_emitter_test` updated. - `mix test test/merge_orchestration/` → **81 tests, 0 failures**. - Full suite: the ~14 failures are pre-existing and unrelated (workflow-audit count drift, missing `:proof_model_retrain_count` metric, watcher `:already_started` isolation) — identical with this branch reverted. Cross-repo counterpart: hyperpolymath/bag-of-actions `claude/peaceful-pascal-IRlgq` (brain node + end-to-end test). `BatonEmitter.to_spec` output matches that PR's routed spec byte-for-byte. Core-tier → **draft for owner review** (not auto-armed). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (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.
BatonEmitter — actuate armed merges on the bag-of-actions mesh
Item #2 of what you picked: the real bag-of-actions integration. Since the repo still isn't in this session's MCP scope (your grant applies to a new session; the
add_repotool isn't available here), I read its real API by publicgit cloneand built the integration hypatia-side — which is where it belongs anyway.What the real API turned out to be
Bag.Mesh.submit_planned(spec, budget)takes%{check_id, command, required_cap, mutating?, risk?}; the planner routes to the cheapest capable node and gatesmutating: truework on a verifier — which is the independent re-verification. So a merge needs no custom Ephapax action: it's just acommand(gh pr merge …) carryingrequired_cap: "secret-access"— the capability onlymesh-github-runnerholds in the estatenodes.scm(the token-bearer). The brain's node lacks it, so the Baton can't run on the brain and migrates to the runner: the token-free-brain invariant expressed as capability routing. No bag-of-actions changes needed.Hypatia.MergeOrchestration.BatonEmitterto_spec/2(pure) → thesubmit_plannedspec, carryinglease_id+route+rationaleas the trust/residue link.emit/2→ submits one Baton per armedLoopentry (gate{:armed, lease}); deferred/flagged entries are skipped. TheBag.Meshcall is late-bound (apply/3) and injectable, so this stays compile-decoupled from bag-of-actions and the logic tests run without it.This is the alternative actuation backend to
merge-decisions.jsonlfrom the #498 design doc — now real, not just sketched.Testing (actual, not looks-right)
74 ExUnit, 0 failures (was 71), mix-format-clean, scanner-clean:
The +3 BatonEmitter tests: the spec shape (check_id,
gh pr mergecommand,required_cap: "secret-access",mutating: true, attestation), the method→gh-flag + aggressive-pool→:high-risk mapping, and thatemitsubmits only armed entries (via an injectedsubmit).Scope / what's left on BoA
lib/, your review.emitinto the liveLoopas the actuation backend (alongsidewrite_manifest) and register hypatia as a mesh node — no new emitter logic.LEDGER
v0.10.0records the real-API findings + this build.Generated by Claude Code