diff --git a/syndicate-server/protocols/schema-bundle.bin b/syndicate-server/protocols/schema-bundle.bin
index a1c14d7..86f634a 100644
--- a/syndicate-server/protocols/schema-bundle.bin
+++ b/syndicate-server/protocols/schema-bundle.bin
@@ -2,7 +2,7 @@
 ProcessDir´³orµµ±present´³dict·³dir´³named³dir´³atom³String„„„„„µ±invalid´³dict·³dir´³named³dir³any„„„„µ±absent´³dict·„„„„„³
 ProcessEnv´³orµµ±present´³dict·³env´³named³env´³dictof´³refµ„³EnvVariable„´³refµ„³EnvValue„„„„„„µ±invalid´³dict·³env´³named³env³any„„„„µ±absent´³dict·„„„„„³CommandLine´³orµµ±shell´³atom³String„„µ±full´³refµ„³FullCommandLine„„„„³EnvVariable´³orµµ±string´³atom³String„„µ±symbol´³atom³Symbol„„µ±invalid³any„„„³FullProcess´³andµ´³dict·³argv´³named³argv´³refµ„³CommandLine„„„„´³named³env´³refµ„³
 ProcessEnv„„´³named³dir´³refµ„³
-ProcessDir„„´³named³clearEnv´³refµ„³ClearEnv„„„„³ReadyOnStart´³orµµ±present´³dict·³readyOnStart´³named³readyOnStart´³atom³Boolean„„„„„µ±invalid´³dict·³readyOnStart´³named³readyOnStart³any„„„„µ±absent´³dict·„„„„„³RestartField´³orµµ±present´³dict·³restart´³named³restart´³refµ„³
RestartPolicy„„„„„µ±invalid´³dict·³restart´³named³restart³any„„„„µ±absent´³dict·„„„„„³
DaemonProcess´³rec´³lit³daemon„´³tupleµ´³named³id³any„´³named³config´³refµ„³DaemonProcessSpec„„„„„³
DaemonService´³rec´³lit³daemon„´³tupleµ´³named³id³any„„„„³
ProtocolField´³orµµ±present´³dict·³protocol´³named³protocol´³refµ„³Protocol„„„„„µ±invalid´³dict·³protocol´³named³protocol³any„„„„µ±absent´³dict·„„„„„³
RestartPolicy´³orµµ±always´³lit³always„„µ±onError´³lit³on-error„„µ±all´³lit³all„„„„³FullCommandLine´³tuplePrefixµ´³named³program´³atom³String„„„´³named³args´³seqof´³atom³String„„„„³DaemonProcessSpec´³orµµ±simple´³refµ„³CommandLine„„µ±full´³refµ„³FullDaemonProcess„„„„³FullDaemonProcess´³andµ´³named³process´³refµ„³FullProcess„„´³named³readyOnStart´³refµ„³ReadyOnStart„„´³named³restart´³refµ„³RestartField„„´³named³protocol´³refµ„³
ProtocolField„„„„„³embeddedType´³refµ³	EntityRef„³Cap„„„µ³internalServices„´³schema·³version‘³definitions·³	ConfigEnv´³dictof´³atom³Symbol„³any„³	Milestone´³rec´³lit³	milestone„´³tupleµ´³named³name³any„„„„³DebtReporter´³rec´³lit³
debt-reporter„´³tupleµ´³named³intervalSeconds´³atom³Double„„„„„³
ConfigWatcher´³rec´³lit³config-watcher„´³tupleµ´³named³path´³atom³String„„´³named³env´³refµ„³	ConfigEnv„„„„„³TcpRelayListener´³rec´³lit³relay-listener„´³tupleµ´³named³addr´³refµ³TransportAddress„³Tcp„„´³named³
+ProcessDir„„´³named³clearEnv´³refµ„³ClearEnv„„„„³ReadyOnStart´³orµµ±present´³dict·³readyOnStart´³named³readyOnStart´³atom³Boolean„„„„„µ±invalid´³dict·³readyOnStart´³named³readyOnStart³any„„„„µ±absent´³dict·„„„„„³RestartField´³orµµ±present´³dict·³restart´³named³restart´³refµ„³
RestartPolicy„„„„„µ±invalid´³dict·³restart´³named³restart³any„„„„µ±absent´³dict·„„„„„³
DaemonProcess´³rec´³lit³daemon„´³tupleµ´³named³id³any„´³named³config´³refµ„³DaemonProcessSpec„„„„„³
DaemonService´³rec´³lit³daemon„´³tupleµ´³named³id³any„„„„³
ProtocolField´³orµµ±present´³dict·³protocol´³named³protocol´³refµ„³Protocol„„„„„µ±invalid´³dict·³protocol´³named³protocol³any„„„„µ±absent´³dict·„„„„„³
RestartPolicy´³orµµ±always´³lit³always„„µ±onError´³lit³on-error„„µ±all´³lit³all„„„„³FullCommandLine´³tuplePrefixµ´³named³program´³atom³String„„„´³named³args´³seqof´³atom³String„„„„³DaemonProcessSpec´³orµµ±simple´³refµ„³CommandLine„„µ±oneShot´³rec´³lit³one-shot„´³tupleµ´³named³setup´³refµ„³CommandLine„„„„„„µ±full´³refµ„³FullDaemonProcess„„„„³FullDaemonProcess´³andµ´³named³process´³refµ„³FullProcess„„´³named³readyOnStart´³refµ„³ReadyOnStart„„´³named³restart´³refµ„³RestartField„„´³named³protocol´³refµ„³
ProtocolField„„„„„³embeddedType´³refµ³	EntityRef„³Cap„„„µ³internalServices„´³schema·³version‘³definitions·³	ConfigEnv´³dictof´³atom³Symbol„³any„³	Milestone´³rec´³lit³	milestone„´³tupleµ´³named³name³any„„„„³DebtReporter´³rec´³lit³
debt-reporter„´³tupleµ´³named³intervalSeconds´³atom³Double„„„„„³
ConfigWatcher´³rec´³lit³config-watcher„´³tupleµ´³named³path´³atom³String„„´³named³env´³refµ„³	ConfigEnv„„„„„³TcpRelayListener´³rec´³lit³relay-listener„´³tupleµ´³named³addr´³refµ³TransportAddress„³Tcp„„´³named³
 gatekeeper´³embedded´³refµ³
 gatekeeper„³Resolve„„„„„„³UnixRelayListener´³rec´³lit³relay-listener„´³tupleµ´³named³addr´³refµ³TransportAddress„³Unix„„´³named³
 gatekeeper´³embedded´³refµ³
