GitHub Sync
Define one bounded synchronization between local Runx state and a GitHub
repository. The skill makes direction, resource set, filters, content identity,
scope, cursor, and authority posture explicit before the selected GitHub
transport is allowed to read or mutate GitHub.
The default github-sync runner performs the requested pull or push. plan
is the explicit no-effect runner; pull and push remain explicit execution
lanes for compatible callers. Pulls are bounded reads. A push carries one to
eight typed mutations under the admitted repository grant and returns an
individual status, sync reference, and mutation digest for every item. It
closes only on independent
GitHub readback for every applied item. A partial or unknown item is deferred
for reconciliation and is never silently retried. No GitHub token enters this
package.
Composes
data-store#append_event
data-store#read_projection
When to use it
Use github-sync when an operator needs a reproducible pull or push contract for
issues, pull requests, threads, or a mixed batch—especially when cursor state must survive
across runs. Use plan only when the requested outcome is a plan. Use pull
for an explicitly selected read lane. Use push for one already-decided issue,
pull-request, or thread mutation. Batches are bounded and best-effort, not
atomic: if one item fails, the result identifies each item and the operator
must reconcile before retrying. Use issue-triage to decide what an issue means
and issue-to-pr to govern an implementation lane.
Do not use a plan as evidence that remote state was read or changed. Only the
native runx.provider.operation.v1 result from pull or push is provider
evidence. Do not silently turn a denied push into a pull.
How it works
- Validate the exact
owner/name repository, direction, resource kind, bounded
filters, maximum result count, and requested scope.
- A
pull plan requires read scope and records the exact resources a provider
may fetch.
- A
push plan requires write scope and one to eight typed mutations. It
rejects unknown fields and oversized content, then returns
ready_for_execution; planning itself does not grant provider authority.
- Optional
plan_and_append_cursor composes the canonical data-store skill
to append the bounded plan and read the projection back. That proves local
cursor persistence, not GitHub synchronization; this package does not own a
second cursor database or storage adapter.
- The default runner selects the same bounded read or write path from the
validated direction.
pull executes the plan with repo.read. push
hashes the exact mutation set with the native digest tool, executes it under
the admitted repo.write scope, verifies the returned digest, and reads the
resource back.
Both runners use the native provider lane.
Inputs and result
repo is exactly owner/name.
direction is pull or push.
resources contains the issue, PR, thread, or mixed batch selector and a
limit no greater than 100. A push has one to eight mutations entries with ref, op, and an
exact typed payload. Issue and PR changes use op: update; new thread
comments use op: comment. Bodies are capped at 65,536 characters. Pulls
return compact metadata and body digests by default; set include_body: true
only when the full bounded body is needed.
scope is the requested read or write scope.
The runx.github_sync.v1 plan records exact direction, provider operation,
scope, filters, blockers, authority posture, cursor state when used, and the
explicit absence of remote effects. Execution additionally emits the native
provider-operation packet; it does not rewrite the planning packet to imply a
remote effect.
Stop conditions
- Refuse malformed repositories, unknown resource kinds, unbounded selectors,
limits above the contract, more than eight mutations, unknown mutation fields, or
content beyond the declared bounds.
- Refuse push when write scope is missing; do not degrade silently.
- Do not treat local cursor persistence as remote provider readback.
- Resolve the repository from explicit input or the current checkout before
selecting transport. Prefer the already-authenticated local
gh path; use a
compatible hosted grant when local GitHub authority is unavailable or the
operator explicitly binds hosted transport.
- Refuse missing, ambiguous, wrong-provider, or under-scoped authority. Never
treat an available hosted grant as evidence of the intended repository.
- Do not claim comments, labels, issues, or PRs were read or changed until the
native provider operation proves the expected access, operation, and readback.
Example
A caller wants to pull the next 50 open issues after cursor 2. Planning can
persist that cursor locally; pull then performs issues.read through the
configured grant and returns the provider result. To close issue 241, a push
carries ref: issues/241, op: update, and
payload: {state: closed, state_reason: completed}. Runx hashes that exact
mutation, applies only that issue update under the scoped grant, and reads issue
241 back.
1---2name: github-sync3description: Read or synchronize bounded GitHub issues, threads, and pull requests through the local authenticated gh CLI or any compatible hosted connector, with scoped authority and readback.4---56# GitHub Sync78Define one bounded synchronization between local Runx state and a GitHub9repository. The skill makes direction, resource set, filters, content identity,10scope, cursor, and authority posture explicit before the selected GitHub11transport is allowed to read or mutate GitHub.1213The default `github-sync` runner performs the requested pull or push. `plan`14is the explicit no-effect runner; `pull` and `push` remain explicit execution15lanes for compatible callers. Pulls are bounded reads. A push carries one to16eight typed mutations under the admitted repository grant and returns an17individual status, sync reference, and mutation digest for every item. It18closes only on independent19GitHub readback for every applied item. A partial or unknown item is deferred20for reconciliation and is never silently retried. No GitHub token enters this21package.2223## Composes2425<!-- Generated from the native execution closure; run pnpm core-skills:composes:generate. -->2627- `data-store#append_event`28- `data-store#read_projection`2930## When to use it3132Use `github-sync` when an operator needs a reproducible pull or push contract for33issues, pull requests, threads, or a mixed `batch`—especially when cursor state must survive34across runs. Use `plan` only when the requested outcome is a plan. Use `pull`35for an explicitly selected read lane. Use `push` for one already-decided issue,36pull-request, or thread mutation. Batches are bounded and best-effort, not37atomic: if one item fails, the result identifies each item and the operator38must reconcile before retrying. Use `issue-triage` to decide what an issue means39and `issue-to-pr` to govern an implementation lane.4041Do not use a plan as evidence that remote state was read or changed. Only the42native `runx.provider.operation.v1` result from `pull` or `push` is provider43evidence. Do not silently turn a denied push into a pull.4445## How it works46471. Validate the exact `owner/name` repository, direction, resource kind, bounded48 filters, maximum result count, and requested scope.492. A `pull` plan requires read scope and records the exact resources a provider50 may fetch.513. A `push` plan requires write scope and one to eight typed mutations. It52 rejects unknown fields and oversized content, then returns53 `ready_for_execution`; planning itself does not grant provider authority.544. Optional `plan_and_append_cursor` composes the canonical `data-store` skill55 to append the bounded plan and read the projection back. That proves local56 cursor persistence, not GitHub synchronization; this package does not own a57 second cursor database or storage adapter.585. The default runner selects the same bounded read or write path from the59 validated direction. `pull` executes the plan with `repo.read`. `push`60 hashes the exact mutation set with the native digest tool, executes it under61 the admitted `repo.write` scope, verifies the returned digest, and reads the62 resource back.63 Both runners use the native provider lane.6465## Inputs and result6667- `repo` is exactly `owner/name`.68- `direction` is `pull` or `push`.69- `resources` contains the issue, PR, thread, or mixed `batch` selector and a70 limit no greater than 100. A push has one to eight `mutations` entries with `ref`, `op`, and an71 exact typed `payload`. Issue and PR changes use `op: update`; new thread72 comments use `op: comment`. Bodies are capped at 65,536 characters. Pulls73 return compact metadata and body digests by default; set `include_body: true`74 only when the full bounded body is needed.75- `scope` is the requested read or write scope.7677The `runx.github_sync.v1` plan records exact direction, provider operation,78scope, filters, blockers, authority posture, cursor state when used, and the79explicit absence of remote effects. Execution additionally emits the native80provider-operation packet; it does not rewrite the planning packet to imply a81remote effect.8283## Stop conditions8485- Refuse malformed repositories, unknown resource kinds, unbounded selectors,86 limits above the contract, more than eight mutations, unknown mutation fields, or87 content beyond the declared bounds.88- Refuse push when write scope is missing; do not degrade silently.89- Do not treat local cursor persistence as remote provider readback.90- Resolve the repository from explicit input or the current checkout before91 selecting transport. Prefer the already-authenticated local `gh` path; use a92 compatible hosted grant when local GitHub authority is unavailable or the93 operator explicitly binds hosted transport.94- Refuse missing, ambiguous, wrong-provider, or under-scoped authority. Never95 treat an available hosted grant as evidence of the intended repository.96- Do not claim comments, labels, issues, or PRs were read or changed until the97 native provider operation proves the expected access, operation, and readback.9899## Example100101A caller wants to pull the next 50 open issues after cursor `2`. Planning can102persist that cursor locally; `pull` then performs `issues.read` through the103configured grant and returns the provider result. To close issue 241, a push104carries `ref: issues/241`, `op: update`, and105`payload: {state: closed, state_reason: completed}`. Runx hashes that exact106mutation, applies only that issue update under the scoped grant, and reads issue107241 back.