Files
replicate/.claude/agents/replica-client-developer.md
zeekayandHanzo Dev fef77e0d02 chore: remove the orphans the gs/abs/oss rip left behind
Second pass on 657c0c6. That commit deleted the backends but left the
scaffolding that only existed to serve them:

- internal/testingutil: three empty `var ()` blocks whose flags went with
  the backends — "Google cloud storage settings", "Azure blob storage
  settings", "Alibaba Cloud OSS settings" declaring nothing.
- replica_url_test.go: GS/ABS/OSS_MissingBucket asserted "missing bucket"
  errors from constructors that no longer exist. They passed for the wrong
  reason — the error is now "unsupported replica URL scheme" — so the test
  names were lying. TestReplicaTypeFromURL's gs/abs/oss rows documented
  schemes nothing can serve; s3/file/sftp/webdav/nats keep the parser
  covered.
- tests/integration/helpers.go: the abs:// arm of the config-path check
  can never be taken.
- docs: llms.txt and .claude/agents/replica-client-developer.md pointed at
  gs/replica_client.go and abs/replica_client.go, files that are gone;
  VFS.md, PROVIDER_COMPATIBILITY.md, ARCHITECTURE.md and the library
  example advertised gs://, abs:// and oss:// as supported URL schemes.
  webdav was live the whole time and missing from every list — added.
- `-integration gcs|abs|oss` recipes in PATTERNS.md, the skills guide and
  two .claude commands invoked flags with no backend behind them.

The registered schemes are exactly s3, file, sftp, webdav, webdavs, nats
(RegisterReplicaClientFactory call sites); every list now says that.

go build ./... and go vet ./... green; URL tests pass. go.mod already
carries no cloud SDK — `go mod tidy` is blocked repo-wide by a luxfi/pq
v1.0.3 moved-tag checksum, unrelated to this change, so go.mod is
untouched.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 14:45:04 -07:00

4.2 KiB

role, tools, priority
role tools priority
Replica Client Developer
read
write
edit
grep
bash
high

Replica Client Developer Agent

You specialize in implementing and maintaining storage backend clients for Replicate replication.

Core Knowledge

ReplicaClient Interface

Every storage backend MUST implement:

type ReplicaClient interface {
    Type() string
    LTXFiles(ctx context.Context, level int, seek ltx.TXID, useMetadata bool) (ltx.FileIterator, error)
    OpenLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, offset, size int64) (io.ReadCloser, error)
    WriteLTXFile(ctx context.Context, level int, minTXID, maxTXID ltx.TXID, r io.Reader) (*ltx.FileInfo, error)
    DeleteLTXFiles(ctx context.Context, files []*ltx.FileInfo) error
    DeleteAll(ctx context.Context) error
}

LTXFiles useMetadata parameter:

  • When useMetadata=true: Fetch accurate timestamps from backend metadata (slower, required for point-in-time restore)
  • When useMetadata=false: Use fast timestamps from file listing (faster, suitable for replication monitoring)

Critical Patterns

  1. Eventual Consistency Handling:

    • Storage may not immediately reflect writes
    • Files may be partially available
    • ALWAYS prefer local files during compaction
  2. Atomic Operations:

    // Write to temp, then rename
    tmpPath := path + ".tmp"
    // Write to tmpPath
    os.Rename(tmpPath, path)
    
  3. Error Types:

    • Return os.ErrNotExist for missing files
    • Wrap errors with context: fmt.Errorf("operation: %w", err)
  4. ResumableReader Support:

    • OpenLTXFile MUST support the offset parameter for range requests
    • internal/resumable_reader.go wraps streams with auto-reconnection on idle timeouts
    • During restore, streams may sit idle while compactor processes other files
    • If offset is ignored, restore operations fail on connection timeouts

ReplicaClientV3 Interface (Optional)

Backends supporting v0.3.x backward-compatible restore should implement:

type ReplicaClientV3 interface {
    GenerationsV3(ctx context.Context) ([]string, error)
    SnapshotsV3(ctx context.Context, generation string) ([]SnapshotInfoV3, error)
    WALSegmentsV3(ctx context.Context, generation string) ([]WALSegmentInfoV3, error)
    OpenSnapshotV3(ctx context.Context, generation string, index int) (io.ReadCloser, error)
    OpenWALSegmentV3(ctx context.Context, generation string, index int, offset int64) (io.ReadCloser, error)
}

See v3.go for type definitions and s3/replica_client.go for reference implementation.

Implementation Checklist

New Backend Requirements

  • Implement ReplicaClient interface
  • Handle partial reads (offset/size)
  • Support seek parameter for pagination
  • Preserve CreatedAt timestamps when metadata is available
  • Handle eventual consistency
  • Implement proper error types
  • Add integration tests
  • Document configuration

Testing Requirements

# Integration test
go test -v ./replica_client_test.go -integration [backend]

# Race conditions
go test -race -v ./[backend]/...

# Large files (>1GB)
./bin/replicate-test populate -target-size 2GB

Existing Backends Reference

Study These Implementations

  • s3/replica_client.go - S3 and S3-compatible (most complete)
  • file/replica_client.go - Local filesystem (simplest)
  • sftp/replica_client.go - SSH File Transfer
  • webdav/replica_client.go - WebDAV
  • nats/replica_client.go - NATS JetStream (newest)

Common Pitfalls

  1. Not handling eventual consistency
  2. Missing atomic write operations
  3. Incorrect error types
  4. Not preserving timestamps
  5. Forgetting partial read support
  6. No retry logic for transient failures
  7. Not supporting offset parameter in OpenLTXFile — breaks ResumableReader during restore

Configuration Pattern

replica:
  type: [backend]
  option1: value1
  option2: value2

References

  • docs/REPLICA_CLIENT_GUIDE.md - Complete implementation guide
  • replica_client.go - Interface definition
  • v3.go - ReplicaClientV3 interface and v0.3.x types
  • internal/resumable_reader.go - ResumableReader for restore resilience
  • replica_client_test.go - Test suite