diff --git a/apps/confbridge/conf_chan_announce.c b/apps/confbridge/conf_chan_announce.c
index 19224254da..df48aed330 100644
--- a/apps/confbridge/conf_chan_announce.c
+++ b/apps/confbridge/conf_chan_announce.c
@@ -134,7 +134,7 @@ static struct ast_channel_tech announce_tech = {
 	.send_text = ast_unreal_sendtext,
 	.queryoption = ast_unreal_queryoption,
 	.setoption = ast_unreal_setoption,
-	.properties = AST_CHAN_TP_ANNOUNCER,
+	.properties = AST_CHAN_TP_INTERNAL,
 };
 
 struct ast_channel_tech *conf_announce_get_tech(void)
diff --git a/apps/confbridge/conf_chan_record.c b/apps/confbridge/conf_chan_record.c
index c3f717074a..7080d118c9 100644
--- a/apps/confbridge/conf_chan_record.c
+++ b/apps/confbridge/conf_chan_record.c
@@ -86,7 +86,7 @@ static struct ast_channel_tech record_tech = {
 	.call = rec_call,
 	.read = rec_read,
 	.write = rec_write,
-	.properties = AST_CHAN_TP_RECORDER,
+	.properties = AST_CHAN_TP_INTERNAL,
 };
 
 struct ast_channel_tech *conf_record_get_tech(void)
