diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
new file mode 100644
index 0000000000000000000000000000000000000000..dcd0d814bd56c70088e075aab00a801b32c1eab5
--- /dev/null
+++ b/ARCHITECTURE.md
@@ -0,0 +1,54 @@
+# goSDN Architecture
+
+This document describes the the high-level architecture of the goSDN project. All contributors should familiarize themselves with it. To avoid too much divergence from the changing code this document does focus on high-level concepts instead of implementation details.
+
+## Bird's Eye View
+
+[<img src="documentation/architecture.png"  style="height:50%; width:50%" > ](documentation/architecture.png)
+
+On the highest level goSDn provides a gRPC northbound-interface and two types of southbound-interfaces: RESTCONF and gRPC-based. The northbound interface allows the interaction with a running goSDN daemon and may allow the stacking of multiple controllers in the future. The southbound interface (SBI) capabilities are split in `nucleus` models and plugins. The supported `nucleus` models are OpenConfig yang [openconfig-yang](https://github.com/openconfig/yang)  and TAPI. Third party models and more SBI-transports can be attached using the go plugin architecture.
+
+The internal data representation uses [ygot](https://github.com/openconfig/ygot) generated go-structs. 
+It is important to note that these go-structs are generated from yang models and thus are not generic data structures. This means that the `nucleus` code is organized in silos, i.e., one particular southbound-interface is visible in the `nucleus`, as the internal data representation depend on the used yang modes in the southbound-interface.
+
+## Code Map
+
+This section briefly describes important directories and data structures. It also introduces important API calls to relevant libraries.
+
+
+It also mentions **architecture invariants** and **API boundaries**
+### `api`
+
+API specification for gRPC and protobuf definitions.
+
+**Architecture invariant:** To import gRPC related protobuf definitions use `pb` as an import prefix. For gNMI related protobuf definitions use `gpb`
+
+### `forks`
+
+Forks of `google/gnxi/gnmi` and `arista/goarista/gnmi` for gNMI server and client respectively. Subject of change once we converge to own clients and servers.
+
+### `nucleus/principalNetworkDomain`
+
+`nucleus` is the core package of goSDN. The main data structure is the `principalNetworkDomain` (PND). It reflects one administrative entity, i.e., as set of connected network devices,  and is the source of truth for network state and configuration. A PND is SBI agnostic and supports multiple SBI implementations simultaneously. 
+
+**API boundary:** The PND' is the only way to interact with an `orchestratedNetworkingDevice`
+
+### `nucleus/device`
+
+This is the representation of an `orchestratedNetworkingDevice` (OND). An `orchestratedNetworkingDevice` is the network device that is directly managed by goSDN. It holds a reference to the device's `transport` and `southboundInterface` implementation. It contains a fakeroot device based on its attached SBI.
+
+**Architecture invariant:** The device is does not provide any functionality to upper API layers.
+
+### `nucleus/southbound`
+
+Implementation of SBI specifics. Provides SBI models to other callers and SBI specific function deviations.
+
+**Architecture invariant:** Only SBIs defined by a YANG model will be supported by goSDN.
+
+### `nucleus/transport` `nucleus/gnmi_transport` `nucleus/restconf_transport`
+
+Transport between goSDN and ONDs. Current core implementations are gNMI and RESTCONF. Additionally to implementing the transports the packages also provide a mapping from general purpose goSDN API calls to diverging SBI API calls.
+
+For example `gNMI::Subscribe` and `RESTCONF::Push` are mapped to `gosdn::Subscribe`.
+
+The `gnmi_transport` implementation uses `ytypes.SetNode` to write to a device struct.
diff --git a/documentation/architecture.png b/documentation/architecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..d56101394e87c5584b4a770d3fdd201da378b1b1
Binary files /dev/null and b/documentation/architecture.png differ
diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go
index 2efb387ad538583bcd14dc3a393ae848bee33e8f..f0022d2c934a663d21e02094166c5fa6d7128980 100644
--- a/nucleus/gnmi_transport.go
+++ b/nucleus/gnmi_transport.go
@@ -166,8 +166,10 @@ func (g *Gnmi) subscribe(ctx context.Context) error {
 	go func() {
 		for {
 			resp := <-g.RespChan
-			if err := gnmi.LogSubscribeResponse(resp); err != nil {
-				log.Fatal(err)
+			if resp != nil {
+				if err := gnmi.LogSubscribeResponse(resp); err != nil {
+					log.Fatal(err)
+				}
 			}
 		}
 	}()
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
index 6938452e15db3a7ce0c46c4a0394464d55f64885..951f7979c30723e9b2ff281f30c69588529eea93 100644
--- a/nucleus/southbound_test.go
+++ b/nucleus/southbound_test.go
@@ -114,7 +114,8 @@ func TestOpenConfig_Schema(t *testing.T) {
 				schema:    tt.fields.schema,
 				id:        tt.fields.id,
 			}
-			if got := oc.Schema(); !reflect.DeepEqual(got, tt.want) {
+			got := oc.Schema().SchemaTree
+			if !reflect.DeepEqual(got, tt.want.SchemaTree) {
 				t.Errorf("Schema() = %v, want %v", got, tt.want)
 			}
 		})
diff --git a/nucleus/store_test.go b/nucleus/store_test.go
index 8319b4bb7b3ad562501a97510b0378b322e9d615..012b47a4f1d32634a070ad6d2d695c60eb44d95f 100644
--- a/nucleus/store_test.go
+++ b/nucleus/store_test.go
@@ -5,6 +5,7 @@ import (
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 	"reflect"
+	"sort"
 	"testing"
 )
 
@@ -221,7 +222,14 @@ func Test_store_UUIDs(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := tt.s.UUIDs(); !reflect.DeepEqual(got, tt.want) {
+			sort.Slice(tt.want, func(i, j int) bool {
+				return tt.want[i].String() < tt.want[j].String()
+			})
+			got := tt.s.UUIDs()
+			sort.Slice(got, func(i, j int) bool {
+				return got[i].String() < got[j].String()
+			})
+			if !reflect.DeepEqual(got, tt.want) {
 				t.Errorf("UUIDs() = %v, want %v", got, tt.want)
 			}
 		})