You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SaaS pre-work S0.10. Implements the #83SyncCapable contract for Jira — the connector with real write gaps: JQL search + GetTransitions/TransitionIssueTo exist, but there is NO CreateIssue and NO general field-update method (verified 2026-07-13). Also adopts the shared retry package.
NEW CreateIssue (POST /rest/api/3/issue) and UpdateFields (PUT /rest/api/3/issue/{key}) — plain REST, ADF or plain-text body per existing client conventions.
Implement core.SyncCapable: ListUpdatedSince via JQL project = X AND updated >= "<ts>" ORDER BY updated ASC paged by startAt/maxResults; ListAll same without the filter; GetIssue; TransitionState = existing GetTransitions→TransitionIssueTo (name-based); AddComment with the <!-- pilot-op:{idemKey} --> marker (Jira preserves it in ADF); mapping: StateGroup = status category (To Do / In Progress / Done), SequenceID = PROJ-42 key.
Learned from #94/#95 review (2026-07-13) — do NOT repeat these in the Jira impl
Idempotency comment scan MUST paginate: both sibling PRs scanned only the first default comments page (~30-50) — markers beyond it get double-posted on retry. Page the comment listing (maxResults loop) or scan newest-first with an explicit cap + doc comment.
Delta semantics are on-or-after: updated >= "<ts>" (this spec already says >=) — do not regress to strictly-greater; callers dedupe by NativeID. Serialize timestamps in UTC and mind JQL minute-granularity truncation: round since DOWN so boundary issues are never dropped.
Write-method scope: if projectID can select a project, either thread the same scope through GetIssue/UpdateFields/TransitionState/AddComment or reject cross-project NativeIDs loudly — no silent writes to the bound project's same-numbered issue.
Context
SaaS pre-work S0.10. Implements the #83
SyncCapablecontract for Jira — the connector with real write gaps: JQL search +GetTransitions/TransitionIssueToexist, but there is NOCreateIssueand NO general field-update method (verified 2026-07-13). Also adopts the shared retry package.Depends on: #84
Implementation
In
sdk/integrations/jira:CreateIssue(POST /rest/api/3/issue) andUpdateFields(PUT /rest/api/3/issue/{key}) — plain REST, ADF or plain-text body per existing client conventions.core.SyncCapable:ListUpdatedSincevia JQLproject = X AND updated >= "<ts>" ORDER BY updated ASCpaged by startAt/maxResults;ListAllsame without the filter;GetIssue;TransitionState= existing GetTransitions→TransitionIssueTo (name-based);AddCommentwith the<!-- pilot-op:{idemKey} -->marker (Jira preserves it in ADF); mapping: StateGroup = status category (To Do / In Progress / Done), SequenceID = PROJ-42 key.sdk/util/retry(refactor(util): generalize github retry into sdk/util/retry with typed RateLimitError/AuthError #84) for all Jira HTTP calls with per-response error classification (429/Retry-After → RateLimitError; 401/403 → AuthError).Acceptance
Refs
.agent/system/saas-asset-research.md§ studio-sdk · Design: saas-kanban-sync-design.md §2/§5Learned from #94/#95 review (2026-07-13) — do NOT repeat these in the Jira impl
updated >= "<ts>"(this spec already says >=) — do not regress to strictly-greater; callers dedupe by NativeID. Serialize timestamps in UTC and mind JQL minute-granularity truncation: roundsinceDOWN so boundary issues are never dropped.