Skip to content
Pocketto
Core & Enterprise

GitHub synchronization

What Pocket Enterprise creates on GitHub when lifecycle events drain: issues, phase pull requests, stacked branches, and final tasklists.

Enterprise reconciles GitHub only when a lifecycle drain runs:

npx -y pocketto-pi lifecycle drain <spec_dir> --json --contract 3

Drain processes pending events in ascending revision order, serially per plan, and creates no events. This page describes what each delivery does.

The approved-spec issue

The spec-approved delivery finds or creates one issue for the approved spec (with the pocket-plan label), keeping the full spec as issue context via the formatter and marker conventions. Reconciliation is idempotent: existing valid proof is reused, never duplicated. Ambiguity (multiple matches, foreign ownership, closed issue) stops for manual resolution.

Phase PRs (non-stacked)

phase-complete reconciles an existing PR for the phase: the phase summary is upserted under a canonical marker, and inline review findings are reconciled by fingerprint: new findings posted, unchanged threads retained, resolved findings closed out. A missing PR returns PR_REQUIRED; the adapter does not create one: that is create-pr's explicit job.

Stacked phase branches

With --phase-branches stacked (the install default), each phase gets its own branch and PR:

  • Phase 1 targets the root base recorded at log init --phase-branches stacked.
  • Phase N targets the phase N-1 branch, and its PR links the parent PR.
  • log handoff (run by closing) commits the phase-closed event; delivery then verifies every artifact hash, checks consent, pushes the phase branch fast-forward only, creates or reuses the PR, and upserts the stack-context block, summary, and findings.
  • Multi-phase PR bodies end with refs #N: GitHub closes an issue only on a merge into the default branch, and the adapter never closes issues, so close the linked issue by hand after the last phase.
  • Durable: --push-consent phase-branches at install allows fast-forward pushes of Pocket phase branches only, never main, never other branches, never force.
  • Per-commit: without it, each push stops with PUSH_CONSENT_REQUIRED until you approve the exact commit via consent-push <project-root> <spec_dir> <phase_key> --sha <40-hex>. Approval is never recorded on your behalf.

Ordered drain means a held (consent-waiting) event holds later events too, including plan-closed. Nothing is lost; a later drain replays in order.

Blocking cases

CodeMeaningYour move
PR_REQUIREDNo PR exists for the phaseRun create-pr
PUSH_CONSENT_REQUIREDPush needs approvalApprove the exact SHA with consent-push, then drain
PR_BLOCKED (retryable)parent PR merged, no reusable child PROpen/retarget the child PR on GitHub against the base the parent merged into, then publish-phase (each drain rerun spends one of 6 delivery attempts)
PR_BLOCKED (terminal)base retargeted, duplicate open PR, parent PR closed, remote branch diverged, …Fix on GitHub; Pocket never retargets, closes duplicates, rebases, or force-pushes
FORK_PR_IGNOREDA fork PR reusing the phase head nameInformational notice: the fork is never adopted or edited
Delivery attempts exhausted6 total attempts (1 + 5 retries) per eventTerminal: resolve manually

Final tasklist

plan-closed delivery upserts exactly one <!-- pocket-tasklist --> comment on the linked issue, rendered from the final log.json (via format tasklist). The marker is the idempotency key. The adapter still does not close the issue: that stays human.

On this page