Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ derives_from:
- fnd-workshop-shortlist-favors-crumb-graph-over-yeast--tv3ydt3wfb3n4y0g
supersedes:
- dec-brand-the-agent-memory-surface-as-crumb-graph--fvskcvagx3a7sybe
superseded_by:
- dec-keep-effort-graph-as-the-product-name--r5wr2vdjwjs9bs13
Comment on lines +12 to +13

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HIGH (docs-and-positioning) — This PR adds superseded_by but leaves state: accepted and a body that still commits to Crumb Trail as the product name. Frontmatter, edges, and prose disagree.

Minimal fix: Repair via reindexer (state: superseded) per iss-writedecision-with-supersedes-…, or add a top-of-body supersession banner pointing at dec-keep-effort-graph… until repaired.

---

Supersedes Crumb Graph as the product name. Same system and deferred implementation; product brand is now Crumb Trail, with Crumb Graph retained as the datamodel explainer.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
id: dec-keep-effort-graph-as-the-product-name--r5wr2vdjwjs9bs13
effort: eff-flatbread-product-branding--zt7b35sa05kyvhdz
title: Keep Effort Graph as the product name
state: accepted
created_at: '2026-07-26T03:27:20.788Z'
derives_from:
- fnd-crumb-rebrand-refuted-in-review-effort-graph-is--n8kb269z7vz8jhyk
supersedes:
- dec-brand-the-agent-memory-surface-as-crumb-trail--tngncepdbwjkh9jc
---

Supersedes Crumb Trail (and, transitively, Crumb Graph). The rebrand line is refuted: **Effort Graph** is the product name for Flatbread's longform agent memory, and crumb naming is dropped entirely rather than retained as a datamodel explainer.

## Context

Two prior Decisions moved the brand from Effort Graph to Crumb Graph and then to Crumb Trail, each time deferring the package, CLI, path, and skill renames. Review of the accumulated naming stack found the crumb metaphor works against the product: crumbs connote leftovers in a system whose pitch is durable, trustworthy reasoning, and _crumb trail_ is already taken by breadcrumb navigation in UI vocabulary. Meanwhile every identifier a user touches — `@flatbread/effort-graph`, `flatbread effort`, `.flatbread-efforts/`, the `effort-graph` skill — still said Effort.

## Decision

Adopt **Effort Graph** as the product name, not merely an allowed technical descriptor. Retire **Crumb Graph** and **Crumb Trail**; neither is a product name, a datamodel explainer, nor a documented alias.

Describe the datamodel in plain terms — Effort-scoped relational records with typed edges and bounded digests — instead of coining a second branded layer for it.

No rename work is required or deferred: code, packages, CLI, paths, and skills already match the product name, and that alignment is now the point rather than a coincidence.

## Alternatives considered

- **Keep Crumb Trail as the brand and finally execute the renames.** Rejected: it pays a full breaking-rename cost to buy a metaphor that review judged actively misleading.
- **Keep Crumb Trail for marketing, Effort Graph in code.** Rejected: this is the status quo the prior Decisions created, and it is the failure mode — a permanent gap between what the docs call the product and what every command and import path calls it.
- **Keep Crumb Graph as a datamodel explainer only.** Rejected: a second branded vocabulary for the same graph adds a translation step without adding precision over saying Effort-scoped records and edges.
- **Pick a third unleavened, Proof-peer name.** Rejected for now: naming churn has already cost two Decisions and two stale Issues, and no candidate beats the name that the API already teaches.

## Consequences

- Docs, skills copy, and product messaging use Effort Graph with no crumb aliases; existing crumb references are wording bugs to fix, not variants to preserve.
- The rename Issues under this Effort close as wontfix — the work is cancelled, not postponed.
- Brand and implementation vocabulary are unified, so future naming pressure has to argue for renaming real identifiers rather than only marketing copy.
- Flatbread gives up a bread-metaphor peer to Proof for this surface. That is accepted: primitive fidelity beats metaphor symmetry here.

## Reversal criteria

Revisit only if Effort Graph measurably fails external comprehension — for example if users read Effort as project-management effort tracking or story points rather than a thread of work — and a candidate name wins while committing to rename the packages, CLI, and paths in the same Decision rather than deferring them again.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
id: fnd-crumb-rebrand-refuted-in-review-effort-graph-is--n8kb269z7vz8jhyk
effort: eff-flatbread-product-branding--zt7b35sa05kyvhdz
title: Crumb rebrand refuted in review; Effort Graph is the retained name
kind: dead-end
created_at: '2026-07-26T03:26:52.792Z'
derives_from:
- fnd-postable-brand-names-favor-trail-over-graph--zzpgaw0kvqtaqmxt
- fnd-workshop-shortlist-favors-crumb-graph-over-yeast--tv3ydt3wfb3n4y0g
---

## What happened

The Crumb Graph → Crumb Trail branding line was grilled in review and refuted. The owner call is to keep **Effort Graph** as the product name for Flatbread's longform agent memory, not as a fallback technical alias.

## Why the rebrand did not hold

- **Crumb reads as leftovers, not memory.** In a product about durable reasoning, the metaphor undercuts the value claim: crumbs are what falls off the loaf, not the record you are meant to trust.
- **Crumb collides with breadcrumbs.** In UI vocabulary a crumb trail is a navigation path widget. Users landing on the docs pattern-match to breadcrumb navigation before they reach agent memory.
- **Effort Graph already names the load-bearing primitive.** Every record belongs to exactly one Effort. A brand that hides the Effort primitive forces a second vocabulary on top of the one the API, CLI, and skills already teach.
- **The rebrand's own reversal criteria fired.** Both prior Decisions listed external-comprehension failure and crumb ≈ breadcrumbs/scraps confusion as revisit triggers. Review found exactly those failures, so the Decisions closed themselves out on their stated terms.
- **Deferring implementation hid the cost.** Both Decisions deferred the package/CLI/path/skill renames, which kept the accepted brand permanently out of sync with every identifier a user actually touches.

## Standing evidence

The two workshop Findings remain accurate as records of what those exercises produced — the shortlist did favor crumb over yeast metaphors, and trail did test as more postable than graph. Neither is invalidated. What is refuted is treating brandability as decisive over primitive fidelity and collision risk.

## Consequence

The rename work tracked by both implementation Issues is a dead end and should close as wontfix rather than stay open as latent debt.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
id: fnd-supersession-transitions-decision-state-on-the-r--2m807tcfjz2jz9gt
effort: eff-effort-graph-memory-and-agent-wedge--szeqvmgqjqnhd002
title: >-
Supersession transitions Decision state on the retro-link path but not on
create
kind: survey
created_at: '2026-07-26T05:06:57.371Z'
---

## Observation

`packages/effort-graph/src/planner.ts` has two code paths that create a `supersedes` edge, and they disagree about whether the superseded Decision changes state.

- **Retro-link (`Supersede` mutation), planner.ts ~195-215.** When the target is a Decision it composes `supersedeDecisionLifecycle(snapshot, b.id).nextFrontmatter`, which sets `state: 'superseded'`, then appends the `superseded_by` back-pointer.
- **Inline on create (`WriteDecision` with `supersedes: [...]`), planner.ts ~127-160.** The generic forward-edge loop only appends the `superseded_by` reverse projection. It never consults `supersedeDecisionLifecycle` and never touches `state`.

## Evidence

Two records in this repo's own graph show the create-path outcome — both carry `superseded_by` while still reporting `state: accepted`:

- `dec-brand-the-agent-memory-surface-as-crumb-graph--fvskcvagx3a7sybe`
- `dec-brand-the-agent-memory-surface-as-crumb-trail--tngncepdbwjkh9jc`

`DecisionFrontmatterSchema` in `schemas.ts` already admits `'superseded'`, and `decision-lifecycle.ts` exists to produce it, so this is an inconsistency between the two paths rather than a deliberate modelling choice.

The blind spot is a test gap: the planner suite covers the create path with `supersedes` only for Findings, which have no state field, so the Decision case is unexercised.

## Why it matters beyond cosmetics

