From a803da36e1f46eec333dd6f7595e14afab80bcd7 Mon Sep 17 00:00:00 2001 From: beads/crew/dave Date: Sat, 10 Jan 2026 19:33:47 -0800 Subject: [PATCH] feat: add 'attests' edge type for skill attestations Add new DependencyType 'attests' for skill attestations. Enables: Entity X attests that Entity Y has skill Z at level N. - Add DepAttests constant to dependency types - Add AttestsMeta struct for skill, level, date, evidence, notes - Update IsWellKnown() to include attests - Add test cases for the new edge type Foundation for HOP skill portability. Closes: bd-2papc Co-Authored-By: Claude Opus 4.5 Executed-By: beads/crew/dave Rig: beads Role: crew --- internal/types/types.go | 19 ++++++++++++++++++- internal/types/types_test.go | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/internal/types/types.go b/internal/types/types.go index 98d7552f..856eb2dd 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -649,6 +649,7 @@ const ( DepAuthoredBy DependencyType = "authored-by" // Creator relationship DepAssignedTo DependencyType = "assigned-to" // Assignment relationship DepApprovedBy DependencyType = "approved-by" // Approval relationship + DepAttests DependencyType = "attests" // Skill attestation: X attests Y has skill Z // Convoy tracking (non-blocking cross-project references) DepTracks DependencyType = "tracks" // Convoy → issue tracking (non-blocking) @@ -672,7 +673,7 @@ func (d DependencyType) IsWellKnown() bool { switch d { case DepBlocks, DepParentChild, DepConditionalBlocks, DepWaitsFor, DepRelated, DepDiscoveredFrom, DepRepliesTo, DepRelatesTo, DepDuplicates, DepSupersedes, - DepAuthoredBy, DepAssignedTo, DepApprovedBy, DepTracks, + DepAuthoredBy, DepAssignedTo, DepApprovedBy, DepAttests, DepTracks, DepUntil, DepCausedBy, DepValidates: return true } @@ -701,6 +702,22 @@ const ( WaitsForAnyChildren = "any-children" // Proceed when first child completes (future) ) +// AttestsMeta holds metadata for attests dependencies (skill attestations). +// Stored as JSON in the Dependency.Metadata field. +// Enables: Entity X attests that Entity Y has skill Z at level N. +type AttestsMeta struct { + // Skill is the identifier of the skill being attested (e.g., "go", "rust", "code-review") + Skill string `json:"skill"` + // Level is the proficiency level (e.g., "beginner", "intermediate", "expert", or numeric 1-5) + Level string `json:"level"` + // Date is when the attestation was made (RFC3339 format) + Date string `json:"date"` + // Evidence is optional reference to supporting evidence (e.g., issue ID, commit, PR) + Evidence string `json:"evidence,omitempty"` + // Notes is optional free-form notes about the attestation + Notes string `json:"notes,omitempty"` +} + // FailureCloseKeywords are keywords that indicate an issue was closed due to failure. // Used by conditional-blocks dependencies to determine if the condition is met. var FailureCloseKeywords = []string{ diff --git a/internal/types/types_test.go b/internal/types/types_test.go index 4305add8..f17536c3 100644 --- a/internal/types/types_test.go +++ b/internal/types/types_test.go @@ -749,6 +749,7 @@ func TestDependencyTypeIsWellKnown(t *testing.T) { {DepAuthoredBy, true}, {DepAssignedTo, true}, {DepApprovedBy, true}, + {DepAttests, true}, {DepTracks, true}, {DepUntil, true}, {DepCausedBy, true}, @@ -784,6 +785,7 @@ func TestDependencyTypeAffectsReadyWork(t *testing.T) { {DepAuthoredBy, false}, {DepAssignedTo, false}, {DepApprovedBy, false}, + {DepAttests, false}, {DepTracks, false}, {DepUntil, false}, {DepCausedBy, false},