diff --git a/channels/chan_bridge_media.c b/channels/chan_bridge_media.c
index 3abee98323..663578033e 100644
--- a/channels/chan_bridge_media.c
+++ b/channels/chan_bridge_media.c
@@ -89,7 +89,7 @@ static struct ast_channel_tech announce_tech = {
 	.send_text = ast_unreal_sendtext,
 	.queryoption = ast_unreal_queryoption,
 	.setoption = ast_unreal_setoption,
-	.properties = AST_CHAN_TP_ANNOUNCER,
+	.properties = AST_CHAN_TP_INTERNAL,
 };
 
 static struct ast_channel_tech record_tech = {
@@ -111,7 +111,7 @@ static struct ast_channel_tech record_tech = {
 	.send_text = ast_unreal_sendtext,
 	.queryoption = ast_unreal_queryoption,
 	.setoption = ast_unreal_setoption,
-	.properties = AST_CHAN_TP_RECORDER,
+	.properties = AST_CHAN_TP_INTERNAL,
 };
 
 static struct ast_channel *media_request_helper(struct ast_format_cap *cap,
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index cc60debfdb..ad229a9322 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -864,15 +864,11 @@ enum {
 	 */
 	AST_CHAN_TP_CREATESJITTER = (1 << 1),
 	/*!
-	 * \brief Channels have this property if they are an implementation detail
-	 * used for announcing messages; i.e. to a bridge
+	 * \brief Channels with this particular technology are an implementation detail of
+	 * Asterisk and should generally not be exposed or manipulated by the outside
+	 * world
 	 */
-	AST_CHAN_TP_ANNOUNCER = (1 << 2),
-	/*!
-	 * \brief Channels have this property if they are an implementation detail
-	 * used for recording audio; i.e. from a bridge
-	 */
-	AST_CHAN_TP_RECORDER = (1 << 3),
+	AST_CHAN_TP_INTERNAL = (1 << 2),
 };
 
 /*! \brief ast_channel flags */
diff --git a/main/cel.c b/main/cel.c
index ae42a443dd..d9e1d81dfe 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -1103,7 +1103,7 @@ static int cel_filter_channel_snapshot(struct ast_channel_snapshot *snapshot)
 	if (!snapshot) {
 		return 0;
 	}
-	return snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER);
+	return snapshot->tech_properties & AST_CHAN_TP_INTERNAL;
 }
 
 static void cel_snapshot_update_cb(void *data, struct stasis_subscription *sub,
diff --git a/main/channel.c b/main/channel.c
index 8e6a4c945c..9bfe2fabe8 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -830,6 +830,16 @@ struct ast_format *ast_best_codec(struct ast_format_cap *cap, struct ast_format
 	return NULL;
 }
 
+/*! \brief Channel technology used to extract a channel from a running application. The
+ * channel created with this technology will be immediately hung up - most external
+ * applications won't ever want to see this.
+ */
+static const struct ast_channel_tech surrogate_tech = {
+	.type = "Surrogate",
+	.description = "Surrogate channel used to pull channel from an application",
+	.properties = AST_CHAN_TP_INTERNAL,
+};
+
 static const struct ast_channel_tech null_tech = {
 	.type = "NULL",
 	.description = "Null channel (should not see this)",
@@ -852,6 +862,7 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
 	struct ast_sched_context *schedctx;
 	struct ast_timer *timer;
 	struct timeval now;
+	const struct ast_channel_tech *channel_tech;
 
 	/* If shutting down, don't allocate any new channels */
 	if (ast_shutting_down()) {
@@ -965,9 +976,6 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
 		ast_channel_name_set(tmp, "-**Unknown**");
 	}
 
-	/* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
-
-	/* These 4 variables need to be set up for the cdr_init() to work right */
 	if (amaflag != AST_AMA_NONE) {
 		ast_channel_amaflags_set(tmp, amaflag);
 	} else {
@@ -977,39 +985,39 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
 	if (!ast_strlen_zero(acctcode)) {
 		ast_channel_accountcode_set(tmp, acctcode);
 	}
+	ast_channel_language_set(tmp, ast_defaultlanguage);
 
 	ast_channel_context_set(tmp, S_OR(context, "default"));
 	ast_channel_exten_set(tmp, S_OR(exten, "s"));
 	ast_channel_priority_set(tmp, 1);
 
-	ast_atomic_fetchadd_int(&chancount, +1);
-
 	headp = ast_channel_varshead(tmp);
 	AST_LIST_HEAD_INIT_NOLOCK(headp);
 
 	ast_pbx_hangup_handler_init(tmp);
 	AST_LIST_HEAD_INIT_NOLOCK(ast_channel_datastores(tmp));
-
 	AST_LIST_HEAD_INIT_NOLOCK(ast_channel_autochans(tmp));
 
-	ast_channel_language_set(tmp, ast_defaultlanguage);
+	channel_tech = ast_get_channel_tech(tech);
+	if (!channel_tech && !ast_strlen_zero(tech2)) {
+		channel_tech = ast_get_channel_tech(tech2);
+	}
+	if (channel_tech) {
+		ast_channel_tech_set(tmp, channel_tech);
+	} else {
+		ast_channel_tech_set(tmp, &null_tech);
+	}
 
-	ast_channel_tech_set(tmp, &null_tech);
+	ast_channel_internal_finalize(tmp);
 
+	ast_atomic_fetchadd_int(&chancount, +1);
 	ao2_link(channels, tmp);
 
 	/*
-	 * And now, since the channel structure is built, and has its name, let's
-	 * call the manager event generator with this Newchannel event. This is the
-	 * proper and correct place to make this call, but you sure do have to pass
-	 * a lot of data into this func to do it here!
+	 * And now, since the channel structure is built, and has its name, let
+	 * the world know of its existance
 	 */
-	if (ast_get_channel_tech(tech) || (tech2 && ast_get_channel_tech(tech2))) {
-		ast_channel_publish_snapshot(tmp);
-	}
-
-	ast_channel_internal_finalize(tmp);
-	ast_publish_channel_state(tmp);
+	ast_channel_publish_snapshot(tmp);
 	return tmp;
 }
 
@@ -6376,7 +6384,7 @@ void ast_do_masquerade(struct ast_channel *original)
 		struct ast_party_connected_line connected;
 		struct ast_party_redirecting redirecting;
 	} exchange;
-	struct ast_channel *clonechan, *chans[2];
+	struct ast_channel *clonechan;
 	struct ast_channel *bridged;
 	struct ast_format rformat;
 	struct ast_format wformat;
@@ -6459,42 +6467,6 @@ void ast_do_masquerade(struct ast_channel *original)
 	ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
 		ast_channel_name(clonechan), ast_channel_state(clonechan), ast_channel_name(original), ast_channel_state(original));
 