- `planner.ts` gates `MitigateRisk` on `state !== 'accepted'`, so a superseded Decision can currently mitigate a Risk.
- `flatbread effort records --state accepted` returns retired Decisions.
- Consumers reading `state` directly label retired reasoning as committed. `examples/effort-viz` now carries a dedicated module (`lib/lifecycle.ts`) that derives effective lifecycle from edges specifically to work around this.
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ id: iss-implement-crumb-graph-rename-across-packages-cli--dp6jvt2kafab7m4t
effort: eff-flatbread-product-branding--zt7b35sa05kyvhdz
title: 'Implement Crumb Graph rename across packages, CLI, paths, and skills'
kind: gap
status: open
status: wontfix
created_at: '2026-07-19T03:45:50.712Z'
derives_from:
- dec-brand-the-agent-memory-surface-as-crumb-graph--fvskcvagx3a7sybe
superseded_by:
- iss-implement-crumb-trail-rename-across-packages-cli--316rdzpt80sdxkw1
resolved_by:
- dec-keep-effort-graph-as-the-product-name--r5wr2vdjwjs9bs13
---

Branding Decision accepts Crumb Graph as the product name with Effort Graph as descriptor. Implementation is pending and out of scope for the branding commit.

Likely touchpoints (non-exhaustive): `@flatbread/effort-graph`, `effortGraphContent`, `flatbread effort` CLI, `.flatbread-efforts/`, `.flatbread/effort-graph/`, agent skill name/paths, docs/README copy, error codes (`EFFORT_GRAPH_*`), and dogfood references.

Do not start the mechanical rename until an implementation plan chooses which identifiers move vs stay for compatibility.

Resolution: cancelled as `wontfix`; product name is Effort Graph; resolved by `dec-keep-effort-graph-as-the-product-name--r5wr2vdjwjs9bs13`; do not reopen rename work.
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ id: iss-implement-crumb-trail-rename-across-packages-cli--316rdzpt80sdxkw1
effort: eff-flatbread-product-branding--zt7b35sa05kyvhdz
title: 'Implement Crumb Trail rename across packages, CLI, paths, and skills'
kind: gap
status: open
status: wontfix

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HIGH (docs-and-positioning) — Frontmatter is wontfix/resolved_by, but the body still says Crumb Trail branding and “Implementation remains pending,” inviting agents to reopen cancelled rename work.

Minimal fix: Append a short resolution note that the rename is cancelled and Effort Graph is the product name. (Same issue on the Crumb Graph twin Issue.)

created_at: '2026-07-19T03:54:27.962Z'
derives_from:
- dec-brand-the-agent-memory-surface-as-crumb-trail--tngncepdbwjkh9jc
supersedes:
- iss-implement-crumb-graph-rename-across-packages-cli--dp6jvt2kafab7m4t
resolved_by:
- dec-keep-effort-graph-as-the-product-name--r5wr2vdjwjs9bs13
---

Supersedes the Crumb Graph rename Issue. Branding now targets Crumb Trail as the product name (Crumb Graph = datamodel explainer; Effort Graph = technical descriptor).

Implementation remains pending. Likely touchpoints (non-exhaustive): `@flatbread/effort-graph`, `effortGraphContent`, `flatbread effort` CLI, `.flatbread-efforts/`, `.flatbread/effort-graph/`, agent skill name/paths, docs/README copy, error codes (`EFFORT_GRAPH_*`), and dogfood references.

Do not start the mechanical rename until an implementation plan chooses which identifiers move vs stay for compatibility, and how Crumb Trail / Crumb Graph / Effort Graph map onto public vs internal names.

Resolution: cancelled as `wontfix`; product name is Effort Graph; resolved by `dec-keep-effort-graph-as-the-product-name--r5wr2vdjwjs9bs13`; do not reopen rename work.
Comment on lines +21 to +22

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HIGH (docs-and-positioning) — Frontmatter/resolved_by say wontfix, but the body still leads with Crumb Trail branding and pending implementation, inviting agents to reopen cancelled rename work. Same pattern on the Crumb Graph twin Issue.

Minimal fix: Rewrite the body lead to past-tense cancellation (Effort Graph retained per dec-keep-effort-graph…); demote stale Crumb copy to historical context.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
id: iss-writedecision-with-supersedes-leaves-the-superse--by624gyf21ex42sv
effort: eff-effort-graph-memory-and-agent-wedge--szeqvmgqjqnhd002
title: WriteDecision with supersedes leaves the superseded Decision in state accepted
kind: defect
status: open
created_at: '2026-07-26T05:07:15.240Z'
derives_from:
- fnd-supersession-transitions-decision-state-on-the-r--2m807tcfjz2jz9gt
---

## Problem

Creating a Decision with an inline `supersedes` edge appends the `superseded_by` reverse projection to the target but leaves its `state` untouched, so a replaced Decision keeps reporting `state: accepted`. The `Supersede` retro-link mutation on the same target does set `state: superseded`. Same semantic act, two different outcomes depending on which mutation got there first.

## Fix sketch

In the create-path forward-edge loop in `packages/effort-graph/src/planner.ts`, when `edge === 'supersedes'` and the target is a Decision, compose `supersedeDecisionLifecycle(snapshot, target.id).nextFrontmatter` before appending the back-pointer — the same composition the `Supersede` branch already performs. Add a planner test mirroring the existing retro-link supersession test but driven through `WriteDecision`, since the current create-path test only covers Findings and so cannot catch this.

## Repair

Two records in this repo already carry the bad shape (`dec-brand-the-agent-memory-surface-as-crumb-graph--fvskcvagx3a7sybe`, `dec-brand-the-agent-memory-surface-as-crumb-trail--tngncepdbwjkh9jc`). Repair them through the reindexer rather than by hand-editing frontmatter.

## Scope note

Consumers should keep deriving supersession from edges regardless of the fix: forward edges are the authoritative representation, and edge-derived state also covers legacy and hand-edited records. `examples/effort-viz/lib/lifecycle.ts` does this and should not be reverted once the writer is corrected.
76 changes: 66 additions & 10 deletions examples/effort-viz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,69 @@ Flatbread serves GraphQL at **`http://localhost:5057/graphql`**. The app
subscribes to **`http://localhost:5057/events`** (SSE) for schema generation
updates.

## What you get
## What you can read off it

Within a few seconds of opening the page you should be able to answer:

- **What kinds of records are here?** Every primitive has its own hue *and* its
own silhouette — Issues are amber diamonds, Findings blue circles, Decisions
violet squares, Constraints green/teal slabs (flat bars), Risks red triangles,
and each Effort is a ring whose core carries that cluster's tint.
- **What is still live, and what got overturned?** Rejected, superseded,
invalidated, won't-fix, deprecated, and abandoned records fade to a
desaturated ghost with a struck-through label. Supersession is derived from
the graph's edges rather than from frontmatter, because forward edges are the
authoritative representation and `state` can lag behind them — a Decision
replaced through an inline `supersedes` still records `state: accepted`, so
reading the field alone would label retired reasoning as committed.
- **What is blocking?** Open Issues with `kind: blocker` wear an amber warning
outline.
- **How much work is tracked?** The header counts primitives and lifecycle
(`5 Efforts · 4 open Issues · 3 proposed Decisions`) rather than nodes and
edges — roughly half the "edges" are synthesised membership spokes, so a raw
edge count flatters the graph without informing anyone.

## Encoding notes

Hue belongs to the **primitive**, not the Effort. Effort membership is already
carried by three other channels — the force layout pulls same-Effort records to
a shared centroid, each cluster has a large labelled hub, and membership spokes
take the cluster's tint — so spending the strongest nominal channel on it left
record kind with nothing. Shape repeats hue as a colour-vision backstop, since
amber/red and blue/violet partially merge under deuteranopia. Silhouettes are
area-normalized (`lib/glyphs.ts`) so a triangle and a square read at the same
visual weight; otherwise size would imply an importance ranking nobody
intended.

The legend derives its swatches from the same outlines and palette the canvas
builds geometry from (`lib/glyphs.ts`, `lib/primitives.ts`), so it cannot drift
from the render, and it only lists the relations the current generation actually
contains.

## Other features

- **Live graph** — `useEffortGraphLive` opens an `EventSource` on `/events`.
On `ready` and each `generation` event it refetches the Effort Graph query and
updates the canvas. The status pill shows connecting / live / disconnected and
the current generation.
updates the canvas. The status pill shows connecting / live / partial /
disconnected / error and the current generation. **Partial** means records
loaded but relationship fields could not be confirmed yet — retirement links
may be missing until the next successful schema probe.
Comment on lines +82 to +85

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MED (docs-and-positioning; disputed with dx-and-examples) — README defines Partial as “relationship fields could not be confirmed yet,” but sticky last-good after a failed probe still reports Live. Operators can trust Live while newly grown relation fields stay unselected.

Minimal fix (this round): One sentence that sticky cached schema keeps Live; only a successful re-probe picks up new relation fields. Do not require a Partial code flip unless product wants it.

- **Watch mode** — `flatbread start --watch` reloads content and config changes
under `.flatbread-efforts`. Edit an effort, issue, or finding file and the
under `.flatbread-efforts`. Edit an Effort, Issue, or Finding file and the
graph animates in/out without restarting Next.
- **R3F canvas** — orthographic 2D scene with pan/zoom, node labels, edge
“veins”, spawn/retract physics, and a detail drawer on node click.
- **Theme** — sun/moon toggle in the top bar; preference persists in
`localStorage` (`effort-viz-theme`) with a boot script to avoid FOUC.
- **R3F canvas** — orthographic 2D scene with pan/zoom, cluster labels, edge
“veins”, spawn/retract physics, and a detail drawer on record click.
- **Keyboard** — Tab to the canvas, then arrow keys to walk records in a stable
Effort-then-primitive order, Enter to open the drawer, Escape to close. The
camera follows focus and each move is announced to screen readers. The canvas
itself is still a WebGL surface, so this is a focus proxy rather than a full
DOM mirror of the graph.
- **Reduced motion** — `prefers-reduced-motion` settles the layout and finishes
every growth animation before the first paint, and the camera snaps instead
of easing.
- **Theme** — sun/moon toggle in the top bar. The app follows
`prefers-color-scheme` until you pick a mode, after which the choice persists
in `localStorage` (`effort-viz-theme`) with a boot script to avoid FOUC.

## Scripts

Expand All @@ -58,7 +108,7 @@ updates.
| `pnpm play:efforts` | Same as `dev`, from the monorepo root. |
| `pnpm --filter effort-viz build` | `flatbread start` wrapping `next build` (Flatbread must be up during the build). |
| `pnpm --filter effort-viz start` | Production Next only (`next start`); run Flatbread separately if needed. |
| `pnpm --filter effort-viz test` | Physics/simulation unit tests under `lib/physics/`. |
| `pnpm --filter effort-viz test` | Unit tests: physics/simulation, normalizer, lifecycle derivation, glyph invariants. |
| `pnpm --filter effort-viz exec tsc --noEmit` | Typecheck without running dev servers. |

## Configuration
Expand All @@ -74,7 +124,13 @@ updates.
- `app/` — layout, theme tokens, R3F canvas and UI chrome
- `app/hooks/useTheme.tsx` — light/dark context + FOUC boot script
- `app/components/` — `EffortGraphApp`, `GraphCanvas`, `TopBar`, `Legend`,
`DetailDrawer`
`DetailDrawer`, `RelationLegend` (shared relation + badge metadata)
- `lib/primitives.ts` — per-primitive label, hue, and glyph: the encoding's
single source of truth
- `lib/glyphs.ts` — area-normalized glyph outlines shared by the canvas and the
legend
- `lib/lifecycle.ts` — effective lifecycle derived from edges, plus the header
summary
- `lib/physics/` — force simulation, growth, and layout helpers
- `lib/query.ts` — Effort Graph GraphQL query
- `flatbread.config.js` — Effort Graph content preset
Expand Down
Loading
Loading