Problem
A genuinely empty tenant repository carries an authoritative full-materialization manifest with pathsAfterPush: [], but produces no ingest/delete effect. The tenant-sync guard treated that valid empty state as KB_TENANT_REPO_SYNC_EMPTY_MATERIALIZATION.
The initial PR repair returned null for that case. It fixed only the immediate status: no committed attempt id was persisted, checkpoint classification remained failed, revalidation remained armed, and every later sweep replayed from a null base. A completed result without durable proof did not break the permanent-backoff trap.
This ticket is the explicitly reserved empty-manifest successor to #16045. The motivating 50-file live incident was not this defect; it was the already-fixed contract-strip path under #16587 / PR #16583. The empty-repository defect is source- and unit-proven, with no claimed live specimen yet.
Cause
The producer historically minted a materialization receipt only for positive ingest/delete effect. A correct empty repository therefore had neither effect nor proof. The orchestrator could not distinguish a successfully observed empty manifest from an unproved zero-effect materialization at its durable checkpoint boundary.
manifestSnapshot.pathsAfterPush: [] is trustworthy only because revision-path enumeration fails closed: listRevisionPaths throws on enumeration failure and never degrades failure into an empty list.
Fix
The durable proof is producer-owned:
IngestionService observes the authoritative manifest after reconciliation.
- A zero-error empty manifest earns the same digest-bound receipt shape as an effect-bearing materialization.
TenantRepoSyncService accepts zero effect only when the manifest declares no content and the receipt proves the current attempt.
- The checkpoint persists the committed attempt id, classifies
complete, disables revalidation, and the next ordinary sweep carries lastIngestedRev.
This is state-independent for a new authoritative empty materialization. It does not accept stale proof: prior matching positive receipts are preserved before the empty-receipt arm, so a stale already-committed receipt cannot masquerade as the current attempt. The earlier “never committed only” fork is therefore resolved without weakening #16045.
Acceptance criteria
Evidence
PR #16889 cycle 2 produced two direct RED witnesses before the repair: the ingestion producer emitted no receipt, and the checkpoint persisted a null committed attempt id. At exact repair commit 4a6ac93bdf0f6c7cdb0f2f05cc9b6b38f7150d2a, the focused producer+consumer slice is 189 passed; the test asserts receipt digest/attempt identity, complete classification, revalidation false, second-sweep carry, non-empty refusal, and settle-once controls.
Avoided traps
- Do not treat
completed as durable completion without re-reading the persisted checkpoint classifier.
- Do not manufacture proof in the orchestrator; the service that observes and persists the manifest owns the receipt.
- Do not widen the exception to non-empty zero-effect materializations.
- Do not replace a prior positive receipt before it can settle a checkpoint-write failure.
Related
- Parent epic #16566
- #16045 — non-empty zero-effect and settle-once authority retained
- #16587 / PR #16583 — motivating live contract-strip incident, separate and resolved
- #16863 / PR #16864 — effect-versus-proof diagnostic split
- PR #16889 — implementation
Authored by @neo-opus-vega (Claude Opus 5). Cycle-2 repair by @neo-gpt-emmy — Emmy 🪡 (GPT-5.6 Sol Ultra, Codex).
Problem
A genuinely empty tenant repository carries an authoritative full-materialization manifest with
pathsAfterPush: [], but produces no ingest/delete effect. The tenant-sync guard treated that valid empty state asKB_TENANT_REPO_SYNC_EMPTY_MATERIALIZATION.The initial PR repair returned
nullfor that case. It fixed only the immediate status: no committed attempt id was persisted, checkpoint classification remainedfailed, revalidation remained armed, and every later sweep replayed from a null base. Acompletedresult without durable proof did not break the permanent-backoff trap.This ticket is the explicitly reserved empty-manifest successor to #16045. The motivating 50-file live incident was not this defect; it was the already-fixed contract-strip path under #16587 / PR #16583. The empty-repository defect is source- and unit-proven, with no claimed live specimen yet.
Cause
The producer historically minted a materialization receipt only for positive ingest/delete effect. A correct empty repository therefore had neither effect nor proof. The orchestrator could not distinguish a successfully observed empty manifest from an unproved zero-effect materialization at its durable checkpoint boundary.
manifestSnapshot.pathsAfterPush: []is trustworthy only because revision-path enumeration fails closed:listRevisionPathsthrows on enumeration failure and never degrades failure into an empty list.Fix
The durable proof is producer-owned:
IngestionServiceobserves the authoritative manifest after reconciliation.TenantRepoSyncServiceaccepts zero effect only when the manifest declares no content and the receipt proves the current attempt.complete, disables revalidation, and the next ordinary sweep carrieslastIngestedRev.This is state-independent for a new authoritative empty materialization. It does not accept stale proof: prior matching positive receipts are preserved before the empty-receipt arm, so a stale already-committed receipt cannot masquerade as the current attempt. The earlier “never committed only” fork is therefore resolved without weakening #16045.
Acceptance criteria
pathsAfterPush: []and a matching current-attempt receipt.lastCommittedMaterializationAttemptId, classifiescomplete, and returnsrequiresTenantRepoCheckpointRevalidation() === false.lastIngestedRevinstead of replaying from a null base.KB_TENANT_REPO_SYNC_EMPTY_MATERIALIZATION; a forged receipt cannot disable that guard.KB_TENANT_REPO_SYNC_CONTENT_NOT_EMBEDDABLEdiagnostic.Evidence
PR #16889 cycle 2 produced two direct RED witnesses before the repair: the ingestion producer emitted no receipt, and the checkpoint persisted a null committed attempt id. At exact repair commit
4a6ac93bdf0f6c7cdb0f2f05cc9b6b38f7150d2a, the focused producer+consumer slice is189 passed; the test asserts receipt digest/attempt identity, complete classification, revalidation false, second-sweep carry, non-empty refusal, and settle-once controls.Avoided traps
completedas durable completion without re-reading the persisted checkpoint classifier.Related
Authored by @neo-opus-vega (Claude Opus 5). Cycle-2 repair by @neo-gpt-emmy — Emmy 🪡 (GPT-5.6 Sol Ultra, Codex).