feat(sense): add reconciliation safety controls [T-012]
Harness governance / validate (push) Has been cancelled
Harness governance / validate (pull_request) Has been cancelled

This commit is contained in:
QiuSW
2026-08-07 23:00:03 +08:00
parent 677ed732f7
commit 12857fdf32
35 changed files with 2817 additions and 124 deletions
+39
View File
@@ -430,6 +430,24 @@ func (s *SQLite) ListDueReconcile(ctx context.Context, now time.Time, limit int)
return candidates, nil
}
func (s *SQLite) ClaimDueReconcile(ctx context.Context, claim ReconcileClaim) ([]ReconcileCandidate, error) {
// SQLite is retained for one-process M1 development. It deliberately does
// not claim cross-process leases; PostgreSQL is the production M2 boundary.
return s.ListDueReconcile(ctx, claim.Now, claim.Limit)
}
func (s *SQLite) RenewReconcileLease(
ctx context.Context,
_, _, _ string,
_ time.Time,
_ time.Duration,
) (bool, error) {
if err := ctx.Err(); err != nil {
return false, err
}
return true, nil
}
func (s *SQLite) ListEnabledVideoDevices(ctx context.Context, limit int) ([]device.Device, error) {
if limit <= 0 {
return nil, nil
@@ -499,6 +517,16 @@ func (s *SQLite) MarkReconciled(ctx context.Context, id string, generation int64
return nil
}
func (s *SQLite) CompleteReconcile(
ctx context.Context,
id string,
generation int64,
_, _ string,
now time.Time,
) error {
return s.MarkReconciled(ctx, id, generation, now)
}
func (s *SQLite) MarkReconcileFailure(ctx context.Context, id string, failureCount int, nextAttempt time.Time, errorCode string, now time.Time) error {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
@@ -526,6 +554,17 @@ func (s *SQLite) MarkReconcileFailure(ctx context.Context, id string, failureCou
return nil
}
func (s *SQLite) FailReconcile(
ctx context.Context,
id string,
failureCount int,
nextAttempt time.Time,
errorCode, _, _ string,
now time.Time,
) error {
return s.MarkReconcileFailure(ctx, id, failureCount, nextAttempt, errorCode, now)
}
func (s *SQLite) UpdateActualState(ctx context.Context, id string, state device.ActualState, now time.Time) error {
if state != device.ActualPending && state != device.ActualOnline && state != device.ActualOffline && state != device.ActualFailed {
return fmt.Errorf("invalid actual state %q", state)