Skills · goal-tree

Goal tree (dependencies of goals, done without statuses)

Chart and work goal trees whose state is derived from "Done when

TerminalCopy
cnotes skills install goal-tree

Raw markdown: /skills/goal-tree/skill.md

Every CreatorNotes canvas goal ends with a "Done when" sentence. That makes a goal checkable, and a checkable goal can depend on other checkable goals. This skill charts an outcome as a tree of Goal notes and works it one goal at a time. Nobody sets a status. A leaf is done when its board shows its Done when is true; a parent is done when every child is. cnotes goals tree derives all of it fresh on every run.

Everything runs through the cnotes CLI. The cnotes skill documents every command used here; read it rather than guessing. Use wayfind instead when the way to the outcome is still foggy and the next step is a decision, not a deliverable.

The model

ConceptCreatorNotes shape
GoalA Goal note. Its body opens with two sentences: <result>. Done when <what is visibly true>.
ChildA depends-on mention from the parent's body: [GOAL-4: Title](relationship:depends-on)
Parent's doneExactly Done when every child goal is met. A parent makes no claim of its own
BoardThe canvas where a leaf's work happens. The Goal note sits on it as the hero card, and the canvas goal is the same two sentences. That match is how the tree finds the board
Leaf's doneThe board's done score (cnotes canvas done): the judge's reading of whether the Done when is true, 0 not met, 1 partly, 2 met, listing each part of the Done when as met or not yet where the board is judged by parts. Or a met-by link to the evidence: [PROOF-7: Title](relationship:met-by)
FrontierGoals not met whose children are all met: what can start now. Computed by cnotes goals tree, never stored
ClaimAn open canvas comment on the goal's card in the tree canvas: CLAIM <ISO time> — <what this session is doing>
Tree canvasOne canvas named <Outcome> · Goal Tree holding every Goal note: root on the right, leaves on the left

Write a Done when the judge can check

The judge reads the board in order: its sections, then each card's type, title, summary and body. On 15 real boards (14 Oct 2026) it agreed with a careful human reader on 14 when the goals were written loosely, and on all 15 once each Done when named the card that proves it. Its misses were writing faults:

  • Name the card that proves it. "Done when the call is recorded" failed twice because no card is called "the call". "Done when a Decision note records whether we pursue it" passes. Say the type: a Decision note, a Spec note, a Slice per step, a card in the Fixed section.
  • Stay on the board. "Done when a tagged click shows in Amplitude" cannot be judged from the board. Either bring the fact onto the board ("Done when an Observation note records a tagged click from Amplitude") or confirm it with a met-by link once a person has checked.
  • One condition per clause. Join parts with "and"; every part must hold for "met". Three parts is plenty. A list of what the board holds belongs in its orientation banner, never in the goal.

A good leaf goal: Decide which phone-section bugs ship in the next PR. Done when every bug card sits in the PR section or the Won't fix section.

Rules every session follows

  1. Never add a status. No done tag, no "Status: complete" line, no editing a parent to say it is met. If the tree says a goal is not met and the person says it is, fix the board or the Done when, or record the evidence and link it met-by. The tree must stay derivable.
  2. Parents only aggregate. A parent's state comes from its children, in code. If a parent needs a condition of its own, that condition is another child goal.
  3. Rubrics before writing. cnotes types show Goal before authoring a goal; read the cnotes skill's humanizer reference before any prose.
  4. Refer by name. In narration and prose a goal is its title; mentions carry both: [GOAL-12: Title](relationship:depends-on).
  5. Bracket writes in an operation: cnotes operations begin --prompt "<tree name> · <goal title>" before the first write, cnotes operations end after the last.
  6. One frontier goal per session, unless the user names more.

Chart the tree (first invocation)

  1. Make sure the Goal type exists. cnotes types show Goal. If it does not, create it and give it the rubric below (setting a rubric needs a workspace admin; if the call is refused, ask the user to run it):

    cnotes types create Goal --display-name "Goal" --description "An outcome with a Done when sentence; parents depend on child goals" --color "#22C55E"
    cnotes types update Goal --validation-prompt "A Goal opens with two sentences: a result verb and its object, then 'Done when' plus what is visibly true on its board, naming the card that proves it (a Decision note, a Spec note, a card in a named section). A goal with child goals says exactly 'Done when every child goal is met.' and names each child with a depends-on mention. No status lines, no dates, no list of what the board holds." --enable-validation
    
  2. Settle the root. Grill one question at a time until the outcome fits the two-sentence shape. The root is usually a parent: its Done when is Done when every child goal is met.

  3. Break it down, breadth first. Each child is either a leaf with one board where its work happens, or a parent with its own children. Stop splitting when a goal fits one board and one Done when a person could check in a minute. Reuse existing boards: a canvas whose goal already has a Done when is a leaf waiting to be adopted.

  4. Create the goals in one batch, inside the run, children cross-linked with @key placeholders so every depends-on resolves in one transaction. --notes takes the JSON itself, not a path, so read a file in with $(cat …):

    cnotes notes create --notes "$(cat goals.json)" --json
    

    Each item is {"key", "type": "Goal", "markdown"}; a parent's markdown lists its children as [@child-key: Title](relationship:depends-on).

  5. Give every leaf its board. For an existing canvas, put the Goal note on it (cnotes canvas place) and set the canvas goal to the identical two sentences: cnotes canvas update CANVAS-12 --goal "<the leaf's two sentences>". For a new board, cnotes canvas create "<Board name>" --goal "<the same two sentences>".

  6. Lay out the tree canvas: cnotes canvas create "<Outcome> · Goal Tree" --goal "<the root's two sentences>", then one cnotes canvas place spec with one column per depth, root on the right, each Goal note in its column, and "depends on" edges from parent to child. Banner first, in the cnotes skill's banner order: what happened, what the tree decides, who works it, how to read it (right to left).

  7. Read it back. cnotes goals tree <root> must list every goal with no "To fix" lines you can repair. Then close the run and give the user the tree canvas link.

Work the tree (every later invocation)

  1. Load: cnotes goals tree <root>. It prints each goal's state with the reason, then Can start now, then To fix.
  2. Repair before working. Each "To fix" line names its own fix: a missing Done when, a parent making its own claim, a leaf with no board, a loop.
  3. Choose and claim the first frontier goal in the order printed, unless the user names one. Check its card on the tree canvas for an open claim younger than two hours (cnotes canvas comments list <treeCanvasId> --status open), then claim: cnotes canvas comments add <treeCanvasId> --node GOAL-N --text "CLAIM <ISO time> — <what this session will do>".
  4. Do the work on the goal's board, with whatever skill the work needs: shaping, wayfind for a foggy decision, fat-marker-flows for a flow, plain notes for the rest. Aim at the Done when, nothing beyond it.
  5. Ask for a verdict: cnotes canvas done <board> --refresh. If the deployment has scoring off, the command says so; then, once the person agrees the Done when holds, record the evidence (usually a Decision or Proof note on the board) and link it from the goal with met-by.
  6. Re-run cnotes goals tree <root>, resolve your claim (cnotes canvas comments resolve), and report by name: what became met, what that unblocked, and the new frontier.

When the verdict looks wrong

The judge reads literally. When it says "not met" and the board looks done, first suspect the Done when: does it name the card, and is that card on the board? Rewrite the goal on both the Goal note and its canvas (they must stay identical), then --refresh. When it says "met" and the board is not done, the Done when is too loose: tighten it the same way. Do not fight the verdict with a status; fix the sentence or the board.

Finishing

The tree is finished when cnotes goals tree <root> shows the root met and nothing to fix. Say so, name the Decisions or Proofs that met the last goals, and leave the tree canvas as the record.