# Fail-Closed Error Propagation & Transaction Resilience

**Document ID:** `DOC-FAIL-CLOSED-ERROR-PROPAGATION-001`  
**Status:** Approved / Enforced  
**Technical Debt Reference:** `TDE-F-CQ-001`  

---

## 1. Overview

Silent error swallowing via blank identifiers (`_ = err`) and mechanical logging (`logging.LogSwallowedError`) compromises data consistency, masks concurrency deadlocks, and allows corrupted state mutations to proceed.

This standard establishes strict invariants for transaction commits, state transitions, and concurrency locks across the Knowledge Kernel and CLI surfaces.

---

## 2. Core Invariants & Rules

### Rule 1: Fail-Closed Transaction Rollbacks
- All database and storage transactions (`sp.BeginTransaction(ctx)`) must be guarded by explicit error handling.
- If creating idempotency audit stamps or mutating nodes fails:
  1. The transaction must immediately execute `tx.Rollback(ctx)`.
  2. Any error returned by `tx.Rollback` must be joined with the primary failure via `errors.Join(primaryErr, rollbackErr)`.
  3. The combined error must be propagated to the caller without proceeding to subsequent steps.

### Rule 2: Synchronous Status Transition Integrity
- Status transitions on tasks and kernel entities must never discard mutation errors.
- If updating task status to `in_progress`, `blocked`, `complete`, or `failed` fails, the execution loop must abort or surface the error, rather than continuing as if the transition succeeded.

### Rule 3: Storage Lock Timeouts Must Fail Closed
- When acquiring shared or exclusive locks (e.g. `concurrency.WithLockTimeout`, `concurrency.WithRLockTimeout`), lock timeouts must return explicit errors.
- Cache loading or saving operations must never return `true, nil` or silent success when lock acquisition times out.

---

## 3. Verification

Verified by automated test suites:
- `cmd/zqk/agent/sync_loop_test.go` (`TestApplyStateMutation_ErrorPropagation`, `TestSyncLoop_MaxVerificationAttempts`)
- `pkg/storage/reverse_reference_index_test.go` (`TestReverseReferenceIndex_SaveCache_LockContention_PropagatesError`, `TestReverseReferenceIndex_GetDependentsWithError_Contention`)