diff --git a/syndicate-server/protocols/schemas/externalServices.prs b/syndicate-server/protocols/schemas/externalServices.prs
index 8ea6ade..ae67f76 100644
--- a/syndicate-server/protocols/schemas/externalServices.prs
+++ b/syndicate-server/protocols/schemas/externalServices.prs
@@ -6,7 +6,7 @@ Service = DaemonService .
 DaemonService = <daemon @id any> .
 DaemonProcess = <daemon @id any @config DaemonProcessSpec>.
 
-DaemonProcessSpec = @simple CommandLine / @full FullDaemonProcess .
+DaemonProcessSpec = @simple CommandLine / @oneShot <one-shot @setup CommandLine> / @full FullDaemonProcess .
 FullDaemonProcess = @process FullProcess & @readyOnStart ReadyOnStart & @restart RestartField & @protocol ProtocolField .
 ReadyOnStart = @present { readyOnStart: bool } / @invalid { readyOnStart: any } / @absent {} .
 RestartField = @present { restart: RestartPolicy } / @invalid { restart: any } / @absent {} .
diff --git a/syndicate-server/src/services/daemon.rs b/syndicate-server/src/services/daemon.rs
index aeb76df..e4ac4f1 100644
--- a/syndicate-server/src/services/daemon.rs
+++ b/syndicate-server/src/services/daemon.rs
@@ -26,7 +26,7 @@ pub fn on_demand(t: &mut Activation, config_ds: Arc<Cap>, root_ds: Arc<Cap>) {
             Supervisor::start(
                 t,
                 syndicate::name!(parent: None, "daemon", id = ?spec.id),
-                SupervisorConfiguration::default(),
+                SupervisorConfiguration::on_error_only(),
                 enclose!((config_ds, spec) lifecycle::updater(config_ds, spec)),
                 enclose!((config_ds, root_ds) move |t|
                          enclose!((config_ds, root_ds, spec) run(t, config_ds, root_ds, spec))))
@@ -114,6 +114,12 @@ impl DaemonProcessSpec {
                 restart: RestartField::Absent,
                 protocol: ProtocolField::Absent,
             },
+            DaemonProcessSpec::OneShot { setup } => FullDaemonProcess {
+                process: Process::Simple(setup).elaborate(),
+                ready_on_start: ReadyOnStart::Absent,
+                restart: RestartField::Present { restart: Box::new(RestartPolicy::OnError) },
+                protocol: ProtocolField::Absent,
+            },
             DaemonProcessSpec::Full(spec) => *spec,
         }
     }
@@ -379,7 +385,7 @@ fn run(
                                           };
                                           let restart_policy = match config.restart {
                                               RestartField::Present { restart } => *restart,
-                                              RestartField::Absent => RestartPolicy::All,
+                                              RestartField::Absent => RestartPolicy::Always,
                                               RestartField::Invalid { restart } => {
                                                   tracing::error!(?restart, "Invalid restart value");
                                                   Err("Invalid restart value")?
diff --git a/syndicate/src/supervise.rs b/syndicate/src/supervise.rs
index 06deba0..6e819ff 100644
--- a/syndicate/src/supervise.rs
+++ b/syndicate/src/supervise.rs
@@ -66,6 +66,15 @@ impl Default for SupervisorConfiguration {
     }
 }
 
+impl SupervisorConfiguration {
+    pub fn on_error_only() -> Self {
+        Self {
+            restart_policy: RestartPolicy::OnErrorOnly,
+            .. Self::default()
+        }
+    }
+}
+
 impl Entity<Protocol> for Supervisor
 {
     fn assert(&mut self, t: &mut Activation, m: Protocol, _h: Handle) -> ActorResult {
