Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 138 additions & 0 deletions Docs/Blog/PUBLICACION.md
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,144 @@ leyendo mis propios números con otra pregunta en la cabeza.
https://github.com/peopleworks/SignsofAI
```

### X / Twitter — décimo artículo (EN)
```
I put my AI detector inside Word. The first thing it did was refuse to answer.

357 words, a real document. Score: 0/100. Underneath, instead of a conclusion:

No verdict at this length. This text is 357 words. The boundary was measured
only on texts of 649 words and longer, so no verdict is given.

It found six invisible characters anyway, because that is a fact about the file and
carries no threshold.

And it cannot upload your document, because a task pane is a browser: the engine runs
there. Every other add-in in this category posts your text to an API. There is no API
here to post it to.

https://github.com/peopleworks/SignsofAI
```

### X / Twitter — décimo artículo (ES)
```
Metí mi detector de IA dentro de Word. Lo primero que hizo fue negarse a contestar.

357 palabras, un documento real. Puntuación: 0/100. Debajo, en vez de una conclusión:

Sin veredicto a esta longitud. Este texto tiene 357 palabras. La frontera se midió
solo sobre textos de 649 palabras o más, así que aquí no se da veredicto.

Aun así encontró seis caracteres invisibles, porque eso es un hecho sobre el archivo y
no lleva umbral.

Y no puede subir tu documento, porque un panel de tareas es un navegador: el motor corre
ahí. Cualquier otro add-in de esta categoría manda tu texto a una API. Aquí no hay API
a la que mandarlo.

https://github.com/peopleworks/SignsofAI
```

### LinkedIn — décimo artículo (EN)
```
The most requested feature for this project has been the same sentence for months: put it in Word.
It is there now. The first thing it did on a real document was decline to answer.

WHAT HAPPENED

357 words, open in Word. The pane read the document and returned 0 out of 100, and under the score,
instead of a conclusion:

"No verdict at this length. This text is 357 words. The boundary was measured only on texts of 649
words and longer, so no verdict is given — the score is neither evidence that a machine wrote this
nor evidence that a person did."

The boundary this tool judges by, 30 out of 100, was measured on 296 documents written before 2022:
human by their dates, not by anyone's opinion. At that boundary it flags 2 of the 296, a false
positive rate of 0.7% with a 95% interval reaching 2.4%. The shortest of those documents is 649
words. Below that length there is nothing the boundary was fitted on, so there is nothing to say.

WHAT IT FOUND ANYWAY

Six no-break spaces, with the codepoint, the count and every position. That is not a judgement about
prose and it carries no threshold, so it holds at any length. It is a fact about the file: those
characters are in it and typing does not produce them.

The panel says the rest out loud, because a fact left to imply something is worse than an opinion:
this says nothing about who wrote the text, and it is not evidence of dishonesty.

THE PART THAT MATTERS MOST

Every other add-in in this category sends your document to a server, because their analysis is the
server. This one cannot. A task pane is a browser, the engine is WebAssembly, and it runs there —
so there is no endpoint for the document to be sent to.

And the manifest asks Word for ReadDocument, not ReadWriteDocument. Word enforces it. If you are
deciding whether to let a tool near coursework, that line is worth more than any paragraph on a
landing page, including this one.

WHAT DID NOT SHIP

PowerPoint. A deck rarely reaches 649 words, so the same add-in there would withhold the verdict for
almost every deck — correctly, and to nobody's benefit. That is a different product with a different
promise, not this one with an extra line in a file.

Free and open source. The full write-up, including the 404 that made the first install look broken:

https://github.com/peopleworks/SignsofAI
```

### LinkedIn — décimo artículo (ES)
```
La petición más repetida de este proyecto lleva meses siendo la misma frase: mételo en Word. Ya está.
Y lo primero que hizo con un documento real fue negarse a contestar.

QUÉ PASÓ

357 palabras, abiertas en Word. El panel leyó el documento, devolvió 0 sobre 100 y, debajo de la
puntuación, en lugar de una conclusión:

«Sin veredicto a esta longitud. Este texto tiene 357 palabras. La frontera se midió solo sobre textos
de 649 palabras o más, así que aquí no se da veredicto: la puntuación no es prueba de que lo
escribiera una máquina ni prueba de que lo escribiera una persona.»

La frontera con la que juzga, 30 sobre 100, se midió sobre 296 documentos escritos antes de 2022:
humanos por su fecha, no por la opinión de nadie. En esa frontera marca 2 de los 296, una tasa de
falsos positivos del 0,7 % con un intervalo del 95 % que llega al 2,4 %. El más corto de esos
documentos tiene 649 palabras. Por debajo no hay nada sobre lo que la frontera se haya ajustado, así
que no hay nada que decir.

LO QUE SÍ ENCONTRÓ

Seis espacios de no separación, con el punto de código, la cuenta y todas sus posiciones. Eso no es
un juicio sobre la prosa y no lleva umbral, así que vale a cualquier longitud. Es un hecho sobre el
archivo: esos caracteres están ahí y tecleando no salen.

El panel dice el resto en voz alta, porque un hecho que insinúa sin decir es peor que una opinión:
esto no dice nada sobre quién escribió el texto, y no es prueba de deshonestidad.

LA PARTE QUE MÁS IMPORTA

Cualquier otro add-in de esta categoría manda tu documento a un servidor, porque su análisis es el
servidor. Éste no puede. Un panel de tareas es un navegador, el motor es WebAssembly y corre ahí, así
que no hay ningún endpoint al que mandar el documento.

Y el manifest le pide a Word permiso de ReadDocument, no de ReadWriteDocument. Lo impone Word. Si
estás decidiendo si dejas que una herramienta se acerque a los trabajos de tus alumnos, esa línea
vale más que cualquier párrafo de una página de aterrizaje. Éste incluido.

LO QUE NO SALIÓ

PowerPoint. Una presentación casi nunca llega a 649 palabras, así que el mismo add-in ahí retendría
el veredicto con casi cualquiera — correctamente, y sin servirle a nadie. Es otro producto con otra
promesa, no éste con una línea de más en un archivo.

Gratis y de código abierto. El artículo completo, incluido el 404 que hizo parecer que la primera
instalación estaba rota:

https://github.com/peopleworks/SignsofAI
```

## 8. Notas de publicación
- Sube el `.srt` de cada video como subtítulos (clave para reproducción sin sonido en Shorts/Reels/TikTok).
- Cruza los enlaces: el video enlaza al artículo del blog y viceversa; ambos enlazan al demo.
Expand Down
19 changes: 15 additions & 4 deletions Docs/Blog/shorts/GUION-shorts.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Paleta SignsOfAI: `--bg:#0b1020` · léxico `#db2777` · retórico `#f59e0b` ·
| 9 | Bibliografía inventada | ✅ | ✅ | ✅ 36,3 s · 35,5 s |
| 10 | 61% / línea base | ✅ | ✅ | ✅ 40,2 s · 37,4 s |
| 11 | El veredicto que nunca se dio | ✅ | ✅ | ✅ 35,5 s · 32,4 s |
| 12 | La señal más fiable no es una palabra | ✅ | ⬜ | ⬜ |
| 13 | 94/100 y sin veredicto | ✅ | ⬜ | ⬜ |
| 12 | La señal más fiable no es una palabra | ✅ | ✅ | ✅ 25,0 s · 25,0 s |
| 13 | 94/100 y sin veredicto | ✅ | ✅ | ✅ 27,0 s · 25,3 s |
| 14 | Dentro de Word, y se calla | ✅ | ✅ | ✅ 26,0 s · 28,2 s |

Los renders están en `out/<id>.mp4` + `.srt`.

Expand All @@ -33,16 +34,26 @@ es lo que hay que recortar, no la animación.
(`cue-times.mjs`) y **después** escribir el HTML alrededor de la duración medida, porque los
retardos de animación son absolutos. `build-short.mjs` reutiliza el mp3 salvo `--revoice`.

**Los shorts 12 y 13 rompen ese orden a propósito, y se puede copiar.** Sus tiempos no van en
**Los shorts 12, 13 y 14 rompieron ese orden a propósito, y funcionó: se puede copiar.** Sus tiempos no van en
segundos sino en **fracciones de `--dur`**, una variable CSS al principio del archivo. Funciona
porque `cue-times.mjs` reparte la duración medida entre las palabras del guion: la posición
*relativa* de cada frase se conoce sin oír el audio, y lo único que falta es el total. Así que se
escribió el HTML antes de narrar, y al narrar solo hay que poner `--dur` a la duración real:

node narrate-all.mjs short12-residencia-es short12-residencia-en short13-longitud-es short13-longitud-en
node narrate-all.mjs short12-residencia-es short12-residencia-en short13-longitud-es short13-longitud-en short14-word-es short14-word-en
# anota la duración que imprime cada uno, y ponla en --dur del HTML correspondiente
node build-short.mjs scenes/short13-longitud-es.json

**Comprobado en los seis, el 7 de septiembre.** Las duraciones medidas fueron 22,1 / 22,4 (12 ES·EN),
23,0 / 23,9 (13) y 24,0 / 26,8 (14), y cada HTML lleva la suya. Dos cosas que conviene saber antes de
repetirlo:

- `--dur` es la duración de la **narración**, no la del vídeo. El vídeo lleva además `tailSeconds`, y
`minSeconds` puede alargarlo por encima de los dos. Las fracciones reparten frases dentro de la
voz, así que cuadran con la voz.
- **El inglés y el español no duran lo mismo** aunque el guion diga lo mismo: 24,0 frente a 26,8 en
el short 14. Cada idioma necesita su propio `--dur`; ponerles el mismo desincroniza uno de los dos.

Las fracciones están escritas en el comentario de cada HTML, con la frase a la que corresponden.

**Comprobar la maqueta antes de renderizar**, con el `snap.mjs` del kit y **un `t` mayor que la
Expand Down
2 changes: 1 addition & 1 deletion Docs/Blog/shorts/en/short12-residencia.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
La idea visual es una sola: el ensayo en gris, y la frase del asistente con burbuja y color de
chat. No hay que explicar que es de otro sitio — se ve que es de otro sitio. */
html,body{margin:0;padding:0}
body{--dur:25s;
body{--dur:22.4s;
width:1080px;height:1920px;overflow:hidden;position:relative;
background:radial-gradient(700px 700px at 78% 12%,rgba(34,184,207,.14),transparent 60%),
radial-gradient(760px 760px at 14% 70%,rgba(109,124,255,.15),transparent 60%),
Expand Down
2 changes: 1 addition & 1 deletion Docs/Blog/shorts/en/short13-longitud.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
0.179 "Y se niega" · 0.295 "La frontera" · 0.475 "y el más corto" · 0.639 "Este tiene sesenta"
0.803 "Las veintitrés" · 0.885 "Lo que se retira" */
html,body{margin:0;padding:0}
body{--dur:27s;
body{--dur:23.9s;
width:1080px;height:1920px;overflow:hidden;position:relative;
background:radial-gradient(700px 700px at 80% 10%,rgba(109,124,255,.16),transparent 60%),
radial-gradient(760px 760px at 12% 66%,rgba(245,158,11,.13),transparent 60%),
Expand Down
131 changes: 131 additions & 0 deletions Docs/Blog/shorts/en/short14-word.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><style>
/* Short 14 — "It is inside Word now, and the first thing it did was go quiet".

Timings in FRACTIONS of --dur, like shorts 12 and 13: written before it was narrated.
After narrating, set --dur to the measured duration and everything lands where it should.

Fractions from each phrase's word position in the EN script (66 words):
0.106 "The first thing it did" 0.227 "Three hundred and fifty-seven"
0.303 "The boundary was measured" 0.606 "But it found six invisible"
0.818 "And your document never leaves"

Every figure is real: 357 words, 0/100, a floor of 649, six U+00A0. First run inside Word,
7 September. */
html,body{margin:0;padding:0}
body{--dur:26.8s;
width:1080px;height:1920px;overflow:hidden;position:relative;
background:radial-gradient(700px 700px at 78% 8%,rgba(109,124,255,.17),transparent 60%),
radial-gradient(760px 760px at 14% 70%,rgba(34,184,207,.12),transparent 60%),
linear-gradient(165deg,#0b1020,#0d1428 55%,#111a2e);
color:#eaf1fb;font-family:'Segoe UI',system-ui,-apple-system,sans-serif;text-align:center}
@keyframes rv{from{opacity:0;transform:translateY(40px)}to{opacity:1;transform:none}}
@keyframes pop{0%{opacity:0;transform:scale(.5)}60%{transform:scale(1.12)}100%{opacity:1;transform:scale(1)}}
/* The stamp is centred with translateX(-50%), so it needs its own keyframe: any other one that
writes `transform` replaces it wholesale and the piece slides off to one side. */
@keyframes stampin{0%{opacity:0;transform:translateX(-50%) scale(.5) rotate(-9deg)}60%{transform:translateX(-50%) scale(1.1) rotate(-2deg)}100%{opacity:1;transform:translateX(-50%) scale(1) rotate(-4deg)}}
@keyframes grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes drop{from{opacity:0;transform:translateY(-24px)}to{opacity:1;transform:none}}
@keyframes fade{to{opacity:1}}
/* The arrow that does NOT leave: drawn, then struck through. */
@keyframes strike{from{transform:rotate(19deg) scaleX(0)}to{transform:rotate(19deg) scaleX(1)}}

.brand{position:absolute;top:74px;width:100%;display:flex;align-items:center;justify-content:center;gap:20px;font-weight:800;font-size:44px}
.bmark{width:60px;height:60px;border-radius:16px;background:conic-gradient(from 210deg,#db2777,#f59e0b,#22b8cf,#f0556f,#db2777);box-shadow:0 0 0 1px rgba(255,255,255,.15)}

/* The pane, exactly as it answered. */
.pane{position:absolute;top:196px;left:96px;right:96px;padding:44px 48px 52px;border-radius:28px;
background:rgba(21,27,44,.92);border:2px solid rgba(90,104,140,.5);text-align:left;
opacity:0;animation:rv .7s calc(var(--dur)*.02) forwards}
.pane-h{display:flex;align-items:center;justify-content:space-between;font-size:38px;font-weight:700;color:#c3ccdb}
.pane-h span{font-size:30px;font-family:Consolas,monospace;color:#7c8aa6}
.file{margin-top:10px;font-size:32px;font-style:italic;color:#7c8aa6}

/* The number, in grey. It exists and it accuses nobody: that grey is half the argument. */
.score{margin-top:26px;font-size:190px;font-weight:900;line-height:1;color:#9aa8bd;
font-variant-numeric:tabular-nums;opacity:0;animation:rv .6s calc(var(--dur)*.04) forwards}
.score span{font-size:64px;font-weight:700;opacity:.55}
.stamp{position:absolute;top:560px;left:50%;transform:translateX(-50%) rotate(-4deg);
padding:16px 44px;border:5px solid #7c8aa6;border-radius:20px;color:#c3ccdb;
font-size:52px;font-weight:900;opacity:0;animation:stampin .5s calc(var(--dur)*.106) forwards;z-index:3}

/* The ruler: 357 falls to the left of where there is any evidence. */
.ruler{position:absolute;top:730px;left:96px;right:96px;height:330px;opacity:0;animation:rv .7s calc(var(--dur)*.303) forwards}
.track{position:absolute;top:172px;left:0;right:0;height:12px;border-radius:4px;background:rgba(255,255,255,.12)}
.void{position:absolute;top:92px;left:0;width:44%;height:172px;border-radius:16px;
background:linear-gradient(90deg,rgba(124,138,166,.22),rgba(124,138,166,.05));border:2px dashed rgba(124,138,166,.4)}
.wall{position:absolute;top:70px;left:44%;width:6px;height:216px;background:#f59e0b;
transform:scaleY(0);transform-origin:bottom;animation:grow .5s calc(var(--dur)*.34) forwards}
.wall-lab{position:absolute;top:6px;left:44%;transform:translateX(-50%);white-space:nowrap;
font-family:Consolas,monospace;font-size:44px;font-weight:800;color:#f59e0b;opacity:0;animation:fade .4s calc(var(--dur)*.34) forwards}
.void-lab{position:absolute;top:288px;left:0;width:44%;font-size:30px;color:#8a93a6;line-height:1.3;
opacity:0;animation:fade .4s calc(var(--dur)*.36) forwards}
.here{position:absolute;top:152px;left:24%;width:52px;height:52px;border-radius:50%;
background:#f0556f;box-shadow:0 0 0 10px rgba(240,85,111,.2);opacity:0;animation:pop .5s calc(var(--dur)*.227) forwards}
.here-lab{position:absolute;top:88px;left:24%;transform:translateX(-50%);white-space:nowrap;
font-family:Consolas,monospace;font-size:40px;font-weight:800;color:#f0556f;opacity:0;animation:fade .4s calc(var(--dur)*.227) forwards}

/* The fact that does survive at any length. */
.fact{position:absolute;top:1116px;left:96px;right:96px;padding:30px 40px;border-radius:22px;
background:rgba(34,184,207,.09);border:2px solid rgba(34,184,207,.34);text-align:left;
opacity:0;animation:rv .6s calc(var(--dur)*.606) forwards}
.fact-h{font-size:38px;font-weight:800;color:#67e8f9}
.fact-row{margin-top:16px;display:flex;align-items:baseline;justify-content:space-between;font-size:40px}
.fact-row code{font-family:Consolas,monospace;color:#67e8f9;font-weight:800}
.fact-row b{font-family:Consolas,monospace;color:#67e8f9;font-size:46px}
.fact-sub{margin-top:14px;font-size:30px;color:#8a93a6;line-height:1.32}

/* What does not happen: the document does not leave. */
.priv{position:absolute;top:1416px;left:96px;right:96px;opacity:0;animation:rv .7s calc(var(--dur)*.818) forwards}
.priv-row{display:flex;align-items:center;justify-content:center;gap:26px}
.doc{width:86px;height:110px;border-radius:10px;border:3px solid #7c8aa6;background:rgba(124,138,166,.12)}
.arrow{position:relative;width:230px;height:6px;background:rgba(124,138,166,.45);border-radius:3px}
.arrow::after{content:'';position:absolute;right:-2px;top:-13px;border:16px solid transparent;border-left-color:rgba(124,138,166,.45)}
.cross{position:absolute;top:0;left:-4%;width:108%;height:6px;background:#f0556f;border-radius:3px;
transform:rotate(19deg) scaleX(0);transform-origin:center;animation:strike .45s calc(var(--dur)*.858) forwards}
.cloud{width:118px;height:74px;border-radius:38px;border:3px dashed rgba(124,138,166,.5)}
.priv-lab{margin-top:26px;font-size:46px;font-weight:900;line-height:1.24}
.priv-lab b{background:linear-gradient(90deg,#6d7cff,#22b8cf);-webkit-background-clip:text;background-clip:text;color:transparent}

.foot{position:absolute;bottom:88px;width:100%;opacity:0;animation:rv .8s calc(var(--dur)*.93) forwards}
.foot .big{font-size:42px;font-weight:900;line-height:1.26;color:#c3ccdb}
.foot .sub{margin-top:14px;font-size:32px;color:#7c8aa6;font-family:Consolas,monospace}
</style></head><body>
<div class="brand"><span class="bmark"></span> SignsOfAI</div>

<div class="pane">
<div class="pane-h">Signs of AI Writing <span>Word</span></div>
<div class="file">Document 1.docx</div>
<div class="score">0<span>/100</span></div>
</div>
<div class="stamp">NO VERDICT</div>

<div class="ruler">
<div class="track"></div>
<div class="void"></div>
<div class="wall"></div>
<div class="wall-lab">649 words</div>
<div class="void-lab">nothing this short<br>was ever measured</div>
<div class="here"></div>
<div class="here-lab">357</div>
</div>

<div class="fact">
<div class="fact-h">Characters, not prose</div>
<div class="fact-row"><code>U+00A0</code> <span style="color:#8a93a6;font-size:32px">NO-BREAK SPACE</span> <b>×6</b></div>
<div class="fact-sub">A fact about the file. It carries no threshold,<br>so at this length it still holds.</div>
</div>

<div class="priv">
<div class="priv-row">
<div class="doc"></div>
<div class="arrow"><div class="cross"></div></div>
<div class="cloud"></div>
</div>
<div class="priv-lab"><b>Nothing leaves your machine.</b><br>There is nowhere to send it.</div>
</div>

<div class="foot">
<div class="big">A Word task pane is a browser.<br>The engine runs there, not on a server.</div>
<div class="sub">signsofai · free and open source</div>
</div>
</body></html>
Loading
Loading