@@ -22,6 +22,8 @@ func (e *Engine) Feedback(ctx context.Context, id string, action FeedbackAction,
2222 if err := ctx .Err (); err != nil {
2323 return err
2424 }
25+ e .mu .Lock ()
26+ defer e .mu .Unlock ()
2527 node , err := e .store .GetNode (ctx , id )
2628 if err != nil {
2729 return fmt .Errorf ("node %s not found: %w" , id , err )
@@ -38,7 +40,9 @@ func (e *Engine) Feedback(ctx context.Context, id string, action FeedbackAction,
3840 if newContent == "" {
3941 return fmt .Errorf ("edit requires new content" )
4042 }
41- _ = e .store .SaveVersion (ctx , node .ID , node .Content , "user" , "edited via feedback" )
43+ if err := e .store .SaveVersion (ctx , node .ID , node .Content , "user" , "edited via feedback" ); err != nil {
44+ return fmt .Errorf ("save version: %w" , err )
45+ }
4246 node .Content = newContent
4347 node .ContentHash = contentHash (newContent , node .Scope , node .Project )
4448 node .Version ++
@@ -47,7 +51,9 @@ func (e *Engine) Feedback(ctx context.Context, id string, action FeedbackAction,
4751 return e .store .UpdateNode (ctx , node )
4852
4953 case FeedbackDiscard :
50- _ = e .store .SaveVersion (ctx , node .ID , node .Content , "user" , "discarded via feedback" )
54+ if err := e .store .SaveVersion (ctx , node .ID , node .Content , "user" , "discarded via feedback" ); err != nil {
55+ return fmt .Errorf ("save version: %w" , err )
56+ }
5157 node .Confidence = 0
5258 return e .store .UpdateNode (ctx , node )
5359
@@ -61,6 +67,8 @@ func (e *Engine) Rollback(ctx context.Context, id string, version int) error {
6167 if err := ctx .Err (); err != nil {
6268 return err
6369 }
70+ e .mu .Lock ()
71+ defer e .mu .Unlock ()
6472 versions , err := e .store .GetVersions (ctx , id )
6573 if err != nil {
6674 return err
@@ -71,7 +79,9 @@ func (e *Engine) Rollback(ctx context.Context, id string, version int) error {
7179 if err != nil {
7280 return err
7381 }
74- _ = e .store .SaveVersion (ctx , node .ID , node .Content , "system" , fmt .Sprintf ("rollback to v%d" , version ))
82+ if err := e .store .SaveVersion (ctx , node .ID , node .Content , "system" , fmt .Sprintf ("rollback to v%d" , version )); err != nil {
83+ return fmt .Errorf ("save version: %w" , err )
84+ }
7585 node .Content = v .Content
7686 node .Version ++
7787 node .UpdatedAt = time .Now ()
@@ -82,18 +92,22 @@ func (e *Engine) Rollback(ctx context.Context, id string, version int) error {
8292}
8393
8494// PendingNodes returns low-confidence nodes that may need review.
95+ // Limited to 1000 nodes to prevent unbounded memory use on large graphs.
8596func (e * Engine ) PendingNodes (ctx context.Context , project string , threshold float64 ) ([]* storage.Node , error ) {
8697 if err := ctx .Err (); err != nil {
8798 return nil , err
8899 }
89- nodes , err := e .store .ListNodes (ctx , storage.NodeFilter {Project : project })
100+ nodes , err := e .store .ListNodes (ctx , storage.NodeFilter {Project : project , MinConfidence : 0.01 })
90101 if err != nil {
91102 return nil , err
92103 }
93104 var pending []* storage.Node
94105 for _ , n := range nodes {
95106 if n .Confidence > 0 && n .Confidence < threshold {
96107 pending = append (pending , n )
108+ if len (pending ) >= 1000 {
109+ break
110+ }
97111 }
98112 }
99113 return pending , nil
0 commit comments