Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0b3faac
feat: transplant native execution implementation onto merged plan
JAORMX Sep 25, 2026
6abcec2
fix(execution): enforce native Helm lifecycle retirement
JAORMX Sep 24, 2026
27b7506
fix: align native execution with harness context contracts
JAORMX Sep 25, 2026
c962442
fix: preserve independent context across native session publication
JAORMX Sep 25, 2026
248258c
test: tighten harness context review coverage
JAORMX Sep 25, 2026
9827b51
docs: clarify native PVC context exclusion
JAORMX Sep 25, 2026
2a11e1a
fix(server): acquire native execution for persisted approvals
JAORMX Sep 25, 2026
0b399f4
fix(server): retain native claims until shutdown drain
JAORMX Sep 25, 2026
4baff8c
fix(mecatui): classify startup run failures without leaking details
JAORMX Sep 25, 2026
f0895c2
feat(mecatui): add exact pending-approval client controls
JAORMX Sep 25, 2026
c34fc04
feat(mecatui): recover ordinary pending approvals on exact resume
JAORMX Sep 25, 2026
9e5024f
fix(mecatui): preserve recovery history and exact control correlation
JAORMX Sep 25, 2026
ce9d9df
fix(mecatui): retire recovery watchers and reconcile resumed tools
JAORMX Sep 25, 2026
c4e7695
fix(mecatui): follow native recovery telemetry through the TUI
JAORMX Sep 25, 2026
2f4656f
fix(server): preserve awaiting handoffs in durable shutdown history
JAORMX Sep 25, 2026
feab6ec
fix(mecatui): tolerate session metadata during exact-run recovery
JAORMX Sep 25, 2026
b0949cc
docs: explain pending approval recovery and operator limits
JAORMX Sep 25, 2026
a77af75
fix(mecatui): preserve recovery drafts when exiting pending controls
JAORMX Sep 25, 2026
b86d457
refactor(mecatui): separate recovery lifecycle handlers
JAORMX Sep 25, 2026
a2f387f
fix: retain current session creation contracts after rebase
JAORMX Sep 25, 2026
91da4b6
fix(server): admit event projection before blocking log writes
JAORMX Sep 25, 2026
f912c27
fix(server): retain native claim lifecycle across exact plan continua…
JAORMX Sep 25, 2026
12a44ad
test(server): use tagged switches for native plan outcomes
JAORMX Sep 25, 2026
e7470cb
fix: compose native execution with microvm placement
JAORMX Sep 26, 2026
6972c6d
test(server): distinguish placement collision from known retry
JAORMX Sep 26, 2026
05c4f41
fix(ci): compose release validation guards
JAORMX Sep 26, 2026
59cc99f
fix(ci): require exact release revision agreement
JAORMX Sep 26, 2026
b7bf9fa
docs: resolve MicroVM ADR identity collision
JAORMX Sep 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions .github/scripts/microvm-ci-release_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,18 @@ import sys

workflow = open(sys.argv[1], encoding="utf-8").read().splitlines()
jobs = {}
job_lines = {}
current = None
for line in workflow:
match = re.fullmatch(r" ([A-Za-z0-9_-]+):", line)
if match:
current = match.group(1)
jobs[current] = []
job_lines[current] = []
continue
if current is None:
continue
job_lines[current].append(line)
match = re.fullmatch(r" needs: (.+)", line)
if not match:
continue
Expand All @@ -160,10 +163,27 @@ def reaches_validation(job, seen=None):
seen.add(job)
return any(reaches_validation(dep, seen) for dep in jobs.get(job, []))

for job, lines in job_lines.items():
for producer in re.findall(r"needs\.([A-Za-z0-9_-]+)\.outputs\.", "\n".join(lines)):
if producer not in jobs[job]:
raise SystemExit(f"job {job} reads outputs without directly needing {producer}")

