| name | push |
| description | Push skill — draft, preview, push, back-link, audit |
| risk_class | hard |
| confirm_action | push.create |
Push
Push a wiki task page to an external backend as a new ticket.
Arguments
$ARGUMENTS — Path to the task page (e.g., wiki/tasks/fix-login-bug.md)
Behavior
Step 1 — Read the task page
Read the task page specified in $ARGUMENTS. Extract its frontmatter (title, description, tags, status, source) and body content.
If the task already has a backend reference (gh_ref, jira_ref, or asana_ref), warn the user that this task may already exist in the target system.
Step 2 — Identify target backend
Read workspace.md frontmatter to get configured backends. If multiple, ask the user which to push to. If only one, use it. If none, stop.
If the workspace has repo_labels configured AND the task references a particular repo (in body or activity log), pre-fill the appropriate repo:<name> label. If the repo association isn't obvious, ask: "What repo does this work live in?" so the right label gets attached.
Step 3 — Draft ticket content
Use the ticket-writer agent. The agent reads @references/<backend>-ticket-template.md for structure and .claude/voice.md (if present) for tone:
Agent({
subagent_type: "ticket-writer",
prompt: "Draft a <backend-type> ticket from this wiki task page: <task content>"
})
Step 4 — Walk through any NEEDS_INPUT items
If the draft contains NEEDS_INPUT placeholders (fields the agent couldn't infer), walk the user through each in plain prose:
The draft needs a few details before pushing:
- Priority? (high / med / low)
- Component or area?
Or say "ship it" and I'll push as-is with reasonable defaults.
The "ship it" shortcut accepts whatever defaults the agent picked.
Step 5 — Request a confirm-token and call the CLI gate
This skill is risk_class: hard. The external write is performed
exclusively via rubber-ducky push, which consumes the confirm-token
internally — there is no way to bypass the gate.
Build the structured preview as plain text:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
PUSH PREVIEW
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Backend: <name>
Target: (new ticket)
Title: <title>
Priority: <priority>
Labels: <tags + repo label>
Description:
<first 200 chars>...
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Request the token (the CLI surfaces the preview and prompts the user
unless settings.confirm.<backend>.push is auto):
TOKEN=$(rubber-ducky --no-json confirm request \
--action <backend>.push \
--preview "$PREVIEW_TEXT")
If the command exits non-zero, the user declined or the call failed — stop
here and tell the user the push did not happen. One confirmation covers
the full push (the create call, frontmatter update, and back-link
comments). Don't re-ask partway through.
Step 6 — Execute the push via rubber-ducky push
Invoke the CLI verb with the token. The verb consumes the token, calls
the backend, stamps <backend>_ref / pushed / updated on the wiki
task page, and appends the audit-log line. If the token is missing,
expired, or bound to a different action, the verb exits non-zero and
no external call is made — the gate is at the CLI layer, not in this
markdown.
rubber-ducky --json push <task-file> \
--backend <backend> \
--confirm-token "$TOKEN"
Capture the new ref and URL from the JSON response. If the push fails
(any non-zero exit), surface the error to the user; do not retry without
a fresh token.
Step 7 — Wiki frontmatter is already updated by the CLI
rubber-ducky push set <backend>_ref, pushed, and updated
itself. For Jira pushes it also forces jira_needed: yes
regardless of any prior value — the act of pushing settles the
"was Jira needed?" question. No manual frontmatter edits needed.
Step 8 — Post back-link comments if cross-referenced
If the source task originated in one backend (e.g., an Asana intake)
and was just pushed to another (e.g., Jira), post a one-line cross-
reference comment on each side. Each comment is itself a hard write and
needs its own gate — issue a fresh token for each and invoke
rubber-ducky comment:
TOKEN=$(rubber-ducky --no-json confirm request --action <source-backend>.comment --preview "Back-link to $NEW_REF")
rubber-ducky --json comment <source-task-file> \
--backend <source-backend> \
--text "$NEW_URL" \
--confirm-token "$TOKEN"
Repeat for the new side. Comments are URL-only — no commentary.
Step 9 — Audit log + index rebuild
The push CLI already appended its own [write-back] push → ... line.
You only need to rebuild the index:
rubber-ducky index rebuild
Step 10 — Board placement check
Some backends create new tickets in a default backlog state that doesn't appear on active boards. If you suspect that's happened — the ticket exists but won't be visible to teammates without manual action — surface it as an ASAP item:
rubber-ducky asap add "Move <ref> onto the active board"
Skip this step for backends where new-ticket creation lands the issue on the active view automatically (most GitHub setups).
Rules
- One user confirmation covers the full push (create + frontmatter + back-links + audit). Don't fragment.
- If the backend create call fails, do not update wiki frontmatter — the user should know the push didn't succeed.
- Back-link comments are one-liners with URL only; no commentary.