Skip to content

GH-83: feat(core): SyncCapable contract — IssueSnapshot/SyncSource/SyncWriter for board sync (types only)#87

Merged
alekspetrov merged 1 commit into
mainfrom
pilot/GH-83
Jul 13, 2026
Merged

GH-83: feat(core): SyncCapable contract — IssueSnapshot/SyncSource/SyncWriter for board sync (types only)#87
alekspetrov merged 1 commit into
mainfrom
pilot/GH-83

Conversation

@alekspetrov

Copy link
Copy Markdown
Contributor

Summary

Automated PR created by Pilot for task GH-83.

Closes #83

Changes

GitHub Issue GH-83: feat(core): SyncCapable contract — IssueSnapshot/SyncSource/SyncWriter for board sync (types only)

Context

SaaS pre-work S0.2 (kanban sync engine foundation — design doc: qf-studio/pilot .agent/system/saas-kanban-sync-design.md §2). The existing Poller/IssueEvent contract is trigger-label-filtered and carries only Action created|updated — unusable as general sync ingest. We need a NEW contract surface in sdk/core for board synchronization, types only in this issue (no connector implementations — those are separate follow-ups).

Implementation

New file sdk/core/sync.go with exactly this contract (field-for-field):

type IssueSnapshot struct {
    NativeID, SequenceID, Title, Body string
    State       string      // provider-native state id/name
    StateGroup  string      // provider's own state category where it has one
    Labels      []string
    Priority    string      // normalized via core.NormalizePriority
    Assignee    string      // display only
    URL         string
    CreatedAt, UpdatedAt time.Time
    Deleted     bool
}

type Cursor string
type FieldPatch map[string]any

type SyncSource interface {
    ListUpdatedSince(ctx context.Context, projectID string, since time.Time, page Cursor) ([]IssueSnapshot, Cursor, error)
    ListAll(ctx context.Context, projectID string, page Cursor) ([]IssueSnapshot, Cursor, error)
    GetIssue(ctx context.Context, nativeID string) (IssueSnapshot, error)
}

type SyncWriter interface {
    UpdateFields(ctx context.Context, nativeID string, fields FieldPatch) (IssueSnapshot, error)
    TransitionState(ctx context.Context, nativeID, providerState string) error
    AddComment(ctx context.Context, nativeID, body, idemKey string) error
    CreateIssue(ctx context.Context, projectID string, draft IssueDraft) (IssueSnapshot, error)
}

type SyncCapable interface {
    SyncSource
    SyncWriter
}

Define IssueDraft (Title, Body, Labels, Priority) alongside. Doc-comment every type with its role in shadow-based 3-way sync (see design doc §4: the snapshot is diffed against a stored shadow; SequenceID preserves the provider-prefix scheme that Pilot branch naming depends on).

Acceptance

  • sdk/core/sync.go compiles with the contract above; godoc on every exported symbol
  • sdk/core/api.golden re-blessed via the TestPublicAPILocked -update flow with ONLY these additions in the diff
  • No connector implements the interface yet (implementations are follow-up issues)
  • go vet + existing tests green

Refs

  • Design: qf-studio/pilot .agent/system/saas-kanban-sync-design.md §2 (contract), §4 (shadow semantics)

…r for board sync

Adds a new sdk/core contract surface for shadow-based board synchronization,
distinct from the trigger-filtered Poller/IssueEvent path. Types only; no
connector implements SyncCapable yet — implementations are follow-up issues.
@alekspetrov
alekspetrov merged commit fd838f6 into main Jul 13, 2026
3 checks passed
@alekspetrov
alekspetrov deleted the pilot/GH-83 branch July 13, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(core): SyncCapable contract — IssueSnapshot/SyncSource/SyncWriter for board sync (types only)

1 participant