AI for the defense?
Photo by Conny Schneider / Unsplash

AI for the defense?

Can technology recreate the dead to speak on their own behalf?

On December 12, 1890, the London Browning Society gathered to hear their idol, the poet Robert Browning, recite one of his works. This was considered a rare privilege, as Browning had notoriously shied away from performance. What made this particular occasion all the more remarkable, however, was that this was the one-year anniversary of his death.

Chipping away at mortality

Since the nineteenth century, certain advances in technology have chipped away at our notions of mortality. Robert Browning was β€œresurrected” with the help of a phonograph. The very nature of cinema ensures that an actor’s performance can be enjoyed for years, perhaps centuries, after they’ve died. Film technology has advanced to the point that actors can be digitally brought back to reprise famous roles. This has provoked decidedly mixed reactions, but it is nothing new. While some lauded Browning’s β€œsΓ©ance” as a triumph, othersβ€”his own sister among themβ€”were disturbed by the implications. With the advent of AI, these reactions are, however, more pronounced.

In 2021, Christopher Pelkey was murdered in a road rage incident in Arizona. Three and a half years later, he spoke at his killer’s sentencingβ€”resurrected in both voice and image by artificial intelligence and the love of his sister, Stacey. Faced with having to write a victim impact statement, she decided instead to let her brother have the last say. Using his funeral photo and voice recordings, an AI version of Christopher was created.

Following a script written by Stacey, AI Christopher forgave his killer, lamenting that they could have been friends if the circumstances had been different. This, however, brings up a potential problem: would the real Christopher have said these things? Stacey believed he would have, basing the script on what she felt she knew about her brother. It is worth pointing out that she herself certainly did not feel that way. She could not bring herself to say β€œI forgive you,” but genuinely felt Christopher could. Perhaps that’s important to take into account. Stacey had every opportunity to vent her grief and anger, but decided that wouldn’t be true to the man she was honoring.

"Poor Robert’s dead voice to be made interesting amusement!"

Intent matters. AI, indeed all technology, is only as good or bad as the human behind it. Voice cloning and deep fakes have become a very real concern in the past few years for good reason. More often than not, the technology has been used for scams and hoaxes. At best, its use can be viewed as a publicity stunt; at worst, a dangerous tool for deception. The same held true for the phonograph, incidentally β€”Robert Browning’s sister wrote, β€œPoor Robert’s dead voice to be made interesting amusement! God forgive them all. I find it difficult.” Indeed, some might call the case of Christopher Pelkey nothing but a publicity stunt, something that will never be repeated in a court of law.

Can we be sure of that, though? The idea of giving a deceased family member or friend one last chance to speak is a tempting one, even a cathartic one. There is certainly something compelling about it. In a world where AI can be used to cheat someone out of their money or manipulate emotions, this seems far from the worst thing one could choose to do with such a powerful technology.

And yet.

This was just a victim impact statement, and one that swayed the judgeβ€”Pelkey’s killer received the maximum sentence. A judge is meant to be impartial, to make decisions without letting emotion guide them. When a judge allows themselves to be influenced by what is ultimately just scripted programming, what does that mean for the future of the justice system?

Could an AI provide testimony? Could it file a lawsuit, even represent a client? That last one was only recently shot down in a New York court, but it raises an important question: would this AI be scripted by a human or merely generate its own responses? Neither seems totally trustworthy, and it seems like a human script would be immediately thrown out. Imagine if the AI version of Christopher Pelkey had been presented to a jury. If a judge could be affected by it, what chance would a jury have? They don’t possess the training and experience of a judge, and they could perhaps be even more susceptible to it.

AI addiction is a very real problem in today’s world. There is an increasing tendency to rely on it for information (whether it’s actually correct or not), and even an inclination to humanize it. In extreme cases, this has led to tragedy. In 2024, a fourteen-year-old boy committed suicide after allegedly being encouraged to β€œcome home” by a Game of Thrones chatbot on Character.AI. The idea of AI as a stand-in for the deceased is fraught with danger, particularly when the situation calls for cool heads and rational decision-making.

Are we looking at a future where AI takes the witness stand? At this juncture, it’s difficult to say. A world in which AI is increasingly viewed as a necessity, even a friend, could very well lead to this. Boundaries need to be set, and perhaps we need a reminder that AIβ€”all AIβ€”is ultimately a human creation.

Comments