-	chans[0] = clonechan;
-	chans[1] = original;
-	/*** DOCUMENTATION
-		<managerEventInstance>
-			<synopsis>Raised when a masquerade occurs between two channels, wherein the Clone channel's internal information replaces the Original channel's information.</synopsis>
-			<syntax>
-				<parameter name="Clone">
-					<para>The name of the channel whose information will be going into the Original channel.</para>
-				</parameter>
-				<parameter name="CloneUniqueid">
-					<para>The uniqueid of the channel whose information will be going into the Original channel.</para>
-				</parameter>
-				<parameter name="CloneState">
-					<para>The current state of the clone channel.</para>
-				</parameter>
-				<parameter name="Original">
-					<para>The name of the channel whose information will be replaced by the Clone channel's information.</para>
-				</parameter>
-				<parameter name="OriginalUniqueid">
-					<para>The uniqueid of the channel whose information will be replaced by the Clone channel's information.</para>
-				</parameter>
-				<parameter name="OriginalState">
-					<para>The current state of the original channel.</para>
-				</parameter>
-			</syntax>
-		</managerEventInstance>
-	***/
-	ast_manager_event_multichan(EVENT_FLAG_CALL, "Masquerade", 2, chans,
-		"Clone: %s\r\n"
-		"CloneUniqueid: %s\r\n"
-		"CloneState: %s\r\n"
-		"Original: %s\r\n"
-		"OriginalUniqueid: %s\r\n"
-		"OriginalState: %s\r\n",
-		ast_channel_name(clonechan), ast_channel_uniqueid(clonechan), ast_state2str(ast_channel_state(clonechan)), ast_channel_name(original), ast_channel_uniqueid(original), ast_state2str(ast_channel_state(original)));
-
 	/*
 	 * Remember the original read/write formats.  We turn off any
 	 * translation on either one
@@ -7549,6 +7521,7 @@ static void channels_shutdown(void)
 		ao2_ref(channels, -1);
 		channels = NULL;
 	}
+	ast_channel_unregister(&surrogate_tech);
 }
 
 void ast_channels_init(void)
@@ -7559,6 +7532,8 @@ void ast_channels_init(void)
 		ao2_container_register("channels", channels, prnt_channel_key);
 	}
 
+	ast_channel_register(&surrogate_tech);
+
 	ast_stasis_channels_init();
 
 	ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel));
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index 698783707a..f40852f0bd 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -426,13 +426,13 @@ void ast_channel_##field##_set(struct ast_channel *chan, const char *value) \
 	if ((assert_on_null)) ast_assert(!ast_strlen_zero(value)); \
 	if (!strcmp(value, chan->field)) return; \
 	ast_string_field_set(chan, field, value); \
-	if (publish) ast_channel_publish_snapshot(chan); \
+	if (publish && ast_channel_internal_is_finalized(chan)) ast_channel_publish_snapshot(chan); \
 } \
   \
 void ast_channel_##field##_build_va(struct ast_channel *chan, const char *fmt, va_list ap) \
 { \
 	ast_string_field_build_va(chan, field, fmt, ap); \
-	if (publish) ast_channel_publish_snapshot(chan); \
+	if (publish && ast_channel_internal_is_finalized(chan)) ast_channel_publish_snapshot(chan); \
 } \
 void ast_channel_##field##_build(struct ast_channel *chan, const char *fmt, ...) \
 { \
@@ -1481,7 +1481,6 @@ int ast_channel_internal_setup_topics(struct ast_channel *chan)
 
 	chan->topics = stasis_cp_single_create(
 		ast_channel_cache_all(), topic_name);
-
 	if (!chan->topics) {
 		return -1;
 	}
diff --git a/main/manager_bridges.c b/main/manager_bridges.c
index d563c2bc81..b045ca5b5e 100644
--- a/main/manager_bridges.c
+++ b/main/manager_bridges.c
@@ -381,7 +381,7 @@ static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags)
 	}
 
 	snapshot = stasis_message_data(msg);
-	if (snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER)) {
+	if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) {
 		return 0;
 	}
 
diff --git a/main/manager_channels.c b/main/manager_channels.c
index 23418e6a28..485841b69f 100644
--- a/main/manager_channels.c
+++ b/main/manager_channels.c
@@ -383,7 +383,7 @@ struct ast_str *ast_manager_build_channel_state_string_prefix(
 		return NULL;
 	}
 
-	if (snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER)) {
+	if (snapshot->tech_properties & AST_CHAN_TP_INTERNAL) {
 		ast_free(out);
 		return NULL;
 	}