feat(types): add HOP entity tracking types (bd-7pwh)

- Add EntityRef type for structured entity references with URI support
- Add Creator field to Issue for tracking who created work
- Add Validation type and Validations field for proof-of-stake approvals
- Fix RemoveDependency FK violation on external deps (bd-a3sj)
- Include all new fields in content hash computation
- Full test coverage for all new types

🤝 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-22 20:09:55 -08:00
parent 6a2909c686
commit 62bbae9c78
4 changed files with 514 additions and 2 deletions

View File

@@ -221,8 +221,13 @@ func (s *SQLiteStorage) RemoveDependency(ctx context.Context, issueID, dependsOn
return fmt.Errorf("failed to record event: %w", err)
}
// Mark both issues as dirty for incremental export
if err := markIssuesDirtyTx(ctx, tx, []string{issueID, dependsOnID}); err != nil {
// Mark issues as dirty for incremental export
// For external refs, only mark the source issue (target doesn't exist locally)
issueIDsToMark := []string{issueID}
if !strings.HasPrefix(dependsOnID, "external:") {
issueIDsToMark = append(issueIDsToMark, dependsOnID)
}
if err := markIssuesDirtyTx(ctx, tx, issueIDsToMark); err != nil {
return wrapDBError("mark issues dirty after removing dependency", err)
}

View File

@@ -1610,3 +1610,50 @@ func TestDetectCycles_RelatesTypeAllowsBidirectionalWithoutCycleReport(t *testin
t.Error("Expected B to relate-to A")
}
}
// TestRemoveDependencyExternal verifies that removing an external dependency
// doesn't cause FK violation (bd-a3sj). External refs like external:project:capability
// don't exist in the issues table, so we must not mark them as dirty.
func TestRemoveDependencyExternal(t *testing.T) {
store, cleanup := setupTestDB(t)
defer cleanup()
ctx := context.Background()
// Create an issue
issue := &types.Issue{
Title: "Issue with external dep",
Status: types.StatusOpen,
Priority: 1,
IssueType: types.TypeTask,
}
if err := store.CreateIssue(ctx, issue, "test-user"); err != nil {
t.Fatalf("CreateIssue failed: %v", err)
}
// Add an external dependency
externalRef := "external:other-project:some-capability"
dep := &types.Dependency{
IssueID: issue.ID,
DependsOnID: externalRef,
Type: types.DepBlocks,
}
if err := store.AddDependency(ctx, dep, "test-user"); err != nil {
t.Fatalf("AddDependency failed: %v", err)
}
// This should NOT cause FK violation (the bug was marking external ref as dirty)
err := store.RemoveDependency(ctx, issue.ID, externalRef, "test-user")
if err != nil {
t.Fatalf("RemoveDependency on external ref should succeed, got: %v", err)
}
// Verify dependency was actually removed
deps, err := store.GetDependencyRecords(ctx, issue.ID)
if err != nil {
t.Fatalf("GetDependencyRecords failed: %v", err)
}
if len(deps) != 0 {
t.Errorf("Expected 0 dependencies after removal, got %d", len(deps))
}
}