diff --git a/src/include/66/service.h b/src/include/66/service.h
index 1b2dbbe0d08244967ce6de4a46180121be4ff0df..0a41a0a17fd999c827fd2b6a79d4e81571e801d5 100644
--- a/src/include/66/service.h
+++ b/src/include/66/service.h
@@ -318,7 +318,7 @@ extern int service_resolve_get_field_tosa(stralloc *sa, resolve_service_t *res,
 extern int service_resolve_modify_field(resolve_service_t *res, resolve_service_enum_t field, char const *data) ;
 extern int service_resolve_read_cdb(cdb *c, resolve_service_t *res) ;
 extern void service_resolve_write(resolve_service_t *res) ;
-extern void service_resolve_write_tmp(resolve_service_t *res, char const *dst, uint8_t force) ;
+extern void service_resolve_write_remote(resolve_service_t *res, char const *dst, uint8_t force) ;
 extern int service_resolve_write_cdb(cdbmaker *c, resolve_service_t *sres) ;
 extern void service_enable_disable(graph_t *g, unsigned int idx, resolve_service_t *ares, unsigned int areslen, uint8_t action, visit_t *visit, uint8_t propagate) ;
 extern void service_switch_tree(resolve_service_t *res, char const *base, char const *totreename) ;
diff --git a/src/lib66/exec/ssexec_enable.c b/src/lib66/exec/ssexec_enable.c
index 34813a11d39b1d107dfe75592d5de1742c4f27de..64c70507e91279c42093ea727b76c21ab2b362ac 100644
--- a/src/lib66/exec/ssexec_enable.c
+++ b/src/lib66/exec/ssexec_enable.c
@@ -44,26 +44,11 @@ static void parse_it(char const *name, ssexec_t *info)
     PROG = prog ;
 }
 
-static void service_resolve_array_write(char const *base, resolve_service_t *ares, uint32_t *indexes, uint32_t lindex)
-{
-    log_flow() ;
-
-    uint32_t pos = 0 ;
-
-    for (; pos < lindex ; ++pos) {
-
-        resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &ares[indexes[pos]]) ;
-
-        if (!resolve_write_g(wres, base, ares[indexes[pos]].sa.s + ares[indexes[pos]].name))
-            log_dieu(LOG_EXIT_SYS, "write  resolve file of: ", ares[indexes[pos]].sa.s + ares[indexes[pos]].name) ;
-    }
-}
-
 int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 {
     log_flow() ;
 
-    uint32_t flag = 0, indexes[SS_MAX_SERVICE + 1], lindex = 0 ;
+    uint32_t flag = 0 ;
     uint8_t start = 0, propagate = 1 ;
     int n = 0, e = 1 ;
     size_t pos = 0 ;
@@ -74,7 +59,6 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
     visit_t visit[SS_MAX_SERVICE + 1] ;
     visit_init(visit, SS_MAX_SERVICE) ;
-    visit_init(indexes, SS_MAX_SERVICE) ;
 
     FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
 
@@ -115,10 +99,8 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
     _init_stack_(stk, argc * SS_MAX_TREENAME) ;
 
-    for(; n < argc ; n++) {
-        name_isvalid(argv[n]) ;
+    for(; n < argc ; n++)
         parse_it(argv[n], info) ;
-    }
 
     /** build the graph of the entire system */
     graph_build_service(&graph, ares, &areslen, info, flag) ;
@@ -138,8 +120,6 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
             service_switch_tree(&ares[aresid], info->base.s, info->treename.s) ;
 
-            indexes[lindex++] = aresid ;
-
             if (ares[aresid].logger.want && ares[aresid].type == TYPE_CLASSIC) {
 
                 int logid = service_resolve_array_search(ares, areslen, ares[aresid].sa.s + ares[aresid].logger.name) ;
@@ -148,7 +128,6 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
                 service_switch_tree(&ares[logid], info->base.s, info->treename.s) ;
 
-                indexes[lindex++] = logid ;
             }
         }
 
@@ -158,7 +137,6 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
         log_info("Enabled successfully service: ", ares[aresid].sa.s + ares[aresid].name) ;
     }
 
-    service_resolve_array_write(info->base.s, ares, indexes, lindex) ;
     service_resolve_array_free(ares, areslen) ;
     graph_free_all(&graph) ;
 
