This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 74fe2a64d0a6ded65b1ab5127b57ae86679a8a53
Author: Stephen Mallette <[email protected]>
AuthorDate: Mon Aug 10 08:37:57 2026 -0400

    Document the beads workflow for committers
    
    Explains why the project records decisions, how to set up bd against
    the shared database, and what the resulting graph looks like.
    
    Assisted-by: Claude Code:claude-opus-5
---
 docs/src/dev/developer/for-committers.asciidoc | 115 +++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/docs/src/dev/developer/for-committers.asciidoc 
b/docs/src/dev/developer/for-committers.asciidoc
index c4a5af9e4e..afbd9e3cef 100644
--- a/docs/src/dev/developer/for-committers.asciidoc
+++ b/docs/src/dev/developer/for-committers.asciidoc
@@ -57,6 +57,121 @@ listing provides a summary of what to do next:
 ** In particular, see <<rtc,Review then Commit>>
 * If you have trouble committing, email [email protected]
 
+[[beads]]
+== Planning with Beads
+
+Git history and JIRA record what changed in the project. Neither records why, 
and the reasoning
+behind a change is often the part that is most needed when that change is 
revisited years later.
+TinkerPop uses beads, a command line tool named `bd`, to capture that 
reasoning while it is still
+exact. A bead can hold a decision that was taken, an alternative that was 
weighed and turned
+down, or a direction that was abandoned partway.
+
+Beads matters most for work done with an AI coding agent. Such an agent 
explores approaches,
+discards some of them, and is redirected by the contributor guiding it, but 
none of that survives
+the end of the session. Recording it as the work proceeds turns a transient 
conversation into a
+durable project artifact. Beads remains entirely optional. No part of the 
build or the test suite
+depends on it, and a contributor working without an agent has little reason to 
install it.
+
+[[beads-setup]]
+=== Setting Up Beads
+
+The `bd` tool, available from link:https://beads.gascity.com/[the beads 
project], must be installed
+before any of the commands below will work. The planning data is not held in 
Git. It lives in a
+Dolt database published at
+link:https://www.dolthub.com/repositories/tinkerpop/tinkerbeads[tinkerpop/tinkerbeads],
 and only
+`.beads/PRIME.md` and `.beads/config.yaml` are tracked in the repository. 
Running the following
+command from the repository root reads the remote recorded in `config.yaml` 
and clones that
+database into place:
+
+[source,text]
+----
+bd bootstrap
+----
+
+The same command repairs a damaged database and restores one after a move to a 
new machine. It
+never deletes existing beads, which makes it safe to run when the current 
state is unclear.
+
+An agent has to be told about the workflow before it can follow it. The 
`bin/agent-setup.sh`
+script installs the necessary hooks, which load the workflow at the start of 
every session and
+again after the agent's context is compacted:
+
+[source,text]
+----
+bin/agent-setup.sh --contributor claude
+----
+
+Passing `--list` instead reports which agents are supported. The workflow 
itself is
+`.beads/PRIME.md`, which is tracked in Git and kept identical on every 
maintained branch. It
+describes how an agent binds to a root bead, plans work as a dependency graph, 
captures decisions
+as they occur, and pins the result once the work has merged.
+
+[[beads-decisions]]
+=== What Beads Records
+
+Most beads are ordinary tasks, but the ones that justify the setup are the 
decision beads. Each
+records a choice that had a real alternative, and the alternative is stored 
beside it as its own
+bead. The example below is the rejected half of one such pair, taken from the 
Gryo
+deserialization hardening work:
+
+[source,text]
+----
+○ tp-cxt · Public getMapper() on GryoReader and GryoWriter   [● P2 · OPEN]
+Owner: Stephen Mallette · Type: decision
+
+DESIGN
+
+  REJECTED. GryoReader and GryoWriter would retain the Mapper they are handed
+  and expose it via a public getMapper(), matching the existing
+  GryoPool.getMapper() precedent at GryoPool.java:64.
+
+  Why rejected: it is permanent public API, plus a new retained field on both
+  classes, added to satisfy one guard test. TinkerPop cannot withdraw it later
+  without a deprecation cycle, and it invites providers to reach into reader
+  internals. The package-private getKryo() gets the test the same access with
+  none of that surface.
+
+LABELS: gremlin-core, io
+
+METADATA
+  rejected: true
+----
+
+The `rejected: true` metadata is what separates the road not taken from the 
one that was
+followed, since both are stored as decisions. The value of the pair lies in 
the reason rather
+than in the verdict. An objection expressed as a concrete mechanism can be 
tested again later,
+and an alternative whose objection no longer holds is precisely the one worth 
reopening.
+
+[[beads-structure]]
+=== The Shape of a Plan
+
+Work is organised as a graph rather than as a checklist. One root bead stands 
for the
+deliverable, and everything belonging to that effort hangs beneath it:
+
+[source,text]
+----
+root (feature/epic/task)
+  ├─relates-to──▶ record             TINKERPOP-3456
+  ├─parent-child─▶ decision "chose X"          {rejected: false}
+  │                  └─related─▶ decision "Y"  {rejected: true}
+  ├─parent-child─▶ task A "implement X" ──caused-by──▶ decision "chose X"
+  ├─parent-child─▶ task B ──blocks──▶ task A     (B waits for A)
+  └─parent-child─▶ task C                        (no blocker: starts with A)
+----
+
+Four kinds of bead appear in that graph. A `task` is a unit of work. A 
`decision` is a choice
+and carries its reasoning. A `record` points at an external artifact such as a 
JIRA issue or a
+pull request, and is the only link between a bead and the code, because commit 
messages carry no
+bead identifiers. The root itself is usually a task or an epic.
+
+The edges carry as much meaning as the beads. A `parent-child` edge 
establishes membership in
+the effort, while a `blocks` edge establishes order, so a subtree without any 
`blocks` edges is
+merely a list. A `caused-by` edge is what connects a task back to the decision 
that shaped it,
+and without it there is no path from the work to the reasoning behind it.
+
+Beads accumulate as the work proceeds and are pinned once it merges, which 
marks them as
+permanent and protects them from routine cleanup. The result is a record that 
outlives the branch
+it was written on.
+
 == Communication
 
 TinkerPop has a link:http://groups.google.com/group/gremlin-users[user mailing 
list] and a

Reply via email to