[object Object]

← back to Dw Marketing Reels

reels: guard against duplicate social post of an already-'posted' reels[0] on nightly re-run

4f97f1f676fb8bd6b60ca157b4292475d658e6ea · 2026-07-27 16:05:59 -0700 · Steve Abrams

comms-compliance find (TK-14): main() always takes reels[0]; if a nightly build
fails to prepend a new reel but publish-social still runs, an already-posted reel
would be resubmitted to the Graph API (duplicate public post). Skip only a confirmed
'posted'/'already-posted' state; every non-terminal state (pending-creds/
ready-pending-arm/error) is still (re)attempted. Full idempotency-key dedup for the
error-response-leg edge is a follow-up. Contrarian-gated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Files touched

Diff

commit 4f97f1f676fb8bd6b60ca157b4292475d658e6ea
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 27 16:05:59 2026 -0700

    reels: guard against duplicate social post of an already-'posted' reels[0] on nightly re-run
    
    comms-compliance find (TK-14): main() always takes reels[0]; if a nightly build
    fails to prepend a new reel but publish-social still runs, an already-posted reel
    would be resubmitted to the Graph API (duplicate public post). Skip only a confirmed
    'posted'/'already-posted' state; every non-terminal state (pending-creds/
    ready-pending-arm/error) is still (re)attempted. Full idempotency-key dedup for the
    error-response-leg edge is a follow-up. Contrarian-gated.
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
 scripts/publish-social.mjs | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/scripts/publish-social.mjs b/scripts/publish-social.mjs
index 645b858..2c46691 100644
--- a/scripts/publish-social.mjs
+++ b/scripts/publish-social.mjs
@@ -100,8 +100,22 @@ async function main() {
   }
 
   reel.publish = reel.publish || {};
-  if (CHANNELS.includes('instagram')) reel.publish.instagram = await postInstagram(reel);
-  if (CHANNELS.includes('tiktok'))    reel.publish.tiktok    = await postTikTok(reel);
+  // Duplicate-post guard (comms-compliance find, 2026-07-27): main() always takes reels[0].
+  // If a nightly build fails to prepend a new reel but this job still runs, an already-'posted'
+  // reel would be resubmitted to the Graph API — a duplicate public post (Meta prohibits
+  // inauthentic duplicated content). Only a genuine successful post is skipped; every non-terminal
+  // state (pending-creds / ready-pending-arm / error / simulated) is still (re)attempted.
+  const done = st => st && (st.status === 'posted' || st.status === 'already-posted');
+  if (CHANNELS.includes('instagram')) {
+    reel.publish.instagram = done(reel.publish.instagram)
+      ? { ...reel.publish.instagram, status: 'already-posted', skipped: true, at: now() }
+      : await postInstagram(reel);
+  }
+  if (CHANNELS.includes('tiktok')) {
+    reel.publish.tiktok = done(reel.publish.tiktok)
+      ? { ...reel.publish.tiktok, status: 'already-posted', skipped: true, at: now() }
+      : await postTikTok(reel);
+  }
 
   writeFileSync(MAN, JSON.stringify(reels, null, 2));
   console.log(`publish ${reel.file}:`);

← be479b7 auto-save: 2026-07-27T07:18:47 (3 files) — data/new-arrivals  ·  back to Dw Marketing Reels  ·  reels: consolidate LEAK_DENY to one canonical-synced module 19e8ca4 →