/* * OnlySky UTM Capture Shim β€” Sprint 1 / D4 * * Paste into Ghost Admin β†’ Settings β†’ Code Injection β†’ Site Footer (NOT Header). * Append after the existing gtag signup-event block; this script is independent * and stateless across page loads except for localStorage. * * What it does: * 1. On every page load: parse UTM params from window.location.search. If any * utm_* present AND no first-touch UTM already in localStorage, write the * five UTM params + landing slug + capture timestamp into localStorage * with a 90-day TTL. First-touch wins. * * 2. On signup confirmation pages (/free-subs/, /paid-sub/, /premium-sub/, * /hero-sub/): if localStorage has first-touch UTM and we haven't yet * POSTed for this conversion, send the capture to the OnlySky webhook * via navigator.sendBeacon() with a fetch() fallback. * * 3. Captures member identity if Ghost's portal exposes it (email and uuid). * If no member yet (e.g. anonymous landing on signup page), POSTs the * capture without identity β€” the server-side join uses timestamp * proximity as a last-resort match. * * Privacy: localStorage stays per-device. No third-party cookies. No personal * data leaves the device except what the user has voluntarily handed Ghost * (their email at signup). * * Tunable: edit WEBHOOK_URL below to match the deployed tunnel hostname. */ (function () { 'use strict'; // ─── config ────────────────────────────────────────────────────────── var WEBHOOK_URL = 'https://utm.onlys.ky/utm-capture'; // ← deployment target var SIGNUP_PAGES = ['/free-subs/', '/paid-sub/', '/premium-sub/', '/hero-sub/']; var TTL_DAYS = 90; var LS_PREFIX = 'onlysky_utm_'; // single namespace; cheap to grep var UTM_KEYS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term']; // ─── helpers ───────────────────────────────────────────────────────── function lsGet(k) { try { return localStorage.getItem(LS_PREFIX + k); } catch (e) { return null; } } function lsSet(k, v) { try { localStorage.setItem(LS_PREFIX + k, v); } catch (e) { /* quota or private mode */ } } function lsRemove(k) { try { localStorage.removeItem(LS_PREFIX + k); } catch (e) {} } function isStale() { var captured = lsGet('captured_at'); if (!captured) return false; try { var ageMs = Date.now() - new Date(captured).getTime(); return ageMs > TTL_DAYS * 86400 * 1000; } catch (e) { return false; } } function dropAll() { UTM_KEYS.forEach(function (k) { lsRemove(k); }); lsRemove('captured_at'); lsRemove('first_landing_slug'); lsRemove('posted_for_member'); } function nowISO() { return new Date().toISOString(); } function landingSlugFromPath() { var p = window.location.pathname.replace(/^\/|\/$/g, ''); if (!p) return null; var seg = p.split('/')[0]; var reserved = ['tag', 'tags', 'author', 'authors', 'page', 'pages', 'members', 'portal', 'ghost', 'free-subs', 'paid-sub', 'premium-sub', 'hero-sub']; return (reserved.indexOf(seg) >= 0) ? null : seg; } // ─── step 1: first-touch capture on every page load ────────────────── if (isStale()) dropAll(); // expire after TTL var params = new URLSearchParams(window.location.search); var anyUtm = false; UTM_KEYS.forEach(function (k) { if (params.has(k)) anyUtm = true; }); if (anyUtm && !lsGet('captured_at')) { UTM_KEYS.forEach(function (k) { var v = params.get(k); if (v) lsSet(k, v); }); lsSet('captured_at', nowISO()); var slug = landingSlugFromPath(); if (slug) lsSet('first_landing_slug', slug); } // ─── step 2: POST on signup-confirmation pages ────────────────────── if (SIGNUP_PAGES.indexOf(window.location.pathname) === -1) return; if (!lsGet('captured_at')) return; // no first-touch on this device β†’ nothing to send // Try to get member identity from Ghost Portal. function getMember() { try { if (window.MembersJS && typeof window.MembersJS.getMember === 'function') { return window.MembersJS.getMember(); } if (window.ghost && window.ghost.member) return window.ghost.member; } catch (e) {} return null; } function buildPayload(member) { var p = { captured_at: lsGet('captured_at'), conversion_at: nowISO(), conversion_page: window.location.pathname, first_landing_slug: lsGet('first_landing_slug'), member_email: member && member.email ? member.email : null, member_uuid: member && member.uuid ? member.uuid : null }; UTM_KEYS.forEach(function (k) { p[k] = lsGet(k); }); return p; } function postCapture(payload) { var posted_key = (payload.member_email || payload.member_uuid || payload.conversion_at); if (lsGet('posted_for_member') === posted_key) return; // de-dupe same-page reload lsSet('posted_for_member', posted_key); var body = JSON.stringify(payload); var ok = false; try { if (navigator.sendBeacon) { var blob = new Blob([body], { type: 'application/json' }); ok = navigator.sendBeacon(WEBHOOK_URL, blob); } } catch (e) {} if (!ok) { try { fetch(WEBHOOK_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: body, keepalive: true, mode: 'cors', credentials: 'omit' }).catch(function () {}); } catch (e) {} } } // Member may not be ready on the first DOM tick. Try immediately, then // again at 500ms / 1500ms / 3000ms. Idempotency on the server side // (INSERT OR IGNORE) and the posted_for_member guard prevent dupes. function tryPost() { var member = getMember(); postCapture(buildPayload(member)); } tryPost(); setTimeout(tryPost, 500); setTimeout(tryPost, 1500); setTimeout(tryPost, 3000); })();