diff --git a/src/lib66/parse/parse_compute_resolve.c b/src/lib66/parse/parse_compute_resolve.c
index 7fa96452261a6c6427814cc9e24cce08d2da6188..885b5be2b15a9e4aafaea3737c70491a99e2d829 100644
--- a/src/lib66/parse/parse_compute_resolve.c
+++ b/src/lib66/parse/parse_compute_resolve.c
@@ -37,21 +37,41 @@
 #define FAKELEN strlen(run)
 #endif
 
-static uint32_t compute_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
+static uint32_t compute_src_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
 {
+    log_flow() ;
+
     resolve_service_t_ref res = (resolve_service_t *)wres->obj ;
     char *name = res->sa.s + res->name ;
     size_t namelen = strlen(name) ;
 
-    char dir[info->base.len + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1 + namelen + 1] ;
+    char dir[info->base.len + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
 
-    auto_strings(dir, info->base.s, SS_SYSTEM, SS_RESOLVE, SS_SERVICE, "/", name) ;
+    auto_strings(dir, info->base.s, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ;
 
     return resolve_add_string(wres, dir) ;
 }
 
+static uint32_t compute_live_servicedir(resolve_wrapper_t_ref wres, ssexec_t *info)
+{
+    log_flow() ;
+
+    resolve_service_t_ref res = (resolve_service_t *)wres->obj ;
+    char *name = res->sa.s + res->name ;
+    size_t namelen = strlen(name) ;
+
+    char dir[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + namelen + 1] ;
+
+    auto_strings(dir, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", name) ;
+
+    return resolve_add_string(wres, dir) ;
+}
+
+
 static uint32_t compute_status(resolve_wrapper_t_ref wres, ssexec_t *info)
 {
+    log_flow() ;
+
     resolve_service_t_ref res = (resolve_service_t *)wres->obj ;
     char *name = res->sa.s + res->name ;
     size_t namelen = strlen(name) ;
@@ -72,9 +92,9 @@ static uint32_t compute_scan_dir(resolve_wrapper_t_ref wres, ssexec_t *info)
     char *name = res->sa.s + res->name ;
     size_t namelen = strlen(name) ;
 
-    char dir[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + namelen + 1 + SS_SCANDIR_LEN + 1 + namelen + 1] ;
+    char dir[info->live.len + SS_SCANDIR_LEN + 1 + info->ownerlen + 1 + namelen + 1] ;
 
-    auto_strings(dir, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", name, "/", SS_SCANDIR, "/", name) ;
+    auto_strings(dir, info->live.s, SS_SCANDIR, "/", info->ownerstr, "/", name) ;
 
     return resolve_add_string(wres, dir) ;
 }
@@ -102,8 +122,8 @@ static uint32_t compute_pipe_service(resolve_wrapper_t_ref wres, ssexec_t *info,
     size_t servicelen = strlen(service) ;
     size_t namelen = strlen(name) ;
 
-    char tmp[info->live.len + SS_STATE_LEN + 1 + info->ownerlen + 1 + servicelen + 1 + SS_SCANDIR_LEN + 1 + namelen + 1] ;
-    auto_strings(tmp, info->live.s, SS_STATE + 1, "/", info->ownerstr, "/", service, "/", SS_SCANDIR, "/", name) ;
+    char tmp[info->live.len + SS_SCANDIR_LEN + 1 + info->ownerlen + 1 + namelen + 1] ;
+    auto_strings(tmp, info->live.s, SS_SCANDIR, "/", info->ownerstr, "/", name) ;
 
     return resolve_add_string(wres, tmp) ;
 
@@ -149,7 +169,7 @@ static void compute_wrapper_scripts(resolve_service_t *res, resolve_service_addo
 {
     log_flow() ;
 
-    int build = !strcmp(res->sa.s + scripts->build, "custom") ? 1 : 0 ;
+    int build = !strcmp(res->sa.s + scripts->build, "custom") ? BUILD_CUSTOM : BUILD_AUTO ;
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
     char *shebang = "#!" SS_EXECLINE_SHEBANGPREFIX "execlineb -" ;
     size_t shebanglen = strlen(shebang) ;
@@ -210,7 +230,7 @@ static void compute_wrapper_scripts_user(resolve_service_t *res, resolve_service
     char *shebang = scripts->shebang ? res->sa.s + scripts->shebang : SS_EXECLINE_SHEBANGPREFIX "execlineb -P\n" ;
     size_t shebanglen = strlen(shebang) ;
     size_t scriptlen = strlen(res->sa.s + scripts->run_user) ;
-    int build = !strcmp(res->sa.s + scripts->build, "custom") ? 1 : 0 ;
+    int build = !strcmp(res->sa.s + scripts->build, "custom") ? BUILD_CUSTOM : BUILD_AUTO ;
     size_t execlen = !build ? (res->environ.envdir ? (strlen(res->sa.s + res->environ.envdir) + 14 + SS_SYM_VERSION_LEN + 1) : 0) : 0 ;
 
     char run[shebanglen + execlen + scriptlen + 4 + 1] ;
@@ -250,7 +270,7 @@ static void compute_log_script(resolve_service_t *res)
 
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
 
-    int build = !strcmp(res->sa.s + res->logger.execute.run.build, "custom") ? 1 : 0 ;
+    int build = !strcmp(res->sa.s + res->logger.execute.run.build, "custom") ? BUILD_CUSTOM : BUILD_AUTO ;
 
     char *pmax = 0 ;
     char *pback = 0 ;
@@ -391,8 +411,7 @@ static void compute_log(resolve_service_t *res, resolve_service_t *ares, unsigne
 
     lres.path.home = resolve_add_string(wres, str + res->path.home) ;
     lres.path.frontend = resolve_add_string(wres, str + res->path.frontend) ;
-    lres.path.servicedir = compute_servicedir(wres, info) ;
-    lres.path.status = compute_status(wres, info) ;
+    lres.path.servicedir = compute_src_servicedir(wres, info) ;
 
     lres.dependencies.requiredby = resolve_add_string(wres, str + res->name) ;
     lres.dependencies.nrequiredby = 1 ;
@@ -406,6 +425,8 @@ static void compute_log(resolve_service_t *res, resolve_service_t *ares, unsigne
     lres.execute.downsignal = res->logger.execute.downsignal ;
 
     lres.live.livedir = resolve_add_string(wres, info->live.s) ;
+    lres.live.status = compute_status(wres, info) ;
+    lres.live.servicedir = compute_live_servicedir(wres, info) ;
     lres.live.scandir = compute_scan_dir(wres, info) ;
     lres.live.statedir = compute_state_dir(wres, info, SS_STATE + 1) ;
     lres.live.eventdir = compute_state_dir(wres, info, SS_EVENTDIR + 1) ;
@@ -451,12 +472,17 @@ void parse_compute_resolve(unsigned int idx, resolve_service_t *ares, unsigned i
 
     auto_strings(name, res->sa.s + res->name) ;
 
-    res->path.status = compute_status(wres, info) ;
-    res->path.servicedir = compute_servicedir(wres, info) ;
+    res->path.servicedir = compute_src_servicedir(wres, info) ;
 
     /* live */
     res->live.livedir = resolve_add_string(wres, info->live.s) ;
 
+    /* status */
+    res->live.status = compute_status(wres, info) ;
+
+    /* servicedir */
+    res->live.servicedir = compute_live_servicedir(wres, info) ;
+
     /* scandir */
     /**
      *
diff --git a/src/lib66/parse/parse_service.c b/src/lib66/parse/parse_service.c
index faafa54edc368c696512b82d0b382bae3d7dfba9..a09449a3497f4eafc8e3dbf92586747a1f7dbc01 100644
--- a/src/lib66/parse/parse_service.c
+++ b/src/lib66/parse/parse_service.c
@@ -36,6 +36,7 @@
 #include <66/tree.h>
 #include <66/graph.h>
 #include <66/sanitize.h>
+#include <66/symlink.h>
 
 parse_mill_t MILL_GET_SECTION_NAME = \
 { \
@@ -76,16 +77,16 @@ void parse_cleanup(resolve_service_t *res, char const *tmpdir, uint8_t force)
     }
 }
 
-static void parse_copy_online(char const *dst, char const *src, resolve_service_t *res, uint8_t force)
+static void parse_copy_to_source(char const *dst, char const *src, resolve_service_t *res, uint8_t force)
 {
     log_flow() ;
 
-    size_t pos = 0 ;
-    stralloc sa = STRALLOC_ZERO ;
-    size_t srclen = strlen(src) ;
+    size_t pos = 0, srclen = strlen(src) ;
 
     if (!access(dst, F_OK)) {
 
+        stralloc sa = STRALLOC_ZERO ;
+
         char const *exclude[6] = { SS_EVENTDIR + 1, SS_SUPERVISEDIR + 1, SS_SCANDIR, SS_STATE + 1, SS_RESOLVE + 1, 0 } ;
         if (!sastr_dir_get_recursive(&sa, dst, exclude, S_IFDIR|S_IFREG, 1)) {
             parse_cleanup(res, src, force) ;
@@ -115,16 +116,15 @@ static void parse_copy_online(char const *dst, char const *src, resolve_service_
                 }
             }
         }
-    }
 
-    stralloc_free(&sa) ;
+        stralloc_free(&sa) ;
+    }
 
     if (access(dst, F_OK) < 0) {
 
         log_trace("create directory: ", dst) ;
         if (!dir_create_parent(dst, 0755)) {
             parse_cleanup(res, src, force) ;
-            stralloc_free(&sa) ;
             log_dieusys(LOG_EXIT_SYS, "create directory: ", dst) ;
         }
     }
@@ -132,9 +132,16 @@ static void parse_copy_online(char const *dst, char const *src, resolve_service_
     log_trace("copy:", src, " to: ", dst) ;
     if (!hiercopy(src, dst)) {
         parse_cleanup(res, src, force) ;
-        stralloc_free(&sa) ;
         log_dieusys(LOG_EXIT_SYS, "copy: ", src, " to: ", dst) ;
     }
+
+    /** be paranoid after the use of hiercopy and be sure
+     * to have dst in 0755 mode. If not the log cannot be
+     * executed with other permissions than root */
+    if (chmod(dst, 0755)< 0) {
+        parse_cleanup(res, src, force) ;
+        log_dieusys(LOG_EXIT_SYS,"chmod: ", dst) ;
+    }
 }
 
 static void parse_write_state(resolve_service_t *res, char const *dst, uint8_t force)
@@ -156,7 +163,7 @@ static void parse_write_state(resolve_service_t *res, char const *dst, uint8_t f
     state_set_flag(&sta, STATE_FLAGS_ISEARLIER, res->earlier ? STATE_FLAGS_TRUE : STATE_FLAGS_FALSE) ;
     state_set_flag(&sta, STATE_FLAGS_ISDOWNFILE, res->execute.down ? STATE_FLAGS_TRUE : STATE_FLAGS_FALSE) ;
 
-    if (!state_write_tmp(&sta, dst)) {
+    if (!state_write_remote(&sta, dst)) {
         parse_cleanup(res, dst, force) ;
         log_dieu(LOG_EXIT_SYS, "write state file of: ", res->sa.s + res->name) ;
     }
@@ -211,9 +218,9 @@ void parse_service(char const *sv, ssexec_t *info, uint8_t force, uint8_t conf)
 
         parse_write_state(&ares[pos], sa.s, rforce) ;
 
-        service_resolve_write_tmp(&ares[pos], sa.s, rforce) ;
+        service_resolve_write_remote(&ares[pos], sa.s, rforce) ;
 
-        parse_copy_online(servicedir, sa.s, &ares[pos], rforce) ;
+        parse_copy_to_source(servicedir, sa.s, &ares[pos], rforce) ;
 
         /** do not die here, just warn the user */
         log_trace("remove temporary directory: ", sa.s) ;
@@ -222,7 +229,15 @@ void parse_service(char const *sv, ssexec_t *info, uint8_t force, uint8_t conf)
 
         tree_service_add(info->base.s, ares[pos].sa.s + ares[pos].treename, ares[pos].sa.s + ares[pos].name) ;
 
-        write_make_symlink(&ares[pos]) ;
+        if (!symlink_make(&ares[pos]))
+            log_dieusys(LOG_EXIT_SYS, "make service symlink") ;
+
+        /** symlink may exist already, be sure to point to the correct location
+         * may not be necessary as long as the service must pass through sanitize_init at
+         * startup */
+
+        if (!symlink_switch(&ares[pos], SYMLINK_SOURCE))
+            log_dieusys(LOG_EXIT_SYS, "sanitize_symlink") ;
 
         log_info("Parsed successfully: ", ares[pos].sa.s + ares[pos].name, " at tree: ", ares[pos].sa.s + ares[pos].treename) ;
     }
diff --git a/src/lib66/service/service_enable_disable.c b/src/lib66/service/service_enable_disable.c
index 6e4db159152c6ac345620f22e35c7723250fb4df..c1691d8cb9d8c2301b3805d31c65c8f77c958d20 100644
--- a/src/lib66/service/service_enable_disable.c
+++ b/src/lib66/service/service_enable_disable.c
@@ -13,6 +13,7 @@
  */
 
 #include <stdint.h>
+#include <stdlib.h>
 
 #include <oblibs/log.h>
 #include <oblibs/graph.h>