feat: add optional per-issue JSON metadata field (SQLite + Dolt)#1407
Merged
steveyegge merged 6 commits intosteveyegge:mainfrom Jan 31, 2026
Merged
feat: add optional per-issue JSON metadata field (SQLite + Dolt)#1407steveyegge merged 6 commits intosteveyegge:mainfrom
steveyegge merged 6 commits intosteveyegge:mainfrom
Conversation
Add an optional `metadata` field to Issue for storing arbitrary JSON data. This enables extension points for tool annotations, file lists, and external system bridging without expanding the core schema. Changes: - Add `Metadata json.RawMessage` field to types.Issue - Add metadata column to SQLite and Dolt schemas - Add migration 041_metadata_column for existing databases - Wire through insert/update/get/search in both backends - Validate metadata is well-formed JSON on create/update - Include metadata in content hash computation The field uses json.RawMessage to preserve exact JSON and supports omitempty for JSONL export compactness. Closes steveyegge#1406 Co-Authored-By: Claude Opus 4.5 <[email protected]>
Include metadata column in: - SearchIssues SELECT statement (queries.go) - scanIssues function in dependencies.go - transaction.go GetIssue and SearchIssues SELECTs - scanIssueRow helper function Without this, bd list/ready and other search operations would return issues with empty Metadata fields even when stored. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add metadata to GetIssuesByLabel in labels.go - Add metadata to GetReadyWork and GetNewlyUnblockedByClose in ready.go - Fix TestMigrateContentHashColumn test to include metadata column This fixes test failures from the initial metadata implementation where some SELECT statements were missing the new metadata column. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Add "metadata" to SQLite allowedUpdateFields (matches Dolt) - Add TestIssueMetadataRoundTrip test verifying: - Create issue with metadata -> GetIssue returns it - SearchIssues returns metadata - UpdateIssue can modify metadata - Issues without metadata have nil Metadata field This ensures metadata can be updated via bd update and proves the feature works across key code paths (GH#1406). Co-Authored-By: Claude Opus 4.5 <[email protected]>
Dolt's JSON column requires valid JSON, so empty strings cause
"Invalid JSON text" errors. Added jsonMetadata() helper that
returns "{}" when metadata is nil or empty.
This fixes TestBootstrapFromJSONL and related Dolt tests.
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Replace string comparison with jsonEqual() helper that unmarshals and uses reflect.DeepEqual. This prevents test brittleness if JSON gets normalized (whitespace, key order) in the future. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Contributor
Author
Proposed Follow-upsTracking items for post-merge work: 1. CLI support for setting metadataAdd 2. Dolt migration path for existing databasesExisting Dolt databases won't automatically get the new
3. Conventions for common metadata keys (documentation)Document recommended patterns without enforcing them:
4. Optional schema enforcement (future)Config-driven validation beyond
|
steveyegge
approved these changes
Jan 31, 2026
Owner
steveyegge
left a comment
There was a problem hiding this comment.
Clean additive feature. Metadata field works well with Dolt's native JSON type and is compatible with the Dolt-only storage direction. Good test coverage, proper validation, correct content hash inclusion. LGTM.
groblegark
pushed a commit
to groblegark/beads
that referenced
this pull request
Jan 31, 2026
…veyegge#1407) * feat: add optional JSON metadata field to issues Add an optional `metadata` field to Issue for storing arbitrary JSON data. This enables extension points for tool annotations, file lists, and external system bridging without expanding the core schema. Changes: - Add `Metadata json.RawMessage` field to types.Issue - Add metadata column to SQLite and Dolt schemas - Add migration 041_metadata_column for existing databases - Wire through insert/update/get/search in both backends - Validate metadata is well-formed JSON on create/update - Include metadata in content hash computation The field uses json.RawMessage to preserve exact JSON and supports omitempty for JSONL export compactness. Closes steveyegge#1406 Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: add metadata to SQLite SearchIssues and scanIssues Include metadata column in: - SearchIssues SELECT statement (queries.go) - scanIssues function in dependencies.go - transaction.go GetIssue and SearchIssues SELECTs - scanIssueRow helper function Without this, bd list/ready and other search operations would return issues with empty Metadata fields even when stored. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: add metadata column to remaining SELECT statements - Add metadata to GetIssuesByLabel in labels.go - Add metadata to GetReadyWork and GetNewlyUnblockedByClose in ready.go - Fix TestMigrateContentHashColumn test to include metadata column This fixes test failures from the initial metadata implementation where some SELECT statements were missing the new metadata column. Co-Authored-By: Claude Opus 4.5 <[email protected]> * feat: enable metadata updates and add round-trip tests - Add "metadata" to SQLite allowedUpdateFields (matches Dolt) - Add TestIssueMetadataRoundTrip test verifying: - Create issue with metadata -> GetIssue returns it - SearchIssues returns metadata - UpdateIssue can modify metadata - Issues without metadata have nil Metadata field This ensures metadata can be updated via bd update and proves the feature works across key code paths (GH#1406). Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(dolt): handle empty metadata for JSON column type Dolt's JSON column requires valid JSON, so empty strings cause "Invalid JSON text" errors. Added jsonMetadata() helper that returns "{}" when metadata is nil or empty. This fixes TestBootstrapFromJSONL and related Dolt tests. Co-Authored-By: Claude Opus 4.5 <[email protected]> * test: use structural JSON comparison in metadata tests Replace string comparison with jsonEqual() helper that unmarshals and uses reflect.DeepEqual. This prevents test brittleness if JSON gets normalized (whitespace, key order) in the future. Co-Authored-By: Claude Opus 4.5 <[email protected]> --------- Co-authored-by: Claude Opus 4.5 <[email protected]> (cherry picked from commit 92fd124)
groblegark
pushed a commit
to groblegark/beads
that referenced
this pull request
Jan 31, 2026
…veyegge#1407) * feat: add optional JSON metadata field to issues Add an optional `metadata` field to Issue for storing arbitrary JSON data. This enables extension points for tool annotations, file lists, and external system bridging without expanding the core schema. Changes: - Add `Metadata json.RawMessage` field to types.Issue - Add metadata column to SQLite and Dolt schemas - Add migration 041_metadata_column for existing databases - Wire through insert/update/get/search in both backends - Validate metadata is well-formed JSON on create/update - Include metadata in content hash computation The field uses json.RawMessage to preserve exact JSON and supports omitempty for JSONL export compactness. Closes steveyegge#1406 Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: add metadata to SQLite SearchIssues and scanIssues Include metadata column in: - SearchIssues SELECT statement (queries.go) - scanIssues function in dependencies.go - transaction.go GetIssue and SearchIssues SELECTs - scanIssueRow helper function Without this, bd list/ready and other search operations would return issues with empty Metadata fields even when stored. Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix: add metadata column to remaining SELECT statements - Add metadata to GetIssuesByLabel in labels.go - Add metadata to GetReadyWork and GetNewlyUnblockedByClose in ready.go - Fix TestMigrateContentHashColumn test to include metadata column This fixes test failures from the initial metadata implementation where some SELECT statements were missing the new metadata column. Co-Authored-By: Claude Opus 4.5 <[email protected]> * feat: enable metadata updates and add round-trip tests - Add "metadata" to SQLite allowedUpdateFields (matches Dolt) - Add TestIssueMetadataRoundTrip test verifying: - Create issue with metadata -> GetIssue returns it - SearchIssues returns metadata - UpdateIssue can modify metadata - Issues without metadata have nil Metadata field This ensures metadata can be updated via bd update and proves the feature works across key code paths (GH#1406). Co-Authored-By: Claude Opus 4.5 <[email protected]> * fix(dolt): handle empty metadata for JSON column type Dolt's JSON column requires valid JSON, so empty strings cause "Invalid JSON text" errors. Added jsonMetadata() helper that returns "{}" when metadata is nil or empty. This fixes TestBootstrapFromJSONL and related Dolt tests. Co-Authored-By: Claude Opus 4.5 <[email protected]> * test: use structural JSON comparison in metadata tests Replace string comparison with jsonEqual() helper that unmarshals and uses reflect.DeepEqual. This prevents test brittleness if JSON gets normalized (whitespace, key order) in the future. Co-Authored-By: Claude Opus 4.5 <[email protected]> --------- Co-authored-by: Claude Opus 4.5 <[email protected]> (cherry picked from commit 92fd124)
This was referenced Jan 31, 2026
Closed
Closed
turian
added a commit
to turian/beads
that referenced
this pull request
Jan 31, 2026
Add support for setting custom JSON metadata on issues via the bd update command:
- Inline JSON: bd update <id> --metadata '{"key":"value"}'
- File reference: bd update <id> --metadata @file.json
Implementation details:
- Add Metadata field to UpdateArgs in RPC protocol
- Validate JSON with json.Valid() before passing to storage
- Parse @file.json syntax to read metadata from files
- Add tests for both inline and file-based metadata input
The metadata field is already included in bd show --json output via the
Issue struct's Metadata field (from PR steveyegge#1407).
Closes steveyegge#1413
Co-Authored-By: Claude Opus 4.5 <[email protected]>
turian
added a commit
to turian/beads
that referenced
this pull request
Jan 31, 2026
Add support for setting custom JSON metadata on issues via the bd update command:
- Inline JSON: bd update <id> --metadata '{"key":"value"}'
- File reference: bd update <id> --metadata @file.json
Implementation details:
- Add Metadata field to UpdateArgs in RPC protocol
- Validate JSON with json.Valid() before passing to storage
- Parse @file.json syntax to read metadata from files
- Add tests for both inline and file-based metadata input
The metadata field is already included in bd show --json output via the
Issue struct's Metadata field (from PR steveyegge#1407).
Closes steveyegge#1413
Co-Authored-By: Claude Opus 4.5 <[email protected]>
This was referenced Feb 4, 2026
4 tasks
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.
Summary
This PR adds an optional
metadatafield totypes.Issueto support structured, extensible attachments (tool annotations, file lists, integration payloads, etc.) without requiring new first-class columns for every use case.The field is:
TEXT NOT NULL DEFAULT '{}') and Dolt (JSON DEFAULT (JSON_OBJECT()))Motivation / Use Cases
Beads already uses JSON blobs in a few places (e.g. dependency metadata, event payloads, JSON-encoded arrays). This PR extends that pattern to issues themselves.
Example use cases:
{"files":["foo.go","bar.go"]}(explicit filenames/paths; no globs)Implementation Details
internal/types/types.go
Metadata json.RawMessage \json:"metadata,omitempty"``ValidateWithCustomandValidateForImportComputeContentHash()SQLite
issues.metadatacolumn via new migration041_metadata_column.goUpdateIssue(allowedUpdateFields["metadata"]=true)internal/storage/sqlite/metadata_test.goto verify create/get/search/update and nil behavior when unsetDolt
issues.metadataJSON column in schemajsonMetadata()helper (empty →"{}")types.IssueisAllowedUpdateField("metadata")Compatibility / Why this shouldn't break existing users
This is an additive, backwards-compatible change for typical Beads usage:
omitempty). Older JSONL without metadata imports as before.'{}').Potential edge cases:
metadatafield.ALTER TABLEto add the new column (Dolt schema creation isCREATE TABLE IF NOT EXISTS, which does not modify existing tables). New databases are unaffected.Related Issues / Context
Follow-ups (proposed)
bd update --metadata @file.jsonorbd annotate --metadata ...)metadata.files: explicit filenames/paths only (no globs)metadata.tool: tool name/versionmetadata.diagnostics: structured findings summaryALTER TABLEstep during init/open when column missing.🤖 Generated with Claude Code