From d03d4493bd772b14568fd163457f3371b84fab1f Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Fri, 1 May 2026 11:50:38 +0200 Subject: [PATCH 1/2] fix(blog-autopublish): use App-minted token instead of GITHUB_TOKEN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Org policy "Allow GitHub Actions to create and approve pull requests" is disabled, which silently kills `gh pr create` calls authed with GITHUB_TOKEN. The cron has been failing for two days running (#43, #45) with "GitHub Actions is not permitted to create or approve pull requests" — three scheduled posts (overdoing-the-verification-chain, variant-pruning-rust-mcdc, cross-language-lto) sat as drafts. Mint a token from the PulseEngine Actions Helper App (actions/create-github-app-token@v1) using the ACTIONS_BOT_APP_ID and ACTIONS_BOT_PRIVATE_KEY repository secrets. The App's installation grants Contents R/W + Pull requests R/W + Metadata R on this repo only — strictly narrower than what the org-disabled GITHUB_TOKEN would have had. App-minted tokens authenticate as the App, not as Actions, so the org-level restriction stays intact for the default token while this single workflow has the explicit grant it needs. Five surgical changes: - New "Mint App token" step before checkout - actions/checkout@v4 takes the App token (so credential helper uses it for `git push` later) - Four env: GH_TOKEN swaps (Ensure labels exist, Publish ready posts, Post / update status comment, Open failure issue) The existing permissions: block (contents/pull-requests/issues: write) stays as-is for clarity / defense in depth, even though we no longer use the default GITHUB_TOKEN in this job. Token expires in 1 hour; workflow timeout is 15 min, so no rotation logic needed. Trigger workflow_dispatch after merge to flush the three stuck posts in one run. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/blog-autopublish.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/blog-autopublish.yml b/.github/workflows/blog-autopublish.yml index 37eb3b4..1941da1 100644 --- a/.github/workflows/blog-autopublish.yml +++ b/.github/workflows/blog-autopublish.yml @@ -46,9 +46,23 @@ jobs: RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} REPO: ${{ github.repository }} steps: + # Mint a token from the PulseEngine Actions Helper App so this job + # can `gh pr create` despite the org policy that disables PR-creation + # for the default GITHUB_TOKEN. The App's installation grants + # contents: write + pull-requests: write + metadata: read on this + # repo only — strictly narrower than what GITHUB_TOKEN would have + # had with the org permission flipped. + - name: Mint App token + id: app_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ secrets.ACTIONS_BOT_APP_ID }} + private-key: ${{ secrets.ACTIONS_BOT_PRIVATE_KEY }} + - uses: actions/checkout@v4 with: fetch-depth: 0 + token: ${{ steps.app_token.outputs.token }} - uses: actions/setup-python@v5 with: @@ -61,7 +75,7 @@ jobs: - name: Ensure labels exist env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.app_token.outputs.token }} run: | # `gh label create --force` upserts (creates or updates), so this # step is idempotent and immune to a label being deleted manually. @@ -91,7 +105,7 @@ jobs: id: publish if: steps.scan.outputs.ready_count != '0' env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.app_token.outputs.token }} run: | set -euo pipefail published='[]' @@ -146,7 +160,7 @@ jobs: - name: Post / update status comment if: always() env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.app_token.outputs.token }} run: | set -euo pipefail @@ -179,7 +193,7 @@ jobs: - name: Open failure issue if: failure() env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.app_token.outputs.token }} run: | today=$(date -u +%Y-%m-%d) gh issue create \ From 0726d3305136e4eb84ac71e769a3f4c82e24500f Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Fri, 1 May 2026 15:52:40 +0200 Subject: [PATCH 2/2] publish: ship 3 stuck posts manually (cron blocked behind App-token PR) The autopublish cron has been blocked by org policy disallowing GITHUB_TOKEN PR creation. The fix (App-minted token) is in PR #46 but its CI is stuck queued. To not delay shipping further, flip draft manually on the 3 posts that should have published 2026-04-29 / 30 / 05-01: - overdoing-the-verification-chain (was due 2026-04-29) - variant-pruning-rust-mcdc (was due 2026-04-30) - cross-language-lto-three-quiet-barriers (was due today, 2026-05-01) Once PR #46 lands and the cron resumes, future posts publish on their date with no manual flip. Co-Authored-By: Claude Opus 4.7 (1M context) --- content/blog/2026-04-22-overdoing-the-verification-chain.md | 2 +- content/blog/2026-04-24-variant-pruning-rust-mcdc.md | 2 +- .../blog/2026-05-01-cross-language-lto-three-quiet-barriers.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/blog/2026-04-22-overdoing-the-verification-chain.md b/content/blog/2026-04-22-overdoing-the-verification-chain.md index 85ea377..8ee0131 100644 --- a/content/blog/2026-04-22-overdoing-the-verification-chain.md +++ b/content/blog/2026-04-22-overdoing-the-verification-chain.md @@ -2,7 +2,7 @@ title = "Overdoing the verification chain — and mapping it to six safety domains" description = "The prior posts argued for proofs and for traceability. This one shows the full chain, why I chose to overdo rather than undercommit, and where the stack earns credit across six safety domains — with an honest read on what still does not clear the bar." date = 2026-04-29 -draft = true +draft = false [taxonomies] tags = ["verification", "deep-dive"] authors = ["Ralf Anton Beier"] diff --git a/content/blog/2026-04-24-variant-pruning-rust-mcdc.md b/content/blog/2026-04-24-variant-pruning-rust-mcdc.md index 724da71..8b780d9 100644 --- a/content/blog/2026-04-24-variant-pruning-rust-mcdc.md +++ b/content/blog/2026-04-24-variant-pruning-rust-mcdc.md @@ -2,7 +2,7 @@ title = "MC/DC for AI-authored Rust is tractable — the variant-pruning argument" description = "The received wisdom is that Rust's pattern matching makes MC/DC harder than C. Under variant-managed AI-authored code, the opposite is true. Five layers of variant pruning, one oracle per layer, and a certification burden proportional to the single variant you ship — not the combinatorial product." date = 2026-04-30 -draft = true +draft = false [taxonomies] tags = ["verification", "process", "deep-dive"] authors = ["Ralf Anton Beier"] diff --git a/content/blog/2026-05-01-cross-language-lto-three-quiet-barriers.md b/content/blog/2026-05-01-cross-language-lto-three-quiet-barriers.md index 6424357..82e82a5 100644 --- a/content/blog/2026-05-01-cross-language-lto-three-quiet-barriers.md +++ b/content/blog/2026-05-01-cross-language-lto-three-quiet-barriers.md @@ -2,7 +2,7 @@ title = "Cross-language LTO on Cortex-M: three barriers and a wrong prediction" description = "We pushed LLVM cross-language LTO between verified Rust and Zephyr's C kernel. Three barriers nobody documents. Cleared them. Then measured — and the prediction we'd shipped was wrong by a lot. The story of what that taught us, and the framework for picking a regime when the data doesn't dominate." date = 2026-05-01 -draft = true +draft = false [taxonomies] tags = ["verification", "process", "deep-dive"] authors = ["Ralf Anton Beier"]