Skip to content

feat(ci): report Baton verdicts to GitHub (commit-status bridge) + nix capability - #7

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/ci-report-to-github
Jun 16, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
feat/ci-report-to-github

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Closes the last loop docs/ci-check-baton.adoc names ("Publication ... a separate cloud-native bridge"): getting an owned-compute CI verdict back onto a GitHub PR so a required status check is satisfied without a GitHub-hosted runner (zero Actions minutes).

  • Bag.GitHubBridge — posts a verdict as a GitHub commit status via gh (dependency-free). Status, not check-run: a PAT can write statuses (which satisfy a required context) but not check-runs (App-only). Discharges Bag.ActionResult's {:owes, :github_required_check}. (6 tests)
  • mix bag.report — the dispatcher: sweep on owned compute → report_sweep each verdict to the commit from GITHUB_REPOSITORY/GITHUB_SHA. (context_map_from tested)
  • nix capability — across all three synced layers (Protocol.idr capToTag=13, estate.zig enum/fromString, mesh.ex) + mesh-server-1 tagged. idris2 + zig build green; match mesh-server-1 nix → 0; fail-safe intact.
  • docs/ci-report-to-github.adoc — trigger recipe (thin GHA dispatcher or owned webhook) + branch-protection cut-over. Worked example: hyperpolymath/snifs (its ci-checks.exs lives in that repo, not here).

Verification

  • New: 8 tests pass (github_bridge_test 6 + bag_report_test 2).
  • idris2 --build bag.ipkg exit 0; zig build exit 0; bag_of_actions match mesh-server-1 nix exit 0; bogus cap exit 1.
  • Full suite: 32 tests, 4 failures that are pre-existing + unrelated (a zig fmt --check src/estate.zig fixture expects a fail but the file is now well-formatted — flagged, not touched here).

Not in this PR (genuine infra, owner-provisioned)

A reachable nix-capable node with the toolchain + a repo checkout, the trigger (SSH dispatcher or webhook), and the branch-protection cut-over to the bag / … contexts. Until then, mix bag.report runs on demand from the CLI.

🤖 Generated with Claude Code

Close the last loop named in docs/ci-check-baton.adoc: publish an owned-compute CI verdict to a GitHub PR so a *required* status check is satisfied without a GitHub-hosted runner (zero Actions minutes).

- Bag.GitHubBridge: post a verdict as a commit STATUS via the gh CLI (dependency-free). Status not check-run because a PAT can write statuses (which satisfy a required context) but not check-runs (App-only). Discharges the {:owes, :github_required_check} residue. (6 tests) - mix bag.report: the dispatcher — sweep on owned compute, then report_sweep each verdict to the commit from GITHUB_REPOSITORY/GITHUB_SHA. (context_map_from tested) - nix capability across all three synced layers (Protocol.idr capToTag=13, estate.zig enum/fromString, mesh.ex) + mesh-server-1 tagged; idris2 + zig build green, match mesh-server-1 nix = 0, fail-safe intact. - docs/ci-report-to-github.adoc: trigger recipe + branch-protection cut-over.

Pre-existing + unrelated: 4 suite failures (a zig fmt --check src/estate.zig fixture expects fail but the file is now well-formatted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@hyperpolymath
hyperpolymath merged commit aca3c79 into main Jun 16, 2026
@hyperpolymath
hyperpolymath deleted the feat/ci-report-to-github branch June 16, 2026 15:55
hyperpolymath added a commit that referenced this pull request Jun 29, 2026
…rd-close; removes banned nix) (#11)

## bag-of-actions → production readiness: Phases 0–1.5 + partial Phase 2

Lands the prod-readiness work that had accumulated, unpushed, on
`feat/prod-readiness-phase0` (rebased onto current `main`, commit series
preserved, linear history). Closes the live security holes from the
production-readiness audit **and** removes the banned `nix` capability
that `main` currently ships.

### What's in it
- **Phase 0 — foundations:** `src/crypto.zig` + `src/store.zig`
extracted from `main.zig` (pure refactor); `mix release` + fail-closed
`Bag.Config` (gated to prod boot — test/dev stay green); de-templated
`Justfile` (real `build`/`test`/`release` + `estate-sync` rosters
guard); docs reconciled honestly (anti-overclaim).
- **Phase 1 — security hard-close (the live exploit):** removed the
hardcoded **dev-HMAC-key fallback** → `BAG_ATTEST_KEY` mandatory (≥32B)
or refuse (exit 78); **`BAG-CHECK-BATON v2`** envelope binding `mode` +
`key_id`; `BAG_MODE` (prod-default, fail-closed); **mandatory ed25519**
signing + verification (no HMAC-only / unsigned acceptance).
- **Phase 1.5 — bridge greening gate:** `Bag.GitHubBridge` refuses to
post a green status unless the verdict is `mode=prod` +
`ed25519:verified` — a dev/laptop node can never green a required check
(+ 138-line test).
- **Phase 2 (partial):** `guix/manifest.scm` + `guix/bootstrap.sh`
(reproducible node toolchain), verified on a real `mesh-server-1`.
- **Fixes a live estate-policy violation:** removes the banned `nix`
capability from `src/estate.zig` / `Protocol.idr` / `Estate.idr` (Guix
is canon). `main` currently ships it via the PR #7 bridge merge; this
lands the removal.

### Verified green (rebased tree, run not asserted)
- `zig build` ✓ (+ `zig-out/lib/zig_fmt.wasm` installed)
- `idris2 --typecheck verification/proofs/bag.ipkg` ✓ (4 modules)
- `cd bag && mix test` → **1 doctest, 35 tests, 0 failures**
- `./scripts/ci-baton-demo.sh` → step-0 fail-closed (no key → exit 78),
pass/fail/suspended/pass, tamper rejected two ways (hmac + unsigned)
- `just estate-sync` → "all three estate manifests agree"

### Not in this PR (forward roadmap)
Phase 2-finish (per-node Guix configs, laptop as 2nd node, pilot
branch-protection cut-over), Phase 3 (durable store / claim-lease-commit
registry / hash-chained ledger + custody chain / SSH-mailbox transport /
dynamic roster / conformance gate), Phase 4 (zero-GHA webhook +
observability), Phase 5 (Wasm linear-memory snapshot migration), Phase 6
(estate rollout + OSS scaffolding). Plan:
`~/.claude/plans/woolly-zooming-gizmo.md`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant