Skip to content

Comments

feat: add has_metadata_key to bd query DSL#2

Open
turian wants to merge 108 commits intofeat/metadata-queryablefrom
feat/metadata-has-key-dsl
Open

feat: add has_metadata_key to bd query DSL#2
turian wants to merge 108 commits intofeat/metadata-queryablefrom
feat/metadata-has-key-dsl

Conversation

@turian
Copy link
Owner

@turian turian commented Feb 20, 2026

Summary

  • Add has_metadata_key=<keyname> field to the bd query DSL
  • Works in filter mode (AND chains) and predicate mode (OR queries)
  • Added to KnownFields registry for documentation
  • Reuses existing IssueFilter.HasMetadataKey and SQL JSON_EXTRACT IS NOT NULL

Base: feat/metadata-queryable (PR steveyegge#1908 against upstream)

Test plan

  • TestEvaluatorHasMetadataKeyQueries — 4 cases: basic, combined with status, OR predicate, invalid key
  • TestHasMetadataKeyPredicateEvaluation — predicate mode with key present, absent, and OR fallback

🤖 Generated with Claude Code

@turian turian force-pushed the feat/metadata-queryable branch from 58f05e6 to ca318fe Compare February 22, 2026 20:58
@steveyegge steveyegge force-pushed the feat/metadata-queryable branch from ca318fe to 5ba0887 Compare February 22, 2026 23:30
turian and others added 5 commits February 22, 2026 15:30
…teveyegge#1908)

Add SQL-level metadata filtering using Dolt's JSON_EXTRACT/JSON_UNQUOTE
with parameterized queries. New CLI flags: --metadata-field key=value
(repeatable, AND semantics) and --has-metadata-key key. Add metadata.<key>
support to bd query DSL. Strict key validation prevents JSON path injection.

Remove //go:build cgo tag from metadata_filter_test.go (CGO bifurcation
was removed in c4010c1).
…e#1900)

* Fix waits-for readiness in ready and molecule analysis

- enforce waits-for gates in Dolt ready-work blocker computation

- honor waits-for in molecule parallel/ready analysis

- dedupe waits-for gate metadata parser into internal/types

- add regression tests and short-mode skip/subtests improvements

* docs(waits-for): clarify canonical spawner identity (steveyegge#1899)
Adds bd setup mux with support for layered AGENTS.md installation
(root, project .mux/, global ~/.mux/) and managed hook files
(.mux/init, .mux/tool_post, .mux/tool_env). Makes AGENTS removal
non-destructive (preserves user content outside managed markers).

From: PR steveyegge#1888 by alexx-ftw (cherry-picked, rebased onto current main)

Co-Authored-By: Alexx <alexx-ftw@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat(otel): comprehensive OpenTelemetry instrumentation

Phase 1 (telemetry foundation + SQL + CLI + AI):
- Add internal/telemetry package: Init/Shutdown, Tracer/Meter helpers,
  stdout + OTLP/gRPC exporters, noop providers when disabled
- Add internal/telemetry/storage.go: InstrumentedStorage decorator for
  SDK consumers with bd.storage.* counters and duration histograms
- Instrument DoltStore SQL layer (execContext, queryContext, queryRowContext)
  with dolt.exec / dolt.query / dolt.query_row spans
- Instrument Anthropic API calls in compact/haiku.go and find_duplicates.go
  with bd.ai.input_tokens, bd.ai.output_tokens, bd.ai.request.duration
- Add bd.command.<name> span in PersistentPreRun/PostRun with actor attribute

Phase 2 (VC ops, hooks, sync, metrics):
- Add dolt.commit / dolt.push / dolt.force_push / dolt.pull / dolt.branch /
  dolt.checkout / dolt.merge spans for Dolt version-control procedures
  (these bypass execContext so needed dedicated spans)
- Add bd.db.retry_count counter in withRetry (server mode retries)
- Add bd.db.lock_wait_ms histogram in AcquireAccessLock (flock contention)
- Add ephemeral.count / ephemeral.nuke spans for SQLite ephemeral store
- Add hook.exec spans in hooks_unix/windows runHook (background root spans)
- Add tracker.sync / tracker.pull / tracker.push / tracker.detect_conflicts
  spans with per-phase stats attributes in tracker/engine.go
- Add bd.issue.count gauge (by status) in InstrumentedStorage.GetStatistics
- Fix: call initAIMetrics via sync.Once in newHaikuClient so ai metrics
  are actually registered

Configuration:
  BD_OTEL_ENABLED=true              enable (default: off, zero overhead)
  BD_OTEL_STDOUT=true               write to stdout for dev/debug
  OTEL_EXPORTER_OTLP_ENDPOINT=...  ship to Jaeger/Grafana/Honeycomb/etc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(otel): align with VictoriaMetrics HTTP stack

- Switch metric exporter: gRPC → HTTP (otlpmetrichttp)
- Activation: BD_OTEL_METRICS_URL presence (no more BD_OTEL_ENABLED flag)
  matches GT_OTEL_METRICS_URL convention from the local observability stack
- BD_OTEL_METRICS_URL=http://localhost:8428/opentelemetry/api/v1/push
- BD_OTEL_LOGS_URL=http://localhost:9428/insert/opentelemetry/v1/logs (reserved)
- Traces: stdout only (BD_OTEL_STDOUT=true); noop otherwise since VictoriaMetrics
  is a metrics-only backend — no trace overhead in production
- Remove: otlptracegrpc, otlpmetricgrpc
- Update docs/OBSERVABILITY.md to match the diffusiontown README style

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(otel): capture hook stdout/stderr and bd.args in spans

- hook.exec span now records stdout and stderr as span events after
  the hook process exits (including partial output on timeout)
- Output is truncated to 1024 bytes; the event carries both the text
  (output) and the original size (bytes) as attributes
- bd.command.<name> span now includes bd.args with the raw CLI
  arguments (e.g. "create 'title' -p 2")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(otel): address review feedback — stale comment, span leak, hot-path alloc

1. Fix stale BD_OTEL_ENABLED comment in main.go (actual env vars are
   BD_OTEL_METRICS_URL and BD_OTEL_STDOUT)
2. Use defer+named returns in Merge() to prevent span leaks
3. Cache doltSpanAttrs() via sync.Once to avoid per-call allocation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: beads/crew/emma <steve.yegge@gmail.com>
Every RunInTransaction call now provides a descriptive commit message
and the transaction includes a DOLT_COMMIT call before SQL commit,
making writes atomically visible in Dolt version history.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/jasper
Rig: beads
Role: polecats
@turian turian force-pushed the feat/metadata-has-key-dsl branch 2 times, most recently from 5f5e145 to 3df9753 Compare February 23, 2026 00:16
renovate bot and others added 21 commits February 23, 2026 00:19
Add beforeTestsHook implementation that starts a dedicated Dolt
sql-server in a temp directory on a dynamic port. Tests now create
testdb_* databases on this isolated server instead of the production
one, preventing lock contention and server crashes.

Also fix telemetry/storage.go RunInTransaction signature to match
the updated Storage interface (commitMsg parameter).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/obsidian
Rig: beads
Role: polecats
…rrency

- Wrap RunInTransaction with withRetry for automatic transient error recovery
- Add transact() helper that marks commandDidExplicitDoltCommit, preventing
  redundant maybeAutoCommit in PersistentPostRun
- Remove BD_BRANCH env var handling (all writers now operate on main)
- Batch-wrap label add/remove, single-issue delete, and markdown create
  in single transactions for atomicity

Closes: gt-bewatn.3, gt-bewatn.4, gt-bewatn.5, gt-bewatn.15

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- queryContext: close leaked sql.Rows on retry (bd-bdfoe)
- CreateIssue, UpdateIssue, ClaimIssue, CloseIssue, DeleteIssue,
  CreateIssuesWithFullOptions, DeleteIssues: add DOLT_COMMIT inside
  transaction so writes are visible in Dolt version history (bd-zscqd)
- UpdateIssue: move GetIssue inside transaction to fix TOCTOU (bd-1x1q9)
- ClaimIssue: move GetIssue and assignee query inside transaction to
  fix TOCTOU race and CAS consistency (bd-o8kqq, bd-p61yo, bd-rvfau)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sweep 65 markdown files across docs/, website/, claude-plugin/, examples/,
integrations/, and root to replace removed `bd daemon` references with
current Dolt server mode equivalents. CHANGELOG.md preserved per policy.

Key replacements:
- `bd daemon start/stop/status` → `bd dolt start/stop` / `bd doctor`
- `bd daemons killall/health/logs` → `bd dolt stop` / `bd doctor`
- `--no-daemon` flag → removed (embedded mode is default)
- `BEADS_NO_DAEMON` / `BEADS_DAEMON_MODE` env vars → removed
- `.beads/bd.sock` → removed
- "daemon mode" / "direct mode" → "server mode" / "embedded mode"
- daemon.pid/daemon.log → .beads/dolt/sql-server.pid/.log

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/topaz
Rig: beads
Role: polecats
… tags

- mol_squash.go: replace --delete-children with --keep-children in help
  text (the flag is --keep-children, deletion is the default)
- markdown.go: fix dead code where Description=="" guard made the inner
  Description!="" check unreachable, truncating multi-line descriptions
- internal/storage/dolt/*_test.go: remove stale //go:build cgo tags
  since embedded Dolt was replaced with server-mode (pure Go)

Closes: bd-rw2tf, bd-8o2le, bd-lrl7u

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…abels, deps

Previously cookFormula performed two separate committed operations:
1. CreateIssuesWithFullOptions (own internal transaction)
2. transact() for labels and dependencies

If phase 2 failed, orphaned template issues would remain in the database
with no labels or dependencies, and the best-effort cleanup could also fail.

Now all three operations (issue creation, label addition, dependency creation)
happen in a single transact() call. If anything fails, the entire transaction
rolls back cleanly — no orphaned issues possible.

Closes: bd-5cyte

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TestMain to internal/storage/dolt/ that starts a dedicated Dolt server
in a temp directory on a dynamic port, preventing tests from creating
testdb_* databases on the production Dolt server. Uses BEADS_DOLT_PORT
env var (already wired by mayor in applyConfigDefaults).

Also fix missing dbPath assignment in newServerMode (lost during
embedded-to-server refactoring), which caused store.Path() to return "".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d-4kgbq)

bondProtoMolWithSubgraph: spawn and dependency attachment now happen in a
single transaction via CloneOptions.AttachToID, preventing orphaned issues
if the attach step fails.

squashMolecule: digest creation, child deletion, and root close all happen
in a single transaction instead of three separate operations, preventing
inconsistent state on partial failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…H#1237, GH#1234)

GH#1237: When --sort is specified, defer LIMIT from SQL to Go so sorting
operates on the full result set before truncation.

GH#1234: TrimSpace the edited value before saving, not just for empty check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The daemon was removed in v0.50. Remove remaining references from
NEWSLETTER.md, docs/LINTING.md, website sidebar, and llms.txt files.
Regenerated llms-full.txt from clean source docs. CHANGELOG.md
historical entries preserved.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… propagate blocked status to children (GH#2009, GH#1495)

Two bugs fixed:

1. GH#2009: bd ready --parent filter was silently ignored. The ParentID
   field was parsed from CLI flags and set on WorkFilter but never used
   in the SQL query. Added parent filtering to both GetReadyWork and
   GetBlockedIssues, mirroring the existing logic in SearchIssues.

2. GH#1495: Children of blocked parents appeared in bd ready because
   blocked status did not propagate to children. Now GetReadyWork excludes
   children of blocked parents. Also fixed stale blocked-IDs cache:
   CloseIssue, UpdateIssue (status changes), and ClaimIssue now
   invalidate the cache so waits-for gate changes take effect immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…#1945, GH#1524)

Two bug fixes:

1. GH#1945: bd repo sync now iterates additional repos from config.yaml,
   parses their issues.jsonl files, and imports cross-prefix issues with
   source_repo set. Uses repo_mtimes cache to skip unchanged repos.
   Also fixes duplicate key error on re-sync by adding ON DUPLICATE KEY
   UPDATE to insertIssue().

2. GH#1524: IsBlocked() now uses computeBlockedIDs() as the single source
   of truth, consistent with GetReadyWork. This ensures close guard
   respects waits-for dependencies, not just direct blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, GH#2007)

GH#1981: (b) Replace stale 'bd sync' advice in doctor messages with
correct commands (bd import, bd init, bd doctor). (c) Fix noms LOCK
false positive — run CheckLockHealth before any embedded Dolt opens
so doctor's own flock()s don't trigger warnings. Remove age-based
noms LOCK detection from CheckStaleLockFiles (redundant with flock
probing in CheckLockHealth).

GH#2007: Remove stale 'bd sync --status' and 'bd sync' references
from bd prime output. Replace with bd dolt push/pull, bd export,
bd search. Simplify close protocol (beads auto-commit to Dolt).
Update onboard and init_team references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…it hook body

The preCommitHookBody() inline template still used 'bd hook pre-commit'
after the command was renamed to 'bd hooks run'. The template files in
cmd/bd/templates/hooks/ were already fixed (a7e1203) but this inline
path used by bd init was missed.

Fixes: gt-0qii3n, gt-sue187, gt-u7qk7q, gt-e9wkz0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: gastown/crew/gus
Rig: gastown
Role: crew
1. FORMATTING: gofmt 14 files.

2. LINT:
   - Delete dead code cmd/bd/bootstrap.go (unused bootstrapEmbeddedDolt)
   - Prefix unused 'actor' param in wisps.go updateWisp with _
   - Prefix unused 'ctx' param in telemetry.go buildTraceProvider with _

3. TESTS: Add skipIfNoDolt to test helpers that call dolt.New() without
   a running test server. In CI (no dolt installed), these tests now skip
   instead of failing with "server unreachable at 127.0.0.1:3307".
   Delete TestOpenFromConfig_Embedded and TestOpenFromConfig_DefaultsToEmbedded
   which tested removed embedded Dolt functionality.

   Fixed packages: beads_test, cmd/bd, cmd/bd/doctor, cmd/bd/doctor/fix,
   internal/tracker, internal/utils

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Regression tests were connecting to the production Dolt server on port
3307, polluting it with test databases. Start a dedicated Dolt server
on a dynamic port in TestMain and pass BEADS_DOLT_PORT to all bd
subprocess invocations via runEnv().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/crew/emma
Rig: beads
Role: crew
Delete fork_protection.go and its test — these only protected
.beads/issues.jsonl from being committed by forks, which is no
longer relevant with Dolt-native storage. Remove ensureForkProtection()
call from main.go PersistentPreRun.

Part of bd-9ni (JSONL removal Phase 2+3).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/crew/emma
Rig: beads
Role: crew
v0.56.0 release failed because verify-cgo.sh was added to darwin and
freebsd builds which intentionally use CGO_ENABLED=0. Bump to v0.56.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/crew/emma
Rig: beads
Role: crew
…G-4)

The --status flag filters by the stored status column, but dependency-
blocked issues keep status "open" — they only appear via 'bd blocked'.
The old help text listed "blocked" without explaining this distinction,
leading users to expect 'bd list --status blocked' to find dependency-
blocked issues.

Updated help text for list, count, search, and query to say "stored
status" and point to 'bd blocked' for dependency-blocked issues.

Adds TestBUG4_BlockedStatusVsBlocked protocol test documenting the
distinction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
steveyegge and others added 29 commits February 23, 2026 10:41
Convert doctor test files to use Dolt-based test fixtures instead of
creating temporary SQLite databases. Tests that are fundamentally
SQLite-specific (file corruption, sidecars, DB locking, legacy schema
migration) are skipped with clear notes about why they dont apply to
the Dolt backend.

Files converted:
- doctor/deep_test.go: use newTestDoltStore + UnderlyingDB()
- doctor/database_test.go: remove setupTestDatabase(), simplify cases
- doctor/fix/validation_test.go: skip SQLite fixture tests (bd-o0u.5)
- doctor_test.go: skip DetectHashBasedIDs (child_counters always exists)
- gate_test.go: remove SQLite DB creation, skip placeholder test
- doctor_repair_test.go: skip SQLite corruption repair test
- doctor_repair_chaos_test.go: skip all SQLite chaos tests
- doctor_migrate_fix_test.go: skip legacy SQLite schema migration test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove SQLite dependencies from doctor test files and convert to
Dolt-based test fixtures. Tests that created temporary SQLite databases
now use DoltStore with the shared test server for proper isolation.

Key changes:
- Add DB() accessor to DoltStore for test infrastructure access
- Create shared test_helpers_test.go in doctor package (newTestDoltStore,
  newTestIssue, insertIssueDirectly, ptrTime)
- Convert fix/validation_test.go to use newFixTestStore with metadata.json
  for end-to-end ChildParentDependencies testing via openAnyDB
- Remove SQLite imports from gate_test.go, doctor_test.go, database_test.go
- Skip TestDetectHashBasedIDs (Dolt always has child_counters table)
- Skip TestCheckBeadGate_TargetClosed (dead test, needs routing infra)
- Consolidate duplicate helpers from migration_validation_test.go

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/obsidian
Rig: beads
Role: polecats
…d-o0u.2)

- Remove SQLite code paths from CheckDatabaseVersion, CheckSchemaCompatibility,
  CheckDatabaseIntegrity, CheckDatabaseSize (Dolt-only now)
- Remove classifyDatabaseError and getDatabaseVersionFromPath helpers
- Add sqliteBackendWarning for legacy SQLite backend detection
- Implement CheckDatabaseSize using Dolt store API (was SQLite-only before)
- Refactor RunDeepValidation to use openDoltConn instead of SQLite dispatch
- Replace SQLite pragma_table_info queries with INFORMATION_SCHEMA.COLUMNS
- Replace json_extract with JSON_UNQUOTE(JSON_EXTRACT) for MySQL/Dolt compat
- Delete deep_open.go (Dolt/SQLite dispatch no longer needed)
- Update tests to remove SQLite fixtures, keep Dolt-compatible assertions
- Net: -745 lines of SQLite-specific code

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… (bd-o0u.3)

- Remove SQLite code path from CheckRepoFingerprint (was ~100 lines)
- Simplify CheckIDFormat and CheckDependencyCycles to Dolt-only
- Refactor checkDatabaseConfigValues to use Dolt store API instead of sql.Open
- Remove ncruces/go-sqlite3 imports from both files
- Add sqliteBackendWarning for legacy detection consistency
- Net: ~180 lines of SQLite-specific code removed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on.go (bd-o0u.4)

- perf.go: delegate RunPerformanceDiagnostics to Dolt backend, remove
  all SQLite query functions (collectDatabaseStats, runQuery, etc.)
- multirepo.go: convert readTypesFromDB and findUnknownTypesInHydratedIssues
  from sql.Open("sqlite3") to Dolt store API
- installation.go: replace SQLite db open test with Dolt store open,
  remove ncruces imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…go (bd-o0u.5)

- migration.go: remove dead code checkDatabaseVersionMismatch (SQLite-only)
- migration_validation.go: remove getSQLiteDBPath, compareSQLiteWithJSONL,
  and SQLite comparison block in CheckMigrationReadiness
- fix/validation.go: rewrite openAnyDB as openDoltDB (Dolt server only),
  remove openDB (SQLite), remove isDolt conditionals
- fix/validation_test.go: skip SQLite fixture tests pending bd-o0u.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…flag (bd-o0u.6)

Delete 4 sqlite_open CGO variant files (doctor/ and fix/), connstring.go
(SQLite URI builder), handleToSQLiteMigration stubs, and --to-sqlite CLI
flag. ncruces/go-sqlite3 stays in go.mod for extractFromSQLite() legacy
upgrade path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…-veh)

CollectPlatformInfo now returns backend: dolt instead of sqlite_version.
Update TestExportDiagnostics fixture data to match.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/obsidian
Rig: beads
Role: polecats
Executed-By: beads/polecats/quartz
Rig: beads
Role: polecats
… (bd-rbzi)

Adds the missing bd dolt start and bd dolt stop commands referenced
in the 0.56.0 changelog and throughout documentation. These commands
manage a local dolt sql-server process via PID file at
.beads/dolt/dolt-server.pid.

Closes steveyegge#2058

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/quartz
Rig: beads
Role: polecats
Prevents users from accidentally committing Dolt database files by
automatically adding exclusion patterns to the project-root .gitignore
during bd init. Also adds a doctor check and fix for this.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/opal
Rig: beads
Role: polecats
…gso)

bd ready --json was missing the labels field and other fields (dependency
counts, dependencies, parent) that bd list --json includes. This broke
tooling expecting consistent JSON shape across list commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/onyx
Rig: beads
Role: polecats
DoltStore had both DB() and UnderlyingDB() returning the same s.db.
Remove DB() (6 callers in new tests) and keep UnderlyingDB() (13
callers in production code and older tests).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/onyx
Rig: beads
Role: polecats
Add transparent auto-start/stop of dolt sql-server so standalone beads
users never need to manually manage the server. bd init and all commands
now auto-start a local server when one is not running.

- New internal/doltserver package: Start/Stop/EnsureRunning/IsRunning
- Per-project port derived from path hash (range 13307-14307)
- Auto-start in store.go on TCP dial failure (localhost only)
- Disabled under Gas Town (GT_ROOT set) or BEADS_DOLT_AUTO_START=0
- bd dolt start/stop/status CLI commands for explicit control
- Server survives bd exit (Setpgid), PID tracked in .beads/
- File lock prevents concurrent start races
- Gitignore updated for dolt-server.pid/log/lock files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/crew/emma
Rig: beads
Role: crew
…void stale catalog crashes (bd-ggnx)

information_schema queries fail when the Dolt server catalog contains stale
database entries from cleaned-up worktrees. SHOW COLUMNS/TABLES are inherently
database-scoped and don't trigger full catalog scans.

Also makes init.go and migrate_dolt.go respect existing config's DoltDatabase
before deriving from prefix, preventing phantom catalog entry creation.

Fixes GH#2051.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/quartz
Rig: beads
Role: polecats
newTestDoltStore, setupDoltTestDir, and setupStaleClosedTestDB all shared
the default beads database, causing cross-test pollution where tests saw
thousands of issues from other tests. Each helper now generates a unique
doctest_<hex> database name and drops it in t.Cleanup, matching the
isolation pattern from fix/validation_test.go newFixTestStore.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/jasper
Rig: beads
Role: polecats
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/obsidian
Rig: beads
Role: polecats
…olt server (test-hqvv5t, test-n99ihy)

Port collision: if derived port is busy, tries next 9 ports in range.
Writes actual port to .beads/dolt-server.port for reliable discovery.

Idle monitor: sidecar process (bd dolt idle-monitor) auto-stops server
after 30min idle (configurable via dolt.idle-timeout in config.yaml).
If server crashes but activity is recent, watchdog restarts it.

Also removes unused DisableWatchdog field from dolt.Config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/crew/emma
Rig: beads
Role: crew
Re-implement the --from-jsonl flag for bd init that was removed during the
JSONL storage layer removal refactor. The flag reads .beads/issues.jsonl and
imports issues into the Dolt server database, enabling fresh clone hydration
in server mode.

Closes GH#2023

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/jasper
Rig: beads
Role: polecats
The noDbCommands list in PersistentPreRun included "dolt" which caused ALL
dolt subcommands to skip store initialization. This broke push, pull, and
commit which need the store for version-control operations.

Now uses a positive list (needsStoreDoltSubcommands) so push/pull/commit
fall through to normal store initialization while config/diagnostic
subcommands (show, set, test, start, stop, status) still skip it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/obsidian
Rig: beads
Role: polecats
…ey errors (GH#2061)

insertIssueIntoTable() used plain INSERT without ON DUPLICATE KEY UPDATE,
causing Error 1062 when re-importing issues with existing IDs. Now matches
the upsert logic already present in insertIssue(). Also prevents redundant
"created" events on re-import by checking issue existence before recording.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/quartz
Rig: beads
Role: polecats
…d--9w6)

openStoreDB now uses doltServerConfig to read server host/port from
metadata.json, fixing validation checks that returned false-ok when
Dolt runs in server mode. Also wrap raw SQL INSERTs in orphaned-dep
tests with explicit transactions (required by --no-auto-commit).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Executed-By: beads/polecats/onyx
Rig: beads
Role: polecats
The testmain_test.go that starts an isolated test Dolt server had a
//go:build cgo constraint, but nothing in it requires CGo (it uses
exec.Command + pure Go MySQL driver). Without CGo, TestMain was never
compiled, so tests fell through to the default port 3307 (production).

Remove the CGo constraint so the isolated test server always starts.
Also harden skipIfNoDolt to require testServerPort != 0, preventing
any fallback to production if the test server fails to start.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Under Gas Town (GT_ROOT set), all dolt server operations now resolve to
$GT_ROOT/.beads/ with fixed port 3307, so N worktrees share one server
instead of spawning N servers (was accumulating 62 servers / 9GB RAM).

- Add resolveServerDir/ResolveServerDir for canonical path resolution
- DefaultConfig uses fixed port 3307 under Gas Town, DerivePort standalone
- EnsureRunning resolves internally; bd dolt start/stop/status resolve at CLI
- Add bd dolt killall to find and kill orphan dolt sql-server processes
- Extract shared test server helper (internal/testutil/testdoltserver.go)
  with PID file tracking, stale cleanup, and signal handler for Ctrl+C
- Refactor 3 test files to use shared helper (-224 lines of duplication)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both cmd/bd/doctor and cmd/bd/doctor/fix had test helpers that fell back
to port 3307 (production) when BEADS_DOLT_PORT was not set. Added TestMain
server startup to both packages so they get their own isolated test servers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
beads_test.go was hardcoded to 127.0.0.1:3307, hitting the production
server. Added TestMain that starts its own test server via testutil.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents beads from accidentally killing or stopping the daemon-managed
shared dolt server:

- Stop() refuses under GT_ROOT (use --force or gt dolt stop)
- KillStaleServers() checks both .beads/dolt-server.pid and
  daemon/dolt.pid to avoid killing the daemon-managed server
- bd dolt start detects daemon-managed server via TCP probe
- Idle monitor not forked under GT_ROOT (daemon manages lifecycle)

Based on vulnerability report from beads/emma.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Merge with upstream daemon-aware changes and add additional guardrails:

- Idle monitor: never forked under Gas Town (forkIdleMonitor + RunIdleMonitor)
- KillStaleServers: refuse to kill when no canonical PID found under Gas Town
- Consolidate on IsDaemonManaged() (remove duplicate isExternallyManaged)
- Remove redundant CLI guards where library-level guards already protect

Upstream already added: StopWithForce, daemon PID lookup in killall,
nuanced bd dolt start (allows emergency start when daemon server is down).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Support metadata existence checks in the query DSL:
  bd query "has_metadata_key=team AND status=open"

Completes the list/search/query triangle for metadata existence
filtering. Uses existing IssueFilter.HasMetadataKey field and
SQL-level JSON_EXTRACT IS NOT NULL from PR2.

Implements GH#1406.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@turian turian force-pushed the feat/metadata-has-key-dsl branch from 778d259 to 3e49f00 Compare February 24, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants