feat(P10b): drift detection (R-018/R-019/R-020, REQ-103..113)

internal/drift/drift.go: Detector (Watch via iter.Seq2, Aggregate,
Remediate with cooldown-on-success, Acknowledge), Config with tiered
cadence (critical 5s + Path units, standard 30s, default 60s).
internal/cli/drift.go: orca drift {show,watch,acknowledge,remediate,
config}. internal/emitter/drift_path.go: systemd Path+service unit
emitter (User=orca, ProtectSystem=strict). scripts/orca-drift-notify.sh
(sha256 event JSON), orca-remediate.sh (cooldown-on-success, transient
retry). Pre-flight gate (R-020, --force + per-ns scoping). orca
system user (REQ-111), NFS detection (D-233), orca job restart for
EnvironmentFile drift (D-235).

---ci---
project: orca
phase: 10b
milestone: v0.11
status: execute
---/ci---
This commit is contained in:
Jon Chery
2026-08-07 07:17:41 +00:00
parent 635e07e7a5
commit 03f3585f16
13 changed files with 2970 additions and 0 deletions
+25
View File
@@ -14,6 +14,7 @@
# 3 = rollback failure
# 4 = invalid arguments
# 5 = already-applied no-op (re-run of a completed txn)
# 6 = drift detected (R-020; override with --force)
#
# This script is invoked by the Go-side txn.Apply over SSH on the lead
# peer. It wraps apply.sh / verify.sh / rollback.sh in the C-09 contract.
@@ -31,6 +32,7 @@ EXIT_VERIFY_FAIL=2
EXIT_ROLLBACK_FAIL=3
EXIT_INVALID_ARGS=4
EXIT_ALREADY_APPLIED=5
EXIT_DRIFT_DETECTED=6
# --- bounded retry (C-09) ---
MAX_RETRIES=3
@@ -103,6 +105,29 @@ else
:
fi
# --- pre-flight drift gate (R-020, REQ-110, P10b-T7) ---
# Before applying, check the lead-side aggregated drift state for the
# target namespace. If unacknowledged drift is detected, refuse with
# exit 6 (drift detected) unless --force is given. Per-namespace
# scoping: a drifted peer in ns-A does NOT block ns-B.
if [ "$FORCE" != "true" ]; then
DRIFT_AGG_JSON="${ORCA_DRIFT_AGG_JSON:-/etc/orca/state/drift-events-aggregated.json}"
if [ -f "$DRIFT_AGG_JSON" ]; then
NS_FILTER="${NAMESPACE:-}"
NS_REGEX="${NS_FILTER//\//.}"
if [ -n "$NS_FILTER" ]; then
DRIFT_HITS="$(grep -o '"path"[[:space:]]*:[[:space:]]*"[^"]*"' "$DRIFT_AGG_JSON" 2>/dev/null | sed 's/.*: *"//;s/"//' | grep -E "/etc/orca/actual/${NS_REGEX}/" | grep -v '"action"[[:space:]]*:[[:space:]]*"acknowledged"' || true)"
else
DRIFT_HITS="$(grep -o '"drift_confirmed"[[:space:]]*:[[:space:]]*true' "$DRIFT_AGG_JSON" 2>/dev/null || true)"
fi
if [ -n "$DRIFT_HITS" ]; then
orca_log_error "orca-pull" "$TXN_DIR" "drift-detected" "namespace=${NAMESPACE:-cluster-wide}"
echo "error: drift detected (exit 6); use --force to override or acknowledge the drift (R-020)" >&2
exit "$EXIT_DRIFT_DETECTED"
fi
fi
fi
# --- locate bundle files ---
APPLY="$TXN_DIR/apply.sh"
VERIFY="$TXN_DIR/verify.sh"