Support audited repo verbs from detached CI merge commits #1632

Closed
opened 2026-08-01 05:26:36 +00:00 by coilyco-ops · 0 comments
Member

Problem

Ward refuses repository verbs in a standard Forgejo pull-request checkout because actions/checkout@v4 leaves the synthetic merge commit at detached HEAD.

Observed in infrastructure PR 710:

Reproduction

  1. Check out commit 4c0d32f9d7790b473b332041f9a9b27dce124bc7 detached.
  2. Run ward exec ansible-sync-test. Ward refuses before executing the test.
  3. Put the same commit on a local branch tracking origin/main.
  4. Run the same Ward verb. All 13 tests pass.
  5. Run ward exec pre-commit. The full suite passes.

Impact

Ward cannot run repository verbs against the standard synthetic pull-request merge commit. Consumer workflows must bypass Ward or synthesize a local tracking branch. This prevents merge-result validation across Ward-enabled pull-request workflows.

The current workaround is to create a temporary local branch at the checked-out merge commit and give it an upstream such as the fetched base branch. That preserves the tested merge commit, but it is consumer boilerplate and exposes an implementation detail of the audit gate.

Desired contract

Support detached CI commits without weakening workstation clean-and-synced safety:

  • Admit detached HEAD only under an explicit, validated CI context.
  • Record immutable HEAD SHA plus provider repository, event ref, base, head, and run attribution in the audit row.
  • Require a clean tree and validate the relevant commit relationships.
  • Fail closed when CI metadata is missing or inconsistent.
  • Cover Forgejo pull-request merge commits and ordinary branch pushes in tests.

Acceptance

  • ward exec runs from Forgejo default pull-request checkout when evidence is sufficient.
  • A local detached checkout without trusted CI evidence remains refused.
  • The audit row preserves commit and pull-request/run attribution.
  • Existing named-branch behavior remains unchanged.
  • The exec-verb contract and feature inventory describe CI detached-checkout support.
## Problem Ward refuses repository verbs in a standard Forgejo pull-request checkout because actions/checkout@v4 leaves the synthetic merge commit at detached HEAD. Observed in infrastructure PR 710: * PR: https://forgejo.coilysiren.me/coilyco-flight-deck/infrastructure/pulls/710 * Failing run: https://forgejo.coilysiren.me/coilyco-flight-deck/infrastructure/actions/runs/1973 * ward exec ansible-sync-test exits 2 before command execution with: ward: refusing repo verb "repo.ansible-sync-test" - HEAD is detached (no branch) * Checkout and dependency sync pass. * The separate secret scan passes. * Recent pull-request lint runs show the same failure, while main push lint runs pass. ## Reproduction 1. Check out commit 4c0d32f9d7790b473b332041f9a9b27dce124bc7 detached. 2. Run ward exec ansible-sync-test. Ward refuses before executing the test. 3. Put the same commit on a local branch tracking origin/main. 4. Run the same Ward verb. All 13 tests pass. 5. Run ward exec pre-commit. The full suite passes. ## Impact Ward cannot run repository verbs against the standard synthetic pull-request merge commit. Consumer workflows must bypass Ward or synthesize a local tracking branch. This prevents merge-result validation across Ward-enabled pull-request workflows. The current workaround is to create a temporary local branch at the checked-out merge commit and give it an upstream such as the fetched base branch. That preserves the tested merge commit, but it is consumer boilerplate and exposes an implementation detail of the audit gate. ## Desired contract Support detached CI commits without weakening workstation clean-and-synced safety: * Admit detached HEAD only under an explicit, validated CI context. * Record immutable HEAD SHA plus provider repository, event ref, base, head, and run attribution in the audit row. * Require a clean tree and validate the relevant commit relationships. * Fail closed when CI metadata is missing or inconsistent. * Cover Forgejo pull-request merge commits and ordinary branch pushes in tests. ## Acceptance * ward exec runs from Forgejo default pull-request checkout when evidence is sufficient. * A local detached checkout without trusted CI evidence remains refused. * The audit row preserves commit and pull-request/run attribution. * Existing named-branch behavior remains unchanged. * The exec-verb contract and feature inventory describe CI detached-checkout support.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/ward#1632
No description provided.