diff --git a/api/initialise_test.go b/api/initialise_test.go
index 11ea37d71cc0c0c4464ac9bbf54c403b43c51e26..39fd31483246ca8a7b54f58f2f5237ed99061290 100644
--- a/api/initialise_test.go
+++ b/api/initialise_test.go
@@ -5,6 +5,7 @@ import (
 	"net"
 	"os"
 	"testing"
+	"time"
 
 	cpb "code.fbi.h-da.de/cocsn/api/go/gosdn/core"
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
@@ -71,13 +72,17 @@ func bootstrapUnitTest() {
 		log.Fatal(err)
 	}
 
+	mockChange := &mocks.Change{}
+	mockChange.On("Age").Return(time.Hour)
+	mockChange.On("State").Return(ppb.Change_INCONSISTENT)
+
 	mockPnd := mocks.NetworkDomain{}
 	mockPnd.On("ID").Return(pndUUID)
 	mockPnd.On("GetName").Return("test")
 	mockPnd.On("GetDescription").Return("test")
 	mockPnd.On("PendingChanges").Return([]uuid.UUID{changeUUID})
 	mockPnd.On("CommittedChanges").Return([]uuid.UUID{changeUUID})
-	mockPnd.On("GetChange", mock.Anything).Return(&nucleus.Change{}, nil)
+	mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil)
 	mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil)
 	mockPnd.On("GetDevice", mock.Anything).Return(&nucleus.CommonDevice{
 		UUID:     deviceUUID,
diff --git a/go.mod b/go.mod
index 3352d794160883bce4428e0e5ae4220c2ed2e87b..a08af136b5f58a1b4abcc8c26f6465b851558df0 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module code.fbi.h-da.de/cocsn/gosdn
 go 1.16
 
 require (
-	code.fbi.h-da.de/cocsn/api v0.2.2
+	code.fbi.h-da.de/cocsn/api v0.2.3
 	code.fbi.h-da.de/cocsn/yang-models v0.0.7
 	github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a
 	github.com/docker/docker v20.10.6+incompatible
diff --git a/go.sum b/go.sum
index 7e38b738e82ae94a458608b99b5399eb21b924f3..5ef6055e5ebd8c702b23cce100414d576e0b1830 100644
--- a/go.sum
+++ b/go.sum
@@ -21,8 +21,8 @@ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIA
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
 cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-code.fbi.h-da.de/cocsn/api v0.2.2 h1:pJ1P3+l8Fl+JWEkoLTSBOvB6LrxUYYqRbfdt+eSWQSk=
-code.fbi.h-da.de/cocsn/api v0.2.2/go.mod h1:s+P4Lrxl5rHyo/Q0UTABZrDfH4zuAoRKdzktlL0UsRI=
+code.fbi.h-da.de/cocsn/api v0.2.3 h1:zyXVU2yuRuS5a+UMGUj8eT86E+sxw15NHtFN9tjXfCk=
+code.fbi.h-da.de/cocsn/api v0.2.3/go.mod h1:s+P4Lrxl5rHyo/Q0UTABZrDfH4zuAoRKdzktlL0UsRI=
 code.fbi.h-da.de/cocsn/yang-models v0.0.7 h1:3TOo8J+EdAJKeq4o3aaNWZRhjSwguIS8wciW1U9PkSk=
 code.fbi.h-da.de/cocsn/yang-models v0.0.7/go.mod h1:M+2HinfhTT8nA8qvn2cpWNlOtuiizTNDWA3yfy72K/g=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
diff --git a/interfaces/change/change.go b/interfaces/change/change.go
index 493c2183fb3cb3b416badaf39d1c9e449f7e1db4..28b15cbe8be4bbb43959eb1a134e3670c9406f35 100644
--- a/interfaces/change/change.go
+++ b/interfaces/change/change.go
@@ -1,6 +1,8 @@
 package change
 
 import (
+	"time"
+
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
@@ -15,6 +17,7 @@ type Change interface {
 	Commit() error
 	Confirm() error
 	State() ppb.Change_State
+	Age() time.Duration
 }
 
 // Payload contains two ygot.GoStructs, the first represents the original state
diff --git a/mocks/Change.go b/mocks/Change.go
index c211183e76791592c3dcb4274f3fd250df54969f..945413247293aa4e2d6aba02b6cca46b9a0024f3 100644
--- a/mocks/Change.go
+++ b/mocks/Change.go
@@ -6,6 +6,8 @@ import (
 	pnd "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 	mock "github.com/stretchr/testify/mock"
 
+	time "time"
+
 	uuid "github.com/google/uuid"
 )
 
@@ -14,6 +16,20 @@ type Change struct {
 	mock.Mock
 }
 
+// Age provides a mock function with given fields:
+func (_m *Change) Age() time.Duration {
+	ret := _m.Called()
+
+	var r0 time.Duration
+	if rf, ok := ret.Get(0).(func() time.Duration); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(time.Duration)
+	}
+
+	return r0
+}
+
 // Commit provides a mock function with given fields:
 func (_m *Change) Commit() error {
 	ret := _m.Called()
diff --git a/northbound/server/pnd.go b/northbound/server/pnd.go
index 42168323f949af46682f7246ca54cd7882a0aaaa..887ded7dccc5ef9adfb069b403cf109c4e34f092 100644
--- a/northbound/server/pnd.go
+++ b/northbound/server/pnd.go
@@ -281,18 +281,11 @@ func fillChanges(pnd networkdomain.NetworkDomain, all bool, cuid ...string) ([]*
 			log.Error(err)
 			return nil, status.Errorf(codes.Aborted, "%v", err)
 		}
-		change, ok := c.(*nucleus.Change)
-		if !ok {
-			return nil, &errors.ErrInvalidTypeAssertion{
-				Value: change,
-				Type:  reflect.TypeOf(&nucleus.Change{}),
-			}
-		}
 
 		changes[i] = &ppb.Change{
 			Id:    ch.String(),
-			Age:   change.Age().Microseconds(),
-			State: change.State(),
+			Age:   c.Age().Microseconds(),
+			State: c.State(),
 		}
 	}
 	return changes, nil
diff --git a/northbound/server/pnd_test.go b/northbound/server/pnd_test.go
index 0137cde1a7d54bd6aab8bd48a563a3a7f55111c5..83ca057c7d0127e0e2cb434dc7866c0e2dc3683b 100644
--- a/northbound/server/pnd_test.go
+++ b/northbound/server/pnd_test.go
@@ -5,6 +5,7 @@ import (
 	"os"
 	"reflect"
 	"testing"
+	"time"
 
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
 	spb "code.fbi.h-da.de/cocsn/api/go/gosdn/southbound"
@@ -75,6 +76,10 @@ func TestMain(m *testing.M) {
 		log.Fatal(err)
 	}
 
+	mockChange := &mocks.Change{}
+	mockChange.On("Age").Return(time.Hour)
+	mockChange.On("State").Return(ppb.Change_INCONSISTENT)
+
 	mockPnd = &mocks.NetworkDomain{}
 	mockPnd.On("ID").Return(pndUUID)
 	mockPnd.On("GetName").Return("test")
@@ -83,7 +88,7 @@ func TestMain(m *testing.M) {
 	mockPnd.On("Devices").Return([]uuid.UUID{deviceUUID})
 	mockPnd.On("PendingChanges").Return([]uuid.UUID{pendingChangeUUID})
 	mockPnd.On("CommittedChanges").Return([]uuid.UUID{committedChangeUUID})
-	mockPnd.On("GetChange", mock.Anything).Return(&nucleus.Change{}, nil)
+	mockPnd.On("GetChange", mock.Anything).Return(mockChange, nil)
 	mockPnd.On("AddDevice", mock.Anything, mock.Anything, mock.Anything).Return(nil)
 	mockPnd.On("GetDevice", mock.Anything).Return(mockDevice, nil)
 	mockPnd.On("Commit", mock.Anything).Return(nil)
diff --git a/nucleus/change.go b/nucleus/change.go
index 391a90bfe4da99142f820e840e6b0f262151ac32..8bccf6deec1d88952bef7cdfc3aa7be0965b6e51 100644
--- a/nucleus/change.go
+++ b/nucleus/change.go
@@ -28,26 +28,25 @@ func init() {
 	}
 }
 
-// NewChange takes a Device UUID, a pair GoStructs (current and intended state)
-// a callback function and a channel for errors and returns a *Change
+// NewChange takes a Device UUID, a pair GoStructs (current and intended state),
+// a callback function, and returns a *Change.
 // The callback function is used by the Commit() and Confirm() functions. It
 // must define how the change is carried out.
-func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruct, callback func(ygot.GoStruct, ygot.GoStruct) error, errChan chan error) *Change {
-	commit, confirm, out := stateManager(changeTimeout)
-	return &Change{
+func NewChange(device uuid.UUID, currentState ygot.GoStruct, change ygot.GoStruct, callback func(ygot.GoStruct, ygot.GoStruct) error) *Change {
+	c := &Change{
 		cuid:          uuid.New(),
 		duid:          device,
 		timestamp:     time.Now(),
 		previousState: currentState,
 		intendedState: change,
-		committed:     false,
-		confirmed:     false,
 		callback:      callback,
-		errChan:       errChan,
-		out:           out,
-		commit:        commit,
-		confirm:       confirm,
 	}
+	stateIn, stateOut, requestState, errChan := stateManager(c, changeTimeout)
+	c.stateIn = stateIn
+	c.stateOut = stateOut
+	c.requestState = requestState
+	c.errChan = errChan
+	return c
 }
 
 // Change is an intended change to an OND. It is unique and immutable.
@@ -60,14 +59,11 @@ type Change struct {
 	timestamp     time.Time
 	previousState ygot.GoStruct
 	intendedState ygot.GoStruct
-	committed     bool
-	confirmed     bool
-	inconsistent  bool
 	callback      func(ygot.GoStruct, ygot.GoStruct) error
-	errChan       chan error
-	out           <-chan bool
-	commit        chan<- *Change
-	confirm       chan<- *Change
+	errChan       <-chan error
+	requestState  chan<- bool
+	stateIn       chan<- ppb.Change_State
+	stateOut      <-chan ppb.Change_State
 }
 
 // ID returns the Change's UUID
@@ -79,36 +75,30 @@ func (c *Change) ID() uuid.UUID {
 // and starts the timeout-timer for the Change. If the timer expires
 // the change is rolled back.
 func (c *Change) Commit() error {
-	if c.committed {
+	if c.State() == ppb.Change_COMMITTED {
 		return fmt.Errorf("change %v already committed", c.cuid)
 	}
-	c.commit <- c
+	c.stateIn <- ppb.Change_COMMITTED
 	select {
 	case err := <-c.errChan:
-		if err != nil {
-			return err
-		}
-	case <-c.out:
+		return err
+	case <-c.stateOut:
 		return nil
 	}
-	return nil
 }
 
 // Confirm confirms a committed Change and stops the rollback timer.
 func (c *Change) Confirm() error {
-	if !c.committed {
+	if c.State() != ppb.Change_COMMITTED {
 		return fmt.Errorf("cannot confirm uncommitted change %v", c.cuid)
 	}
-	c.confirm <- c
+	c.stateIn <- ppb.Change_CONFIRMED
 	select {
 	case err := <-c.errChan:
-		if err != nil {
-			return err
-		}
-	case <-c.out:
+		return err
+	case <-c.stateOut:
 		return nil
 	}
-	return nil
 }
 
 // Age returns the passed time since the Change was created
@@ -118,44 +108,51 @@ func (c *Change) Age() time.Duration {
 
 // State returns the changes's state.
 func (c *Change) State() ppb.Change_State {
-	if !c.committed {
-		return ppb.Change_PENDING
-	} else if !c.confirmed {
-		return ppb.Change_COMMITTED
-	} else {
-		return ppb.Change_CONFIRMED
-	}
+	c.requestState <- true
+	return <-c.stateOut
 }
 
-func stateManager(timeout time.Duration) (chan<- *Change, chan<- *Change, <-chan bool) {
-	commit := make(chan *Change)
-	confirm := make(chan *Change)
-	out := make(chan bool)
+func stateManager(ch *Change, timeout time.Duration) (chan<- ppb.Change_State, <-chan ppb.Change_State, chan<- bool, <-chan error) {
+	stateIn := make(chan ppb.Change_State)
+	stateOut := make(chan ppb.Change_State)
+	stateRequest := make(chan bool)
+	errChan := make(chan error)
 	ticker := time.NewTicker(timeout)
 
 	go func() {
-		ch := <-commit
-		err := ch.callback(ch.previousState, ch.intendedState)
-		if err != nil {
-			ch.errChan <- err
-		}
-		ch.committed = true
-		out <- true
+		state := ppb.Change_PENDING
 		for {
 			select {
 			case <-ticker.C:
-				err := ch.callback(ch.intendedState, ch.previousState)
-				if err != nil {
-					ch.errChan <- err
+				// only roll back committed changes
+				if state == ppb.Change_COMMITTED {
+					err := ch.callback(ch.intendedState, ch.previousState)
+					if err != nil {
+						state = ppb.Change_INCONSISTENT
+						errChan <- err
+					}
+					errChan <- fmt.Errorf("change %v timed out", ch.cuid)
+					break
+				}
+			case s := <-stateIn:
+				switch s {
+				case ppb.Change_COMMITTED:
+					err := ch.callback(ch.previousState, ch.intendedState)
+					if err != nil {
+						state = ppb.Change_INCONSISTENT
+						errChan <- err
+						continue
+					}
+					state = ppb.Change_COMMITTED
+					stateOut <- state
+				case ppb.Change_CONFIRMED:
+					state = ppb.Change_CONFIRMED
+					stateOut <- state
 				}
-				ch.errChan <- fmt.Errorf("change %v timed out", ch.cuid)
-				break
-			case <-confirm:
-				ch.confirmed = true
-				out <- true
-				break
+			case <-stateRequest:
+				stateOut <- state
 			}
 		}
 	}()
-	return commit, confirm, out
+	return stateIn, stateOut, stateRequest, errChan
 }
diff --git a/nucleus/change_test.go b/nucleus/change_test.go
index 422b172619329a65189cf6acb130fc554ca410ed..3f16dd04a61b75b60c677d613dad4ec7e4fa7d31 100644
--- a/nucleus/change_test.go
+++ b/nucleus/change_test.go
@@ -3,6 +3,7 @@ package nucleus
 import (
 	"errors"
 	"reflect"
+	"sync"
 	"testing"
 	"time"
 
@@ -28,16 +29,11 @@ var rollbackDevice = &exampleoc.Device{
 }
 
 func TestChange_CommitRollback(t *testing.T) {
+	wg := sync.WaitGroup{}
 	wantErr := false
 	want := rollbackHostname
 	callback := make(chan string)
-	errChan := make(chan error, 10)
-	commit, confirm, out := stateManager(time.Millisecond * 100)
 	c := &Change{
-		commit:        commit,
-		confirm:       confirm,
-		errChan:       errChan,
-		out:           out,
 		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
@@ -45,7 +41,7 @@ func TestChange_CommitRollback(t *testing.T) {
 		intendedState: commitDevice,
 		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
 			hostname := *first.(*exampleoc.Device).System.Hostname
-			t.Logf("hostname: %v", hostname)
+			t.Logf("callback in test %v", t.Name())
 			switch hostname {
 			case rollbackHostname:
 				callback <- rollbackHostname
@@ -53,27 +49,33 @@ func TestChange_CommitRollback(t *testing.T) {
 			return nil
 		},
 	}
+	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
+	c.stateIn = stateIn
+	c.stateOut = stateOut
+	c.requestState = requestState
+	c.errChan = errChan
+	wg.Add(1)
 	go func() {
+		defer wg.Done()
 		time.Sleep(time.Millisecond * 10)
 		if err := c.Commit(); (err != nil) != wantErr {
 			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
 		}
-		time.Sleep(time.Millisecond * 100)
+		time.Sleep(time.Millisecond * 200)
 	}()
 	got := <-callback
 	if !reflect.DeepEqual(got, want) {
 		t.Errorf("Commit() = %v, want %v", got, want)
 	}
+	wg.Wait()
 }
 
 func TestChange_CommitRollbackError(t *testing.T) {
+	wg := sync.WaitGroup{}
+	wg.Add(1)
 	wantErr := false
 	want := errors.New("this is an expected error")
-	commit, confirm, out := stateManager(time.Millisecond * 100)
 	c := &Change{
-		commit:        commit,
-		confirm:       confirm,
-		out:           out,
 		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
@@ -81,35 +83,38 @@ func TestChange_CommitRollbackError(t *testing.T) {
 		intendedState: commitDevice,
 		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
 			hostname := *second.(*exampleoc.Device).System.Hostname
-			t.Logf("hostname: %v", hostname)
+			t.Logf("callback in test %v", t.Name())
 			switch hostname {
 			case rollbackHostname:
 				return errors.New("this is an expected error")
 			}
 			return nil
 		},
-		errChan: make(chan error),
 	}
+	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
+	c.stateIn = stateIn
+	c.stateOut = stateOut
+	c.requestState = requestState
+	c.errChan = errChan
+
 	go func() {
+		defer wg.Done()
 		time.Sleep(time.Millisecond * 10)
 		if err := c.Commit(); (err != nil) != wantErr {
 			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
 		}
-		time.Sleep(time.Millisecond * 100)
+		time.Sleep(time.Millisecond * 200)
 	}()
 	got := <-c.errChan
 	if !reflect.DeepEqual(got, want) {
 		t.Errorf("Commit() = %v, want %v", got, want)
 	}
+	wg.Wait()
 }
 
 func TestChange_CommitError(t *testing.T) {
-	wantErr := true
-	commit, confirm, out := stateManager(time.Millisecond * 100)
+	want := ppb.Change_INCONSISTENT
 	c := &Change{
-		commit:        commit,
-		confirm:       confirm,
-		out:           out,
 		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
@@ -119,38 +124,41 @@ func TestChange_CommitError(t *testing.T) {
 			return errors.New("this is an expected error")
 		},
 	}
-	go func() {
-		time.Sleep(time.Millisecond * 10)
-		if err := c.Commit(); (err != nil) != wantErr {
-			t.Errorf("Commit() error = %v, wantErr %v", err, wantErr)
-		}
-	}()
-	got := c.committed
-	if !reflect.DeepEqual(got, false) {
-		t.Errorf("Commit() = %v, want %v", got, false)
+	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
+	c.stateIn = stateIn
+	c.stateOut = stateOut
+	c.requestState = requestState
+	c.errChan = errChan
+
+	time.Sleep(time.Millisecond * 10)
+	if err := c.Commit(); err == nil {
+		t.Errorf("Commit() expected error, error = %v", err)
+	}
+	got := c.State()
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Commit() = %v, want %v", got, want)
 	}
 }
 
 func TestChange_Commit(t *testing.T) {
 	want := ppb.Change_COMMITTED
-
-	commit, confirm, out := stateManager(time.Millisecond * 100)
 	c := &Change{
-		commit:        commit,
-		confirm:       confirm,
-		out:           out,
 		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
 		previousState: rollbackDevice,
 		intendedState: commitDevice,
 		callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
-			hostname := *first.(*exampleoc.Device).System.Hostname
-			t.Logf("hostname: %v", hostname)
+			t.Logf("callback in test %v", t.Name())
 			return nil
 		},
-		errChan: make(chan error, 10),
 	}
+	stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
+	c.stateIn = stateIn
+	c.stateOut = stateOut
+	c.requestState = requestState
+	c.errChan = errChan
+
 	if err := c.Commit(); err != nil {
 		t.Errorf("Commit() error = %v", err)
 	}
@@ -179,13 +187,7 @@ func TestChange_Confirm(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			errChan := make(chan error, 10)
-			commit, confirm, out := stateManager(time.Millisecond * 100)
 			c := &Change{
-				commit:  commit,
-				confirm: confirm,
-				errChan: errChan,
-				out:     out,
 				previousState: &exampleoc.Device{
 					System: &exampleoc.System{
 						Hostname: &rollbackHostname,
@@ -197,11 +199,16 @@ func TestChange_Confirm(t *testing.T) {
 					},
 				},
 				callback: func(first ygot.GoStruct, second ygot.GoStruct) error {
-					hostname := *first.(*exampleoc.Device).System.Hostname
-					t.Logf("hostname: %v", hostname)
+					t.Logf("callback in test %v", t.Name())
 					return nil
 				},
 			}
+			stateIn, stateOut, requestState, errChan := stateManager(c, time.Millisecond*100)
+			c.stateIn = stateIn
+			c.stateOut = stateOut
+			c.requestState = requestState
+			c.errChan = errChan
+
 			if tt.name == "committed" {
 				if err := c.Commit(); err != nil {
 					t.Errorf("Commit() error = %v, wantErr %v", err, tt.wantErr)
@@ -262,12 +269,10 @@ func TestChange_State(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
-				hostname := *first.(*exampleoc.Device).System.Hostname
-				t.Logf("hostname: %v", hostname)
+				t.Logf("callback in test %v", t.Name())
 				return nil
 			}
-			errChan := make(chan error)
-			c := NewChange(did, rollbackDevice, commitDevice, callback, errChan)
+			c := NewChange(did, rollbackDevice, commitDevice, callback)
 			if tt.name != "pending" {
 				if err := c.Commit(); err != nil {
 					t.Errorf("Commit() error = %v", err)
diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go
index c93c3615ff866b3adcfd69e6e82acd185fa44bda..ed715276991df0cb7602ffbd345d7189652b8972 100644
--- a/nucleus/initialise_test.go
+++ b/nucleus/initialise_test.go
@@ -155,6 +155,5 @@ func newPnd() pndImplementation {
 		devices:     NewDeviceStore(),
 		changes:     ChangeStore{genericStore{}},
 		id:          defaultPndID,
-		errChans:    make(map[uuid.UUID]chan error),
 	}
 }
diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go
index 4655a0b074dcfdbf9dcbfb1187ab3c3a36b04cd6..18b06083047476836375ee690fae350988fad3de 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -35,7 +35,6 @@ func NewPND(name, description string, id uuid.UUID, sbi southbound.SouthboundInt
 		devices:     NewDeviceStore(),
 		changes:     ChangeStore{genericStore{}},
 		id:          id,
-		errChans:    make(map[uuid.UUID]chan error),
 
 		csbiClient: c,
 		callback:   callback,
@@ -53,7 +52,6 @@ type pndImplementation struct {
 	devices     *DeviceStore
 	changes     ChangeStore
 	id          uuid.UUID
-	errChans    map[uuid.UUID]chan error
 
 	csbiClient cpb.CsbiClient
 	callback   func(uuid.UUID, chan DeviceDetails)
@@ -312,11 +310,7 @@ func (pnd *pndImplementation) ChangeOND(duid uuid.UUID, operation ppb.ApiOperati
 		payload := change.Payload{Original: original, Modified: modified}
 		return d.Transport().Set(ctx, payload)
 	}
-
-	errChan := make(chan error)
-	ch := NewChange(duid, d.Model(), cpy, callback, errChan)
-	pnd.errChans[ch.ID()] = errChan
-
+	ch := NewChange(duid, d.Model(), cpy, callback)
 	if err := pnd.changes.Add(ch); err != nil {
 		return uuid.Nil, err
 	}
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
index 536d4d71993971b2cedd071dd4438230a9f61cfb..b273821a04c0dce6c6faab303064f12616d246c9 100644
--- a/nucleus/principalNetworkDomain_test.go
+++ b/nucleus/principalNetworkDomain_test.go
@@ -16,6 +16,7 @@ import (
 	"github.com/google/uuid"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	"github.com/openconfig/ygot/ygot"
+	log "github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/mock"
 )
 
@@ -790,21 +791,31 @@ func Test_pndImplementation_Confirm(t *testing.T) {
 }
 
 func Test_pndImplementation_PendingChanges(t *testing.T) {
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+
+	store := NewChangeStore()
+	pending := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := store.Add(pending); err != nil {
+		t.Error(err)
+		return
+	}
 	tests := []struct {
 		name string
 		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			want: []uuid.UUID{cuid},
+			want: []uuid.UUID{pending.cuid},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			pnd := newPnd()
-			pnd.changes.genericStore[cuid] = &Change{
-				cuid: cuid,
-			}
+			pnd.changes = *store
 			if got := pnd.PendingChanges(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("pndImplementation.PendingChanges() = %v, want %v", got, tt.want)
 			}
@@ -813,22 +824,35 @@ func Test_pndImplementation_PendingChanges(t *testing.T) {
 }
 
 func Test_pndImplementation_CommittedChanges(t *testing.T) {
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+
+	store := NewChangeStore()
+	committed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := committed.Commit(); err != nil {
+		t.Error(err)
+		return
+	}
+	if err := store.Add(committed); err != nil {
+		t.Error(err)
+		return
+	}
 	tests := []struct {
 		name string
 		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			want: []uuid.UUID{cuid},
+			want: []uuid.UUID{committed.cuid},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			pnd := newPnd()
-			pnd.changes.genericStore[cuid] = &Change{
-				cuid:      cuid,
-				committed: true,
-			}
+			pnd.changes = *store
 			if got := pnd.CommittedChanges(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("pndImplementation.CommittedChanges() = %v, want %v", got, tt.want)
 			}
@@ -837,23 +861,38 @@ func Test_pndImplementation_CommittedChanges(t *testing.T) {
 }
 
 func Test_pndImplementation_ConfirmedChanges(t *testing.T) {
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+	store := NewChangeStore()
+	confirmed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := confirmed.Commit(); err != nil {
+		t.Error(err)
+		return
+	}
+	if err := confirmed.Confirm(); err != nil {
+		t.Error(err)
+		return
+	}
+	if err := store.Add(confirmed); err != nil {
+		t.Error(err)
+		return
+	}
 	tests := []struct {
 		name string
 		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			want: []uuid.UUID{cuid},
+			want: []uuid.UUID{confirmed.cuid},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			pnd := newPnd()
-			pnd.changes.genericStore[cuid] = &Change{
-				cuid:      cuid,
-				committed: true,
-				confirmed: true,
-			}
+			pnd.changes = *store
 			if got := pnd.ConfirmedChanges(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("pndImplementation.ConfirmedChanges() = %v, want %v", got, tt.want)
 			}
diff --git a/nucleus/store_test.go b/nucleus/store_test.go
index 42f6a95d6677e31c8227c016fba9cfdcac986277..2e19b2ff2f30d995a789c735a5706f46577f3381 100644
--- a/nucleus/store_test.go
+++ b/nucleus/store_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	ppb "code.fbi.h-da.de/cocsn/api/go/gosdn/pnd"
+	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
 
 	"code.fbi.h-da.de/cocsn/gosdn/interfaces/device"
 	"code.fbi.h-da.de/cocsn/gosdn/interfaces/networkdomain"
@@ -14,6 +15,8 @@ import (
 
 	"code.fbi.h-da.de/cocsn/gosdn/mocks"
 	"github.com/google/uuid"
+	"github.com/openconfig/ygot/ygot"
+	log "github.com/sirupsen/logrus"
 )
 
 func Test_Store_add(t *testing.T) {
@@ -423,29 +426,30 @@ func Test_deviceStore_get(t *testing.T) {
 }
 
 func TestChangeStore_Pending(t *testing.T) {
-	type fields struct {
-		genericStore genericStore
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+
+	store := NewChangeStore()
+	pending := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := store.Add(pending); err != nil {
+		t.Error(err)
+		return
 	}
 	tests := []struct {
-		name   string
-		fields fields
-		want   []uuid.UUID
+		name string
+		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			fields: fields{
-				genericStore: genericStore{
-					cuid: &Change{cuid: cuid},
-				},
-			},
-			want: []uuid.UUID{cuid},
+			want: []uuid.UUID{pending.cuid},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			s := ChangeStore{
-				genericStore: tt.fields.genericStore,
-			}
+			s := store
 			if got := s.Pending(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("Pending() = %v, want %v", got, tt.want)
 			}
@@ -454,32 +458,34 @@ func TestChangeStore_Pending(t *testing.T) {
 }
 
 func TestChangeStore_Committed(t *testing.T) {
-	type fields struct {
-		genericStore genericStore
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+
+	store := NewChangeStore()
+	committed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := committed.Commit(); err != nil {
+		t.Error(err)
+		return
+	}
+	if err := store.Add(committed); err != nil {
+		t.Error(err)
+		return
 	}
 	tests := []struct {
-		name   string
-		fields fields
-		want   []uuid.UUID
+		name string
+		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			fields: fields{
-				genericStore: genericStore{
-					cuid: &Change{
-						cuid:      cuid,
-						committed: true,
-					},
-				},
-			},
-			want: []uuid.UUID{cuid},
+			want: []uuid.UUID{committed.cuid},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			s := ChangeStore{
-				genericStore: tt.fields.genericStore,
-			}
+			s := store
 			if got := s.Committed(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("Committed() = %v, want %v", got, tt.want)
 			}
@@ -488,33 +494,39 @@ func TestChangeStore_Committed(t *testing.T) {
 }
 
 func TestChangeStore_Confirmed(t *testing.T) {
-	type fields struct {
-		genericStore genericStore
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+
+	store := NewChangeStore()
+	confirmed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := confirmed.Commit(); err != nil {
+		t.Error(err)
+		return
 	}
+	if err := confirmed.Confirm(); err != nil {
+		t.Error(err)
+		return
+	}
+	if err := store.Add(confirmed); err != nil {
+		t.Error(err)
+		return
+	}
+
 	tests := []struct {
-		name   string
-		fields fields
-		want   []uuid.UUID
+		name string
+		want []uuid.UUID
 	}{
 		{
 			name: "default",
-			fields: fields{
-				genericStore: genericStore{
-					cuid: &Change{
-						cuid:      cuid,
-						committed: true,
-						confirmed: true,
-					},
-				},
-			},
-			want: []uuid.UUID{cuid},
+			want: []uuid.UUID{confirmed.cuid},
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			s := ChangeStore{
-				genericStore: tt.fields.genericStore,
-			}
+			s := store
 			if got := s.Confirmed(); !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("Confirmed() = %v, want %v", got, tt.want)
 			}
@@ -523,18 +535,27 @@ func TestChangeStore_Confirmed(t *testing.T) {
 }
 
 func Test_filterChanges(t *testing.T) {
+	testName := t.Name()
+	callback := func(first ygot.GoStruct, second ygot.GoStruct) error {
+		log.Infof("callback in test %v", testName)
+		return nil
+	}
+
 	store := NewChangeStore()
-	pending := &Change{
-		cuid: uuid.New(),
+	pending := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	committed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := committed.Commit(); err != nil {
+		t.Error(err)
+		return
 	}
-	committed := &Change{
-		cuid:      uuid.New(),
-		committed: true,
+	confirmed := NewChange(did, &openconfig.Device{}, &openconfig.Device{}, callback)
+	if err := confirmed.Commit(); err != nil {
+		t.Error(err)
+		return
 	}
-	confirmed := &Change{
-		cuid:      uuid.New(),
-		committed: true,
-		confirmed: true,
+	if err := confirmed.Confirm(); err != nil {
+		t.Error(err)
+		return
 	}
 	if err := store.Add(pending); err != nil {
 		t.Error(err)