platypeeps

sd-plan

Interview the user into a work item under docs/work, review the plan, and open its branch.

platypeeps 0 Actualitzat fa 1 setm.

Recursos

1
GitHub

Instal·la

npx skillscat add platypeeps/sd-ai-command-pack/sd-plan

Instal·la des del registre de SkillsCat.

SKILL.md

sd-plan

sd-plan <slug> turns an intention into one tracked work item: an sd row,
plus docs/work/<YYYY-MM-DD>-<slug>/design.md only when the shape needs
agreement
(sd:3000). New items get no prd.md or implement.md. Invocation is explicit approval to write
inside the selected work root, create the item's branch, and record that
item's progress and decisions through sd_db. The work root defaults to
docs/work; --work-dir selects another root within this repository. This
does not authorize unrelated database rows, other project files, or external
writes.

When the deliverable is a finished document, apply
references/publication-contract.md: it publishes to the Obsidian
vault and the dashboard's Documents tab by default, and reaches an
outward destination — Notion, Google Drive — only where the user designated that
document for it.

When to use

Use when requested for work spanning more than one session or more than about
300 changed lines, as WORKFLOW.md describes. A smaller change follows the
normal branch, check, review and ship path without a planning artifact. Do not
write a design just to record routine progress or work already merged.

The sequence

  1. Use the existing context. Ask only for answers that would change the
    work and are not already available. The
    problem stated in terms an outsider would recognise; requirements each
    testable by someone who did not write them; acceptance criteria that name a
    check and its result ("pytest tests/auth passes with 0 failures"), never
    an intention ("tests pass"). Keep stated requirements apart from assumptions.
    Do not restart an interview when a handoff or an existing decision supplies
    the answer. In an authorized unattended run, record routine choices on the
    item and continue under WORKFLOW.md's stop conditions.
  2. Track the item as a row. Use the row the work already has, or
    sd task add. Status, progress and decisions live on the row.
  3. Write design.md from the template, only when the shape needs
    agreement. The templates are in skills/sd-plan/templates/ (design.md,
    decision.md, work-README.md). Name the row in its frontmatter as
    item: sd:<id>, and add no status: field. Before writing it, run
    sd-rules --for <work>/<item>/design.md (or --for docs/decisions/<record>.md
    under --decision) from the repository root, and cite the rule ids it
    prints rather than restating the rules. Create <work>/README.md from
    the template if the directory is new. For an item with a prd.md, keep
    progress in the database and add no status: field. Do not recreate
    retired frontmatter from a template.
  4. Register the row, when the item is under docs/work and has a prd.md.
    A folder with design.md alone names its row with item: sd:<id> and is
    not registered (sd:3255). Run
    sd work register docs/work/<item>/prd.md as soon as the file exists. Under a --work-dir root the step does not
    apply and the command will refuse: a row's identity is
    <checkout>::docs/work/<item>/prd.md, where <checkout> is the
    registered key -- ~/repos/<name> for a checkout under $HOME -- and
    every reader keys on it, so
    there is no row shape for an item that lives somewhere else. Say the item
    is unregistered rather than inventing one. The
    retirement handed status to the database and took the importer away with
    it, so a folder written after the cutover has a prd.md and no row, which
    is the state sd-status reports as status-unreadable. Registering is
    idempotent: a second call prints already registered and changes nothing,
    so re-running it on an item that already has a row is safe. The row takes
    its name and its date from the file's title: and created:, which must
    both be present.
  5. Review the plan. Run sd-review --scope planning, which resolves one
    active planning/in_progress item's design.md (and an older item's
    prd.md/implement.md) and routes them to the reviewer the registry gives. Which one: the item
    whose branch: is the branch you are on. With several active items and
    none of them on this branch, it refuses and names them rather than
    reviewing them together — say which with --item. With one active item
    the branch decides nothing and that item is the subject. This is the
    development
    flow's prd and design review point. The review table in
    .claude/rules/sd-planning-adversarial-review.md gives the cap on that row.
    That file lives only in the sd-ai-command-pack checkout, and planning runs
    in whatever repository encloses cwd (R10-D6), so read the cap there. Record
    the findings on the item's row.
  6. Promote. planning → ready only when acceptance criteria are present
    and no open BLOCKING line remains. An unresolved blocking concern is a
    stop, not a note. In a checkout using row status, write the transition
    through sd_db; a missing item row is reported as missing, never replaced
    by a status field or a GitHub issue.
  7. Branch. Create the branch when work starts; the row records it. The branch's checkout holds one writer:
    this session in its own worktree (--worktree), or the runner in its
    clone. See the sd-ai-command-pack checkout's WORKFLOW.md, section
    Parallel work. An in_progress item still needs a branch
    (sd-docs-lint rule 2); in a checkout using row status, the status itself
    remains on the row.

There is no automatic archive, parking or sweep step. sd-status reports
idle planning items as idle-planning rows and moves nothing. Planning and
the first commit leave unrelated work items where they are.

Flags

Flag Effect
--decision Write a docs/decisions/ record instead of a work item
--work-dir Work root other than docs/work
--worktree Create the branch in its own git worktree (one writer per checkout)
--from gh:owner/repo#123 / --from jira:KEY-123 Seed ## References from a tracker item, resolved against the shadow rows in the shared database
--from sd:123 Seed the interview and ## References from a row in the shared database
--from-suggestion Reserved: seed from a local proposal note; not implemented
--from-proposal Seed from a skill proposal

Seeding from a tracker

--from resolves against the shared database, so the citation is what the
tracker said when sd shadow sync last ran rather than what anyone
remembered. sd-trackers ref did this until it retired with sd:719 step 4;
the two remote schemes now read sd_db.progress.tracker_items and take the
row whose URL tail is the reference (42 for gh:openai/whisper#42,
ABC-45 for jira:ABC-45). Run it from the pack checkout, whose lib/ is
the one sd_db (sd:3280):

PYTHONPATH=lib .venv/bin/python -c 'import sd_db, sd_db.progress as p
c = sd_db.connect(write=False)
print([r for r in p.tracker_items(c, tracker="github", repo="openai/whisper") if r["url"].endswith("/42")])'
sd store item 455 --json

Write one bullet from the row — the link, the title, the state, and the date
the item was last seen — which goes verbatim under the PRD's ## References
heading; add the heading if the page has none. A reference the shadow does
not hold is pasted by hand from the tracker page.

sd:<id> seeds the interview too

The two remote schemes seed a citation and nothing else, deliberately: an
issue's prose copied into a work item is stale the moment somebody edits the
issue. sd: is different, because the row is not somewhere else. It is in the
same database this item will be registered in, and the person who wrote it is
the person planning now.

So read the row before the interview and use it:

sd store item 455 --json
  • title is the item's opening line. Do not re-ask for it.
  • body is what the filer already said. Treat it as the answer to "what
    is wrong", and interview for what it does not settle — scope, the
    acceptance criteria, what is out of scope — rather than from a blank page.
  • repo is the repository the row belongs to. It is something to check
    against, never somewhere to go: the repository is still the one enclosing
    cwd, and Never accept a repo path below holds here too. When the row names
    a repository and it is not this checkout, stop and print both paths. The
    user moves, or says which one is right; a plan written into the checkout the
    agent chose is the failure that rule exists to prevent.

The citation still goes under ## References, and it carries no link: the row
lives in this machine's database, so sd:455 and sd store item 455 are the
whole reference. A URL there would look checkable and resolve nowhere.

The row is not the plan. Seeding is a starting point, not permission to
skip the interview — a one-line row does not become a design by being read
aloud.

Read the exit code before pasting. 1 means the tracker was asked and the
reference did not resolve — no such issue or item, a repository you cannot
see, or an answer this could not read. 2 means it could not be asked at
all: gh missing or unauthenticated, the Jira variables unset, a database
this machine cannot open or read, or a reference that does not parse. The
line between them matters most for sd:, where both ends are local: a typo in
an id exits 1, and an unprovisioned or unreadable store exits 2. Reading the
second as the first would report a machine that was never asked as an item
that does not exist. Neither is a licence to hand-write a citation: an
unresolvable reference is a question for the user, and a made-up link in a
work item outlives the session that invented it.

The issue's own text stays in the issue. Cite the link, read the issue for the
interview, and leave its prose where it will still be current next month.

Never

  • Never accept a repo path. The repository is the one enclosing cwd
    (R10-D6). A work item whose branch: resolves to a different checkout is a
    refusal with the path printed, never a silent cd.
  • Keep writes within the authorized scope. Files belong under the selected
    work root (plus docs/decisions/ under --decision); database progress and
    decision writes belong only to the current item and go through sd_db.
    No unrelated rows, .claude/, other tools' state directories, hooks,
    labels, managed gitignore blocks, bookkeeping commits, or AGENTS.md edits
    are authorized here.
  • Never promote past an open BLOCKING line, and never claim approval from
    a review lane that was skipped or that failed.
  • In mode: guest, never write artifacts into the upstream tree — the
    triad lives on the fork's integration branch. This one is no longer only an
    instruction: step 4's sd-review --scope planning resolves sd_lib.mode()
    over the paths it is about to review and exits 2 with one sentence naming
    them, so a guest checkout cannot reach planning → ready with a triad in the
    upstream tree. The refusal fires after the files are written, not before —
    move them to the fork's integration branch and re-run.
  • Never write a design to look thorough. One page at most, and none
    when the shape needs no agreement.

Reattaching

If sd-handoff --show reports a pending packet for this directory, read it
before re-planning: it carries the previous session's summary, next[] and —
the field that saves the most rework — dont[].

State of the tooling

sd-plan has no bin/ half, and is not waiting for one: the templates ship
and the procedure is carried out by the agent. The one part that would drift if
it stayed in prose — turning a tracker reference into the ## References
block — reads the shadow rows above; the command that did it, sd-trackers ref, retired with sd:719 step 4. sd-review, sd-check, sd-status,
sd-handoff and sd-docs-lint are real and callable today.

sd suggest add can record a proposal on an existing imported work item, but
--from-suggestion and --from-proposal have no resolution path yet. Do not
invent one. sd task add makes the row; sd-status only reports.

Categories