validation = "\n".join(job_lines["validate-release-ref"])
assert ' needs: guard' in validation
assert ' ref: ${{ github.sha }}' in validation
assert ' run: test "$(git rev-parse HEAD)" = "${GITHUB_SHA}"' in validation
assert ''' - name: Assert guard and immutable run commits agree
env:
RELEASE_COMMIT: ${{ needs.guard.outputs.commit }}
run: test "$(git rev-parse HEAD)" = "${RELEASE_COMMIT}"''' in validation

for job in sorted(name for name in jobs if name == "publish" or name.startswith("publish-")):
if not reaches_validation(job):
raise SystemExit(f"publishing job {job} bypasses validate-release-ref")
PY
# Exercise the real guard and validator agreement step with divergent on-main
# commits; counting checkout producers alone cannot establish revision authority.
sh "$repo_root/.github/scripts/release-tag-guard_test.sh"
# GoReleaser uploads to the release created above without replacing its notes.
require 'mode: keep-existing' "$goreleaser"

Expand Down Expand Up @@ -197,13 +217,15 @@ test "$(printf '%s\n' "$assemble_bundle" | grep -Fc 'signing_ref="${{ needs.vali
require 'release.yml@${signing_ref}' "$release"
checkout_count=$(grep -c 'uses: actions/checkout@' "$release")
bound_checkout_count=$(grep -c 'ref: ${{ github.sha }}' "$release")
version_checkout_count=$(grep -c 'ref: ${{ env.VERSION }}' "$release")
verified_commit_checkout_count=$(grep -c 'ref: .*needs.guard.outputs.commit' "$release")
trusted_guard_checkout_count=$(grep -c 'ref: refs/heads/main' "$release")
head_assertion_count=$(grep -c 'run: test "$(git rev-parse HEAD)" = "${GITHUB_SHA}"' "$release")
# The guard checkout validates the requested release tag is on main, and the CLI
# publisher checks out that same tag so GoReleaser can inspect tag history; every
# other release checkout remains bound to the workflow SHA and immediately asserts it.
test "$version_checkout_count" -eq 2
test "$checkout_count" -eq "$((bound_checkout_count + version_checkout_count))"
# The guard implementation is checked out once from protected main. Jobs that need
# tag history use the guard's verified commit; all other publishing checkouts are
# bound to the workflow SHA and immediately assert it.
test "$trusted_guard_checkout_count" -eq 1
test "$verified_commit_checkout_count" -eq 3
test "$checkout_count" -eq "$((bound_checkout_count + verified_commit_checkout_count + trusted_guard_checkout_count))"
test "$bound_checkout_count" -eq "$head_assertion_count"
if "$validate_release_ref" v1.2.3 refs/heads/main >/dev/null 2>&1; then
echo 'branch-dispatched release tag input was accepted' >&2
Expand Down
67 changes: 67 additions & 0 deletions .github/scripts/release-tag-guard.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/sh
set -eu

: "${VERSION:?VERSION is required}"
: "${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"

if ! printf '%s\n' "$VERSION" | grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'; then
echo "release tag must match vMAJOR.MINOR.PATCH" >&2
exit 1
fi

tag_ref="refs/tags/$VERSION"
if ! git show-ref --verify --quiet "$tag_ref"; then
echo "release tag does not exist: $VERSION" >&2
exit 1
fi
commit=$(git rev-parse --verify "$tag_ref^{commit}")
if ! printf '%s\n' "$commit" | grep -Eq '^[0-9a-f]{40}$'; then
echo "release tag did not peel to a commit" >&2
exit 1
fi

case "${GITHUB_EVENT_NAME:-}" in
push|workflow_dispatch)
if [ "${GITHUB_REF:-}" != "$tag_ref" ]; then
echo "event ref does not match the release tag" >&2
exit 1
fi
;;
*)
echo "unsupported release event: ${GITHUB_EVENT_NAME:-unset}" >&2
exit 1
;;
esac
case "${GITHUB_SHA:-}" in
''|*[!0-9a-f]*) echo "event commit is not a full SHA" >&2; exit 1 ;;
esac
if [ "${#GITHUB_SHA}" -ne 40 ]; then
echo "event commit is not a full SHA" >&2
exit 1
fi
# Preserve annotated-tag peeling, but never resolve authority from a mutable ref.
event_commit=$(git rev-parse --verify "${GITHUB_SHA}^{commit}" 2>/dev/null) || {
echo "event commit did not peel to a commit" >&2
exit 1
}
if [ "$event_commit" != "$commit" ]; then
echo "event commit does not match the release tag" >&2
exit 1
fi
if ! git merge-base --is-ancestor "$commit" origin/main; then
echo "release tag commit is not on origin/main" >&2
exit 1
fi

