Index: src/services/guardianship/gated.js
===================================================================
--- src/services/guardianship/gated.js	(revision 88d7c8fc087ab49a2fd3ee63bf184d15d1f0fa31)
+++ src/services/guardianship/gated.js	(revision e27b8db4e316874f7498fbe36e20270bc39b1d7f)
@@ -56,5 +56,8 @@
 
 /** The column a feature maps onto. Unknown features are refused, not guessed. */
-const FEATURES = { 'shaer:externalEmbeds': 'external_embeds' };
+const FEATURES = {
+  'shaer:externalEmbeds': 'external_embeds',
+  'shaer:externalPlayback': 'external_playback',
+};
 export function featureColumn(feature) {
   return Object.prototype.hasOwnProperty.call(FEATURES, feature) ? FEATURES[feature] : null;
Index: src/services/guardianship/index.js
===================================================================
--- src/services/guardianship/index.js	(revision 88d7c8fc087ab49a2fd3ee63bf184d15d1f0fa31)
+++ src/services/guardianship/index.js	(revision e27b8db4e316874f7498fbe36e20270bc39b1d7f)
@@ -16,5 +16,5 @@
  */
 export { SHAER_CONTEXT, GUARDIAN_RELATIONSHIP, GUARDIAN_RELATIONSHIP_COMPACT, isGuardianRelationship } from './context.js';
-export { helpRequestProps, isHelpRequest, waveProps, isWave, awayProps, hasGuardiansProps, objectHasGuardians, externalEmbedsAllowed } from './notes.js';
+export { helpRequestProps, isHelpRequest, waveProps, isWave, awayProps, hasGuardiansProps, objectHasGuardians, externalEmbedsAllowed, externalPlaybackAllowed } from './notes.js';
 export { wireDelivery, c2sVisibility, deliverDirectNote } from './delivery.js';
 export { wireHandshake, handleOutbox as handleGuardianshipOutbox, handleInbox as handleGuardianshipInbox, parseRelationship, parseUndoRelationship, endGuardianship } from './handshake.js';
Index: src/services/guardianship/notes.js
===================================================================
--- src/services/guardianship/notes.js	(revision 88d7c8fc087ab49a2fd3ee63bf184d15d1f0fa31)
+++ src/services/guardianship/notes.js	(revision e27b8db4e316874f7498fbe36e20270bc39b1d7f)
@@ -30,4 +30,17 @@
  */
 export function externalEmbedsAllowed(setting, isWard) {
+  if (setting === 0 || setting === 1) return setting === 1;
+  return !isWard;
+}
+
+/**
+ * May a player run INSIDE the app/page for this account? The heavier sibling
+ * of the setting above, and deliberately separate: seeing that a video exists
+ * is not the same decision as handing the screen to a third party's player,
+ * with its engine, its end-screen and its next-video machine. Same shape, same
+ * default (off for a ward), and it only ever matters once embeds are allowed:
+ * you cannot play what you may not see.
+ */
+export function externalPlaybackAllowed(setting, isWard) {
   if (setting === 0 || setting === 1) return setting === 1;
   return !isWard;
@@ -74,3 +87,3 @@
 }
 
-export default { helpRequestProps, isHelpRequest, waveProps, isWave, awayProps, hasGuardiansProps, objectHasGuardians, externalEmbedsAllowed };
+export default { helpRequestProps, isHelpRequest, waveProps, isWave, awayProps, hasGuardiansProps, objectHasGuardians, externalEmbedsAllowed, externalPlaybackAllowed };
