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 4b7ef1f4fc6d7c59b1ee270f468f36af37558ec5
Author: Stephen Mallette <[email protected]>
AuthorDate: Mon Aug 10 08:11:14 2026 -0400

    Mark rejected alternatives with metadata instead of a label
    
    Labels are copied to children at birth, so a structural fact attached to
    one bead could propagate to another. Metadata never inherits. Record kind
    is dropped entirely, since --external-ref already identifies the artifact,
    leaving labels to mean only descriptive dimensions.
    
    Assisted-by: Claude Code:claude-opus-5
---
 .beads/PRIME.md | 52 +++++++++++++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 27 deletions(-)

diff --git a/.beads/PRIME.md b/.beads/PRIME.md
index 1a37066629..6c69ddf421 100644
--- a/.beads/PRIME.md
+++ b/.beads/PRIME.md
@@ -43,7 +43,7 @@ when the code does.
 
 | What happened | Do |
 |---|---|
-| A specific course was considered and **not taken** — a design, a scope item, 
a validation step, a target branch, a task you wrote and threw away | Decision 
bead **plus** its `rejected-alternative` sibling, now |
+| A specific course was considered and **not taken** — a design, a scope item, 
a validation step, a target branch, a task you wrote and threw away | Decision 
bead **plus** its rejected sibling, now |
 | Something is simply true, with no fork in it — evidence, a measurement, a 
discovery, a constraint | `bd comment <root> "..."` |
 
 **The rejected thing does not have to be a design.** Before writing any 
comment, try to name
@@ -55,9 +55,10 @@ OptionsStrategy" describes code and stays a comment.
 
 ```bash
 # Only when something was actually ruled out. No fork = implementation; the 
code documents that.
-bd create --type=decision --parent=<root> --title="Chose X" --design="why, and 
what X rules out"
+bd create --type=decision --parent=<root> --title="Chose X" --metadata 
'{"rejected":false}' \
+          --design="why, and what X rules out"
 # An approach you tried and abandoned is the strongest sibling — someone 
already walked it.
-bd create --type=decision --parent=<root> --title="Y" 
--labels="rejected-alternative" \
+bd create --type=decision --parent=<root> --title="Y" --metadata 
'{"rejected":true}' \
           --design="what Y concretely was, why it lost, what settled it"
 bd dep add <decision> <alternative> -t related    # never put either of these 
on a task bead
 bd close <decision> <alternative>   # both: a decision is resolved the moment 
you write it
@@ -69,7 +70,7 @@ the decision to a day it was not made. It gets pinned with 
the rest of the subtr
 (section 4).
 
 **A rejected alternative's `--design` names three things: what the option 
concretely was, why it
-lost, and what settled it.** The verdict is already in the label, so the 
reason is the whole
+lost, and what settled it.** The verdict is already in `rejected`, so the 
reason is the whole
 value — give it as a mechanism ("it leaves the shared database with a 
vocabulary no single
 PRIME.md describes"), never a judgment ("rejected as worse"). A mechanism can 
be checked again
 later: when the problem it names no longer applies, the option is worth 
reconsidering. A
@@ -201,10 +202,10 @@ Pinning is what makes a bead permanent — every 
destructive operation keys on
 
 ```
 root (feature/epic/task)
-  ├─relates-to──▶ record [jira]      TINKERPOP-3456
-  ├─relates-to──▶ record [pr]        apache/tinkerpop#2891
-  ├─parent-child─▶ decision  "chose X"
-  │                  └─related─▶ decision "Y" [rejected-alternative]
+  ├─relates-to──▶ record             TINKERPOP-3456
+  ├─relates-to──▶ record             apache/tinkerpop#2891
+  ├─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)
@@ -215,10 +216,9 @@ a list, and `bd ready` cannot tell you anything useful 
about it.
 
 - `--parent` builds the tree, and copies the parent's labels onto the child 
once, at birth —
   see section 7.