git checkout --detach "$commit" >/dev/null 2>&1
head=$(git rev-parse --verify HEAD)
if [ "$head" != "$commit" ]; then
echo "checked-out commit does not match the verified release tag" >&2
exit 1
fi

{
echo "version=$VERSION"
echo "commit=$commit"
} >>"$GITHUB_OUTPUT"
printf '%s is verified at %s\n' "$VERSION" "$commit"
120 changes: 120 additions & 0 deletions .github/scripts/release-tag-guard_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/bin/sh
set -eu

script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P)
script="$script_dir/release-tag-guard.sh"
work=${TEST_TMPDIR:-.scratch}/release-tag-guard-$$
mkdir -p "$work"
work=$(CDPATH= cd -- "$work" && pwd -P)

repo="$work/repo"
mkdir "$repo"
repo=$(CDPATH= cd -- "$repo" && pwd -P)
git -C "$repo" init -q -b main
git -C "$repo" config user.name test
git -C "$repo" config user.email test@example.com
git -C "$repo" config commit.gpgSign false
git -C "$repo" config tag.gpgSign false
printf 'release\n' >"$repo/file"
git -C "$repo" add file
git -C "$repo" commit -qm release
release_commit=$(git -C "$repo" rev-parse HEAD)
git -C "$repo" tag v1.2.3
printf 'main\n' >>"$repo/file"
git -C "$repo" commit -qam main
main=$(git -C "$repo" rev-parse HEAD)
git -C "$repo" remote add origin "$repo"
git -C "$repo" fetch -q origin main:refs/remotes/origin/main

run_ok() {
output="$work/output"
: >"$output"
(cd "$repo" && VERSION="$1" GITHUB_EVENT_NAME="$2" GITHUB_REF="$3" GITHUB_SHA="$4" GITHUB_OUTPUT="$output" "$script") >/dev/null
grep -Fx "version=$1" "$output" >/dev/null
grep -Fx "commit=$5" "$output" >/dev/null
[ "$(git -C "$repo" rev-parse HEAD)" = "$5" ]
}
run_fail() {
output="$work/output"
: >"$output"
if (cd "$repo" && VERSION="$1" GITHUB_EVENT_NAME="$2" GITHUB_REF="$3" GITHUB_SHA="$4" GITHUB_OUTPUT="$output" "$script") >/dev/null 2>&1; then
echo "unexpectedly accepted: $1" >&2
exit 1
fi
[ ! -s "$output" ]
}

# Dispatch must select the same immutable tag ref as its input.
run_ok v1.2.3 workflow_dispatch refs/tags/v1.2.3 "$release_commit" "$release_commit"
run_fail v1.2.3 workflow_dispatch refs/heads/main "$main"
run_fail v1.2.3 workflow_dispatch refs/tags/v1.2.4 "$release_commit"
run_fail main workflow_dispatch refs/tags/main "$main"
run_fail refs/heads/main workflow_dispatch refs/tags/refs/heads/main "$main"
marker="$work/pwned"
run_fail "v1.2.3; touch $marker" workflow_dispatch refs/heads/main "$main"
[ ! -e "$marker" ]
run_fail v01.2.3 workflow_dispatch refs/heads/main "$main"
run_fail v9.9.9 workflow_dispatch refs/heads/main "$main"
run_fail v1.2.3 push refs/heads/main "$release_commit"
run_fail v1.2.3 push refs/tags/v1.2.3 0000000000000000000000000000000000000000
run_ok v1.2.3 push refs/tags/v1.2.3 "$release_commit" "$release_commit"

