HOW TO USE · BY SCENARIO

Find your scenario,
then walk one loop.

Whether a need starts as a handwritten note / Obsidian, a Claude Code / Codex chat, a GitHub Issue or a ZenTao Story—all four entries converge into Markdown in your vault and flow through one drop → scan → triage loop. This page gives the shortest viable steps + gotchas for 9 user paths.

Three intuitions first: ① every entry becomes Markdown in the vault; ② one loop drives it to a trustworthy merge; ③ the 9 scenarios differ only in the "first half" (how vault/repo/task gets in)—the second half is identical.
SHEET 01
FOUR ENTRIES, ONE PIPELINE

Where the need comes from
doesn't matter—it becomes Markdown.

Hopper doesn't care what your need looked like at first. Dropped into the central vault (default ~/Hopper), a scribble, an Obsidian note, a plan from a Claude Code / Codex chat, a GitHub Issue, a ZenTao Story all become the same file-driven task on the same pipeline.

Handwritten / Obsidianlocal Markdown · linked notes Claude Code / Codex chatsplan from a chat → saved file GitHub Issueshopper github sync (read-only) ZenTao Storyhopper zentao import (upstream) vault Markdown~/Hopper/00-Inbox/*.md DROPsubmit · dedupe SCANregister · triage TRIAGErisk · deps · project READYqueue drop registers immediately and writes events.jsonl; new / writing into Inbox relies on scan. After ready comes the shared loop (run → review → merge).

FIG.01 — Four entries converge into vault Markdown, then the same drop → scan → triage → ready

SHEET 02
THE LOOP EVERY SCENARIO SHARES

Once a task is in the vault,
all 9 scenarios run the same stretch.

Memorise this loop and the 9 scenarios reduce to "first-half differences" (how the vault arrives, how the project links, where the task comes from). The second half is always the same:

Shared loop · bash
# once in the vault, every scenario is identical
hopper scan                 # register + deterministic triage
hopper triage --no-llm      # (optional) re-triage, no LLM
hopper status               # queue / status
hopper queue explain        # (optional) why each ready task is (not) picked
hopper run next             # run one ready task (or hopper drain / daemon)
hopper review list
hopper review show <id>      # results + evidence
hopper review diff <id>      # code changes
hopper review approve <id>
hopper merge <id>            # code tasks need merge to be done; non-code: archive after approve = done

One-time setup (once per vault/project)

  • hopper setup creates the vault
  • hopper link-project links an existing repo
  • ZenTao: hopper zentao configuredoctor

Daily repeat (each new need)

  • Hopper only: new/drop → scan → run → review → merge
  • +ZenTao: zentao import → … → sync-back --yes
  • Pull remote changes: zentao pull [--apply --yes]
Set an env var to save typing: export HOPPER_VAULT="$HOME/Hopper" — vault resolution is --vault > $HOPPER_VAULT > ~/Hopper.
SHEET 03
PICK YOUR PATH

Two or three questions
land you on a path.

"Newcomer vs veteran" = whether one-time setup is done; "Hopper only vs +ZenTao" = whether the source of truth lives in ZenTao. Follow the tree to a number, then read the matching card.

Source of truth in ZenTao?START no · Hopper only yes · +ZenTao vault exists? no · new yes · veteran have a local repo? no yes Case 3 vault + mapping set? yes · veteran no · new today's need comes from? ZenTao Hopper need/project where?4 branches Case 1 Case 2 Case 9 Case 8 Case 4start in Hopper Case 5ZenTao new Case 6ZenTao old Case 7Hopper → old Amber (Cases 4/7) = start in Hopper but truth must land in ZenTao: native tasks need zentao attach to an existing story before sync-back.

FIG.02 — Decision tree: route to one of 9 paths by source of truth / vault / repo

Quick matrix · scenario × entry
#  who                              vault  repo       ZenTao  task entry          sync-back?
1  Hopper new · no project          new    none→later —       drop→_unassigned    —
2  Hopper new · existing repo       new    existing   —       drop / Inbox        —
3  Hopper veteran                   exists linked     —       new / drop          —
4  +ZenTao new · start in Hopper    new    new        later    new                 attach first
5  +ZenTao new · start in ZenTao    new    any        first    zentao import       yes
6  +ZenTao new · import old project new    old repo   first    zentao import       yes
7  +ZenTao new · Hopper → old       new    old repo   later    drop / Inbox        attach first
8  +ZenTao vet · in Hopper project  exists linked     set      new/drop(+import)   import / after attach
9  +ZenTao vet · in ZenTao project  exists linked     set      zentao import/pull  yes
SHEET 04
HOPPER ONLY · NO ZENTAO

Cases 1–3:
Hopper as the only pipeline.

Case 1 · Newcomer, no project yet

For: no existing repo; you want Hopper to hold ideas / needs / plans, maybe starting code from scratch.

Steps · bash
hopper setup                                  # create vault; answer "no" to link repo for now
# A) just collect ideas: drop into _unassigned
cat idea.md | hopper drop --stdin
hopper scan && hopper triage --no-llm
# B) to run code: repo first → register → create task
mkdir -p ~/Work/my-app && cd ~/Work/my-app && git init
hopper link-project --project my-app --repo "$PWD"
hopper new "Initialize project skeleton" --project my-app

Gotcha: without a repo you can only collect docs; worktree / verification / merge all need a registered repo. Hopper does not provide project create / scaffolding—git init is on you.

Case 2 · Newcomer, importing an old project

For: you already have a local repo and have never used Hopper.

Steps · bash
hopper setup --link-repo /abs/path/to/old-repo --project old-repo
# equivalent: hopper init → hopper link-project --project old-repo --repo …
hopper drop --project old-repo a.md b.md     # multiple files; for many use a shell glob: hopper drop --project old-repo *.md
hopper scan && hopper triage --no-llm

Gotcha: there is no "import the repo's whole issue history and auto-split" command; old code links via link-project, old needs enter via drop / Inbox. Drop always dedupes (identical content → duplicate_ignored).

Case 3 · Veteran, continuing in an existing project

For: ~/Hopper and project / task history already exist; skip all one-time setup.

Daily + recovery · bash
hopper status
hopper new "Fix login error message" --project old-project
hopper scan && hopper drain
hopper review approve <id> && hopper merge <id>
# health check: when projection and events disagree
hopper reconcile --dry-run
hopper doctor

Gotcha: never hand-edit .hopper/events.jsonl / state/ / locks/. Editing body in Obsidian is fine (protected projection), but the frontmatter status is projected from the event stream—don't write it by hand.

SHEET 05
+ZENTAO · NEWCOMERS

Cases 4–7:
first time wiring Hopper to ZenTao.

Generate the mapping with hopper zentao configure (no hand-writing). ZenTao is a read-only upstream; the only write-back is sync-back. Prereq: install and log in to zentao-cli (credentials go through its own login, never to Hopper).

Case 4 · Start a new project in Hopper (ZenTao later)

For: write needs / execute in Hopper first, wire ZenTao later.

Steps · bash
hopper setup
mkdir -p ~/Work/my-app && cd ~/Work/my-app && git init
hopper link-project --project my-app --repo "$PWD"
hopper new "First feature task" --project my-app
# wire ZenTao later (needs an existing product/story on ZenTao)
hopper zentao configure --site https://zentao.example.com --product 1 --project my-app
hopper zentao doctor

Gotcha (core limit): Hopper cannot create a ZenTao story from a native task. Native tasks have no zentao:// source_path; to write back, first hopper zentao attach --task <id> --story <id> to an existing story. If ZenTao must be the source of truth and should create the story, just take Case 5.

Case 5 · Start from ZenTao (smoothest)

For: ZenTao owns product / release / story; Hopper runs the pipeline. Tasks carry zentao:// source_path and close the loop to sync-back.

Steps + write-back · bash
hopper setup --link-repo /abs/path/to/repo --project my-app
hopper zentao configure --site https://zentao.example.com --product 1 --project my-app
hopper zentao doctor
hopper zentao import --product 1 --dry-run      # preview Markdown + predicted triage
hopper zentao import --product 1 && hopper scan
# … shared loop run → review → merge …
hopper zentao sync-back --task <id>             # preview without --yes
hopper zentao sync-back --task <id> --yes       # publish (comment by default)

Gotcha: imported tasks are received (not ready) and must be triaged; the body is external_untrusted—no relaxing guardrails. doctor requires the mapped project to be registered, so link-project/configure come before import.

Case 6 · Import an old project from ZenTao

For: old product / stories in ZenTao, with (or about to link) the matching local repo.

Steps · bash
hopper init
hopper link-project --project legacy-app --repo /abs/path/to/legacy-repo
hopper zentao configure --site https://zentao.example.com --product 1 --project legacy-app
hopper zentao import --product 1 --release 2026-Q3 --dry-run   # blockers / missing AC
hopper zentao import --product 1 --release 2026-Q3
hopper scan && hopper triage --no-llm

Gotcha: currently stories only (tasks/bugs/cases/plans out of scope). Old stories often lack acceptance criteria—dry-run warns, fill them in. Use hopper zentao pull for later remote changes.

Case 7 · Import an old project from Hopper (ZenTao maybe later)

For: old repo + old Markdown needs; take over with Hopper first.

Steps · bash
hopper setup --link-repo /abs/path/to/legacy-repo --project legacy-app
hopper drop --project legacy-app old-1.md old-2.md   # multiple files
hopper scan && hopper triage --no-llm
# if ZenTao already has a matching story, attach to write back:
hopper zentao attach --task <id> --story 109

Gotcha (same as Case 4): there is no "turn Hopper tasks into ZenTao stories in bulk"; attach only links an existing story. If ZenTao must be the source of truth, organise old needs into ZenTao stories first, then import per Case 6.

SHEET 06
+ZENTAO · VETERANS

Cases 8–9:
steady-state daily + remote sync.

Case 8 · Continuing in an existing Hopper project

For: vault / project exist and ZenTao was (or is being) wired in.

Daily · bash
hopper zentao doctor
hopper zentao import --product 1 --dry-run     # new / dup / skipped
hopper zentao import --product 1 && hopper scan
hopper drain
hopper review approve <id> && hopper merge <id>
hopper zentao sync-back --task <id> --yes
hopper zentao pull && hopper zentao pull --apply --yes   # sync remote close/spec

Gotcha: only import-origin tasks carry zentao:// source_path for direct sync-back; native old tasks need zentao attach to an existing story first. Re-importing the same story won't silently overwrite in-flight tasks (only received/draft).

Case 9 · Continuing in an existing ZenTao project

For: ZenTao is the team's entry; you've run Hopper+ZenTao—steady state.

Each round + remote changes · bash
hopper zentao import --product 1 --release 2026-Q3 --dry-run
hopper zentao import --product 1 --release 2026-Q3
# or one story: hopper zentao import --story 109
hopper scan && hopper triage --no-llm
# … run → review → merge … then write back
hopper zentao sync-back --task <id> --yes
hopper zentao pull                  # suggestions only
hopper zentao pull --apply --yes    # close→archive; spec changed & local done→follow-up

Gotcha: no background polling, all manual; assignedTo / remote status changes are display-only; spec changes only surface as applyable after the local task is done.

SHEET 07
GO DEEPER

What to read next.

Operations & commands

  • Docs — init, link, run, review, merge, CLI reference
  • FAQ — common questions & boundaries
  • llms-full.txt — full public guide and implementation boundaries

Design & scenarios