bd: write labels in CreateIssue tx instead of N AddLabel calls#1
Open
eric-jones wants to merge 169 commits into
Open
bd: write labels in CreateIssue tx instead of N AddLabel calls#1eric-jones wants to merge 169 commits into
eric-jones wants to merge 169 commits into
Conversation
Embedded-mode push/pull route through versioncontrolops.{Push,Pull,
ForcePush,Fetch}, which always invoked CALL DOLT_PUSH/PULL/FETCH
without --user. The non-embedded DoltStore path has the
'if s.remoteUser != ""' branch that fires CALL DOLT_PUSH('--user',
?, ?, ?), but the embedded path bypasses it entirely.
Result: against a Dolt remotesapi server that requires CLONE_ADMIN
authentication, bd dolt push/pull from embedded mode fails with
"unauthenticated user does not have privilege CLONE_ADMIN", even when
DOLT_REMOTE_USER and DOLT_REMOTE_PASSWORD are set in the environment.
The shell-level workaround was to bypass bd: cd into the embedded
database dir and run 'dolt push --user beads origin main' directly.
Fix: extend versioncontrolops.{Push,Pull,ForcePush,Fetch} with a
trailing 'user string' (empty preserves prior behavior). When non-empty,
the SQL stored procedures get '--user' appended. EmbeddedDoltStore
reads DOLT_REMOTE_USER from the environment at call time and threads
it through; DOLT_REMOTE_PASSWORD is read by the in-process Dolt
server from the same env, matching the existing contract documented
on bd dolt push/pull.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
the long help in `bd import --help` listed only four optional fields (description, issue_type, priority, acceptance_criteria) but the importer just `json.Unmarshal`s each line straight into `types.Issue`, so it round-trips every field `bd export` emits. this update points at `bd export` as the canonical schema and enumerates the common fields users are most likely to hand-author or hand-edit, plus notes a few special cases (tombstone rows skipped, timestamps preserved when present, legacy `wisp` alias for `ephemeral`). no logic change. Fixes gastownhall#3507
The help previously listed 'issue_type (or type)' but the struct tag is
json:"issue_type,omitempty" with no aliasing in runImport — importing
{"type":"bug"} silently produced the default issue_type=task.
This PR is docs-only (help should match reality), so remove the false
claim rather than adding the alias.
Caught by maphew in code review on PR gastownhall#3509.
…ownhall#3713) * docs: fix broken xref to docs/EXTENDING.md in extension example The extension example README referenced docs/EXTENDING.md in three places, but that file was deliberately deleted in the SQLite -> Dolt migration (see CHANGELOG entry "Deleted deprecated docs - removed EXTENDING.md and MULTI_REPO_HYDRATION.md (SQLite-era, no longer applicable)"). Anyone following the example hits a broken link. Removed all three references. The example README is itself the canonical reference for the extension pattern, so no redirect target is needed. Note: other docs in the repo still reference the deleted EXTENDING.md (docs/ADVANCED.md, docs/CONFIG.md, examples/library-usage/README.md, website/docs/reference/advanced.md). Those are out of scope for this fix and should be addressed in follow-up issues. Tracking bead: mybd-q71 GH: gastownhall#3683 PR: builds on follow-up audit from PR gastownhall#3706 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: fix remaining broken xrefs to deleted EXTENDING.md across repo Round 1 (commit ddeff31) only fixed the extension example README because the original prompt scoped that PR narrowly. The bead (mybd-q71) acceptance is repo-wide ("no broken xrefs anywhere"), so this follow-up sweeps the rest in the same PR per the project's "one issue per PR" rule. Per-file treatment (EXTENDING.md was deleted in commit 5083873 before v1.0.0 was tagged, so even the v1.0.0 versioned snapshot has been broken since release): - docs/ADVANCED.md (3 refs): * Note in Extensible Database section: drop trailing "See EXTENDING.md for details" — the surrounding sentence about Dolt-era alternatives stands on its own. * Bold "See EXTENDING.md for complete documentation" line: redirect to the canonical working example (examples/bd-example-extension-go). * Next Steps bullet: same redirect. - docs/CONFIG.md (2 refs): * Namespace doc for compact_*: replace "(see EXTENDING.md)" with "(used by `bd admin compact`)" — the doc itself describes the keys, no external reference needed. * See Also bullet: replace with link to docs/ADVANCED.md (Extensible Database section). - examples/library-usage/README.md (1 ref): * See Also bullet: replace EXTENDING.md link with link to the sibling bd-example-extension-go example. - website/docs/reference/advanced.md (1 ref): * Custom Tables section: replace EXTENDING.md link with link to the bd-example-extension-go README on GitHub. - website/versioned_docs/version-1.0.0/reference/advanced.md (1 ref): * Same fix as the live docs. EXTENDING.md was deleted before v1.0.0 release (commit 5083873 is an ancestor of tag v1.0.0), so this versioned snapshot has been broken since cut and a fix here doesn't violate frozen-in-time correctness — the link was never valid in the v1.0.0 release. - website/static/llms-full.txt (1 ref, auto-generated artifact): * Updated to match the corrected source so the on-disk artifact isn't broken until next regeneration. - beads.go and internal/beads/beads.go (package doc comments): * Replaced "see docs/EXTENDING.md" / "see EXTENDING.md" with a pointer to examples/bd-example-extension-go. These were real broken pointers in published Go source comments. CHANGELOG.md historical entries left untouched (intentional history). cmd/bd/info.go:747 left untouched (it's a programmatic CHANGELOG entry rendered by `bd info`, equivalent to a CHANGELOG line). Verification: grep -rn 'EXTENDING\.md' --include='*.md' . returns only CHANGELOG.md hits. Tracking bead: mybd-q71 GH: gastownhall#3683 PR: gastownhall#3713 (round 2) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: CI Bot <ci@beads.test> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…astownhall#3714) The published reference page documented `.beads/config.toml` and `BEADS_*` env vars, but the live implementation has used YAML config (`config.yaml`) and the `BD_*` env prefix for some time — the site has been misleading newcomers ever since. Rewritten against `internal/config/config.go` and `internal/config/yaml_config.go` to match live behavior. Updates both `website/docs/reference/configuration.md` and the `version-1.0.0` versioned snapshot, since v1.0.0 itself shipped with the YAML/BD_* implementation (`SetConfigType("yaml")` and `SetEnvPrefix("BD")` are present in the v1.0.0 source). Tracks: mybd-hxq Refs: GH#3683 (newcomer trust-gap pattern), PR gastownhall#3706 (mybd-p71 doc inventory that surfaced this). Co-authored-by: CI Bot <ci@beads.test> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…all#3635) Bumps [DeterminateSystems/determinate-nix-action](https://github.com/determinatesystems/determinate-nix-action) from 3.18.1 to 3.19.0. - [Release notes](https://github.com/determinatesystems/determinate-nix-action/releases) - [Commits](DeterminateSystems/determinate-nix-action@92ffb54...f4c468f) --- updated-dependencies: - dependency-name: DeterminateSystems/determinate-nix-action dependency-version: 3.19.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.6.0 to 6.4.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](actions/setup-go@v5.6.0...4a36011) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…stownhall#3712) The FAQ opened by calling beads a "git-based issue tracker", which contradicts the Dolt-native architecture documented elsewhere (README opens with "Distributed graph issue tracker for AI agents, powered by Dolt"; the FAQ itself later explains `bd dolt push` / `bd dolt pull` and Dolt branches independent of git branches). Newcomers reading the FAQ first formed an incorrect mental model: storage backend = git, sync mechanism = git push/pull. In reality, issues live in a local Dolt database and sync via Dolt remotes; git is only involved for project code (and optionally for ferrying the exported `.beads/issues.jsonl` between machines). Replaced "git-based issue tracker" with "version-controlled issue tracker" — accurate without dropping the "Dolt" vendor name in the opening line (newcomers do not yet recognize Dolt; it is introduced later in the FAQ where context is built up). Also fixed downstream misframings in the same file: - "Git-First, ..." differentiator header -> "Offline-First, ..." - "git-synchronized task memory" -> "version-controlled task memory" - "Git-native sync" -> "Built-in sync" (Taskwarrior comparison) - "Sync via git commits" -> "Sync via `bd dolt push` / `bd dolt pull`" - "bd's git-based sync" -> "bd's version-controlled storage" + cell-level merge - "Sync happens via git push/pull" -> "Sync happens via `bd dolt push` / `bd dolt pull`" Left genuine git references untouched: the merge-conflict section showing JSONL diffs (issues.jsonl is a real git-tracked artifact for portability), git hooks, `bd init`'s git interaction, the "walks up like git" auto-discovery analogy, and the worktree FAQs. Tracking: mybd-ujr GH: gastownhall#3683 PR: gastownhall#3706 (precursor) Co-authored-by: CI Bot <ci@beads.test> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Current Status" section opened with "**22 issues** as of Nov 6, 2025", a date-stamped count that fossilizes immediately after the date passes and leaves readers unsure whether the rest of the doc is current. Removed the count and date, plus the "Historical note" paragraph tracking the cleanup arc through October 2025. While in the file, also dropped the "(N issues)" sub-counts on each linter section heading and on the gosec pattern bullets, and reworded the two later references to "the 22 lint warnings" / "the baseline 22" in the Recommendation section. These were the same antipattern at smaller scale and would have drifted out of sync the moment the baseline changed. The narrative point — that the remaining warnings are intentional / idiomatic and not a quality problem — is preserved, and readers who want a current count are pointed at running golangci-lint locally. Refs: mybd-6yw, GH#3683, PR#3706 Co-authored-by: CI Bot <ci@beads.test> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…gastownhall#3645) bd audit says interactions.jsonl is intended to be versioned in git for auditing and dataset generation. Remove it from the gitignore template, required-pattern checks, and tracked-runtime warnings so doctor stops flagging a file that the audit subsystem explicitly wants tracked.
…wnhall#3616) When `bd hooks install` runs in beads mode, hooksDir points to <beadsDir>/hooks — inside the .beads/ hierarchy. Creating it with 0755 was inconsistent with BeadsDirPerm and caused spurious world-readable directory warnings. git-managed hook directories (.git/hooks, .beads-hooks) retain 0755 since git itself needs to traverse and execute scripts in them. Co-authored-by: bugspray <jeremy@geocaching.com>
When `bd dep list` is invoked with multiple IDs (batch mode), a single unresolvable ID currently aborts the entire call with exit 1. This makes the command unusable as a transport primitive for callers that want to fetch deps for a snapshot of IDs from another store, since their snapshot may transiently include IDs that the resolver cannot find. Concrete consumer: gascity's CachingStore reconcile loop calls `bd dep list <all-bead-ids> --json` every 30-60s. Ephemeral `*-wisp-*` patrol-molecule beads are visible to `bd list` but not resolvable by `bd show` / `bd dep list` (separate consistency bug to track), so the supervisor's batch fails wholesale on every cycle. See gastownhall/gascity#1560. Behavior change - Single-arg mode (len(args) == 1): UNCHANGED. Fatal exit on resolution failure, matching `bd show` semantics. - Batch mode (len(args) > 1): unresolvable IDs are skipped with a stderr warning ("warning: resolving X: ... (skipped)"); the command continues with the remaining resolvable IDs and still produces a valid JSON array on stdout. If NO IDs resolve, an empty `[]` is emitted under --json (exit 0) so callers parse cleanly. This keeps `bd` ZFC-compliant for its caller: the transport mechanically degrades on bad input instead of forcing the caller to pre-validate every ID.
…tus (gastownhall#3718) ParseBeadsStatus silently mapped unrecognized status strings to StatusOpen via the default case. This caused "done" beads to be treated as "open" during push, and "deferred" beads to collide with "open" in state_map resolution. Add all valid beads statuses as recognized cases so the function only falls back to StatusOpen for genuinely unknown strings.
…GH#3565) (gastownhall#3675) The root node's [BLOCKED] badge now only appears when open dependencies have a blocking edge type (blocks, conditional-blocks, waits-for). Parent-child, related, discovered-from, and other non-blocking types no longer trigger the badge. Adds DependencyType.IsBlockingEdge() to distinguish hard blockers from structural/associative dependency types.
* fix(mol): clear root Ephemeral on bd mol squash
bd mol squash auto-closes a wisp molecule's root but did not clear its
Ephemeral flag, contrary to the wisp lifecycle help text ("Squash: bd
mol squash <id> (clears Ephemeral flag, promotes to persistent)").
The closed-but-still-ephemeral root row remained in the wisps table, so
auto-export queries (Ephemeral=true) re-emitted it as a duplicate JSONL
row on every export cycle, accumulating noise indefinitely.
Within the squash transaction, after closing the root, also call
tx.UpdateIssue to set wisp=false. This mirrors what the bd update
<id> --persistent workaround does today and matches the natural
"squash absorbs the molecule into a digest" mental model.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* test(mol): add embedded-dolt regression for squash root Ephemeral
The standalone-Dolt regression test in mol_test.go skips in the
Embedded Dolt CI tier, leaving the squash fix's lines uncovered
(Codecov 0% on the patch).
Add a parallel test using embeddeddolt.New so the fix is exercised
in the default CI matrix.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
…H#3683) (gastownhall#3727) * docs(templates): prepend architecture summary to bd-init AGENTS.md Closes part of GH#3683 by adding a short architecture summary at the top of the AGENTS.md template that bd init / bd setup writes to disk, so AI agents see the cross-machine sync model *before* the operational quick reference — not after building a wrong mental model first. Responds to @thewoolleyman's gastownhall#2 ask in the gastownhall#3683 thread: > Auto-include the architecture statement at the top of bd-init- > generated AGENTS.md / CLAUDE.md. Even just one line like > "Cross-machine sync uses refs/dolt/data on your git remote; > JSONL is a passive export view, not the wire protocol" — plus > the link list above — would have caught us. Concretely: - agents.md.tmpl gets a blockquote between the existing intro line and the "## Quick Reference" header. The blockquote states the architecture in 1 paragraph (Dolt local DB + refs/dolt/data sync + JSONL as export-only) and links to the canonical SYNC_CONCEPTS.md entry-point introduced in gastownhall#3726. - The link uses the absolute github.com URL on purpose: the existing template sprinkles relative `docs/...` paths that don't resolve when the file is installed into a user's project (pre-existing wart not in scope here). Absolute URL keeps the link useful in any consumer's AGENTS.md regardless of project layout. - New test `TestEmbeddedDefaultArchitectureSummary` guards the change against silent regression: required fragments must be present and appear before "## Quick Reference". Scope notes: - Only `agents.md.tmpl` is touched — not `beads-section.md` or `beads-section-minimal.md`. Those two are the swap-in body for ReplaceSection() and are operational ("how to use bd"), not architectural ("how the system works"). Architecture framing belongs at the higher level of the surrounding template. - Existing AGENTS.md files generated before this change won't get the blockquote retroactively from a `bd setup` re-run, since ReplaceSection only updates content between BEGIN/END BEADS INTEGRATION markers. That's acceptable: thewoolleyman's case is newcomers landing on a fresh AGENTS.md, which this fix covers. - Template tests pass: go test -tags gms_pure_go ./internal/ templates/agents/... Depends-on: gastownhall#3726 (introduces docs/SYNC_CONCEPTS.md, the link target). The link in this PR works as soon as gastownhall#3726 lands on main. Tracking: bead `mybd-bdr` (depended on `mybd-4ee`, now closed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(templates): also propagate architecture pointer via beads-section.md (GH#3683) The previous commit only added the architecture summary to agents.md.tmpl, which means it reaches greenfield AGENTS.md but never propagates to existing user files: ReplaceSectionWithOpts (called by `bd init` on re-runs) only swaps content between the BEGIN/END markers, so anything outside the markers in agents.md.tmpl is invisible to the audience that needs the statement most — users with stale or wrong mental models built before SYNC_CONCEPTS.md existed. Both-files approach: - Greenfield (`bd init` on a fresh repo) writes EmbeddedDefault() once and gets the rich blockquote at the very top of AGENTS.md, via agents.md.tmpl. Unchanged from the previous commit. - Re-run (`bd init` on an existing AGENTS.md) calls ReplaceSectionWithOpts, which sees the body hash has shifted (new pointer line in beads-section.md) and re-renders the section with the architecture pointer included. The hash mechanism in render.go is doing exactly what it was designed for here. Placement choice: the new pointer goes into the Auto-Sync subsection, since that subsection is already where Dolt sync is introduced. One sentence, with the canonical SYNC_CONCEPTS.md URL — not a duplicate of the rich blockquote. Mirrored a single-sentence pointer into beads-section-minimal.md as well. The minimal profile is intentionally pointer-only ("run `bd prime`"), and a one-sentence architecture pointer with a URL is in character. Did not bloat the minimal profile beyond that. Tests: render_test.go now asserts both profiles include the pointer (checks for "refs/dolt/data" and "SYNC_CONCEPTS.md"). Existing hash-stability and freshness tests auto-update with the new content and continue to pass under `go test -tags gms_pure_go ./internal/templates/agents/...`. Wording polish: tightened the agents.md.tmpl blockquote — "Dolt's native push/pull" was slightly circular without context, replaced with "`bd dolt push/pull` (a git-compatible protocol)". URL pinning hazard: the architecture pointer URL hard-codes `github.com/gastownhall/beads/blob/main/...` in two files (agents.md.tmpl and beads-section.md). If the canonical repo ever moves, both sites need a grep-and-update. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: CI Bot <ci@beads.test> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Add explicit Codex skill setup * Refine Codex setup guidance
…hall#3735) Address PR gastownhall#3670 review nits: 1. The managed Codex AGENTS.md section pointed at "the beads skill" without saying where SKILL.md lives. Codex does not auto-discover .agents/skills/, so include explicit project and global paths in the section body so an agent reading AGENTS.md can find the skill. 2. bd setup codex uses its own BEADS CODEX SETUP markers, separate from the BEADS INTEGRATION markers used by factory/mux. Document in docs/SETUP.md that both can coexist in the same AGENTS.md and that each setup's --check/--remove only touches its own section.
* deps: update vulnerable Go modules * nix: update vendor hash for go deps
Reverts PR gastownhall#3498 / commit 0fffa44.\n\nPR gastownhall#3498 added BEADS_DOLT_CLI_DIR routing without a confirmed reproduction and introduced an external-server push/pull regression. Remove that override and its docs/tests so main no longer requires a local CLI database directory in external-server mode.\n\n_codex-gpt-5- on behalf of CI Bot_
This reverts commit 9b0cf9e.
…)" (gastownhall#3890) This reverts commit 0fffa44.
This reverts commit 9b0cf9e. Reverts gastownhall#3862 . Clean up after rogue agent merged before Dolt-related PR was cleared by @coffeegoddd
…rt-3862-fix/gh3860-dolt-cli-dir Revert "Revert "revert: remove external server CLI dir override""
…stownhall#3830) Bumps github.com/dolthub/driver from 1.86.4 to 1.88.1 and includes CI repair for the Nix vendor hash plus generated CLI docs.\n\n_codex-gpt-5-medium on behalf of CI Bot_
Db/split writes
`bd create --labels A,B,C` previously emitted N+1 audit events: one EventCreated with no labels, then N EventLabelAdded events as the post-create code looped `store.AddLabel` per label. Each AddLabel also generated a separate Dolt working-set write that needed a follow-up commit (per gastownhall#2055). `buildCreateIssue` builds an *Issue without a Labels field, and `PersistLabels` (called inside CreateIssueInTx) is a no-op on an empty slice — so labels weren't landing in the create transaction. Fix: merge inherited + user-specified labels before the CreateIssue call and assign them to `issue.Labels`. PersistLabels then writes them inside the same SQL transaction. Drop the post-create AddLabel loop. Net behavior: - 1 EventCreated row with the labels persisted, 0 EventLabelAdded rows for the initial label set. - One Dolt commit instead of one + N working-set writes. - Per-label INSERT failures now roll back the whole create instead of WarnError-and-continue. Minor; labels are simple strings and the prior loose behavior masked write errors that should surface. Regression test added in cmd/bd/create_test.go (CreateWithLabelsAtomic). The same shape exists in cmd/bd/create_form.go (interactive create); not touched in this PR to keep the change scoped to the symptom documented in stg-u81 (`bd create --labels` CLI path). Happy to mirror the fix there in a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…LI-level test Addresses three review flags from a structured post-submit walk: 1. Parallel fix in cmd/bd/create_form.go. The interactive create- from-form path (CreateIssueFromFormValues) had the identical AddLabel-loop shape as the CLI path: s.CreateIssue with empty Labels, then a per-label s.AddLabel loop emitting N spurious EventLabelAdded events. Same root cause, same fix shape — merge inherited + user labels before s.CreateIssue, assign fv.Labels onto the *Issue, drop the post-create loop. 2. CLI-level regression test (cmd/bd/create_embedded_test.go, labels_atomic). The previous regression test exercised the storage layer directly (s.CreateIssue with Labels pre-populated) — that validates the PersistLabels contract but would pass before the fix too, since the bug was in CLI plumbing (the CLI never set issue.Labels). The new test runs `bd create -l a,b,c` as a subprocess and inspects the events table directly: must see 1 created + 0 label_added rows. 3. Form-path regression test (cmd/bd/create_form_test.go, WithLabelsAtomic). Calls CreateIssueFromFormValues directly with pre-populated fv.Labels and asserts the same event-count invariant. The storage-layer test in cmd/bd/create_test.go is kept as a contract test for the underlying PersistLabels behavior, with a clarified comment pointing at the CLI-level test for the actual regression coverage. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Upstream-PR: gastownhall#3868
72aa505 to
b587010
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fork-PR for review. Upstream: gastownhall#3868 (OPEN). Carrying as a topic branch on the fork; integrated into local/integration via mol-bed-refresh.