-- **`record` beads** hold external artifacts — JIRA, PR, dev@ thread, 
proposal. Kind is a
-  **label** (`jira`, `pr`, `dev-list`, `proposal`); the URL or ticket goes in
-  `--external-ref`. Attach them to the **root**, not to every bead. Create 
them pinned.
-  Search first — duplicates are the main risk.
+- **`record` beads** hold external artifacts — JIRA, PR, dev@ thread, 
proposal. The ticket or
+  URL goes in `--external-ref`, which identifies the kind as well. Attach them 
to the
+  **root**, not to every bead. Create them pinned. Search first — duplicates 
are the risk.
 - Records are the only link between beads and code. There is no bead ID in 
commit messages.
 - Only **one dependency type per pair** — `blocks` and `discovered-from` 
cannot coexist
   between the same two beads.
@@ -230,8 +230,8 @@ a list, and `bd ready` cannot tell you anything useful 
about it.
 
 ## 7. Labels
 
-Labels are categorization **orthogonal to type and priority** — a bead carries 
as many as
-apply, giving cross-cutting views the tree cannot.
+Labels are categorization **orthogonal to type and priority**, giving 
cross-cutting views the
+tree cannot.
 
 **Never invent a label.** What is listed below is the entire vocabulary. 
 
@@ -242,24 +242,21 @@ bd label list <id>
 bd label list-all                        # what is in use — includes drift; 
this file is the authority
 ```
 
-**Set every dimension label on the root when you create it, before any child 
exists.**
+**Set every label on the root when you create it, before any child exists.**
 `bd create --parent` copies the *parent's* labels onto a child at birth and 
never again, so a
 root labelled up front propagates to the whole subtree for free — and a root 
labelled afterwards
 propagates to nothing. If a label must change later, `bd label add|remove` on 
the root does not
 backfill: apply the change to every existing descendant by hand. Skip that and 
siblings born
-either side of the change disagree, and each new level snapshots whichever 
version its parent
-happened to hold. Structural labels are the exception; they describe the bead 
itself and belong
-wherever they apply.
+either side of the change disagree.
 
-### Structural labels — part of the data model, never optional
+**A fact about the bead itself is metadata, not a label.** `--metadata 
'{"rejected":true}'`
+marks the road not taken — both siblings are `type=decision`, and nothing else 
tells them
+apart. Metadata never inherits, which is why it suits such facts. `bd query` 
compares it with
+`=` only and case-sensitively, and hides closed beads unless you pass `--all` 
— which every
+decision is, so the flag is mandatory when looking for one. `human` stays a 
label because bd's own
+`bd human list/respond/dismiss` queries that literal string — never rename it.
 
-| Label | Why it exists |
-|---|---|
-| `human` | bd's own contract: `bd human list/respond/dismiss` query this 
exact string |
-| `rejected-alternative` | the chosen decision and the road not taken are 
**both** `type=decision`; this label is the only thing telling them apart |
-| `jira` `pr` `dev-list` `proposal` | which kind of external artifact a 
`record` bead holds — exactly one per record |
-
-### Dimensions — descriptive; several may apply
+Every label is descriptive and several may apply.
 
 **Module** — a unit of code. The list spans every maintained branch, so it 
includes modules
 this branch does not have. Beads outlive branches, and one vocabulary keeps 
the database
@@ -292,7 +289,8 @@ bd children <root>               # the subtree, recursive
 bd ready --parent <root>         # startable now; ALWAYS scope to your root
 bd blocked --parent <root>       # what is waiting, and on what
 bd show <id>                     # one bead with dependencies
-bd query "status=open AND type=decision"   # should be empty; an open decision 
was left unclosed
+bd query "status=open AND type=decision"    # should be empty; an open 
decision was left unclosed
+bd query "metadata.rejected=true" --all     # roads not taken; --all or closed 
beads are hidden
 bd comment <id> "..."            # a fact with no fork in it (never on a task 
bead)
 bd create --type=... --parent=<root> --design=... --labels=...
 bd dep add <task> <blocker>      # default type is blocks: <task> waits for 
<blocker>

Reply via email to