# Visibility Barrier

Status: Frozen architecture note
Owner: Search Platform Architecture

## 1. Scope

This document defines the execution design of `Visibility Barrier`, the stateful high-availability write-plane owner that aggregates touched-modality durability and emits publish-ready intents into `Manifest Publisher`.

This document is subordinate to the canonical owner stack:
- machine-readable public contract: `api/proto/searchfabric/v1/search_fabric.proto`
- internal owner files for this boundary: `api/proto/searchfabric/v1/commit_coordinator.proto` and `api/proto/searchfabric/v1/manifest_publisher.proto`
- public ingest/query/control semantics: `docs/specs/core/search-fabric-api.md`
- canonical error registry: `docs/specs/core/error-codes.md`
- system topology and state ownership: `docs/specs/core/search-fabric-architecture.md`

Relevant trusted internal contracts already exist and remain subordinate to that stack:
- `api/proto/searchfabric/v1/commit_coordinator.proto`
- `api/proto/searchfabric/v1/manifest_publisher.proto`

This document must not redefine:
- public `MutationAck` timing semantics,
- `safe_ts` ownership,
- manifest version allocation or committed-pointer CAS ownership,
- public query-readiness behavior.

## 2. Canonical Position in the System

`Visibility Barrier` sits after authoritative write-intent creation and modality execution, but before manifest publication:

```text
Commit Coordinator
  -> VisibilityBarrierInternalService.RegisterWriteIntent
  -> Metadata / Semantic Writers
  -> VisibilityBarrierInternalService.ReportModalityDurability
  -> Visibility Barrier
  -> ManifestPublisherInternalService.PublishCommittedWrite
  -> Manifest Publisher
```

The checked-out architecture fixes the owner split:
- `Commit Coordinator` creates authoritative row-bearing `WriteIntent` values,
- writers own per-modality durable completion and anchor reporting,
- `Visibility Barrier` decides when one canonical admitted write scope is publish-ready,
- `Manifest Publisher` alone decides which committed manifest version makes that scope query-visible.

## 3. Contract Binding

### 3.1 Trusted Inputs from Commit Coordinator and Writers

The current trusted barrier boundary is already defined in `commit_coordinator.proto`:
- `RegisterWriteIntentRequest.intent`
- `ReportModalityDurabilityRequest`

Important checked-out fields on that boundary:
- `WriteIntent.slice`
- `WriteIntent.touched_modalities[]`
- copied `visibility` / `durability` / `atomicity` / `continue_on_error`
- fenced `coordinator_epoch`
- per-modality `DurableAnchor`
- resulting `applied_modality_ts`

### 3.2 Trusted Output to Manifest Publisher

Once a write scope becomes publish-ready, the barrier emits the current trusted publisher handoff:
- `PublishCommittedWriteIntent`
- `PublishCommittedWriteRequest`

That handoff remains intentionally narrow:
- one canonical admitted write scope,
- one durable modality delta per touched modality,
- resulting watermarks after the final touched modality completed,
- a fenced barrier epoch for diagnostics/fencing.

## 4. Responsibilities and Non-Responsibilities

### 4.1 Responsibilities

`Visibility Barrier` is responsible for:

1. Registering row-bearing `WriteIntent` values before or alongside writer fanout.
2. Tracking which modalities are required for each pending write scope.
3. Aggregating per-modality durable completion reports against the registered intent.
4. Supporting the modality-selective fast path:
   - metadata-only writes wait only for metadata durability,
   - semantic-only writes wait only for semantic durability,
   - mixed writes wait for every touched modality.
5. Deriving the new collection watermarks after the final touched modality completes.
6. Emitting exactly one publish-ready intent per ready write scope.
7. Preserving enough durable barrier state that crash recovery can replay pending work and reissue publish intents idempotently.

### 4.2 Non-Responsibilities

`Visibility Barrier` is not responsible for:

- assigning or preserving `commit_ts`,
- constructing `WriteIntent`,
- producing durable writer anchors,
- publishing manifests,
- advancing CCS derivative head state,
- serving public readiness or `safe_ts` APIs,
- reconstructing source-facing success/error envelopes.

## 5. Barrier State Model

The checked-out architecture already constrains one pending-write aggregation record per row-bearing `WriteIntent`.

Recommended durable barrier record:
- `write_intent_id` or the equivalent canonical slice identity
- `CommitBatchSlice`
- touched modality set
- completed modality set
- per-modality durable anchors
- resulting `applied_ts` per completed modality
- last accepted `barrier_epoch`
- publish-issued marker / publish response identity when known

This state exists only to aggregate durability toward publish-readiness.
It is not a second manifest or watermark truth source.

## 6. Runtime Flow

### 6.1 Registration

For each row-bearing committed slice:
1. `Commit Coordinator` creates authoritative `WriteIntent`.
2. `Visibility Barrier` registers that intent under a fenced barrier epoch.
3. Writers execute the touched modalities.

Registration must happen before the barrier can truthfully aggregate durable completion.

### 6.2 Modality Durability Aggregation

Each touched modality reports one durable completion using:
- the canonical slice identity,
- the modality enum,
- the durable anchor,
- the resulting applied watermark for that modality.

Barrier rules:
- duplicate or zombie reports are fenced by epoch and idempotent slice identity,
- untouched modalities must not be waited on,
- publish-ready becomes true only once the final touched modality is durably complete.

### 6.3 Publish-Ready Handoff

When the final touched modality completes:
1. barrier derives the resulting collection watermarks,
2. barrier constructs one `PublishCommittedWriteIntent`,
3. barrier calls `ManifestPublisherInternalService.PublishCommittedWrite`,
4. publisher returns only the committed manifest identity.

The barrier does not:
- allocate manifest versions,
- mutate manifest objects,
- advance `manifest_committed_head.json` itself.

## 7. ACK Timing Relationship

Public ACK timing remains the canonical ingest contract:

| Policy combination | Internal gate |
|---|---|
| `durability=INGEST_ACK`, `visibility=ASYNC` | work accepted into downstream write control |
| `durability=WAL_CHUNK_DURABLE`, `visibility=ASYNC` | touched modalities reached durable anchors |
| `visibility=WAIT_FOR_VISIBLE` | barrier emitted publish-ready intent and publisher completed manifest CAS publish |

`Visibility Barrier` therefore matters only for the branches whose public contract waits on publish-readiness or publish completion.
It does not introduce a second public ACK vocabulary.

## 8. Failure Handling and Recovery

Failure rules:
- if barrier cannot register or aggregate one intent truthfully, the write path must fail closed rather than guessing visibility state,
- stale or zombie completion reports must be fenced or replayed idempotently,
- publisher failure after barrier aggregation remains a retryable downstream failure; the barrier keeps the write in pending/replayable state until publish is resolved.

Recovery rules:
- durable barrier log / pending-intent state is the recovery input owned by this component,
- replay must reissue unresolved publish-ready work idempotently,
- manifest publisher CAS/idempotency keeps repeated publish attempts safe,
- barrier recovery must not depend on worker-local memory.

## 9. Deployment Guidance

The checked-out deployment model allows `Visibility Barrier` to be:
- an independent control-plane service in the cloud profile, or
- co-located with `Commit Coordinator` and `Manifest Publisher` in the control bundle.

Co-location may reduce RTT, but logical ownership must remain separate:
- coordinator creates intents,
- barrier aggregates touched-modality durability,
- publisher owns manifest progression and visibility CAS.
