Skip to content

[P1/mid] fix(preflight): pin deploy-drift target at pipeline start (#1955)#342

Merged
cipher813 merged 2 commits into
mainfrom
groom/1955-deploy-drift-sha-pin
Jul 8, 2026
Merged

[P1/mid] fix(preflight): pin deploy-drift target at pipeline start (#1955)#342
cipher813 merged 2 commits into
mainfrom
groom/1955-deploy-drift-sha-pin

Conversation

@ne-groomer

@ne-groomer ne-groomer Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Priority: P1 · Complexity: mid

Refs #1955 (executor half of a cross-repo pair; companion nousergon-data PR sets the pin).

Executor-merge gate: this is an executor/ safety-gate change — propose-only for the autonomous groomer; human-merged. Opening for review, not self-merge.

What / why

executor/preflight.py::check_deploy_drift compared the deployed checkout HEAD against a live-fetched origin/main — a moving target during the ~48-min weekday pipeline. ne-groomer[bot] merges benign docs/config commits through the trading day, so any commit landing between the freshness gate (T0) and this preflight (~T0+48min) retroactively failed an already-freshness-validated run. 2026-07-08 preopen FailExecution: a docs-only CONTRIBUTING.md merge tripped it — no orders placed, on a box that had all executor code.

Fix — pin the target at pipeline start (issue Option A)

check_deploy_drift now resolves a pinned SHA, precedence:

  1. EXPECTED_EXECUTOR_SHA env var (exported by the RunMorningPlanner SSM step — direct-python, same process tree);
  2. the freshness-gate pin file /home/ec2-user/.frozen_executor_sha (override EXPECTED_EXECUTOR_SHA_FILE), mtime-guarded (stale file → ignored);
  3. None → today's live origin/main fetch (manual / off-pipeline; GitHub-unreachable → warn-and-continue unchanged).

When a SHA is pinned it validates deployed == pinned and never consults the moving upstream. Fail-loud is re-pointed, not loosened: a genuine mid-run de-sync of the box still hard-fails, now on the correct invariant (box == what-this-run-synced).

Why the pin FILE (not just an env var): the daemon is started by systemctl restart alpha-engine-daemon.service, whose process env does not inherit the RunDaemon SSM shell's exports — so the issue's "export EXPECTED_EXECUTOR_SHA into RunDaemon" cannot reach the daemon. A gate-written file is the only channel that reaches BOTH the direct-python RunMorningPlanner and the systemd daemon. The mtime guard prevents a stale file (off-pipeline daemon auto-restart a day later) from pinning yesterday's SHA → it falls back to a live fetch.

Ordering

Land this before the nousergon-data side starts writing the pin — it is fully backward-compatible (no pin present → identical to today), so it is safe to land first per the issue's cross-repo ordering.

Tests

tests/test_preflight.py::TestCheckDeployDriftPinnedSha (8 new, hermetic): pinned-match-passes-without-live-fetch, passes-even-when-origin-main-advanced (the exact 2026-07-08 shape), pinned-mismatch-hard-fails, env-var / pin-file / stale-file / env-wins-over-file / empty→live-fetch fallback. pytest tests/test_preflight.py21 passed.


Groom-Run: ccf1ffc9f5c44284b19a06d6e6176b4c

check_deploy_drift compared the box HEAD against a LIVE-fetched origin/main —
a moving target during the ~48-min pipeline. A benign mid-run merge (docs OR
code) by ne-groomer[bot] retroactively failed an already-freshness-validated
run (2026-07-08 preopen FailExecution, no orders placed). Now resolve a pinned
SHA from EXPECTED_EXECUTOR_SHA env -> the freshness-gate pin file
(/home/ec2-user/.frozen_executor_sha, mtime-guarded) -> live-fetch fallback,
and validate box==pinned-SHA. The file channel is required because the
systemd-restarted daemon's env can't inherit the RunDaemon SSM shell exports.
Fail-loud is re-pointed (box == what-this-run-synced), never loosened. 8 new
tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ne-groomer ne-groomer Bot added the source:groom Opened by the backlog groomer label Jul 8, 2026
@cipher813 cipher813 merged commit 8de4e34 into main Jul 8, 2026
2 checks passed
@cipher813 cipher813 deleted the groom/1955-deploy-drift-sha-pin branch July 8, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

source:groom Opened by the backlog groomer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant