DWSD.md

Change Trail — Syntax Reference

The Change Trail shows how change moves through an organization, left to right: what was observed (signals), what it means (understood: insights), which need is behind it (needed: drivers), what was proposed, decided (organizational decision records) and agreed (agreements), and where it lands (the work systems and units the agreements name). Roles, interactions and other entities that a decision brought about show up in an Outcome column. The whole network stays open; every open end gets a ghost with its next step, and two lists sit in the view’s toolbar above it: Open ends (oldest first) and Recently decided (the newest decisions, agreements and outcomes). Each is a button with its count (“Open ends 5”) that opens the list. (The lists were called “Continue” and “Done recently” in earlier versions; only the labels changed.) The lists hold only what the view shows: with around or show, an open end or a decision outside the view is left out, and a list with nothing in view reads 0. The grid uses the whole width and opens fitted to it, like the other views (−, Fit and + in the same toolbar), but never below 75 % of its natural size, so the names stay readable; a trail wider than its column then scrolls sideways, and − still zooms out to the full width. Its height follows the rows of entries.

The view is drawn in the text color of the page around it, on a transparent canvas, so it reads the same in a light and a dark theme; only a selection is colored (the selection blue of every view).

By default the view has no entities of its own: it reads the organization’s change entities (mode: infer). A fence can also declare a trail, or lay inline entries over the organization’s trail (see Modes). Inside Markdown the fence is ```dwsd.change-trail (dwsd-change-trail, wsd.change-trail and wsd-change-trail are tolerated); a sketch can also live in its own .dwsd-change-trail file (see The file type). The body is plain YAML, and it may be empty:

```dwsd.change-trail
```

Parameters

KeyValuesDefaultMeaning
around"[[Entity]]" or selfnoneCenter on one entity: everything it comes from, back to the signals, and everything that follows from it, forward to where it lands — nothing else. A driver spreads to both sides, an agreement only backwards. With radius, the entities within that many steps instead. self is the entity whose file holds the fence. The old spelling focus still works and shows an INFO (change-trail.retired-focus). With both keys, around wins (change-trail.around-and-focus). The center may also be an inline entry of the fence.
showall | open | recentallopen: only the paths through open ends. recent: only the paths through Recently decided.
radiusa whole number, or infnoneSteps around around, along the trail in both directions.
modeinfer | declared | mixedinferWhere the trail comes from (next section).
entriesa list of inline entries (name, type, derived-from, …) and references ("[[Name]]")noneThe fence’s own entries: a declared trail, or entries laid over the organization’s. Ignored in infer (warning change-trail.entries-ignored).
```dwsd.change-trail
around: "[[Prioritize Morning Sourdough]]"
radius: 1
```

Put the fence into an entity’s own file with around: self and it shows that entity’s part of the trail; the same fence works in every such file. The entity in the middle carries a dashed ring. A sibling is not part of it: two drivers drawn from the same insight do not show each other — radius brings the neighborhood in on purpose. A work system or unit in “Lands in” is only context on the way; as the center itself (in its own file, or around: "[[Bakehouse]]") it shows every agreement that lands there and everything each one came from — the question “do the old and the new agreements of this work system fit together?” Outside an entity’s file self names nothing, and the view shows the whole trail with a note.

```dwsd.change-trail
around: self
```

The stages are fixed: Observed, Understood, Needed, Proposed, Decided, Agreed (headed Outcome, see Reading), plus Lands in. Unknown keys (also an entry key at the top level) and bad values raise a warning and fall back to the default; the view always draws (an organization without change entities shows the empty grid and a note). More than 20 entries with no around: the view shows the most recent whole chains that fit in 20 entries (a chain is never cut in the middle, and the newest chain is always shown), with the places they land in, and says how many there are in all (“17 of 26 entries shown”); set around: to choose another part.

Migrating a fence that still says focus:: rename it to around: (same values). Nothing breaks if you do not; the INFO is a reminder.

Modes

mode: decides where the trail comes from.

modeThe trail isNeeds the organization
infer (default)read from the organization’s change entities, as alwaysyes
declaredexactly what entries: lists, plus the files it references; the rest of the organization is ignoredno — a workshop sketch (references need it)
mixedthe organization’s trail with entries: laid over ityes

Inline entries and references

The brackets decide what an entries: item is: [[...]] always means a file; a bare name means something in this fence.

ItemIs
name: Night Shift Strainan inline entry: defined right here, no file behind it
- "[[Night Shift Strain]]" or name: "[[Night Shift Strain]]"a reference: the file is the definition; the fence only says “this one is on the sketch” and may annotate it with delta

An inline entry carries the keys of its file, in the same format. A reference carries only delta; any other key on a reference warns (change-trail.reference-key: “the file defines this”).

KeyValuesMeaning
nametextThe entry’s name. It stands for the file name; this is the one key a file does not have.
typesignal, insight, driver, proposal, organizational-decision-record, agreementWhich column it sits in, with the same value the file’s type: has. A missing or unknown type drops the item (change-trail.unknown-type).
derived-froma bare name, "[[Name]]", or a list of themThe step (or steps) it comes from; draws the curve.
observesa bare name, "[[Name]]", or a listOn a decision record or an agreement: the loop-back, as in a file.
for-domain, agreement-of"[[Unit or Work System]]"On an agreement: the line into “Lands in”, when that place is already on the trail. These point at things that are never inline, so a bare name warns.
statustextCounts as in a file: declined, rejected, withdrawn, superseded close the entry.
created_atYYYY-MM-DDThe entry’s date: its age, its place in the order.
deltaadd, remove, or noneA note for the sketch, on either kind of item. add paints the item as a draft (dashed, in the add color). remove keeps the node on the canvas, struck through, in the remove color: “going away”. Without a delta an item is a plain one.

A link says where its target lives by its form. derived-from: Handover Depends on Memory points at the inline entry of that name in this fence; derived-from: "[[Handover Depends on Memory]]" points at the file. One rule for every link key. A locator such as "[[Board]]#col:Review" stays as it is. around: is a fence parameter, not an entry link, so around: "[[Name]]" may name an inline entry too.

How they are drawn:

  • An inline entry in a mixed fence is dashed, in the add color, wired to what it derives from. The entry it derives from is no longer an open end (the inline entry is the next step); the inline entry gets its own ghost one column on. In a declared fence it is an ordinary node (dashed only with delta: add). Either way it is not an entity: nothing opens when you click its name, because there is no file yet.
  • A reference is drawn as the file’s entity, with its kind, date and status. In declared it is drawn from the organization’s file, with the organization’s own curves between the items the fence lists; without the organization’s files it cannot be drawn and warns (change-trail.unresolved-reference). In mixed a reference to a file already on the trail changes nothing by itself; with delta: add it is drawn dashed, with delta: remove struck through.
  • Where a file of the same name as an inline entry exists, the file wins and the inline entry is not drawn twice. The line in the fence stays, and Problems says change-trail.inline-file-exists: “a file of that name exists”; write "[[Name]]" to point at it.
  • Warnings on the item’s own line: change-trail.bare-link-unresolved (a bare link that names no inline entry of this fence: “did you mean [[Name]]?”), change-trail.unresolved-derived-from (a "[[Name]]" link that names nothing on the trail), change-trail.remove-unknown (a remove that names nothing; a place cannot be removed), change-trail.invalid-entry (not a list, not a mapping, no name, an unknown key), change-trail.unknown-delta, change-trail.duplicate-entry (the second one is ignored), change-trail.unknown-mode. delta: change is not supported yet: it warns and the item is drawn without a delta.
  • To make a node appear for real, author the entity (a Markdown file with type: and derived-from:) — or, in a mixed fence, write an inline entry and make the entity later (Interaction).

Migrating a fence written before the entry format changed. Rename the entry key stage: to type:, and spell the decision record organizational-decision-record (the short odr is gone). A link between two inline entries of the same fence loses its brackets; a link to a file keeps them. There is no alias: an item that still says stage: warns (change-trail.retired-stage-key) and, without a valid type:, is dropped. A quoted name: "[[X]]" now means a reference.

What it reads

FrontmatterOnDraws
type:every entitythe column (stage)
derived-from: "[[X]]" (or a list)insight, driver, proposal, decision record, agreement — and any other entity that came out of a proposal, a decision record or an agreementa curve from X, one rung back. A decision record is optional: an agreement may derive from the proposal
observes: "[[X]]"signal, insight naming a decision record or agreementa dotted loop-back under the nodes
for-domain:, bare agreement-of: "[[X]]"agreement naming a unit or work systema fine dotted line into Lands in
created_at:every entitythe age in Open ends, the order in Recently decided
status:every entitydeclined, rejected, withdrawn, superseded close an entity

An open end is an entity nothing derives from yet (agreements and outcomes are never open).

Outcomes. A decision does not only end in an agreement. Any entity that is not itself a stage and whose derived-from names a proposal, a decision record or an agreement is an outcome: a role, an interaction, a unit, a work system. It is drawn in the sixth column, headed Outcome (noun line “Agreement, role, …”), with its own kind icon and a curve from its source, and it appears in Recently decided with its date. A decision whose only follow-up is an outcome is not an open end. A unit or work system that an agreement lands in and that also derives from something is drawn once, in “Lands in”, with the curve. To show a role as the outcome of a decision, put derived-from: "[[The decision record]]" into the role’s frontmatter.

Reading and using it

  • Each column is centered on one middle line, and nodes order themselves by their neighbors, so where several signals feed one insight or one proposal fans out into several agreements, the network narrows and widens (the typical hourglass).
  • A stage with nothing in it is a narrow strip (30 px) with its label turned on its side, so the width goes to the stages in use. A stage that holds only a “Next step” ghost keeps its full width, so the ghost always has room for the ghost’s input; an empty trail keeps every column. A curve that skips a stage with nodes in it steps through the gap between them instead of across a node.
  • Names are cut with …; the full name shows in the host’s hover card.

Interaction

The first click stays on the page, like a box click that opens the drawer in the other views; leaving is the second step.

GestureOnDoes
Clickan entry, an outcome, an inline entry, a “Lands in” node, a ghost, or an item in the toolbar’s Open ends or Recently decided list (the lists hold only entries in the view)lights up every path through it, the rest goes quiet; the strip under the grid names it
Click again, or Escthe selected entryclears the selection
Clickthe backgroundnothing
Click, or Enterthe name in the stripopens the entity (its page, or its file in VS Code); a ghost and an inline entry have no link
Ctrl+click or Cmd+clickan entry, a “Lands in” node or an outcomeopens its file right away, without selecting anything. On a ghost or an inline entry (no file) it is a plain click. Shift+click is still the mark
Entera focused entry or list itemthe same as a click
Click, or Enter”+ New insight” (or the next step) in the strip of a selected ghostcreates that entity’s file; only after an entity that has a file, and only where the host can create entities (VS Code asks for the name and opens the new file with the cursor in it; the Dawn Seed App opens its New dialog). After an inline entry the strip offers nothing: the ghost itself is the way on
Click, or Entera ghostputs the text cursor into the ghost: its “Next step: Insight?” label is the placeholder. Type a name and press Enter to add an inline entry of the ghost’s own next stage (type: and derived-from:, no delta); Esc or a click elsewhere discards. Only in hosts that write the fence (the DWSD side preview in VS Code, the Dawn Seed App). There is no stage choice: to skip a stage, write the entry in the fence
Click again, Enter, or F2a selected inline entryrenames it in place: its name opens as the input, pre-filled and selected. Enter with a new name renames the entry and moves every bare derived-from / observes link in the fence that points at it along; a "[[Name]]" link is a file link and stays. The same name changes nothing. A refused name (a duplicate, or one with /) keeps the input open and the reason shows in the strip
Click, or Enter”Center here” in the strip of a selected entry, outcome, “Lands in” node or file-backed draft that is not the centerthe trail glides to the picture around: that node would draw. Offered on every node of a picture that has a center, whether or not something lies beyond it; the strip says “+N outside” for a node with neighbors that are not in view. The fence is not touched. Where the host offers it (the DWSD side preview in VS Code, the Dawn Seed App, dwsd.md)
ClickBack (the left arrow) in the toolbarone step back through the centers you visited
Right click, hold, or Shift+EnterBackthe list of every earlier center, newest first, the fence’s own center last; choose one to jump there
Clickthe center icon in the toolbarall the way back to the picture the fence asks for
ClickForward in the toolbarthe next center after going back, as in a browser. A new “Center here” clears it
Click the radius button in the toolbar, then click or drag a tick, or use the arrow keysthe radius pop-out (one row, “Steps”)the picture around the current center with that radius: Chain (the center, what it comes from and what follows from it), 1, 2, 3 steps, or all (∞). “Reset” returns to the fence’s radius:. The fence text never changes. It shows only while the picture has a center
Click”Make entity” in the strip of a selected inline entrymoves it out into a file (next to what it derives from) and leaves a reference in the fence; see below
Click”Remove draft” in the strip of a selected inline entrytakes the entry out of the fence
Shift+click, Shift+Enteran entry, a “Lands in” node or a ghostmarks it: a ring and a number badge; again removes it. Nothing else changes
Clickthe number on a mark’s badgemakes that mark the focus: everything else fades, and a click highlight ends
Clickthe X on a mark’s badgeremoves the mark
Escwith no selectionremoves your marks

The inline-entry gestures write the fence: adding an entry inserts an entries: item (and mode: mixed if the fence was infer), as the smallest possible text change; one Ctrl+Z undoes it. A fence whose entries: is an inline list (entries: [ ... ]) is read fine but the canvas will not edit it; it says so, and you edit the fence by hand. The Markdown preview only shows inline entries; it has no ghost input, no rename, no re-center, no radius and no Ctrl+click. dwsd.md shows them too and re-centers (Center here and the toolbar), but adds and renames nothing.

Make entity moves an inline entry out of the fence into a file and leaves the picture as it was. The keys that define the entity (type, derived-from, observes, status, created_at, …) go into the file, which lands next to the file the entry derives from (or next to the entity at the center), in the folder for its type when the vault has one. A delta stays in the fence. In a declared fence the item becomes a reference (- "[[Name]]", with its delta if it had one). In a mixed fence an item with nothing left to say is removed, because the organization’s trail now draws the file; one that still has a delta becomes a reference that carries it. Links to it from other items of the fence change from Name to "[[Name]]". The chain comes along: the inline entries it derives from become files too, up to the next file, so a file never contains a bare name. Make entity needs declared or mixed. An entity that lands outside radius: drops out of a mixed picture; raise the radius (the radius button in the toolbar) to bring it back. One Ctrl+Z restores the inline entries in the fence; the new files stay.

If the fence changes while you type a name into a ghost, your entry is still written: the edit is applied to the text as it is now, and only a name that clashes, or a source that is gone, is refused (and the refusal quotes what you typed).

Re-center changes what you look at and nothing you wrote: the center you choose with “Center here” and the radius you choose in the radius pop-out are view state, and the fence keeps meaning the picture its author asked for. While you type in the fence, the trail stays centered on the node you chose as long as that node is still on the trail; the center icon then returns to whatever picture the fence asks for at that moment. If the node is gone after an edit, the trail returns to the fence’s picture by itself. In the VS Code side preview a center is not saved: another fence or another note starts at its own picture.

Marks work as in the other views: an agent can point at, mark and focus an entry by its name, and an open end as <Name>/next (see the agent guide, docs/agent-usage/pointing-marking-focusing.md).

What is not there yet: the drawer, the toolbar filter and export, and re-center in the Markdown preview (it only shows). Host integration: docs/host-integration/change-trail.md; for hosts that let the canvas write, docs/host-integration/fence-edit.md.

The file type

A trail sketch can be saved as <name>.dwsd-change-trail. The file holds the fence body — the same YAML, no ``` lines. In VS Code it gets syntax highlighting, the “Open DWSD Preview” CodeLens on the first line, the side preview (which can write inline entries like a fence) and Problems. Two things to know:

  • A trail file is a view, not an entity, so there is no “own file”: around: self warns (change-trail.unresolved-focus) and shows the whole trail. Name the entity: around: "[[Name]]".
  • A mode: declared sketch needs no organization at all as long as it uses only inline entries; infer and mixed, and any reference, read the workspace’s.
  • The command-line exporter (dwsd-dsl) recognizes the file and refuses it with exit 1: the trail needs the workspace’s records and has no headless export yet.

Why there are no published Change Trail examples

The published examples/ cover the five kinds the publish pipeline can render without a workspace (board, flight route, topology, org chart, units). The Change Trail reads the whole organization’s records and has no render host in that pipeline, so there is nothing to render a picture from, and “export for the trail” is not built. The examples below are for reading and for pasting into VS Code; the demo folders and the skill card carry the rest.

Examples

Examples 1 to 4 and 6 run against the Goldcrust Bakery example organization; example 5 needs no organization.

1. The whole trail

An empty body draws every change entity of the organization, with the open ends as ghosts; the two lists are in the toolbar.

Inferred from the org folder · click an entry to light up its paths, click the name in the strip below to open it

2. Only what is still open

show: open keeps the paths through the open ends: what has been observed or decided and has not gone further yet.

Inferred from the org folder · click an entry to light up its paths, click the name in the strip below to open it

3. One proposal and its neighbors

around with radius: 1 shows the proposal, the driver it comes from and what was decided and agreed from it. Nothing in this neighborhood is open or newly decided, so both lists read 0.

Inferred from the org folder · click an entry to light up its paths, click the name in the strip below to open it

4. An inline entry over the organization’s trail

mode: mixed lays an entry over what the organization already has. The signal “Van Off the Road Twice” had no insight yet; the inline entry “Night Shift Strain” is that insight, drawn dashed, and the signal is no longer an open end. Its derived-from is a file link (the signal has a file), so it keeps the brackets. Make the entity later, from the canvas.

The org folder plus this fence's own entries · click an entry to light up its paths, click the name in the strip below to open it

5. A workshop sketch with no organization

mode: declared draws exactly the listed entries. The links between the entries are bare names, because the targets are inline entries of the same fence. The stages that hold nothing (Outcome, Lands in) are narrow strips; Decided keeps its width, because the proposal’s ghost sits there. The proposal carries delta: add to show the draft look.

Drawn from this fence's own entries · click an entry to light up its paths, click the name in the strip below to open it

6. A reference in a sketch

A declared fence can pull a file from the organization into the sketch with a "[[...]]" item. It is drawn as the file’s entity (kind, date, status); the inline entry below it derives from the file, so its link keeps the brackets.

Drawn from this fence's own entries · click an entry to light up its paths, click the name in the strip below to open it

See also

  • Units DSL — where the agreements land: the units and work systems over member-of.
  • Locator grammar — the bare [[Name]] wikilink that around takes.

Like what you see? → Start — build your own org folder in ~2 min

index.md
# Change Trail — Syntax Reference
The **Change Trail** shows how change moves through an organization, left to right: what was
**observed** (signals), what it means (**understood**: insights), which need is behind it
(**needed**: drivers), what was **proposed**, **decided** (organizational decision records) and
**agreed** (agreements), and where it **lands** (the work systems and units the agreements name). Roles,
interactions and other entities that a decision brought about show up in an **Outcome** column.
The whole network stays open; every open end gets a ghost with its next step, and two lists sit
in the view's toolbar above it: **Open ends** (oldest first) and **Recently decided** (the
newest decisions, agreements and outcomes). Each is a button with its count ("Open ends 5") that opens the
list. (The lists were called "Continue" and "Done recently" in earlier versions; only the labels changed.)
The lists hold only what the view shows: with `around` or `show`, an open end or a decision outside the
view is left out, and a list with nothing in view reads 0. The grid uses the whole width and opens
fitted to it, like the other views (−, Fit and + in the same toolbar), but never below 75 % of its
natural size, so the names stay readable; a trail wider than its column then scrolls sideways, and −
still zooms out to the full width. Its height follows the rows of entries.
The view is drawn in the text color of the page around it, on a transparent canvas, so it reads the
same in a light and a dark theme; only a selection is colored (the selection blue of every view).
By default the view has no entities of its own: it reads the organization's change entities
(`mode: infer`). A fence can also **declare** a trail, or lay **inline entries** over the organization's
trail (see Modes). Inside Markdown the fence is **```` ```dwsd.change-trail ````** (`dwsd-change-trail`,
`wsd.change-trail` and `wsd-change-trail` are tolerated); a sketch can also live in its own
`.dwsd-change-trail` file (see The file type). The body is plain **YAML**, and it may be empty:
````markdown
```dwsd.change-trail
```
````
## Parameters
| Key | Values | Default | Meaning |
|---|---|---|---|
| `around` | `"[[Entity]]"` or `self` | none | Center on one entity: everything it comes from, back to the signals, and everything that follows from it, forward to where it lands — nothing else. A driver spreads to both sides, an agreement only backwards. With `radius`, the entities within that many steps instead. `self` is the entity whose file holds the fence. The old spelling `focus` still works and shows an INFO (`change-trail.retired-focus`). With both keys, `around` wins (`change-trail.around-and-focus`). The center may also be an inline entry of the fence. |
| `show` | `all` \| `open` \| `recent` | `all` | `open`: only the paths through open ends. `recent`: only the paths through Recently decided. |
| `radius` | a whole number, or `inf` | none | Steps around `around`, along the trail in both directions. |
| `mode` | `infer` \| `declared` \| `mixed` | `infer` | Where the trail comes from (next section). |
| `entries` | a list of inline entries (`name`, `type`, `derived-from`, …) and references (`"[[Name]]"`) | none | The fence's own entries: a declared trail, or entries laid over the organization's. Ignored in `infer` (warning `change-trail.entries-ignored`). |
````markdown
```dwsd.change-trail
around: "[[Prioritize Morning Sourdough]]"
radius: 1
```
````
Put the fence into an entity's own file with `around: self` and it shows that entity's part of the
trail; the same fence works in every such file. The entity in the middle carries a dashed ring.
A sibling is not part of it: two drivers drawn from the same insight do not show each other — `radius`
brings the neighborhood in on purpose. A work system or unit in "Lands in" is only context on the way;
as the center itself (in its own file, or `around: "[[Bakehouse]]"`) it shows every agreement that lands
there and everything each one came from — the question "do the old and the new agreements of this
work system fit together?" Outside an entity's file `self` names nothing, and the
view shows the whole trail with a note.
````markdown
```dwsd.change-trail
around: self
```
````
The stages are fixed: Observed, Understood, Needed, Proposed, Decided, Agreed (headed Outcome, see
Reading), plus Lands in. Unknown keys (also an entry key at the top level) and bad values raise a warning and
fall back to the default; the view always draws (an organization without change entities shows the empty
grid and a note). More than 20 entries with no `around`: the view shows the most recent whole chains
that fit in 20 entries (a chain is never cut in the middle, and the newest chain is always shown), with
the places they land in, and says how many there are in all ("17 of 26 entries shown"); set `around:`
to choose another part.
**Migrating a fence that still says `focus:`:** rename it to `around:` (same values). Nothing breaks if
you do not; the INFO is a reminder.
## Modes
`mode:` decides where the trail comes from.
| `mode` | The trail is | Needs the organization |
|---|---|---|
| `infer` (default) | read from the organization's change entities, as always | yes |
| `declared` | exactly what `entries:` lists, plus the files it references; the rest of the organization is ignored | no — a workshop sketch (references need it) |
| `mixed` | the organization's trail with `entries:` laid over it | yes |
### Inline entries and references
The brackets decide what an `entries:` item is: **`[[...]]` always means a file; a bare name means something in this fence.**
| Item | Is |
|---|---|
| `name: Night Shift Strain` | an **inline entry**: defined right here, no file behind it |
| `- "[[Night Shift Strain]]"` or `name: "[[Night Shift Strain]]"` | a **reference**: the file is the definition; the fence only says "this one is on the sketch" and may annotate it with `delta` |
An inline entry carries the keys of its file, in the same format. A reference carries only `delta`; any other key on a
reference warns (`change-trail.reference-key`: "the file defines this").
| Key | Values | Meaning |
|---|---|---|
| `name` | text | The entry's name. It stands for the file name; this is the one key a file does not have. |
| `type` | `signal`, `insight`, `driver`, `proposal`, `organizational-decision-record`, `agreement` | Which column it sits in, with the same value the file's `type:` has. A missing or unknown type drops the item (`change-trail.unknown-type`). |
| `derived-from` | a bare name, `"[[Name]]"`, or a list of them | The step (or steps) it comes from; draws the curve. |
| `observes` | a bare name, `"[[Name]]"`, or a list | On a decision record or an agreement: the loop-back, as in a file. |
| `for-domain`, `agreement-of` | `"[[Unit or Work System]]"` | On an agreement: the line into "Lands in", when that place is already on the trail. These point at things that are never inline, so a bare name warns. |
| `status` | text | Counts as in a file: `declined`, `rejected`, `withdrawn`, `superseded` close the entry. |
| `created_at` | `YYYY-MM-DD` | The entry's date: its age, its place in the order. |
| `delta` | `add`, `remove`, or none | A note for the sketch, on either kind of item. `add` paints the item as a draft (dashed, in the add color). `remove` keeps the node on the canvas, struck through, in the remove color: "going away". Without a `delta` an item is a plain one. |
**A link says where its target lives by its form.** `derived-from: Handover Depends on Memory` points at the inline entry
of that name in this fence; `derived-from: "[[Handover Depends on Memory]]"` points at the file. One rule for every link key.
A locator such as `"[[Board]]#col:Review"` stays as it is. `around:` is a fence parameter, not an entry link, so
`around: "[[Name]]"` may name an inline entry too.
How they are drawn:
- An **inline entry** in a `mixed` fence is dashed, in the add color, wired to what it derives from. The entry it derives from
is no longer an open end (the inline entry is the next step); the inline entry gets its own ghost one column on. In a
`declared` fence it is an ordinary node (dashed only with `delta: add`). Either way it is **not an entity**: nothing opens
when you click its name, because there is no file yet.
- A **reference** is drawn as the file's entity, with its kind, date and status. In `declared` it is drawn from the
organization's file, with the organization's own curves between the items the fence lists; without the organization's files
it cannot be drawn and warns (`change-trail.unresolved-reference`). In `mixed` a reference to a file already on the trail
changes nothing by itself; with `delta: add` it is drawn dashed, with `delta: remove` struck through.
- Where a **file of the same name as an inline entry exists**, the file wins and the inline entry is not drawn twice. The
line in the fence stays, and Problems says `change-trail.inline-file-exists`: "a file of that name exists"; write
`"[[Name]]"` to point at it.
- Warnings on the item's own line: `change-trail.bare-link-unresolved` (a bare link that names no inline entry of this fence:
"did you mean `[[Name]]`?"), `change-trail.unresolved-derived-from` (a `"[[Name]]"` link that names nothing on the trail),
`change-trail.remove-unknown` (a `remove` that names nothing; a place cannot be removed),
`change-trail.invalid-entry` (not a list, not a mapping, no name, an unknown key), `change-trail.unknown-delta`,
`change-trail.duplicate-entry` (the second one is ignored), `change-trail.unknown-mode`. `delta: change` is not supported
yet: it warns and the item is drawn without a delta.
- To make a node appear for real, author the **entity** (a Markdown file with `type:` and `derived-from:`) — or, in a
`mixed` fence, write an **inline entry** and make the entity later (Interaction).
**Migrating a fence written before the entry format changed.** Rename the entry key `stage:` to `type:`, and spell the
decision record `organizational-decision-record` (the short `odr` is gone). A link between two inline entries of the same fence
loses its brackets; a link to a file keeps them. There is no alias: an item that still says `stage:` warns
(`change-trail.retired-stage-key`) and, without a valid `type:`, is dropped. A quoted `name: "[[X]]"` now means a reference.
## What it reads
| Frontmatter | On | Draws |
|---|---|---|
| `type:` | every entity | the column (stage) |
| `derived-from: "[[X]]"` (or a list) | insight, driver, proposal, decision record, agreement — and any other entity that came out of a proposal, a decision record or an agreement | a curve from X, one rung back. A decision record is optional: an agreement may derive from the proposal |
| `observes: "[[X]]"` | signal, insight naming a decision record or agreement | a dotted loop-back under the nodes |
| `for-domain:`, bare `agreement-of: "[[X]]"` | agreement naming a unit or work system | a fine dotted line into **Lands in** |
| `created_at:` | every entity | the age in Open ends, the order in Recently decided |
| `status:` | every entity | `declined`, `rejected`, `withdrawn`, `superseded` close an entity |
An **open end** is an entity nothing derives from yet (agreements and outcomes are never open).
**Outcomes.** A decision does not only end in an agreement. Any entity that is not itself a stage and whose
`derived-from` names a proposal, a decision record or an agreement is an **outcome**: a role, an interaction,
a unit, a work system. It is drawn in the sixth column, headed **Outcome** (noun line "Agreement, role, …"),
with its own kind icon and a curve from its source, and it appears in **Recently decided** with its date. A
decision whose only follow-up is an outcome is not an open end. A unit or work system that an agreement lands
in and that also derives from something is drawn once, in "Lands in", with the curve. To show a role as the
outcome of a decision, put `derived-from: "[[The decision record]]"` into the role's frontmatter.
## Reading and using it
- Each column is centered on one middle line, and nodes order themselves by their neighbors, so
where several signals feed one insight or one proposal fans out into several agreements, the
network narrows and widens (the typical hourglass).
- **A stage with nothing in it is a narrow strip** (30 px) with its label turned on its side, so the width
goes to the stages in use. A stage that holds only a "Next step" ghost keeps its full width, so the ghost
always has room for the ghost's input; an empty trail keeps every column. A curve that skips a stage with nodes in it
steps through the gap between them instead of across a node.
- Names are cut with `…`; the full name shows in the host's hover card.
## Interaction
The first click stays on the page, like a box click that opens the drawer in the other views;
leaving is the second step.
| Gesture | On | Does |
|---|---|---|
| Click | an entry, an outcome, an inline entry, a "Lands in" node, a ghost, or an item in the toolbar's Open ends or Recently decided list (the lists hold only entries in the view) | lights up every path through it, the rest goes quiet; the strip under the grid names it |
| Click again, or Esc | the selected entry | clears the selection |
| Click | the background | nothing |
| Click, or Enter | the name in the strip | opens the entity (its page, or its file in VS Code); a ghost and an inline entry have no link |
| **Ctrl+click** or **Cmd+click** | an entry, a "Lands in" node or an outcome | opens its file right away, without selecting anything. On a ghost or an inline entry (no file) it is a plain click. Shift+click is still the mark |
| Enter | a focused entry or list item | the same as a click |
| Click, or Enter | "+ New insight" (or the next step) in the strip of a selected ghost | creates that entity's **file**; only after an entity that has a file, and only where the host can create entities (VS Code asks for the name and opens the new file with the cursor in it; the Dawn Seed App opens its New dialog). After an inline entry the strip offers nothing: the ghost itself is the way on |
| Click, or Enter | a ghost | puts the text cursor **into the ghost**: its "Next step: Insight?" label is the placeholder. Type a name and press **Enter** to add an **inline entry** of the ghost's own next stage (`type:` and `derived-from:`, no `delta`); **Esc** or a click elsewhere discards. Only in hosts that write the fence (the DWSD side preview in VS Code, the Dawn Seed App). There is no stage choice: to skip a stage, write the entry in the fence |
| Click again, Enter, or F2 | a selected inline entry | renames it in place: its name opens as the input, pre-filled and selected. **Enter** with a new name renames the entry **and moves every bare `derived-from` / `observes` link in the fence that points at it** along; a `"[[Name]]"` link is a file link and stays. The same name changes nothing. A refused name (a duplicate, or one with `/`) keeps the input open and the reason shows in the strip |
| Click, or Enter | "Center here" in the strip of a selected entry, outcome, "Lands in" node or file-backed draft that is not the center | the trail glides to the picture `around:` that node would draw. Offered on every node of a picture that has a center, whether or not something lies beyond it; the strip says "+N outside" for a node with neighbors that are not in view. The fence is not touched. Where the host offers it (the DWSD side preview in VS Code, the Dawn Seed App, dwsd.md) |
| Click | **Back** (the left arrow) in the toolbar | one step back through the centers you visited |
| Right click, hold, or Shift+Enter | **Back** | the list of every earlier center, newest first, the fence's own center last; choose one to jump there |
| Click | the **center** icon in the toolbar | all the way back to the picture the fence asks for |
| Click | **Forward** in the toolbar | the next center after going back, as in a browser. A new "Center here" clears it |
| Click the **radius** button in the toolbar, then click or drag a tick, or use the arrow keys | the radius pop-out (one row, "Steps") | the picture around the current center with that radius: Chain (the center, what it comes from and what follows from it), 1, 2, 3 steps, or all (∞). "Reset" returns to the fence's `radius:`. The fence text never changes. It shows only while the picture has a center |
| Click | "Make entity" in the strip of a selected inline entry | moves it out into a file (next to what it derives from) and leaves a reference in the fence; see below |
| Click | "Remove draft" in the strip of a selected inline entry | takes the entry out of the fence |
| Shift+click, Shift+Enter | an entry, a "Lands in" node or a ghost | marks it: a ring and a number badge; again removes it. Nothing else changes |
| Click | the number on a mark's badge | makes that mark the focus: everything else fades, and a click highlight ends |
| Click | the X on a mark's badge | removes the mark |
| Esc | with no selection | removes your marks |
The inline-entry gestures **write the fence**: adding an entry inserts an `entries:` item (and `mode: mixed` if the
fence was `infer`), as the smallest possible text change; one Ctrl+Z undoes it. A fence whose `entries:` is
an inline list (`entries: [ ... ]`) is read fine but the canvas will not edit it; it says so, and you edit
the fence by hand. The Markdown preview only **shows** inline entries; it has no ghost input, no rename, no
re-center, no radius and no Ctrl+click. dwsd.md shows them too and re-centers (Center here and the toolbar), but adds and
renames nothing.
**Make entity** moves an inline entry out of the fence into a file and leaves the picture as it was. The keys that define the
entity (`type`, `derived-from`, `observes`, `status`, `created_at`, …) go into the file, which lands next to the file the entry
derives from (or next to the entity at the center), in the folder for its type when the vault has one. A `delta` stays in the
fence. In a `declared` fence the item becomes a reference (`- "[[Name]]"`, with its `delta` if it had one). In a `mixed` fence
an item with nothing left to say is removed, because the organization's trail now draws the file; one that still has a `delta`
becomes a reference that carries it. Links to it from other items of the fence change from `Name` to `"[[Name]]"`. **The chain
comes along:** the inline entries it derives from become files too, up to the next file, so a file never contains a bare
name. Make entity needs `declared` or `mixed`. An entity that lands outside `radius:` drops out of a `mixed` picture; raise
the radius (the radius button in the toolbar) to bring it back. One Ctrl+Z restores the inline entries in the fence; the new files stay.
If the fence changes while you type a name into a ghost, your entry is still written: the edit is applied to the text as it is
now, and only a name that clashes, or a source that is gone, is refused (and the refusal quotes what you typed).
**Re-center** changes what you look at and nothing you wrote: the center you choose with "Center here" and the radius you
choose in the radius pop-out are view state, and the fence keeps meaning the picture its author asked for. While you type in the fence, the trail stays centered on the node you
chose as long as that node is still on the trail; the center icon then returns to whatever picture the fence asks for at
that moment. If the node is gone after an edit, the trail returns to the fence's picture by itself. In the VS Code side preview a center is not saved:
another fence or another note starts at its own picture.
Marks work as in the other views: an agent can point at, mark and focus an entry by its name, and an
open end as `<Name>/next` (see the agent guide, `docs/agent-usage/pointing-marking-focusing.md`).
What is not there yet: the drawer, the toolbar filter and export, and re-center in the Markdown preview
(it only shows). Host integration: `docs/host-integration/change-trail.md`; for hosts that let the
canvas write, `docs/host-integration/fence-edit.md`.
## The file type
A trail sketch can be saved as **`<name>.dwsd-change-trail`**. The file holds the fence body — the same YAML,
no ```` ``` ```` lines. In VS Code it gets syntax highlighting, the "Open DWSD Preview" CodeLens on the first
line, the side preview (which can write inline entries like a fence) and Problems. Two things to know:
- A trail file is a view, not an entity, so there is no "own file": `around: self` warns
(`change-trail.unresolved-focus`) and shows the whole trail. Name the entity: `around: "[[Name]]"`.
- A `mode: declared` sketch needs no organization at all as long as it uses only inline entries; `infer` and `mixed`, and any
reference, read the workspace's.
- The command-line exporter (`dwsd-dsl`) recognizes the file and refuses it with exit 1: the trail needs the
workspace's records and has no headless export yet.
## Why there are no published Change Trail examples
The published `examples/` cover the five kinds the publish pipeline can render without a workspace (board,
flight route, topology, org chart, units). The Change Trail reads the whole organization's records and has no
render host in that pipeline, so there is nothing to render a picture from, and "export for the trail" is
not built. The examples below are for reading and for pasting into VS Code; the demo folders and the skill card carry the
rest.
## Examples
Examples 1 to 4 and 6 run against the Goldcrust Bakery example organization; example 5 needs no organization.
### 1. The whole trail
An empty body draws every change entity of the organization, with the open ends as ghosts; the
two lists are in the toolbar.
```dwsd.change-trail
# 1 — the whole trail: every change entity of the organization, left to right.
```
### 2. Only what is still open
`show: open` keeps the paths through the open ends: what has been observed or decided and has not
gone further yet.
```dwsd.change-trail
# 2 — only the paths through open ends.
show: open
```
### 3. One proposal and its neighbors
`around` with `radius: 1` shows the proposal, the driver it comes from and what was decided and
agreed from it. Nothing in this neighborhood is open or newly decided, so both lists read 0.
```dwsd.change-trail
# 3 — one proposal, one step around it in both directions.
around: "[[Prioritize Morning Sourdough]]"
radius: 1
```
### 4. An inline entry over the organization's trail
`mode: mixed` lays an entry over what the organization already has. The signal "Van Off the Road Twice" had
no insight yet; the inline entry "Night Shift Strain" is that insight, drawn dashed, and the signal is no longer an
open end. Its `derived-from` is a file link (the signal has a file), so it keeps the brackets. Make the entity later, from the canvas.
```dwsd.change-trail
# 4 — one inline insight over the organization's trail.
around: "[[Van Off the Road Twice]]"
mode: mixed
entries:
- name: Night Shift Strain
type: insight
derived-from: "[[Van Off the Road Twice]]"
```
### 5. A workshop sketch with no organization
`mode: declared` draws exactly the listed entries. The links between the entries are bare names, because the targets are
inline entries of the same fence. The stages that hold nothing (Outcome, Lands in) are narrow strips; Decided keeps its
width, because the proposal's ghost sits there. The proposal carries `delta: add` to show the draft look.
```dwsd.change-trail
# 5 — a sketch from the fence alone: four inline entries, the last one marked as a draft.
mode: declared
entries:
- name: Orders Missed at Shift Change
type: signal
- name: Handover Depends on Memory
type: insight
derived-from: Orders Missed at Shift Change
- name: Reliable Handover
type: driver
derived-from: Handover Depends on Memory
- name: Written Shift Log
type: proposal
derived-from: Reliable Handover
delta: add
```
### 6. A reference in a sketch
A `declared` fence can pull a file from the organization into the sketch with a `"[[...]]"` item. It is drawn as the file's
entity (kind, date, status); the inline entry below it derives from the file, so its link keeps the brackets.
```dwsd.change-trail
# 6 — a reference to a file, and an inline entry that continues it.
mode: declared
entries:
- "[[Market Street Morning Sourdough Shortfall]]"
- name: Weekend Sourdough Buffer
type: driver
derived-from: "[[Market Street Morning Sourdough Shortfall]]"
```
## See also
- [Units DSL](../units/index.md) — where the agreements land: the units and work systems over
`member-of`.
- [Locator grammar](../locator-grammar.md) — the bare `[[Name]]` wikilink that `around` takes.