# An annotated tag push reports its tag-object SHA; both sides must peel it.
git -C "$repo" tag -a v1.2.4 -m annotated "$release_commit"
annotated_tag=$(git -C "$repo" rev-parse v1.2.4)
run_ok v1.2.4 push refs/tags/v1.2.4 "$annotated_tag" "$release_commit"
run_ok v1.2.4 push refs/tags/v1.2.4 "$release_commit" "$release_commit"
run_ok v1.2.4 workflow_dispatch refs/tags/v1.2.4 "$release_commit" "$release_commit"

# Both commits are on main: moving the same tag after the event was captured
# must fail before checkout/output, even though ref-name and ancestry checks pass.
git -C "$repo" tag -f v1.2.3 "$main" >/dev/null
for event in push workflow_dispatch; do
run_fail v1.2.3 "$event" refs/tags/v1.2.3 "$release_commit"
run_fail v1.2.4 "$event" refs/tags/v1.2.4 "$main"
run_ok v1.2.3 "$event" refs/tags/v1.2.3 "$main" "$main"
for invalid_sha in '' HEAD refs/tags/v1.2.3 "${main%?}" "${main}0" \
0000000000000000000000000000000000000000 "$(printf '%s\nHEAD' "$main")"; do
run_fail v1.2.3 "$event" refs/tags/v1.2.3 "$invalid_sha"
done
done
# An annotated event object must not hide a moved-tag mismatch either.
git -C "$repo" tag -f -a v1.2.4 -m moved "$main" >/dev/null
run_fail v1.2.4 push refs/tags/v1.2.4 "$annotated_tag"
run_fail v1.2.4 workflow_dispatch refs/tags/v1.2.4 "$release_commit"

workflow="$script_dir/../workflows/release.yml"
# Execute the real validator agreement step, not a duplicate test-only check.
agreement=$(awk '/^ - name: Assert guard and immutable run commits agree$/{on=1; next} on && /^ run: /{sub(/^ run: /, ""); print; exit}' "$workflow")
[ -n "$agreement" ]
(cd "$repo" && RELEASE_COMMIT="$main" sh -eu -c "$agreement")
if (cd "$repo" && RELEASE_COMMIT="$release_commit" sh -eu -c "$agreement"); then
echo 'validator accepted a different on-main guard commit' >&2
exit 1
fi
if (cd "$repo" && RELEASE_COMMIT='' sh -eu -c "$agreement"); then
echo 'validator accepted an empty guard commit' >&2
exit 1
fi

git -C "$repo" switch -q --detach "$release_commit"
printf 'branch\n' >>"$repo/file"
git -C "$repo" commit -qam branch
off_main=$(git -C "$repo" rev-parse HEAD)
git -C "$repo" tag v2.0.0
run_fail v2.0.0 workflow_dispatch refs/tags/v2.0.0 "$off_main"
run_fail v2.0.0 push refs/tags/v2.0.0 "$off_main"
run_fail v1.2.3 schedule refs/tags/v1.2.3 "$release_commit"

workflow="$script_dir/../workflows/release.yml"
# The privileged graph consumes only the commit emitted by a guard implementation
# checked out from protected main; dispatch must select the requested tag ref.
grep -F "if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.ref == format('refs/tags/{0}', inputs.tag))" "$workflow" >/dev/null
grep -F 'ref: refs/heads/main' "$workflow" >/dev/null
if grep -F 'org.opencontainers.image.revision=${{ github.sha }}' "$workflow" >/dev/null; then
echo "release image revision still uses the event workflow SHA" >&2
exit 1
fi
[ "$(grep -Fc 'org.opencontainers.image.revision=${{ needs.guard.outputs.commit }}' "$workflow")" -eq 5 ]

printf 'release tag guard tests passed\n'
Loading
Loading