this repo has no description atmosphereconf-vods.wisp.place/
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

update subtitles

+7148 -2071
+1
package.json
··· 18 18 "generate:room-images": "node ./scripts/generate-room-images.mjs", 19 19 "generate:transcript-search-index": "node --experimental-strip-types ./scripts/generate-transcript-search-index.mjs", 20 20 "generate:video-subtitles": "node --experimental-strip-types ./scripts/generate-video-subtitles.mjs", 21 + "regen:video-subtitles-if-record-changed": "node --experimental-strip-types ./scripts/regen-video-subtitles-if-record-changed.mjs", 21 22 "sync:atmo-rsvp-events": "node --experimental-strip-types ./scripts/sync-atmo-rsvp-events.ts" 22 23 }, 23 24 "dependencies": {
+943 -1431
public/subtitles/how-streamplace-works-vods.vtt
··· 1 1 WEBVTT 2 2 3 3 1 4 - 00:00:00.000 --> 00:00:02.000 5 - Thank you. 4 + 00:00:00.000 --> 00:00:06.960 5 + All right. 6 6 7 7 2 8 - 00:00:30.000 --> 00:00:32.000 9 - Thank you. 8 + 00:00:06.960 --> 00:00:09.280 9 + So that's how Streamplace VOD works. 10 10 11 11 3 12 - 00:01:00.000 --> 00:01:02.000 13 - Hello. 12 + 00:00:09.280 --> 00:00:11.200 13 + I hope you all enjoyed the presentation. 14 14 15 15 4 16 - 00:01:02.000 --> 00:01:04.000 17 - We're good? 16 + 00:00:11.200 --> 00:00:13.120 17 + My name is Eli Malin. 18 18 19 19 5 20 - 00:01:04.000 --> 00:01:06.000 21 - Nice. 20 + 00:00:13.120 --> 00:00:15.800 21 + I'm the CEO and founder of Streamplace. 22 22 23 23 6 24 - 00:01:06.000 --> 00:01:10.000 25 - Everybody, my name is Eli Malin. 24 + 00:00:15.800 --> 00:00:21.600 25 + I don't care about my Caribbeaner update version. 26 26 27 27 7 28 - 00:01:10.000 --> 00:01:14.000 29 - Someday, I will figure out how to change slides. 28 + 00:00:21.600 --> 00:00:29.320 29 + So the crux of this talk was if you are going to make a system that has both VOD and live, 30 30 31 31 8 32 - 00:01:14.000 --> 00:01:16.000 33 - Hmm. 32 + 00:00:29.320 --> 00:00:32.280 33 + that'd be good at all. 34 34 35 35 9 36 - 00:01:16.000 --> 00:01:19.000 37 - My buttons on my keyboard no longer do anything. 36 + 00:00:32.280 --> 00:00:33.640 37 + You should probably start with live. 38 38 39 39 10 40 - 00:01:19.000 --> 00:01:22.000 41 - Well, stream place VOD is cancelled. 40 + 00:00:33.640 --> 00:00:35.640 41 + Live video is more difficult than VOD. 42 42 43 43 11 44 - 00:01:22.000 --> 00:01:26.000 45 - I told Boris last year if he wanted the videos up, my whole laptop 44 + 00:00:35.640 --> 00:00:42.040 45 + It is much easier to generalize live video to VOD than it is to go the opposite direction. 46 46 47 47 12 48 - 00:01:26.000 --> 00:01:28.000 49 - is frozen now. 48 + 00:00:42.040 --> 00:00:43.600 49 + So we started out with live. 50 50 51 51 13 52 - 00:01:28.000 --> 00:01:30.000 53 - This is awesome. 52 + 00:00:43.600 --> 00:00:45.520 53 + We're pretty happy with that. 54 54 55 55 14 56 - 00:01:30.000 --> 00:01:33.000 57 - I told Boris last year if he wanted the videos up, I could 56 + 00:00:45.520 --> 00:00:47.360 57 + And knock on wood. 58 58 59 59 15 60 - 00:01:33.000 --> 00:01:37.000 61 - make for each video a stream place stream that loops every 60 + 00:00:47.360 --> 00:00:49.920 61 + Of course, as soon as I walked out of the other room, people started reporting playback 62 62 63 63 16 64 - 00:01:37.000 --> 00:01:40.000 65 - video 24-7 and then you have VOD. 64 + 00:00:49.920 --> 00:00:50.920 65 + issues over there. 66 66 67 67 17 68 - 00:01:40.000 --> 00:01:42.000 69 - And that's a joke. 68 + 00:00:50.920 --> 00:00:55.560 69 + But overall, everything's been going really well at all of this. 70 70 71 71 18 72 - 00:01:42.000 --> 00:01:45.000 73 - But the design of VOD is going to look more similar to that 72 + 00:00:55.560 --> 00:01:00.800 73 + So I'll start by sort of explaining how Streamplace, a quick explanation of how Streamplace live 74 74 75 75 19 76 - 00:01:45.000 --> 00:01:47.000 77 - than you might think. 76 + 00:01:00.800 --> 00:01:03.080 77 + works because I've talked about this a lot before. 78 78 79 79 20 80 - 00:01:47.000 --> 00:01:50.000 81 - This is strange. 80 + 00:01:03.080 --> 00:01:09.240 81 + And then we'll talk about how we're adapting that for a decentralized VOD primitive. 82 82 83 83 21 84 - 00:01:50.000 --> 00:01:52.000 85 - Give me a moment. 84 + 00:01:09.240 --> 00:01:15.280 85 + What does it mean to have something like, you know, what would a decentralized YouTube 86 86 87 87 22 88 - 00:01:52.000 --> 00:01:58.000 89 - Really, just a black screen on my laptop right now. 88 + 00:01:15.280 --> 00:01:16.280 89 + look like? 90 90 91 91 23 92 - 00:01:58.000 --> 00:02:02.000 93 - Let's get one ready. 92 + 00:01:16.280 --> 00:01:20.480 93 + What things do you need in order to make that happen? 94 94 95 95 24 96 - 00:02:02.000 --> 00:02:04.000 97 - Okay. 96 + 00:01:20.480 --> 00:01:22.560 97 + So yeah, this is just about Streamplace. 98 98 99 99 25 100 - 00:02:04.000 --> 00:02:06.000 101 - Just a second. 100 + 00:01:22.560 --> 00:01:29.320 101 + There's been three Streamplace third-party clients created since the beginning of this 102 102 103 103 26 104 - 00:02:06.000 --> 00:02:09.000 105 - Just like Google thing. 104 + 00:01:29.320 --> 00:01:30.840 105 + conference. 106 106 107 107 27 108 - 00:02:09.000 --> 00:02:22.000 109 - Okay. 108 + 00:01:30.840 --> 00:01:35.960 109 + So I don't know if that reflects poorly on our front end or if it just refers to the 110 110 111 111 28 112 - 00:02:49.000 --> 00:02:52.000 113 - Okay. 112 + 00:01:35.960 --> 00:01:38.280 113 + entrepreneurial spirit of the app proto community. 114 114 115 115 29 116 - 00:03:19.000 --> 00:03:22.000 117 - Okay. 116 + 00:01:38.280 --> 00:01:41.760 117 + But this one's from Jack.xyz. 118 118 119 119 30 120 - 00:03:49.000 --> 00:03:52.000 121 - Okay. 120 + 00:01:41.760 --> 00:01:46.240 121 + And it shows all of the streams at once, really given the Streamplace servers the maximum 122 122 123 123 31 124 - 00:04:19.000 --> 00:04:22.000 125 - Okay. 124 + 00:01:46.240 --> 00:01:50.720 125 + workout to give everybody what they're looking for there. 126 126 127 127 32 128 - 00:04:50.000 --> 00:04:52.000 129 - Okay. 128 + 00:01:50.720 --> 00:01:55.160 129 + Before we do anything else, I found this MP4 file on the ground. 130 130 131 131 33 132 - 00:05:07.000 --> 00:05:10.000 133 - All right. 132 + 00:01:55.160 --> 00:02:01.160 133 + Let's see what it is. 134 134 135 135 34 136 - 00:05:10.000 --> 00:05:12.000 137 - Yeah. 136 + 00:02:01.160 --> 00:02:06.520 137 + You can all imagine the great noises Trabio is making here. 138 138 139 139 35 140 - 00:05:12.000 --> 00:05:14.000 141 - All right. 140 + 00:02:06.520 --> 00:02:12.560 141 + What's going to happen? 142 142 143 143 36 144 - 00:05:14.000 --> 00:05:16.000 145 - So that's how stream place VOD works. 144 + 00:02:12.560 --> 00:02:15.560 145 + And wait for it. 146 146 147 147 37 148 - 00:05:16.000 --> 00:05:18.000 149 - I hope you all enjoyed the presentation. 148 + 00:02:15.560 --> 00:02:18.240 149 + Yeah, we got them. 150 150 151 151 38 152 - 00:05:18.000 --> 00:05:20.000 153 - I'm a developer and founder of stream place. 152 + 00:02:18.240 --> 00:02:19.240 153 + Yeah. 154 154 155 155 39 156 - 00:05:20.000 --> 00:05:24.000 157 - I don't care about my Caribbean update version. 156 + 00:02:19.280 --> 00:02:26.000 157 + So that MP4 file I found on the ground turned out to be my glorious victory over Trabio. 158 158 159 159 40 160 - 00:05:24.000 --> 00:05:30.000 161 - So the crux of this talk was if you are going to make a system 160 + 00:02:26.000 --> 00:02:27.000 161 + So how do I know that? 162 162 163 163 41 164 - 00:05:30.000 --> 00:05:35.000 165 - that has both VOD and live, can that be muted at all? 164 + 00:02:27.000 --> 00:02:30.480 165 + How do I know it's Eli's livestream that happened there? 166 166 167 167 42 168 - 00:05:35.000 --> 00:05:37.000 169 - You should probably start with live. 168 + 00:02:30.480 --> 00:02:35.720 169 + And that has to do with Streamplace's signing format. 170 170 171 171 43 172 - 00:05:37.000 --> 00:05:39.000 173 - Live video is more difficult than VOD. 172 + 00:02:35.720 --> 00:02:39.040 173 + So we needed to... 174 174 175 175 44 176 - 00:05:39.000 --> 00:05:43.000 177 - It is much easier to generalize live video to VOD than it is to 176 + 00:02:39.040 --> 00:02:41.840 177 + So decentralized VOD is something that's kind of existed before, right? 178 178 179 179 45 180 - 00:05:43.000 --> 00:05:45.000 181 - go the opposite direction. 180 + 00:02:41.840 --> 00:02:42.840 181 + You could argue... 182 182 183 183 46 184 - 00:05:45.000 --> 00:05:47.000 185 - So we started out with live. 184 + 00:02:42.840 --> 00:02:43.920 185 + This will be a popular opinion. 186 186 187 187 47 188 - 00:05:47.000 --> 00:05:49.000 189 - We are pretty happy with that. 188 + 00:02:43.920 --> 00:02:47.680 189 + You could argue video NFTs are kind of like a decentralized VOD, right? 190 190 191 191 48 192 - 00:05:49.000 --> 00:05:51.000 193 - And, you know, knock on wood. 192 + 00:02:47.680 --> 00:02:51.680 193 + You've got an IPFS reference to something that's out there and not controlled by any 194 194 195 195 49 196 - 00:05:51.000 --> 00:05:53.000 197 - Of course, as soon as I walked out of the other room, people 196 + 00:02:51.680 --> 00:02:52.680 197 + one party. 198 198 199 199 50 200 - 00:05:53.000 --> 00:05:55.000 201 - started reporting playback issues over there. 200 + 00:02:52.680 --> 00:02:54.880 201 + Lots of other IPFS based. 202 202 203 203 51 204 - 00:05:55.000 --> 00:05:58.000 205 - But overall, everything has been going really well at all of 204 + 00:02:54.880 --> 00:02:59.640 205 + There's like DAT based livestreaming that maybe falls into that. 206 206 207 207 52 208 - 00:05:58.000 --> 00:05:59.000 209 - this. 208 + 00:02:59.640 --> 00:03:03.160 209 + But for the most part, we needed to invent what a decentralized livestream is. 210 210 211 211 53 212 - 00:05:59.000 --> 00:06:03.000 213 - So I'll start by sort of explaining how stream place, a 212 + 00:03:03.160 --> 00:03:06.200 213 + So what we did was we took... 214 214 215 215 54 216 - 00:06:03.000 --> 00:06:05.000 217 - quick explanation of how stream place live works because I've 216 + 00:03:06.200 --> 00:03:10.080 217 + The first thing that happens is you generate a signing key, same as the one that's used 218 218 219 219 55 220 - 00:06:05.000 --> 00:06:07.000 221 - talked about this a lot before. 220 + 00:03:10.080 --> 00:03:13.800 221 + to secure your app proto repository. 222 222 223 223 56 224 - 00:06:07.000 --> 00:06:10.000 225 - And then we'll talk about how we are adapting that for a 224 + 00:03:13.800 --> 00:03:16.080 225 + We then take that signing key. 226 226 227 227 57 228 - 00:06:10.000 --> 00:06:13.000 229 - decentralized VOD primitive. 228 + 00:03:16.080 --> 00:03:23.360 229 + You then configure your OBS instance, just like we're doing here, to stream in to Streamplace. 230 230 231 231 58 232 - 00:06:13.000 --> 00:06:18.000 233 - What does it mean to have something like, you know, what 232 + 00:03:23.360 --> 00:03:25.160 233 + You actually provide it with that signing key. 234 234 235 235 59 236 - 00:06:18.000 --> 00:06:20.000 237 - would a decentralized YouTube look like? 236 + 00:03:25.160 --> 00:03:27.120 237 + So it has the capability of signing on your behalf. 238 238 239 239 60 240 - 00:06:20.000 --> 00:06:24.000 241 - What things do you need in order to make that happen? 240 + 00:03:27.120 --> 00:03:31.000 241 + If you really care about your key custody, you should run Streamplace locally and then 242 242 243 243 61 244 - 00:06:24.000 --> 00:06:26.000 245 - So, yeah, this is just about stream place. 244 + 00:03:31.000 --> 00:03:34.760 245 + syndicate it out to a server. 246 246 247 247 62 248 - 00:06:26.000 --> 00:06:31.000 249 - There's been three stream place third party clients created 248 + 00:03:34.760 --> 00:03:37.280 249 + Then this is basically every livestream you've ever watched. 250 250 251 251 63 252 - 00:06:31.000 --> 00:06:34.000 253 - since the beginning of this conference. 252 + 00:03:37.280 --> 00:03:42.740 253 + If you haven't messed with video infrastructure before, it's just a bunch of short video files 254 254 255 255 64 256 - 00:06:34.000 --> 00:06:38.000 257 - So I don't know if that reflects poorly on our front end or if 256 + 00:03:42.740 --> 00:03:44.600 257 + that are thrown into your face in sequence. 258 258 259 259 65 260 - 00:06:38.000 --> 00:06:41.000 261 - it just refers to the entrepreneurial spirit of the 260 + 00:03:44.600 --> 00:03:46.940 261 + And it provides the illusion of a livestream. 262 262 263 263 66 264 - 00:06:41.000 --> 00:06:42.000 265 - community. 264 + 00:03:46.940 --> 00:03:48.220 265 + So that's how we do it. 266 266 267 267 67 268 - 00:06:42.000 --> 00:06:47.000 269 - But this one is from Jack.XYZ and it shows all of the streams 268 + 00:03:48.220 --> 00:03:50.660 269 + Each MP4 file comes in. 270 270 271 271 68 272 - 00:06:47.000 --> 00:06:51.000 273 - at once, given the stream place servers, the maximum workout to 272 + 00:03:50.660 --> 00:03:56.220 273 + We give each one of them an embedded signature using technology from the C2PA, the Coalition 274 274 275 275 69 276 - 00:06:51.000 --> 00:06:54.000 277 - give everybody what they're looking for there. 276 + 00:03:56.220 --> 00:03:59.480 277 + for Content Provenance and Authenticity. 278 278 279 279 70 280 - 00:06:54.000 --> 00:06:58.000 281 - Before we do anything else, I found this MP4 file on the 280 + 00:03:59.480 --> 00:04:00.780 281 + Cool format. 282 282 283 283 71 284 - 00:06:58.000 --> 00:06:59.000 285 - ground. 284 + 00:04:00.780 --> 00:04:06.200 285 + It provides a mechanism for giving you an MP4 file that contains an embedded signature 286 286 287 287 72 288 - 00:06:59.000 --> 00:07:05.000 289 - Let's see what it is. 288 + 00:04:06.200 --> 00:04:11.380 289 + over a hash of all of that MP4 file, except for that part of the signature. 290 290 291 291 73 292 - 00:07:05.000 --> 00:07:09.000 293 - You can all imagine the great noises Trabio is making here. 292 + 00:04:11.380 --> 00:04:12.640 293 + That's really tricky to get right. 294 294 295 295 74 296 - 00:07:10.000 --> 00:07:13.000 297 - What's going to happen? 296 + 00:04:12.660 --> 00:04:16.780 297 + And that's one of the things I really like about the C2PA's tooling is you've got this 298 298 299 299 75 300 - 00:07:13.000 --> 00:07:20.000 301 - And wait for it. 300 + 00:04:16.780 --> 00:04:23.540 301 + a lot of decentralized media projects have external signatures. 302 302 303 303 76 304 - 00:07:20.000 --> 00:07:21.000 305 - Yeah, we got them. 304 + 00:04:23.540 --> 00:04:26.780 305 + So you might have this actually including like Blue Sky videos, right? 306 306 307 307 77 308 - 00:07:21.000 --> 00:07:22.000 309 - Yeah. 308 + 00:04:26.780 --> 00:04:28.660 309 + How do you know it's my Blue Sky video? 310 310 311 311 78 312 - 00:07:22.000 --> 00:07:26.000 313 - So that MP4 file I found on the ground turned out to be my 312 + 00:04:28.660 --> 00:04:34.780 313 + It's because there's a blob out there that is referenced by a record in my repository 314 314 315 315 79 316 - 00:07:26.000 --> 00:07:28.000 317 - glorious victory over Trabio. 316 + 00:04:34.780 --> 00:04:37.220 317 + and my repository has a signature on the root commit. 318 318 319 319 80 320 - 00:07:28.000 --> 00:07:30.000 321 - So how do I know that? 320 + 00:04:37.220 --> 00:04:39.300 321 + So that's how you know it's mine, right? 322 322 323 323 81 324 - 00:07:30.000 --> 00:07:34.000 325 - How do I know it's Eli's live stream that happened there? 324 + 00:04:39.320 --> 00:04:44.080 325 + What I like about this format is I can have this is the MP4 file on the ground example 326 326 327 327 82 328 - 00:07:34.000 --> 00:07:39.000 329 - And that has to do with stream places signing format. 328 + 00:04:44.080 --> 00:04:45.080 329 + I just gave, right? 330 330 331 331 83 332 - 00:07:39.000 --> 00:07:44.000 333 - So we needed to, so decentralized VOD is something that's 332 + 00:04:45.080 --> 00:04:49.000 333 + You can have arbitrary MP4 file on your computer and all of that signing and provenance data 334 334 335 335 84 336 - 00:07:44.000 --> 00:07:45.000 337 - kind of existed before, right? 336 + 00:04:49.000 --> 00:04:51.920 337 + is intact and embedded in the MP4 file. 338 338 339 339 85 340 - 00:07:45.000 --> 00:07:48.000 341 - You could argue, this will be a popular opinion, you could argue 340 + 00:04:51.920 --> 00:04:52.920 341 + So I like that a lot. 342 342 343 343 86 344 - 00:07:48.000 --> 00:07:51.000 345 - video NFTs are kind of like a decentralized VOD, right, where 344 + 00:04:52.920 --> 00:04:58.160 345 + It's something we really wanted to preserve as we move from live to VOD. 346 346 347 347 87 348 - 00:07:51.000 --> 00:07:54.000 349 - you've got an IPFS reference to something that's like out there 348 + 00:04:58.160 --> 00:05:00.600 349 + And lots of very cool metadata in here. 350 350 351 351 88 352 - 00:07:54.000 --> 00:07:58.000 353 - and not controlled by any one party, lots of other like IPFS 352 + 00:05:00.600 --> 00:05:02.720 353 + We're not doing too much with this mechanism yet. 354 354 355 355 89 356 - 00:07:58.000 --> 00:08:02.000 357 - based, like there's like DAT based live streaming that maybe 356 + 00:05:02.720 --> 00:05:08.460 357 + I spent a long time talking to Trezi yesterday about embedding this part of the embedded 358 358 359 359 90 360 - 00:08:02.000 --> 00:08:03.000 361 - falls into that. 360 + 00:05:08.480 --> 00:05:10.680 361 + metadata here should be that I'm playing Silksong, right? 362 362 363 363 91 364 - 00:08:03.000 --> 00:08:06.000 365 - But for the most part, we needed to invent what a decentralized 364 + 00:05:10.680 --> 00:05:15.880 365 + And then if you care about Silksong, you can watch that live stream and get that data from 366 366 367 367 92 368 - 00:08:06.000 --> 00:08:07.000 369 - live stream is. 368 + 00:05:15.880 --> 00:05:17.680 369 + like pretty much any direction, right? 370 370 371 371 93 372 - 00:08:07.000 --> 00:08:11.000 373 - So what we did was we took the first thing that happens is you 372 + 00:05:17.680 --> 00:05:22.400 373 + Like you can download it from sketchiest website in the world.ru and still be confident that 374 374 375 375 94 376 - 00:08:11.000 --> 00:08:14.000 377 - generate a signing key, same as the one with kinds that's used 376 + 00:05:22.400 --> 00:05:25.360 377 + you're looking at the right thing, right? 378 378 379 379 95 380 - 00:08:14.000 --> 00:08:17.000 381 - to secure your app proto repository. 380 + 00:05:25.360 --> 00:05:27.360 381 + And then I'm playing Silksong. 382 382 383 383 96 384 - 00:08:17.000 --> 00:08:21.000 385 - We then take that signing key, you then configure your OBS 384 + 00:05:27.360 --> 00:05:31.160 385 + Those, yeah, that's this example. 386 386 387 387 97 388 - 00:08:21.000 --> 00:08:25.000 389 - instance, just like we're doing here to stream in to stream 388 + 00:05:31.160 --> 00:05:34.140 389 + I have, yeah, we've made streamplace as easy to run as possible. 390 390 391 391 98 392 - 00:08:25.000 --> 00:08:26.000 393 - place. 392 + 00:05:34.140 --> 00:05:38.320 393 + So you can run your own streamplace nodes, syndicate my streams. 394 394 395 395 99 396 - 00:08:26.000 --> 00:08:28.000 397 - You actually provide it with that signing key. 396 + 00:05:38.340 --> 00:05:41.700 397 + You get copied over in this sort of trustless, unauthenticated way. 398 398 399 399 100 400 - 00:08:28.000 --> 00:08:30.000 401 - So it has the capability of signing on your behalf. 400 + 00:05:41.700 --> 00:05:43.220 401 + And then you see it over there. 402 402 403 403 101 404 - 00:08:31.000 --> 00:08:33.000 405 - If you really care about your key custody, you should run 404 + 00:05:43.220 --> 00:05:48.980 405 + So the thinking here is we probably won't beat Twitch by making a bigger data center 406 406 407 407 102 408 - 00:08:33.000 --> 00:08:36.000 409 - stream place locally and then syndicate it out to a server. 408 + 00:05:48.980 --> 00:05:51.540 409 + or buying more bandwidth than Amazon. 410 410 411 411 103 412 - 00:08:38.000 --> 00:08:41.000 413 - Then this is basically every live stream you've ever watched. 412 + 00:05:51.540 --> 00:05:55.340 413 + But we might be able to beat them by following the example of BitTorrent, right? 414 414 415 415 104 416 - 00:08:41.000 --> 00:08:44.000 417 - If you haven't messed with video infrastructure before is just a 416 + 00:05:55.340 --> 00:05:59.220 417 + You can have lots of decentralized infrastructure that's replicating all of this, but through 418 418 419 419 105 420 - 00:08:44.000 --> 00:08:48.000 421 - bunch of short video files that are thrown into your face in 420 + 00:05:59.220 --> 00:06:02.500 421 + the magic of digital signatures, you know that the video is authentic. 422 422 423 423 106 424 - 00:08:48.000 --> 00:08:50.000 425 - sequence and it provides the illusion of a live stream. 424 + 00:06:02.500 --> 00:06:07.100 425 + So what's the problem? 426 426 427 427 107 428 - 00:08:50.000 --> 00:08:51.000 429 - So that's how we do it. 428 + 00:06:07.100 --> 00:06:09.240 429 + This isn't very convenient. 430 430 431 431 108 432 - 00:08:51.000 --> 00:08:54.000 433 - Each MP4 file comes in. 432 + 00:06:09.240 --> 00:06:13.360 433 + So when I say slice the video up into one second MP4 files, I'm being very literal about 434 434 435 435 109 436 - 00:08:54.000 --> 00:08:57.000 437 - We give each one of them an embedded signature using 436 + 00:06:13.360 --> 00:06:14.360 437 + that. 438 438 439 439 110 440 - 00:08:57.000 --> 00:09:00.000 441 - technology from the C2PA, the Coalition for Content 440 + 00:06:14.360 --> 00:06:17.440 441 + If you run streamplace on your computer, you can navigate to this and see lots and lots 442 442 443 443 111 444 - 00:09:00.000 --> 00:09:02.000 445 - Provenance and Authenticity. 444 + 00:06:17.440 --> 00:06:20.080 445 + and lots of one second MP4 files. 446 446 447 447 112 448 - 00:09:02.000 --> 00:09:03.000 449 - Cool format. 448 + 00:06:20.080 --> 00:06:22.600 449 + And when the computer is processing them all and feeding to you as a live stream, that's 450 450 451 451 113 452 - 00:09:03.000 --> 00:09:07.000 453 - It provides a mechanism for giving you an MP4 file that 452 + 00:06:22.600 --> 00:06:23.600 453 + okay. 454 454 455 455 114 456 - 00:09:07.000 --> 00:09:12.000 457 - contains an embedded signature over a hash of all of that MP4 456 + 00:06:23.600 --> 00:06:27.440 457 + Afterward, when you want to work with this as a VOD, it's a pain in the ass. 458 458 459 459 115 460 - 00:09:12.000 --> 00:09:14.000 461 - file except for that part of the signature. 460 + 00:06:27.440 --> 00:06:34.480 461 + So we wanted, this was one of the design goals of VOD for us is how do we handle that? 462 462 463 463 116 464 - 00:09:14.000 --> 00:09:16.000 465 - That's really tricky to get right. 464 + 00:06:34.480 --> 00:06:39.920 465 + And unfortunately, because we used regular MP4 files, they're non-concatenatable. 466 466 467 467 117 468 - 00:09:16.000 --> 00:09:19.000 469 - One of the things I really like about the C2PA's tooling is 468 + 00:06:39.920 --> 00:06:45.560 469 + You can't take two MP4 files, squish all the bytes together and get valid output, right? 470 470 471 471 118 472 - 00:09:19.000 --> 00:09:25.000 473 - you've got this, a lot of decentralized media projects have 472 + 00:06:45.560 --> 00:06:47.900 473 + That's just not MP4 works. 474 474 475 475 119 476 - 00:09:26.000 --> 00:09:27.000 477 - external signatures. 476 + 00:06:47.900 --> 00:06:49.980 477 + It's not valid data there. 478 478 479 479 120 480 - 00:09:27.000 --> 00:09:30.000 481 - So you might have this actually including Bluesky videos. 480 + 00:06:49.980 --> 00:06:55.260 481 + So you'd have to mux it and the signature that you get there wouldn't match the input. 482 482 483 483 121 484 - 00:09:30.000 --> 00:09:32.000 485 - How do you know it's my Bluesky video? 484 + 00:06:55.260 --> 00:06:58.900 485 + And all of a sudden you've broken this entire cool BitTorrent deprovenance mechanism that 486 486 487 487 122 488 - 00:09:32.000 --> 00:09:37.000 489 - It's because there's a blob out there that is referenced by a 488 + 00:06:58.900 --> 00:07:01.940 489 + I was just describing. 490 490 491 491 123 492 - 00:09:37.000 --> 00:09:40.000 493 - record in my repository and my repository has a signature on 492 + 00:07:01.940 --> 00:07:09.560 493 + So this is the other reason we were already looking at forking C2PA. 494 494 495 495 124 496 - 00:09:40.000 --> 00:09:41.000 497 - the root commit. 496 + 00:07:09.560 --> 00:07:13.960 497 + So here we have a list of signing algorithms. 498 498 499 499 125 500 - 00:09:41.000 --> 00:09:42.000 501 - So that's how you know it's mine. 500 + 00:07:13.960 --> 00:07:25.680 501 + As you can see here, we have the good and virtuous ECDSA signature over a SHA256 hash 502 502 503 503 126 504 - 00:09:42.000 --> 00:09:46.000 505 - What I like about this format is I can have this is the MP4 504 + 00:07:25.680 --> 00:07:37.820 505 + over the P256 curve, but not over the SCCP256K1 curve, the evil shady curve that's used inside 506 506 507 507 127 508 - 00:09:46.000 --> 00:09:48.000 509 - file on the ground example I just gave. 508 + 00:07:37.820 --> 00:07:41.080 509 + BitTorrent and Ethereum and AppProto. 510 510 511 511 128 512 - 00:09:48.000 --> 00:09:51.000 513 - You can have arbitrary MP4 file on your computer and all of 512 + 00:07:41.080 --> 00:07:48.340 513 + So I think my theory here is that somebody in Adobe had to sell some exec that they weren't 514 514 515 515 129 516 - 00:09:51.000 --> 00:09:54.000 517 - that signing and provenance data is intact and embedded in the 516 + 00:07:48.340 --> 00:07:49.940 517 + making blockchain software here. 518 518 519 519 130 520 - 00:09:54.000 --> 00:09:55.000 521 - MP4 file. 520 + 00:07:49.940 --> 00:07:51.800 521 + So we didn't do that kind of signing. 522 522 523 523 131 524 - 00:09:55.000 --> 00:09:56.000 525 - So I like that a lot. 524 + 00:07:51.800 --> 00:07:53.020 525 + We only did this kind of signing. 526 526 527 527 132 528 - 00:09:56.000 --> 00:09:58.000 529 - It's something we really wanted to preserve as we moved from 528 + 00:07:53.020 --> 00:07:58.120 529 + So technically for as long as streamplace has existed, it hasn't been C2PA compatible. 530 530 531 531 133 532 - 00:09:58.000 --> 00:09:59.000 533 - live to VOD. 532 + 00:07:58.120 --> 00:08:00.940 533 + And I had been looking for a while to formalize that. 534 534 535 535 134 536 - 00:09:59.000 --> 00:10:02.000 537 - And lots of very cool metadata in here. 536 + 00:08:00.940 --> 00:08:04.920 537 + So oh, yeah, this is the other. 538 538 539 539 135 540 - 00:10:02.000 --> 00:10:04.000 541 - We're not doing too much with this mechanism yet. 540 + 00:08:04.920 --> 00:08:07.960 541 + So this is the other. 542 542 543 543 136 544 - 00:10:04.000 --> 00:10:09.000 545 - I spent a long time talking to Trezi yesterday about embedding 544 + 00:08:07.960 --> 00:08:13.760 545 + So Adobe is out there right now lobbying, especially European governments and the state 546 546 547 547 137 548 - 00:10:09.000 --> 00:10:13.000 549 - this part of the embedded metadata here should be that I'm 548 + 00:08:13.760 --> 00:08:20.680 549 + of California to require provenance data on everything that you post on social media. 550 550 551 551 138 552 - 00:10:13.000 --> 00:10:14.000 553 - playing Silk Song, right? 552 + 00:08:20.680 --> 00:08:24.200 553 + This is the reason for the C2PA's existence, getting us ready for a world filled with deep 554 554 555 555 139 556 - 00:10:14.000 --> 00:10:16.000 557 - And then if you care about Silk Song, you can watch that 556 + 00:08:24.200 --> 00:08:25.200 557 + takes. 558 558 559 559 140 560 - 00:10:16.000 --> 00:10:19.000 561 - livestream and get that data from like pretty much any 560 + 00:08:25.200 --> 00:08:29.140 561 + This is not inherently a bad idea. 562 562 563 563 141 564 - 00:10:19.000 --> 00:10:20.000 565 - direction, right? 564 + 00:08:29.140 --> 00:08:32.880 565 + Once anybody can deep fake anything, how do you ever trust what you're looking at? 566 566 567 567 142 568 - 00:10:20.000 --> 00:10:23.000 569 - Like you can download it from sketchiest website in the world 568 + 00:08:32.880 --> 00:08:35.460 569 + No one technical mechanism can solve that problem. 570 570 571 571 143 572 - 00:10:23.000 --> 00:10:26.000 573 - .ru and still be confident that you're looking at the right 572 + 00:08:35.460 --> 00:08:40.020 573 + But one way you could be more confident is if there was provenance data embedded in the 574 574 575 575 144 576 - 00:10:26.000 --> 00:10:27.000 577 - thing. 576 + 00:08:40.020 --> 00:08:43.620 577 + live stream, where it says, oh, this video is taken from Eli's camera and then edited 578 578 579 579 145 580 - 00:10:27.000 --> 00:10:29.000 581 - And then I'm playing Silk Song. 580 + 00:08:43.620 --> 00:08:48.160 581 + using this software and makes its way everywhere. 582 582 583 583 146 584 - 00:10:29.000 --> 00:10:32.000 585 - Those, yeah, that's this example. 584 + 00:08:48.280 --> 00:08:51.320 585 + The reason Adobe is doing this lobbying is because they want to try and do some regulatory 586 586 587 587 147 588 - 00:10:32.000 --> 00:10:35.000 589 - I have, yeah, we've made streamplace as easy to run as 588 + 00:08:51.320 --> 00:08:52.320 589 + capture. 590 590 591 591 148 592 - 00:10:35.000 --> 00:10:36.000 593 - possible. 592 + 00:08:52.320 --> 00:08:57.360 593 + So they want to sell governments, these expensive Creative Cloud subscriptions, and be the only 594 594 595 595 149 596 - 00:10:36.000 --> 00:10:39.000 597 - So you can run your own streamplace nodes, syndicate my 596 + 00:08:57.360 --> 00:09:01.920 597 + software that you could possibly use in order to do all of that stuff. 598 598 599 599 150 600 - 00:10:39.000 --> 00:10:40.000 601 - streams. 600 + 00:09:01.920 --> 00:09:07.760 601 + Also the part I think is really funny is they want you to go pay a CA, like $107 a month 602 602 603 603 151 604 - 00:10:40.000 --> 00:10:43.000 605 - They get copied over in this sort of trustless, unauthenticated 604 + 00:09:07.760 --> 00:09:10.440 605 + for a signing certificate. 606 606 607 607 152 608 - 00:10:43.000 --> 00:10:44.000 609 - way. 608 + 00:09:10.440 --> 00:09:12.240 609 + Let's encrypt and everything never happened. 610 610 611 611 153 612 - 00:10:44.000 --> 00:10:45.000 613 - And then you see it over there. 612 + 00:09:12.920 --> 00:09:18.320 613 + Of course, in the app proto and decentralized web communities, we have DIDs and totally other 614 614 615 615 154 616 - 00:10:45.000 --> 00:10:50.000 617 - So the thinking here is we probably won't beat Twitch by 616 + 00:09:18.320 --> 00:09:23.480 617 + stacks of how we would handle some of this stuff. 618 618 619 619 155 620 - 00:10:50.000 --> 00:10:53.000 621 - making a bigger data center or buying more bandwidth than 620 + 00:09:23.480 --> 00:09:27.360 621 + How we would handle key custody, how we would handle authenticity, that kind of thing. 622 622 623 623 156 624 - 00:10:53.000 --> 00:10:54.000 625 - Amazon. 624 + 00:09:27.360 --> 00:09:33.040 625 + PLC directories got its own take on everything. 626 626 627 627 157 628 - 00:10:54.000 --> 00:10:56.000 629 - But we might be able to beat them by following the example of 628 + 00:09:33.040 --> 00:09:39.120 629 + Some good ideas need to be modernized and not try and pay these vendors a bunch of money 630 630 631 631 158 632 - 00:10:56.000 --> 00:10:57.000 633 - BitTorrent, right? 632 + 00:09:39.120 --> 00:09:41.640 633 + for certificates. 634 634 635 635 159 636 - 00:10:57.000 --> 00:11:00.000 637 - That you can have lots of decentralized infrastructure 636 + 00:09:41.720 --> 00:09:48.160 637 + I said all of these things out loud a lot and the good folks at the IPFS Foundation 638 638 639 639 160 640 - 00:11:00.000 --> 00:11:02.000 641 - that's replicating all of this, but through the magic of 640 + 00:09:48.160 --> 00:09:50.960 641 + and the DASL project were very, very receptive to it. 642 642 643 643 161 644 - 00:11:02.000 --> 00:11:07.000 645 - digital signatures, you know that the video is authentic. 644 + 00:09:50.960 --> 00:09:53.240 645 + So they've given us a grant. 646 646 647 647 162 648 - 00:11:07.000 --> 00:11:08.000 649 - So what's the problem? 648 + 00:09:53.240 --> 00:09:59.040 649 + Everything you see past this point in the presentation is a result of the grant that 650 650 651 651 163 652 - 00:11:08.000 --> 00:11:11.000 653 - This isn't very convenient. 652 + 00:09:59.040 --> 00:10:01.800 653 + we got from the IPFS Foundation. 654 654 655 655 164 656 - 00:11:11.000 --> 00:11:14.000 657 - So when I say slice the video up into one second MP4 files, I'm 656 + 00:10:01.800 --> 00:10:07.880 657 + So we're working on two specs with them, Stupa and Muxal. 658 658 659 659 165 660 - 00:11:14.000 --> 00:11:15.000 661 - being very literal about that. 660 + 00:10:07.880 --> 00:10:10.960 661 + Stupa is the simple standard for provenance and authenticity. 662 662 663 663 166 664 - 00:11:15.000 --> 00:11:17.000 665 - If you run streamplace on your computer, you can navigate to 664 + 00:10:10.960 --> 00:10:13.160 665 + This is the simpler of the two standards. 666 666 667 667 167 668 - 00:11:17.000 --> 00:11:18.000 669 - this. 668 + 00:10:13.160 --> 00:10:14.480 669 + It's very much, thank you, Ted. 670 670 671 671 168 672 - 00:11:18.000 --> 00:11:21.000 673 - And see lots and lots and lots of one second MP4 files. 672 + 00:10:14.480 --> 00:10:15.480 673 + Look at that. 674 674 675 675 169 676 - 00:11:21.000 --> 00:11:24.000 677 - And when the computer is processing them all and feeding 676 + 00:10:15.480 --> 00:10:16.760 677 + Ted got me a glass of water. 678 678 679 679 170 680 - 00:11:24.000 --> 00:11:26.000 681 - them to you as a live stream, that's okay. 680 + 00:10:16.760 --> 00:10:17.760 681 + Everybody thank Ted. 682 682 683 683 171 684 - 00:11:26.000 --> 00:11:28.000 685 - Afterward when you want to work with this as a VOD, it's a pain 684 + 00:10:17.760 --> 00:10:19.760 685 + That was awesome. 686 686 687 687 172 688 - 00:11:28.000 --> 00:11:29.000 689 - in the ass. 688 + 00:10:23.280 --> 00:10:29.280 689 + Stupa is our, I don't know what makes a fork a hostile fork, but it's definitely a fork 690 690 691 691 173 692 - 00:11:29.000 --> 00:11:33.000 693 - So we wanted, this is one of the design goals of VOD for us, is 692 + 00:10:29.280 --> 00:10:32.760 693 + of the C2PA that takes out all the things. 694 694 695 695 174 696 - 00:11:33.000 --> 00:11:35.000 697 - how do we handle that? 696 + 00:10:32.760 --> 00:10:34.400 697 + It doesn't really, it actually doesn't take out anything. 698 698 699 699 175 700 - 00:11:35.000 --> 00:11:39.000 701 - And unfortunately, because we used regular MP4 files, they're 700 + 00:10:34.400 --> 00:10:38.080 701 + Like if you want to pay DID just start at 200 bucks a month, you totally can. 702 702 703 703 176 704 - 00:11:39.000 --> 00:11:40.000 705 - non-concatenatable. 704 + 00:10:38.080 --> 00:10:39.920 705 + But we have some different opinions about that. 706 706 707 707 177 708 - 00:11:40.000 --> 00:11:44.000 709 - You can't take two MP4 files, squish all the bytes together, and 708 + 00:10:39.920 --> 00:10:40.920 709 + We have DIDS, right? 710 710 711 711 178 712 - 00:11:44.000 --> 00:11:47.000 713 - get very, very, very close to the end of the stream. 712 + 00:10:40.920 --> 00:10:47.120 713 + So instead of signing it with some cert that you're given by a CA, you sign it with a signing 714 714 715 715 179 716 - 00:11:47.000 --> 00:11:49.000 717 - And get valid output. 716 + 00:10:47.120 --> 00:10:53.200 717 + key that has a provenance chain back to your at-proto identity, right? 718 718 719 719 180 720 - 00:11:49.000 --> 00:11:50.000 721 - Right? 720 + 00:10:53.200 --> 00:11:00.240 721 + And then we also make it consistent with DASL, the C2PA signatures, C2PA manifests rather 722 722 723 723 181 724 - 00:11:50.000 --> 00:11:51.000 725 - That's just not MP4 works. 724 + 00:11:00.240 --> 00:11:01.800 725 + already use Seaboard. 726 726 727 727 182 728 - 00:11:51.000 --> 00:11:53.000 729 - It's not valid data there. 728 + 00:11:01.800 --> 00:11:06.640 729 + So we're just upgrading it to use Drizzle, Drizzle DASLs. 730 730 731 731 183 732 - 00:11:53.000 --> 00:11:56.000 733 - So you'd have to mux it and the signature that you get there 732 + 00:11:06.640 --> 00:11:10.240 733 + Very strict subset of Seaboard used in at-proto, right? 734 734 735 735 184 736 - 00:11:56.000 --> 00:11:59.000 737 - wouldn't match the input. 736 + 00:11:10.240 --> 00:11:11.240 737 + That's Stupa. 738 738 739 739 185 740 - 00:11:59.000 --> 00:12:02.000 741 - And all of a sudden you've broken this entire cool bit torrenty 740 + 00:11:11.240 --> 00:11:12.240 741 + That's all of Stupa. 742 742 743 743 186 744 - 00:12:02.000 --> 00:12:05.000 745 - provenance mechanism that I was just describing. 744 + 00:11:12.240 --> 00:11:14.140 745 + The rest of the presentation is about Muxill because it's way more complicated. 746 746 747 747 187 748 - 00:12:05.000 --> 00:12:12.000 749 - So this is the other reason we were already looking at forking 748 + 00:11:14.140 --> 00:11:16.920 749 + This is just a little change that we're making here. 750 750 751 751 188 752 - 00:12:12.000 --> 00:12:13.000 753 - C2PA. 752 + 00:11:16.920 --> 00:11:18.080 753 + Would love if they upstreamed it. 754 754 755 755 189 756 - 00:12:13.000 --> 00:12:17.000 757 - So here we have a list of signing algorithms. 756 + 00:11:18.080 --> 00:11:25.920 757 + Would love if there were DIDS and K256 signing in C2PA. 758 758 759 759 190 760 - 00:12:17.000 --> 00:12:24.000 761 - As you can see here, we have the good and virtuous ECDSA 760 + 00:11:25.920 --> 00:11:29.920 761 + So let's talk about the design goals for Muxill. 762 762 763 763 191 764 - 00:12:24.000 --> 00:12:35.000 765 - signature over a SHA256 hash over the P256 curve, but not over 764 + 00:11:29.920 --> 00:11:33.960 765 + This is basically what changes do we need to make to those MP4 files that I described 766 766 767 767 192 768 - 00:12:35.000 --> 00:12:41.000 769 - the SCCP256K1 curve, the evil shady curve that's used inside 768 + 00:11:33.960 --> 00:11:37.840 769 + before in order to make them appropriate for VOD. 770 770 771 771 193 772 - 00:12:41.000 --> 00:12:43.000 773 - BitTorrent and Ethereum and AppProto. 772 + 00:11:37.840 --> 00:11:41.800 773 + So you don't have thousands and thousands of MP4 files on your computer after a long 774 774 775 775 194 776 - 00:12:43.000 --> 00:12:44.000 777 - Right? 776 + 00:11:41.800 --> 00:11:43.400 777 + livestream. 778 778 779 779 195 780 - 00:12:44.000 --> 00:12:49.000 781 - So I think my theory here is that somebody in Adobe had to 780 + 00:11:43.400 --> 00:11:46.840 781 + So we want to keep the property that they're self-certifying. 782 782 783 783 196 784 - 00:12:49.000 --> 00:12:53.000 785 - sell some exec that they weren't making blockchain software here 784 + 00:11:46.840 --> 00:11:50.920 785 + It's awesome that you can just find one of these files and then go verify its provenance 786 786 787 787 197 788 - 00:12:53.000 --> 00:12:55.000 789 - so we didn't do that kind of signing. 788 + 00:11:50.920 --> 00:11:51.920 789 + chain. 790 790 791 791 198 792 - 00:12:55.000 --> 00:12:57.000 793 - We only did this kind of signing. 792 + 00:11:51.920 --> 00:11:55.780 793 + It shouldn't be, you shouldn't require external data, right? 794 794 795 795 199 796 - 00:12:57.000 --> 00:12:59.000 797 - So technically for as long as streamplace has existed, it 796 + 00:11:55.780 --> 00:12:01.240 797 + As a design goal, we want to support livestream to VOD so that what video engineers call DVR, 798 798 799 799 200 800 - 00:12:59.000 --> 00:13:01.000 801 - hasn't been C2PA compatible. 800 + 00:12:01.240 --> 00:12:05.040 801 + if you're watching a livestream, that you can seek back and see what happened one minute 802 802 803 803 201 804 - 00:13:01.000 --> 00:13:04.000 805 - And I had been looking for a while to formalize that. 804 + 00:12:05.040 --> 00:12:08.400 805 + ago, two minutes ago, three minutes ago, that kind of thing. 806 806 807 807 202 808 - 00:13:04.000 --> 00:13:08.000 809 - So, oh, yeah, this is the other. 808 + 00:12:08.400 --> 00:12:10.160 809 + It would be nice if it's a useful format. 810 810 811 811 203 812 - 00:13:08.000 --> 00:13:11.000 813 - So this is the other. 812 + 00:12:10.160 --> 00:12:13.240 813 + I don't want to give you some opaque seaboard blob or something. 814 814 815 815 204 816 - 00:13:11.000 --> 00:13:15.000 817 - So Adobe is out there right now lobbying especially European 816 + 00:12:13.240 --> 00:12:18.080 817 + A design goal of this is that at the end of it, you have, at the end of a 24-hour livestream, 818 818 819 819 205 820 - 00:13:15.000 --> 00:13:21.000 821 - governments and the state of California to require provenance 820 + 00:12:18.080 --> 00:12:21.840 821 + you should have a 24-hour MP4 file on your computer. 822 822 823 823 206 824 - 00:13:21.000 --> 00:13:24.000 825 - data on everything that you post on social media. 824 + 00:12:21.840 --> 00:12:25.840 825 + Easiest to work with, maximally compatible, preserves all of the provenance information 826 826 827 827 207 828 - 00:13:24.000 --> 00:13:27.000 829 - This is the reason for the C2PA's existence, getting us ready for 828 + 00:12:25.840 --> 00:12:28.040 829 + I was describing. 830 830 831 831 208 832 - 00:13:27.000 --> 00:13:28.000 833 - a world filled with deep cakes. 832 + 00:12:28.040 --> 00:12:31.040 833 + And it should be streamable with minimal overhead. 834 834 835 835 209 836 - 00:13:28.000 --> 00:13:31.000 837 - This is not inherently a bad idea. 836 + 00:12:31.040 --> 00:12:34.720 837 + I'm not going to get too deep into media over quick in this presentation, though I 838 838 839 839 210 840 - 00:13:31.000 --> 00:13:35.000 841 - You know, once anybody can deep fake anything, how do you ever 840 + 00:12:34.720 --> 00:12:36.400 841 + would love to. 842 842 843 843 211 844 - 00:13:35.000 --> 00:13:36.000 845 - trust what you're looking at? 844 + 00:12:36.400 --> 00:12:45.720 845 + But basically, we don't want to do a bunch of extra effort to go from the canonical format 846 846 847 847 212 848 - 00:13:36.000 --> 00:13:39.000 849 - No one technical mechanism can solve that problem. 848 + 00:12:45.720 --> 00:12:49.680 849 + that we're going to use for all of this to actually streaming it to users. 850 850 851 851 213 852 - 00:13:39.000 --> 00:13:42.000 853 - But one way you could be more confident is if there was 852 + 00:12:49.680 --> 00:12:52.800 853 + We shouldn't need to re-encode or anything like that. 854 854 855 855 214 856 - 00:13:42.000 --> 00:13:45.000 857 - provenance data embedded in the live stream where it says, oh, 856 + 00:12:52.800 --> 00:12:57.920 857 + Unfortunately, that is an impossible series of constraints. 858 858 859 859 215 860 - 00:13:45.000 --> 00:13:48.000 861 - this video is taken from Eli's camera and then edited using 860 + 00:12:57.920 --> 00:13:02.560 861 + Fundamentally, the reason being that if the output is going to be just an MP4 file on 862 862 863 863 216 864 - 00:13:48.000 --> 00:13:51.000 865 - this software and makes its way everywhere. 864 + 00:13:02.560 --> 00:13:06.640 865 + your computer, that is completely different than the format the media over quick uses 866 866 867 867 217 868 - 00:13:51.000 --> 00:13:54.000 869 - But the reason Adobe is doing this lobbying is because they 868 + 00:13:06.640 --> 00:13:11.240 869 + that's going to be useful for sending things to users, in particular with things like multiple 870 870 871 871 218 872 - 00:13:54.000 --> 00:13:56.000 873 - want to try and do some regulatory capture. 872 + 00:13:11.240 --> 00:13:12.240 873 + tracks. 874 874 875 875 219 876 - 00:13:56.000 --> 00:13:58.000 877 - So they want to sell governments, these expensive 876 + 00:13:12.240 --> 00:13:20.000 877 + We really want to do multi-track video, multi-track audio, 720p, a bunch of other 1080p, different 878 878 879 879 220 880 - 00:13:58.000 --> 00:14:01.000 881 - Creative Cloud subscriptions and be like the only software that 880 + 00:13:20.000 --> 00:13:22.800 881 + audio formats, AAC and Opus for different things. 882 882 883 883 221 884 - 00:14:01.000 --> 00:14:05.000 885 - you could possibly use in order to do all of that stuff. 884 + 00:13:22.800 --> 00:13:27.320 885 + All of that complexity we would like to be able to package in this one file, and that 886 886 887 887 222 888 - 00:14:05.000 --> 00:14:08.000 889 - Also, the part I think is really funny is they want you to go 888 + 00:13:27.320 --> 00:13:31.000 889 + skyrockets the bandwidth that you would use to send it out to people. 890 890 891 891 223 892 - 00:14:08.000 --> 00:14:13.000 893 - pay like a CA, like $107 a month for a signing certificate. 892 + 00:13:31.000 --> 00:13:34.440 893 + You don't want to send them every rendition, you want to send them just one. 894 894 895 895 224 896 - 00:14:13.000 --> 00:14:16.000 897 - Like, let's encrypt and everything never happened. 896 + 00:13:34.440 --> 00:13:37.800 897 + So, how do we get around that? 898 898 899 899 225 900 - 00:14:16.000 --> 00:14:19.000 901 - And of course, like the app proto and decentralized web 900 + 00:13:37.800 --> 00:13:39.280 901 + And the answer is we mux. 902 902 903 903 226 904 - 00:14:19.000 --> 00:14:23.000 905 - communities, we have, you know, DIDS and totally other stacks of 904 + 00:13:39.280 --> 00:13:42.640 905 + This is why it's called muxle. 906 906 907 907 227 908 - 00:14:23.000 --> 00:14:26.000 909 - how we would handle some of this stuff, right? 908 + 00:13:42.640 --> 00:13:51.240 909 + So, the key insight here is that the archival format, so this is to say the MP4 file on 910 910 911 911 228 912 - 00:14:26.000 --> 00:14:29.000 913 - How we would handle key custody, how we would handle 912 + 00:13:51.240 --> 00:13:57.080 913 + your computer, the streaming format, which is the format the video is in when it goes 914 914 915 915 229 916 - 00:14:29.000 --> 00:14:31.000 917 - authenticity, that kind of thing. 916 + 00:13:57.080 --> 00:14:03.840 917 + over media over quick, and streams to a user, and the self-certifying format that has this 918 918 919 919 230 920 - 00:14:31.000 --> 00:14:34.000 921 - PLC directories got its own sort of take on everything. 920 + 00:14:03.840 --> 00:14:08.280 921 + intact signature that you use to validate that the media is who it says it is and get 922 922 923 923 231 924 - 00:14:34.000 --> 00:14:40.000 925 - So, yeah, some good ideas needs to be modernized and not try 924 + 00:14:08.280 --> 00:14:15.880 925 + all the nice metadata, they don't all have to be the same format. 926 926 927 927 232 928 - 00:14:40.000 --> 00:14:44.000 929 - and pay these vendors a bunch of money for certificates. 928 + 00:14:15.880 --> 00:14:20.840 929 + As long as we can deterministically mux between them. 930 930 931 931 233 932 - 00:14:44.000 --> 00:14:50.000 933 - So I said all of these things out loud a lot and the folks, 932 + 00:14:20.840 --> 00:14:24.360 933 + As long as if you have one of these formats, there is a deterministic algorithm you can 934 934 935 935 234 936 - 00:14:50.000 --> 00:14:53.000 937 - the good folks at the IPFS Foundation and the DASL project 936 + 00:14:24.360 --> 00:14:28.120 937 + use to turn it into any one of these other formats. 938 938 939 939 235 940 - 00:14:53.000 --> 00:14:54.000 941 - were very, very receptive to it. 940 + 00:14:28.120 --> 00:14:31.320 941 + So we've accomplished this with Wasm, primarily. 942 942 943 943 236 944 - 00:14:54.000 --> 00:14:56.000 945 - So they've given us a grant. 944 + 00:14:31.320 --> 00:14:35.440 945 + Wasm, especially the latest version of Wasm, has a fully deterministic profile. 946 946 947 947 237 948 - 00:14:56.000 --> 00:14:59.000 949 - Everything you see so far, everything you see past this 948 + 00:14:35.440 --> 00:14:40.960 949 + Even short of that, you know, Rust compiled to Wasm and then you pipe some bytes through 950 950 951 951 238 952 - 00:14:59.000 --> 00:15:03.000 953 - point in the presentation is a result of the grant that we got 952 + 00:14:40.960 --> 00:14:44.960 953 + it, you're very, very likely to get the same bytes out through the output, right? 954 954 955 955 239 956 - 00:15:03.000 --> 00:15:05.000 957 - from the IPFS Foundation. 956 + 00:14:44.960 --> 00:14:51.280 957 + So this is, yeah, so let's get into the different formats that we're using inside of here. 958 958 959 959 240 960 - 00:15:05.000 --> 00:15:11.000 961 - So we're working on two specs with them, Stupa and Muxal. 960 + 00:14:51.280 --> 00:14:55.600 961 + I'm going to get deep into MP4 file specifics. 962 962 963 963 241 964 - 00:15:11.000 --> 00:15:14.000 965 - Stupa is the simple standard for provenance and authenticity. 964 + 00:14:55.600 --> 00:15:00.520 965 + I wouldn't wish this upon anyone having to dive this deep into the MP4 specs. 966 966 967 967 242 968 - 00:15:14.000 --> 00:15:16.000 969 - This is the simpler of the two standards. 968 + 00:15:00.520 --> 00:15:06.160 969 + I had to pay $300 for a PDF file. 970 970 971 971 243 972 - 00:15:16.000 --> 00:15:17.000 973 - It's very much. 972 + 00:15:06.160 --> 00:15:09.400 973 + So yes, this is the whole point of StreamPlaces. 974 974 975 975 244 976 - 00:15:17.000 --> 00:15:18.000 977 - Thank you, Ted. 976 + 00:15:09.400 --> 00:15:14.920 977 + These are the hard work we do, the hard problems we solve, so none of you have to, right? 978 978 979 979 245 980 - 00:15:18.000 --> 00:15:19.000 981 - Look at that. 980 + 00:15:15.840 --> 00:15:22.280 981 + So we, the base primitives here that are part of Muxle. 982 982 983 983 246 984 - 00:15:19.000 --> 00:15:20.000 985 - Ted got me a glass of water. 984 + 00:15:22.280 --> 00:15:25.880 985 + First we have video metadata. 986 986 987 987 247 988 - 00:15:20.000 --> 00:15:21.000 989 - Everybody thank Ted. 988 + 00:15:25.880 --> 00:15:31.820 989 + I borrow a lot of this terminology from a spec called Hang that's from Luke Curley who 990 990 991 991 248 992 - 00:15:21.000 --> 00:15:22.000 993 - That was awesome. 992 + 00:15:31.820 --> 00:15:35.840 993 + created the media over QuickSpec. 994 994 995 995 249 996 - 00:15:22.000 --> 00:15:31.000 997 - Stupa is our, I don't know what makes a fork a hostile fork, 996 + 00:15:35.840 --> 00:15:40.920 997 + This is, catalog is his term for this, but this is all of the metadata that you need 998 998 999 999 250 1000 - 00:15:31.000 --> 00:15:35.000 1001 - but it's definitely a fork of the C2PA that takes out all the 1000 + 00:15:40.920 --> 00:15:41.920 1001 + to understand the video. 1002 1002 1003 1003 251 1004 - 00:15:35.000 --> 00:15:36.000 1005 - things. 1004 + 00:15:41.920 --> 00:15:46.160 1005 + I can't just, video decoders won't just accept some random video bytes. 1006 1006 1007 1007 252 1008 - 00:15:36.000 --> 00:15:38.000 1009 - It doesn't really, it actually doesn't take out anything. 1008 + 00:15:46.160 --> 00:15:52.360 1009 + You have to say, no, these video bytes are, for example, 1920 by 1080 at 60 FPS. 1010 1010 1011 1011 253 1012 - 00:15:38.000 --> 00:15:40.000 1013 - Like if you want to pay to just start at 200 bucks a month, 1012 + 00:15:52.360 --> 00:15:57.320 1013 + You've got the time scale and then a canonical track ID for everything that goes into this, 1014 1014 1015 1015 254 1016 - 00:15:40.000 --> 00:15:41.000 1017 - you totally can. 1016 + 00:15:57.320 --> 00:15:58.320 1017 + right? 1018 1018 1019 1019 255 1020 - 00:15:41.000 --> 00:15:43.000 1021 - But we have some different opinions about that. 1020 + 00:15:58.320 --> 00:15:59.320 1021 + How many channels is the audio? 1022 1022 1023 1023 256 1024 - 00:15:43.000 --> 00:15:44.000 1025 - We have dids, right? 1024 + 00:15:59.320 --> 00:16:02.080 1025 + I don't know if it's listed in here, but this would have stuff like what language is the 1026 1026 1027 1027 257 1028 - 00:15:44.000 --> 00:15:48.000 1029 - So instead of signing it with some cert that you're given by 1028 + 00:16:02.080 --> 00:16:03.080 1029 + audio. 1030 1030 1031 1031 258 1032 - 00:15:48.000 --> 00:15:53.000 1033 - a CA, you sign it with a signing key that has a provenance 1032 + 00:16:03.080 --> 00:16:06.200 1033 + If we've got the audio translated into several different languages, that would be included 1034 1034 1035 1035 259 1036 - 00:15:53.000 --> 00:15:56.000 1037 - chain back to your at-proto identity, right? 1036 + 00:16:06.200 --> 00:16:07.520 1037 + in this metadata. 1038 1038 1039 1039 260 1040 - 00:15:56.000 --> 00:16:00.000 1041 - And then we also make it consistent with DASL. 1040 + 00:16:07.520 --> 00:16:14.320 1041 + This is nice to separate out because from a low latency transmission perspective, you 1042 1042 1043 1043 261 1044 - 00:16:00.000 --> 00:16:05.000 1045 - The C2PA signatures, C2PA manifests rather already use Seabour. 1044 + 00:16:14.320 --> 00:16:15.880 1045 + don't want to repeat this stuff, right? 1046 1046 1047 1047 262 1048 - 00:16:05.000 --> 00:16:10.000 1049 - So we're just upgrading it to use Drizzle, Drizzle DASLs. 1048 + 00:16:15.880 --> 00:16:19.640 1049 + You don't want to say, hey, 1080p video, 1080p video, you know it's 1080p video because the 1050 1050 1051 1051 263 1052 - 00:16:10.000 --> 00:16:13.000 1053 - A very strict subset of Seabour used in at-proto, right? 1052 + 00:16:19.640 --> 00:16:22.500 1053 + last 500 segments were 1080p video, right? 1054 1054 1055 1055 264 1056 - 00:16:13.000 --> 00:16:14.000 1057 - That's Stupa. 1056 + 00:16:22.500 --> 00:16:28.040 1057 + So we send, we can send this once at the start and not have to repeat it. 1058 1058 1059 1059 265 1060 - 00:16:14.000 --> 00:16:15.000 1061 - That's all of Stupa. 1060 + 00:16:28.040 --> 00:16:32.520 1061 + I'm not quite getting into the at-proto stuff here, but just at the bottom there, a little 1062 1062 1063 1063 266 1064 - 00:16:15.000 --> 00:16:17.000 1065 - The rest of the presentation is about Muxill because it's way more 1064 + 00:16:32.520 --> 00:16:36.520 1065 + teaser of what this might look like if you wanted to put it in that proto repository, 1066 1066 1067 1067 267 1068 - 00:16:17.000 --> 00:16:18.000 1069 - complicated. 1068 + 00:16:36.520 --> 00:16:40.120 1069 + this could be a place.stream.muxle.catalog record. 1070 1070 1071 1071 268 1072 - 00:16:18.000 --> 00:16:20.000 1073 - This is just a little change that we're making here. 1072 + 00:16:40.120 --> 00:16:43.680 1073 + We'll get to how it actually works in a minute. 1074 1074 1075 1075 269 1076 - 00:16:20.000 --> 00:16:22.000 1077 - Would love if they upstreamed it. 1076 + 00:16:43.680 --> 00:16:45.720 1077 + This lets us make init segments. 1078 1078 1079 1079 270 1080 - 00:16:22.000 --> 00:16:29.000 1081 - Would love if there were dids and K256 signing in C2PA. 1080 + 00:16:45.720 --> 00:16:47.240 1081 + Now we're talking about MP4 atoms. 1082 1082 1083 1083 271 1084 - 00:16:29.000 --> 00:16:33.000 1085 - So let's talk about the design goals for Muxill. 1084 + 00:16:47.240 --> 00:16:50.480 1085 + This is fun. 1086 1086 1087 1087 272 1088 - 00:16:33.000 --> 00:16:37.000 1089 - This is basically what changes do we need to make to those MP4 files 1088 + 00:16:50.480 --> 00:16:59.400 1089 + So this data represented as like JSON or CBOR or whatever and stored in your at-proto repository 1090 1090 1091 1091 273 1092 - 00:16:37.000 --> 00:16:41.000 1093 - that I described before in order to make them appropriate for VOD. 1092 + 00:16:59.400 --> 00:17:05.280 1093 + is enough to create, actually deterministically create the start of the MP4 file, which is 1094 1094 1095 1095 274 1096 - 00:16:41.000 --> 00:16:44.000 1097 - So you don't have thousands and thousands of MP4 files on your 1096 + 00:17:05.280 --> 00:17:06.280 1097 + called the init segment. 1098 1098 1099 1099 275 1100 - 00:16:44.000 --> 00:16:46.000 1101 - computer after a long livestream. 1100 + 00:17:06.280 --> 00:17:09.760 1101 + It's the very beginning of the MP4 file that contains the file type atom telling you this 1102 1102 1103 1103 276 1104 - 00:16:46.000 --> 00:16:50.000 1105 - So we want to keep the property that they're self-certifying. 1104 + 00:17:09.760 --> 00:17:16.600 1105 + is an MP4 file and the move atom that describes, for example, the duration of the video, what 1106 1106 1107 1107 277 1108 - 00:16:50.000 --> 00:16:53.000 1109 - It's awesome that you can just find one of these files and then go 1108 + 00:17:16.600 --> 00:17:17.600 1109 + all the tracks are. 1110 1110 1111 1111 278 1112 - 00:16:53.000 --> 00:16:55.000 1113 - verify its provenance chain. 1112 + 00:17:17.600 --> 00:17:22.040 1113 + There's a bunch of, this is like the MP4 encoding of all that metadata that I just described. 1114 1114 1115 1115 279 1116 - 00:16:55.000 --> 00:16:59.000 1117 - You shouldn't require external data, right? 1116 + 00:17:22.040 --> 00:17:26.840 1117 + This is the beginning of the muxle file init segment. 1118 1118 1119 1119 280 1120 - 00:16:59.000 --> 00:17:02.000 1121 - As a design goal, we want to support livestream to VOD. 1120 + 00:17:26.840 --> 00:17:33.640 1121 + We then split up the video into muxle segments. 1122 1122 1123 1123 281 1124 - 00:17:02.000 --> 00:17:04.000 1125 - So that what video engineers call DVR. 1124 + 00:17:33.640 --> 00:17:37.680 1125 + This again is borrowed, this is pretty much a verbatim hang CMAF, which is part of the 1126 1126 1127 1127 282 1128 - 00:17:04.000 --> 00:17:07.000 1129 - Basically, if you're watching a livestream that you can seek back 1128 + 00:17:37.680 --> 00:17:41.440 1129 + video over QuickSpec, which is awesome because that means it's going to stream very efficiently 1130 1130 1131 1131 283 1132 - 00:17:07.000 --> 00:17:10.000 1133 - and see what happened one minute ago, two minutes ago, three minutes 1132 + 00:17:41.440 --> 00:17:45.000 1133 + to users eventually. 1134 1134 1135 1135 284 1136 - 00:17:10.000 --> 00:17:12.000 1137 - ago, that kind of thing. 1136 + 00:17:45.000 --> 00:17:46.920 1137 + This is just repeated. 1138 1138 1139 1139 285 1140 - 00:17:12.000 --> 00:17:14.000 1141 - It would be nice if it's a useful format. 1140 + 00:17:46.920 --> 00:17:52.040 1141 + Every frame gets its own, what's called a muf and an MDAT, so little segments, little 1142 1142 1143 1143 286 1144 - 00:17:14.000 --> 00:17:17.000 1145 - I don't want to give you some opaque Seabour blob or something. 1144 + 00:17:52.040 --> 00:18:00.880 1145 + slivers of the MP4 file that represent each frame, each video or audio frame, essentially. 1146 1146 1147 1147 287 1148 - 00:17:17.000 --> 00:17:20.000 1149 - A design goal of this is that at the end of it, you have at the end 1148 + 00:18:00.880 --> 00:18:05.120 1149 + Easy enough, but we're going to do a lot with these in a minute. 1150 1150 1151 1151 288 1152 - 00:17:20.000 --> 00:17:24.000 1153 - of a 24-hour livestream, you should have a 24-hour MP4 file on your 1152 + 00:18:05.120 --> 00:18:12.120 1153 + And then we go back to that stupa specification I was talking about a second ago, the CTPA 1154 1154 1155 1155 289 1156 - 00:17:24.000 --> 00:17:25.000 1157 - computer. 1156 + 00:18:12.120 --> 00:18:13.120 1157 + stuff. 1158 1158 1159 1159 290 1160 - 00:17:25.000 --> 00:17:28.000 1161 - Easiest to work with, maximally compatible, preserves all of the 1160 + 00:18:13.120 --> 00:18:18.160 1161 + So this is, we can take, this is the canonical signed format. 1162 1162 1163 1163 291 1164 - 00:17:28.000 --> 00:17:31.000 1165 - provenance information I was describing. 1164 + 00:18:18.160 --> 00:18:22.640 1165 + This is the thing that you, when you get this format, you can validate the signature, validate 1166 1166 1167 1167 292 1168 - 00:17:31.000 --> 00:17:34.000 1169 - And it should be streamable with minimal overhead. 1168 + 00:18:22.640 --> 00:18:23.640 1169 + the provenance claim. 1170 1170 1171 1171 293 1172 - 00:17:34.000 --> 00:17:37.000 1173 - I'm not going to get too deep into media over quick in this 1172 + 00:18:23.640 --> 00:18:30.480 1173 + No, this is actually definitely Eli's CTPA signed video file. 1174 1174 1175 1175 294 1176 - 00:17:37.000 --> 00:17:40.000 1177 - presentation, though I would love to. 1176 + 00:18:30.480 --> 00:18:34.160 1177 + This is actually me beating Trabio or whatever. 1178 1178 1179 1179 295 1180 - 00:17:40.000 --> 00:17:46.000 1181 - But basically, we don't want to do a bunch of extra effort to go 1180 + 00:18:34.160 --> 00:18:38.480 1181 + And this is, this is great. 1182 1182 1183 1183 296 1184 - 00:17:46.000 --> 00:17:51.000 1185 - from the canonical format that we're going to use for all of this 1184 + 00:18:38.480 --> 00:18:43.960 1185 + This is not necessarily the best format for archival and playback. 1186 1186 1187 1187 297 1188 - 00:17:51.000 --> 00:17:53.000 1189 - to actually streaming it to users, right? 1188 + 00:18:43.960 --> 00:18:49.520 1189 + So one key insight and the Eureka moment I had when making this is like, okay, so this 1190 1190 1191 1191 298 1192 - 00:17:53.000 --> 00:17:56.000 1193 - We shouldn't need to re-encode or anything like that. 1192 + 00:18:49.520 --> 00:18:54.640 1193 + is like the canonical thing, but you wouldn't ever write this to your hard drive. 1194 1194 1195 1195 299 1196 - 00:17:56.000 --> 00:18:01.000 1197 - Unfortunately, that is an impossible series of constraints. 1196 + 00:18:54.640 --> 00:18:59.960 1197 + Or if you did because you're repeating the beginning of the file, the file type stuff, 1198 1198 1199 1199 300 1200 - 00:18:01.000 --> 00:18:05.000 1201 - Fundamentally, the reason being that if the output is going to be 1200 + 00:18:59.960 --> 00:19:03.560 1201 + this is how, this would get you right back to one second MP4 files on your computer 1202 1202 1203 1203 301 1204 - 00:18:05.000 --> 00:18:08.000 1205 - just an MP4 file on your computer, that is completely different 1204 + 00:19:03.560 --> 00:19:05.320 1205 + over and over and over. 1206 1206 1207 1207 302 1208 - 00:18:08.000 --> 00:18:11.000 1209 - than the format the media over quick uses that's going to be 1208 + 00:19:05.320 --> 00:19:10.360 1209 + So while this is like, you consider this like the base unit of stream play streaming or 1210 1210 1211 1211 303 1212 - 00:18:11.000 --> 00:18:14.000 1213 - useful for sending things to users, in particular with things 1212 + 00:19:10.360 --> 00:19:15.040 1213 + a VOD or what have you, this, yeah, you'd never actually write one of these to the hard 1214 1214 1215 1215 304 1216 - 00:18:14.000 --> 00:18:15.000 1217 - like multiple tracks, right? 1216 + 00:19:15.040 --> 00:19:17.720 1217 + drive unless you were like debugging or something like that. 1218 1218 1219 1219 305 1220 - 00:18:15.000 --> 00:18:18.000 1221 - We really want to do multi-track video, multi-track audio, 1220 + 00:19:17.720 --> 00:19:19.360 1221 + What would you write to the hard drive? 1222 1222 1223 1223 306 1224 - 00:18:18.000 --> 00:18:25.000 1225 - 720p, a bunch of other 1080p, different audio formats, AAC and 1224 + 00:19:19.360 --> 00:19:20.360 1225 + You ask. 1226 1226 1227 1227 307 1228 - 00:18:25.000 --> 00:18:26.000 1229 - Opus for different things. 1228 + 00:19:20.360 --> 00:19:23.640 1229 + You would write a muxal archive. 1230 1230 1231 1231 308 1232 - 00:18:26.000 --> 00:18:29.000 1233 - All of that complexity we would like to be able to package in 1232 + 00:19:23.640 --> 00:19:24.640 1233 + Blake three. 1234 1234 1235 1235 309 1236 - 00:18:29.000 --> 00:18:32.000 1237 - this one file, and that, like, skyrockets the bandwidth that you 1236 + 00:19:24.640 --> 00:19:26.880 1237 + I know, hang out with that proto people. 1238 1238 1239 1239 310 1240 - 00:18:32.000 --> 00:18:34.000 1241 - would use to send it out to people, right? 1240 + 00:19:26.880 --> 00:19:28.840 1241 + I know a lot of protocol engineers. 1242 1242 1243 1243 311 1244 - 00:18:34.000 --> 00:18:36.000 1245 - You don't want to send them every rendition. 1244 + 00:19:28.840 --> 00:19:32.480 1245 + Every one of them has had a moment where they take me aside and they're like, you should 1246 1246 1247 1247 312 1248 - 00:18:36.000 --> 00:18:38.000 1249 - You want to send them just one. 1248 + 00:19:32.480 --> 00:19:35.520 1249 + really be using Blake three for this stuff. 1250 1250 1251 1251 313 1252 - 00:18:38.000 --> 00:18:41.000 1253 - So how do we get around that? 1252 + 00:19:35.520 --> 00:19:39.040 1253 + And I agree with them eventually. 1254 1254 1255 1255 314 1256 - 00:18:41.000 --> 00:18:43.000 1257 - And the answer is we mux. 1256 + 00:19:39.040 --> 00:19:41.440 1257 + So this is what you would write to your hard drive, right? 1258 1258 1259 1259 315 1260 - 00:18:43.000 --> 00:18:47.000 1261 - This is why it's called muxal. 1260 + 00:19:41.440 --> 00:19:44.040 1261 + So this is the in it segment. 1262 1262 1263 1263 316 1264 - 00:18:47.000 --> 00:18:53.000 1265 - So the key insight here is that the archival format, so this is 1264 + 00:19:44.040 --> 00:19:46.760 1265 + This is the part where you say it's 1080p video. 1266 1266 1267 1267 317 1268 - 00:18:53.000 --> 00:18:57.000 1269 - to say the MP4 file on your computer, the streaming format, 1268 + 00:19:46.760 --> 00:19:49.240 1269 + Then you have all of these. 1270 1270 1271 1271 318 1272 - 00:18:57.000 --> 00:19:01.000 1273 - which is the format the video is in when it goes over media over 1272 + 00:19:49.240 --> 00:19:51.100 1273 + Each of these is what's called a gop segment. 1274 1274 1275 1275 319 1276 - 00:19:01.000 --> 00:19:07.000 1277 - quick, and streams to a user, and the self-certifying format that 1276 + 00:19:51.100 --> 00:19:55.080 1277 + So a key frame, a video followed by a bunch of other frames and then a key frame and then 1278 1278 1279 1279 320 1280 - 00:19:07.000 --> 00:19:10.000 1281 - has this intact signature that you use to validate that the 1280 + 00:19:55.080 --> 00:19:57.160 1281 + a bunch of other frames. 1282 1282 1283 1283 321 1284 - 00:19:10.000 --> 00:19:14.000 1285 - media is who it says it is and get all the nice metadata, they 1284 + 00:19:57.160 --> 00:20:03.640 1285 + And the cool thing about this is we've totally messed up the signature now, right? 1286 1286 1287 1287 322 1288 - 00:19:14.000 --> 00:19:18.000 1289 - don't all have to be the same format. 1288 + 00:20:03.640 --> 00:20:09.680 1289 + Because we, the signature is over this file with a in it segment and a video gop and an 1290 1290 1291 1291 323 1292 - 00:19:18.000 --> 00:19:24.000 1293 - As long as we can deterministically mux between them. 1292 + 00:20:09.680 --> 00:20:11.560 1293 + audio gop and then a manifest, right? 1294 1294 1295 1295 324 1296 - 00:19:24.000 --> 00:19:27.000 1297 - As long as if you have one of these formats, there is a 1296 + 00:20:11.560 --> 00:20:14.000 1297 + This is, this is the thing that we signed. 1298 1298 1299 1299 325 1300 - 00:19:27.000 --> 00:19:30.000 1301 - deterministic algorithm you can use to turn it into any one of 1300 + 00:20:14.000 --> 00:20:15.360 1301 + This doesn't look like that at all. 1302 1302 1303 1303 326 1304 - 00:19:30.000 --> 00:19:31.000 1305 - these other formats. 1304 + 00:20:15.360 --> 00:20:18.120 1305 + I've even just kind of put the manifest at the, at the end there. 1306 1306 1307 1307 327 1308 - 00:19:31.000 --> 00:19:35.000 1309 - So we've accomplished this with Wasm, primarily. 1308 + 00:20:18.120 --> 00:20:22.120 1309 + But because we have deterministic muxing tools, we can recover this. 1310 1310 1311 1311 328 1312 - 00:19:35.000 --> 00:19:37.000 1313 - Wasm, especially the latest version of Wasm, has a fully 1312 + 00:20:22.120 --> 00:20:27.640 1313 + We can, or we can recover the signed canonical thing, right? 1314 1314 1315 1315 329 1316 - 00:19:37.000 --> 00:19:38.000 1317 - deterministic profile. 1316 + 00:20:27.640 --> 00:20:34.920 1317 + This format, however, is really, really useful for VOD because if you are, I'll show you 1318 1318 1319 1319 330 1320 - 00:19:38.000 --> 00:19:43.000 1321 - Even short of that, you know, Rust compiled to Wasm, and then 1320 + 00:20:34.920 --> 00:20:36.800 1321 + why. 1322 1322 1323 1323 331 1324 - 00:19:43.000 --> 00:19:46.000 1325 - you pipe some bytes through it, you're very, very likely to get 1324 + 00:20:36.800 --> 00:20:39.740 1325 + See it's like this. 1326 1326 1327 1327 332 1328 - 00:19:46.000 --> 00:19:48.000 1329 - the same bytes out through the output, right? 1328 + 00:20:39.740 --> 00:20:42.880 1329 + So this is a HLS playlist. 1330 1330 1331 1331 333 1332 - 00:19:48.000 --> 00:19:52.000 1333 - So this is, yeah, so let's get into the different formats that 1332 + 00:20:42.880 --> 00:20:48.280 1333 + This is how you, you don't know it, but most of the time you've played video on the internet. 1334 1334 1335 1335 334 1336 - 00:19:52.000 --> 00:19:54.000 1337 - we're using inside of here. 1336 + 00:20:48.280 --> 00:20:51.440 1337 + You've had one of these happening in the background. 1338 1338 1339 1339 335 1340 - 00:19:54.000 --> 00:19:58.000 1341 - I'm going to get deep into MP4 file specifics. 1340 + 00:20:51.440 --> 00:20:55.160 1341 + And what this does is takes all of those, this is just the video playlist. 1342 1342 1343 1343 336 1344 - 00:19:58.000 --> 00:20:01.000 1345 - I don't, I wouldn't wish this upon anyone having to dive this 1344 + 00:20:55.160 --> 00:20:56.640 1345 + This just tells you how to do the video. 1346 1346 1347 1347 337 1348 - 00:20:01.000 --> 00:20:03.000 1349 - deep into the MP4 specs. 1348 + 00:20:56.640 --> 00:21:01.560 1349 + The audio is referenced in a, in a different, in a different manifest. 1350 1350 1351 1351 338 1352 - 00:20:03.000 --> 00:20:07.000 1353 - I had to pay $300 for a PDF file. 1352 + 00:21:01.560 --> 00:21:08.640 1353 + And basically what this gives you is a byte range in an index into that file. 1354 1354 1355 1355 339 1356 - 00:20:07.000 --> 00:20:13.000 1357 - So, yes, this is the whole point of Stream Places. 1356 + 00:21:08.640 --> 00:21:11.120 1357 + So you can say this, this year says, this is one second of video. 1358 1358 1359 1359 340 1360 - 00:20:13.000 --> 00:20:16.000 1361 - These are the hard work we do, the hard problems we solve, so 1360 + 00:21:11.120 --> 00:21:12.760 1361 + You can find it at this index of this file. 1362 1362 1363 1363 341 1364 - 00:20:16.000 --> 00:20:19.000 1365 - none of you have to, right? 1364 + 00:21:12.760 --> 00:21:13.760 1365 + This is one second of video. 1366 1366 1367 1367 342 1368 - 00:20:19.000 --> 00:20:25.000 1369 - So we, the base primitives here that are part of Muxle. 1368 + 00:21:13.760 --> 00:21:16.480 1369 + You can find it at this index of this file. 1370 1370 1371 1371 343 1372 - 00:20:25.000 --> 00:20:29.000 1373 - First, we have video metadata. 1372 + 00:21:16.480 --> 00:21:19.200 1373 + And this is all, this is all you need for efficient VOD playback. 1374 1374 1375 1375 344 1376 - 00:20:29.000 --> 00:20:33.000 1377 - I borrow a lot of this terminology from a spec called Hang 1376 + 00:21:19.200 --> 00:21:22.640 1377 + If you're doing it live, there's disadvantages to doing it this way. 1378 1378 1379 1379 345 1380 - 00:20:33.000 --> 00:20:39.000 1381 - that's from Luke Curley who created the media over quick spec. 1380 + 00:21:22.640 --> 00:21:25.120 1381 + You probably want to use media over quick and some of the other formats that we talked 1382 1382 1383 1383 346 1384 - 00:20:39.000 --> 00:20:43.000 1385 - So this is, catalog is his term for this, but this is all of the 1384 + 00:21:25.120 --> 00:21:26.120 1385 + about. 1386 1386 1387 1387 347 1388 - 00:20:43.000 --> 00:20:45.000 1389 - metadata that you need to understand the video. 1388 + 00:21:26.120 --> 00:21:28.520 1389 + But for VOD, this is really, really good. 1390 1390 1391 1391 348 1392 - 00:20:45.000 --> 00:20:48.000 1393 - I can't just, video decoders won't just accept some random video 1392 + 00:21:28.520 --> 00:21:33.160 1393 + And we've achieved one of our design goals because all of these, it's just referencing 1394 1394 1395 1395 349 1396 - 00:20:48.000 --> 00:20:49.000 1397 - bytes. 1396 + 00:21:33.160 --> 00:21:37.080 1397 + different byte ranges in archive.muxle.mp4, right? 1398 1398 1399 1399 350 1400 - 00:20:49.000 --> 00:20:53.000 1401 - You have to say, no, these video bytes are, for example, 1920 by 1400 + 00:21:37.080 --> 00:21:41.720 1401 + So we've, the thing that is, I've been saying on your computer, but the thing for video, 1402 1402 1403 1403 351 1404 - 00:20:53.000 --> 00:20:55.000 1405 - 1080 at 60 FPS. 1404 + 00:21:41.720 --> 00:21:48.120 1405 + the thing that's in your app repository is, is just one big MP4 file. 1406 1406 1407 1407 352 1408 - 00:20:55.000 --> 00:20:59.000 1409 - You've got the time scale and then a canonical track ID for 1408 + 00:21:48.120 --> 00:21:52.560 1409 + It's really easy to understand. 1410 1410 1411 1411 353 1412 - 00:20:59.000 --> 00:21:01.000 1413 - everything that goes into this, right? 1412 + 00:21:52.560 --> 00:22:00.920 1413 + The other, the other thing we get from this is, is the Blake three, Sid, the magic of 1414 1414 1415 1415 354 1416 - 00:21:01.000 --> 00:21:03.000 1417 - How many channels is the audio? 1416 + 00:22:00.920 --> 00:22:01.920 1417 + Blake three. 1418 1418 1419 1419 355 1420 - 00:21:03.000 --> 00:21:05.000 1421 - I don't know if it's listed in here, but this would have stuff like 1420 + 00:22:01.920 --> 00:22:04.920 1421 + Why, why was it that all those video engineers were telling me that I needed to use Blake 1422 1422 1423 1423 356 1424 - 00:21:05.000 --> 00:21:06.000 1425 - what language is the audio. 1424 + 00:22:04.920 --> 00:22:05.920 1425 + three? 1426 1426 1427 1427 357 1428 - 00:21:06.000 --> 00:21:08.000 1429 - If we've got the audio translated into several different languages, 1428 + 00:22:05.920 --> 00:22:14.240 1429 + It's because this Blake three hash is a Merkle tree over this file that you see here, which 1430 1430 1431 1431 358 1432 - 00:21:08.000 --> 00:21:11.000 1433 - that would be included in this metadata. 1432 + 00:22:14.240 --> 00:22:19.960 1433 + means you can request to just that part that says track one, gop one there. 1434 1434 1435 1435 359 1436 - 00:21:11.000 --> 00:21:15.000 1437 - This is nice to separate out because from a low latency 1436 + 00:22:19.960 --> 00:22:25.960 1437 + And through cryptographic verification, you can be 100% confident that that is the correct 1438 1438 1439 1439 360 1440 - 00:21:15.000 --> 00:21:19.000 1441 - transmission perspective, you don't want to repeat this stuff, 1440 + 00:22:25.960 --> 00:22:27.960 1441 + data that you've pulled out of there, right? 1442 1442 1443 1443 361 1444 - 00:21:19.000 --> 00:21:20.000 1445 - right? 1444 + 00:22:27.960 --> 00:22:32.080 1445 + You can verify, yes, this is in fact part of this Blake three, Sid, which is really, 1446 1446 1447 1447 362 1448 - 00:21:20.000 --> 00:21:22.000 1449 - You don't want to say, hey, 1080p video, 1080p video, you know it's 1448 + 00:22:32.080 --> 00:22:37.440 1449 + really useful when you're doing something like a CDN because then you can make all these, 1450 1450 1451 1451 363 1452 - 00:21:22.000 --> 00:21:26.000 1453 - 1080p video because the last 500 segments were 1080p video, right? 1452 + 00:22:37.440 --> 00:22:40.560 1453 + you can have be backing it with just one big file. 1454 1454 1455 1455 364 1456 - 00:21:26.000 --> 00:21:30.000 1457 - So we can send this once at the start and not have to repeat it. 1456 + 00:22:40.560 --> 00:22:42.400 1457 + You can make these byte range requests. 1458 1458 1459 1459 365 1460 - 00:21:30.000 --> 00:21:33.000 1461 - I'm not quite getting into the app proto stuff here, but just at 1460 + 00:22:42.400 --> 00:22:47.120 1461 + You still get the cryptographic integrity that like, oh yes, that, that, that hash matches 1462 1462 1463 1463 366 1464 - 00:21:33.000 --> 00:21:36.000 1465 - the bottom there, a little teaser of what this might look like if 1464 + 00:22:47.120 --> 00:22:50.600 1465 + what I saw in Eli's app repository. 1466 1466 1467 1467 367 1468 - 00:21:36.000 --> 00:21:39.000 1469 - you wanted to put it in that repository. 1468 + 00:22:50.600 --> 00:22:53.120 1469 + So this is a really, really good format for this. 1470 1470 1471 1471 368 1472 - 00:21:39.000 --> 00:21:42.000 1473 - This could be a place.stream.muxle.catalog record. 1472 + 00:22:53.120 --> 00:22:54.960 1473 + Um, cool. 1474 1474 1475 1475 369 1476 - 00:21:42.000 --> 00:21:45.000 1477 - We'll get to how it actually works in a minute. 1476 + 00:22:54.960 --> 00:23:02.680 1477 + So yes, three different formats that we, uh, uh, that we have here. 1478 1478 1479 1479 370 1480 - 00:21:45.000 --> 00:21:48.000 1481 - This lets us make in-it segments. 1480 + 00:23:02.680 --> 00:23:07.320 1481 + So, um, the archival format, which is the big MP4 file that goes in your app, proto 1482 1482 1483 1483 371 1484 - 00:21:48.000 --> 00:21:50.000 1485 - Now we're talking about MP4 atoms. 1484 + 00:23:07.320 --> 00:23:12.880 1485 + repository, the self certifying format, which is the part that has the, uh, C2P a signature 1486 1486 1487 1487 372 1488 - 00:21:50.000 --> 00:21:51.000 1489 - This is fun. 1488 + 00:23:12.880 --> 00:23:16.760 1489 + attached and the streaming format, which is just when you're actually sending it out, 1490 1490 1491 1491 373 1492 - 00:21:51.000 --> 00:21:57.000 1493 - So this data represented as like JSON. 1492 + 00:23:16.760 --> 00:23:19.360 1493 + you just send, uh, you just send this part, right? 1494 1494 1495 1495 374 1496 - 00:21:58.000 --> 00:22:02.000 1497 - This data represented as like JSON or CBOR or whatever and stored in 1496 + 00:23:19.360 --> 00:23:25.280 1497 + You stream this stuff, uh, each, each frame of video and audio directly to users. 1498 1498 1499 1499 375 1500 - 00:22:02.000 --> 00:22:06.000 1501 - your at proto repository is enough to create, actually deterministically 1500 + 00:23:25.280 --> 00:23:29.840 1501 + So for all the at proto people that didn't care about all the different structures of 1502 1502 1503 1503 376 1504 - 00:22:06.000 --> 00:22:10.000 1505 - create the start of the MP4 file, which is called the in-it segment. 1504 + 00:23:29.840 --> 00:23:33.600 1505 + the MP4 file, how do you use all of this? 1506 1506 1507 1507 377 1508 - 00:22:10.000 --> 00:22:13.000 1509 - The very beginning of the MP4 file that contains the file type atom 1508 + 00:23:33.600 --> 00:23:36.280 1509 + We're not quite ready for it, but the very first vods available on stream play. 1510 1510 1511 1511 378 1512 - 00:22:13.000 --> 00:22:16.000 1513 - telling you this is an MP4 file. 1512 + 00:23:36.280 --> 00:23:40.160 1513 + Most are going to follow this format and it's going to be all of the talks from this 1514 1514 1515 1515 379 1516 - 00:22:16.000 --> 00:22:20.000 1517 - And the move atom that describes, for example, the duration of the 1516 + 00:23:40.160 --> 00:23:41.160 1517 + conference. 1518 1518 1519 1519 380 1520 - 00:22:20.000 --> 00:22:22.000 1521 - video, what all the tracks are. 1520 + 00:23:41.160 --> 00:23:44.080 1521 + Uh, they will be published to at proto repository. 1522 1522 1523 1523 381 1524 - 00:22:22.000 --> 00:22:25.000 1525 - There's a bunch of, this is like the MP4 encoding of all that metadata 1524 + 00:23:44.080 --> 00:23:45.840 1525 + Um, and you'll be able to work with them. 1526 1526 1527 1527 382 1528 - 00:22:25.000 --> 00:22:26.000 1529 - that I just described. 1528 + 00:23:45.840 --> 00:23:48.560 1529 + This is a little preview of what this looks like. 1530 1530 1531 1531 383 1532 - 00:22:26.000 --> 00:22:30.000 1533 - This is the beginning of the muxle file in its segment. 1532 + 00:23:48.560 --> 00:23:54.760 1533 + Uh, so we have a, uh, yeah. 1534 1534 1535 1535 384 1536 - 00:22:30.000 --> 00:22:37.000 1537 - We then split up the video into muxle segments. 1536 + 00:23:54.760 --> 00:23:59.600 1537 + So the man that as you might expect the, the lexicon type for this is a place.stream.video. 1538 1538 1539 1539 385 1540 - 00:22:37.000 --> 00:22:39.000 1541 - This again is borrowed. 1540 + 00:23:59.600 --> 00:24:04.460 1541 + It's got, uh, things like creator, um, some of the, some of this metadata in here. 1542 1542 1543 1543 386 1544 - 00:22:39.000 --> 00:22:42.000 1545 - This is pretty much a verbatim hang CMAF, which is part of the 1544 + 00:24:04.460 --> 00:24:06.740 1545 + This is like, I'm pretending this is the one for this talk. 1546 1546 1547 1547 387 1548 - 00:22:42.000 --> 00:22:45.000 1549 - video over quick spec, which is awesome because that means it's 1548 + 00:24:06.740 --> 00:24:09.380 1549 + I don't have a vod for this talk cause I'm still doing this talk. 1550 1550 1551 1551 388 1552 - 00:22:45.000 --> 00:22:48.000 1553 - going to stream very efficiently to users eventually. 1552 + 00:24:09.380 --> 00:24:11.220 1553 + So you don't know what the hash is yet. 1554 1554 1555 1555 389 1556 - 00:22:48.000 --> 00:22:51.000 1557 - And so this is just repeated. 1556 + 00:24:11.220 --> 00:24:14.820 1557 + Um, it's got, it's just as I said, it's just a blob. 1558 1558 1559 1559 390 1560 - 00:22:51.000 --> 00:22:54.000 1561 - Every frame gets its own, what's called a move and an MDAT. 1560 + 00:24:14.820 --> 00:24:16.140 1561 + It's a video MP4 file. 1562 1562 1563 1563 391 1564 - 00:22:54.000 --> 00:22:58.000 1565 - So little segments, little slivers of the MP4 file that represent 1564 + 00:24:16.140 --> 00:24:19.500 1565 + Um, but it is very, very easily cacheable. 1566 1566 1567 1567 392 1568 - 00:22:58.000 --> 00:23:04.000 1569 - each frame, each video or audio frame, essentially. 1568 + 00:24:19.500 --> 00:24:22.700 1569 + Um, you've got a nanosecond duration in there. 1570 1570 1571 1571 393 1572 - 00:23:04.000 --> 00:23:08.000 1573 - Easy enough, but we're going to do a lot with these in a minute. 1572 + 00:24:22.700 --> 00:24:27.280 1573 + Uh, we, the design constraints for this I've been targeting that the maximum length of 1574 1574 1575 1575 394 1576 - 00:23:08.000 --> 00:23:14.000 1577 - And then we go back to that stupid specification I was talking about 1576 + 00:24:27.280 --> 00:24:29.860 1577 + one of these is going to be 24 hours. 1578 1578 1579 1579 395 1580 - 00:23:14.000 --> 00:23:16.000 1581 - a second ago, the CTPA stuff. 1580 + 00:24:29.860 --> 00:24:33.660 1581 + Um, because, uh, at a certain point it gets ridiculous. 1582 1582 1583 1583 396 1584 - 00:23:16.000 --> 00:23:22.000 1585 - So this is, we can take, this is the canonical signed format. 1584 + 00:24:33.860 --> 00:24:36.860 1585 + Yeah. 1586 1586 1587 1587 397 1588 - 00:23:22.000 --> 00:23:25.000 1589 - This is the thing that you, when you get this format, you can validate 1588 + 00:24:36.860 --> 00:24:38.540 1589 + Uh, and I don't want to like overflow the nanosecond duration, but if you've got a 24 1590 1590 1591 1591 398 1592 - 00:23:25.000 --> 00:23:28.000 1593 - the signature, validate the provenance claim. 1592 + 00:24:38.540 --> 00:24:42.220 1593 + seven live stream, that seems like a reasonable primitive that like each day of streaming 1594 1594 1595 1595 399 1596 - 00:23:28.000 --> 00:23:34.000 1597 - No, this is actually definitely Eli's CTPA signed video file. 1596 + 00:24:42.220 --> 00:24:46.300 1597 + that you would stream into would become its own vod, uh, with a 24 hour duration. 1598 1598 1599 1599 400 1600 - 00:23:34.000 --> 00:23:37.000 1601 - This is actually me beating Trabia or whatever. 1600 + 00:24:46.300 --> 00:24:47.300 1601 + Right. 1602 1602 1603 1603 401 1604 - 00:23:37.000 --> 00:23:42.000 1605 - And this is, this is great. 1604 + 00:24:47.300 --> 00:24:49.180 1605 + Um, and then it's got a live stream reference. 1606 1606 1607 1607 402 1608 - 00:23:42.000 --> 00:23:47.000 1609 - This is not necessarily the best format for archival and playback. 1608 + 00:24:49.180 --> 00:24:51.700 1609 + So, uh, yeah. 1610 1610 1611 1611 403 1612 - 00:23:47.000 --> 00:23:48.000 1613 - Right? 1612 + 00:24:51.700 --> 00:24:53.300 1613 + So, uh, all of this will be available. 1614 1614 1615 1615 404 1616 - 00:23:48.000 --> 00:23:51.000 1617 - So one key insight and like the Eureka moment I had when making the 1616 + 00:24:53.300 --> 00:24:54.300 1617 + Yeah. 1618 1618 1619 1619 405 1620 - 00:23:51.000 --> 00:23:54.000 1621 - Eureka moment I had when making this is like, okay, so this is like the 1620 + 00:24:54.300 --> 00:24:56.140 1621 + I was hoping to have all of this available and I was like, Oh, I got an ounce in this 1622 1622 1623 1623 406 1624 - 00:23:54.000 --> 00:23:58.000 1625 - canonical thing, but you wouldn't ever write this to your hard drive. 1624 + 00:24:56.140 --> 00:24:57.140 1625 + talk and it's going to be big. 1626 1626 1627 1627 407 1628 - 00:23:58.000 --> 00:24:02.000 1629 - Or if you did because you're repeating the beginning of the file, the file 1628 + 00:24:57.140 --> 00:24:58.340 1629 + And we're like really, really close. 1630 1630 1631 1631 408 1632 - 00:24:02.000 --> 00:24:06.000 1633 - type stuff, this is how, this would get you right back to one second MP4 files 1632 + 00:24:58.340 --> 00:25:01.820 1633 + But I wasn't, I didn't want to push a bunch of changes to stream place right before we 1634 1634 1635 1635 409 1636 - 00:24:06.000 --> 00:24:08.000 1637 - on your computer over and over and over. 1636 + 00:25:01.820 --> 00:25:04.020 1637 + did all the live streaming and screw everything else up. 1638 1638 1639 1639 410 1640 - 00:24:08.000 --> 00:24:09.000 1641 - Right? 1640 + 00:25:04.020 --> 00:25:05.020 1641 + Right. 1642 1642 1643 1643 411 1644 - 00:24:09.000 --> 00:24:12.000 1645 - So while this is like, you consider this like the base unit of streamplay 1644 + 00:25:05.020 --> 00:25:08.700 1645 + So I, I, I did try to do that. 1646 1646 1647 1647 412 1648 - 00:24:12.000 --> 00:24:17.000 1649 - streaming or of, or a VOD or what have you, this, yeah, you'd never actually 1648 + 00:25:08.700 --> 00:25:10.860 1649 + Uh, we did that. 1650 1650 1651 1651 413 1652 - 00:24:17.000 --> 00:24:20.000 1653 - write one of these to the hard drive unless you were like debugging or 1652 + 00:25:10.860 --> 00:25:13.740 1653 + Uh, I did at about seven 10 this morning. 1654 1654 1655 1655 414 1656 - 00:24:20.000 --> 00:24:21.000 1657 - something like that. 1656 + 00:25:13.740 --> 00:25:15.900 1657 + I'm like, all right, let's push the muxal changes. 1658 1658 1659 1659 415 1660 - 00:24:21.000 --> 00:24:22.000 1661 - Right? 1660 + 00:25:15.900 --> 00:25:16.900 1661 + Let's see. 1662 1662 1663 1663 416 1664 - 00:24:22.000 --> 00:24:23.000 1665 - What would you write to the hard drive? 1664 + 00:25:16.900 --> 00:25:20.660 1665 + And then immediately that laptop couldn't stream into stream place anymore for whatever 1666 1666 1667 1667 417 1668 - 00:24:23.000 --> 00:24:24.000 1669 - You ask. 1668 + 00:25:20.660 --> 00:25:21.660 1669 + reason. 1670 1670 1671 1671 418 1672 - 00:24:24.000 --> 00:24:26.000 1673 - You would write a muxal archive. 1672 + 00:25:21.660 --> 00:25:23.220 1673 + So I was like, Nope, Nope, back revert. 1674 1674 1675 1675 419 1676 - 00:24:26.000 --> 00:24:28.000 1677 - Blake three. 1676 + 00:25:23.220 --> 00:25:24.780 1677 + We're gonna, we'll do it. 1678 1678 1679 1679 420 1680 - 00:24:28.000 --> 00:24:30.000 1681 - I know, hang out with that proto people. 1680 + 00:25:24.780 --> 00:25:25.780 1681 + We'll do it after. 1682 1682 1683 1683 421 1684 - 00:24:30.000 --> 00:24:32.000 1685 - I know a lot of protocol engineers. 1684 + 00:25:25.780 --> 00:25:29.740 1685 + Um, so that's all by way of saying this is all very, very close. 1686 1686 1687 1687 422 1688 - 00:24:32.000 --> 00:24:35.000 1689 - Every one of them has had a moment where they take me aside and they're like, 1688 + 00:25:30.100 --> 00:25:33.700 1689 + Um, and we're hoping to give it to the community very, very soon. 1690 1690 1691 1691 423 1692 - 00:24:35.000 --> 00:24:39.000 1693 - Eli, you should really be using Blake three for this stuff. 1692 + 00:25:34.260 --> 00:25:37.180 1693 + Um, and, uh, yeah, and then build it with everybody, right? 1694 1694 1695 1695 424 1696 - 00:24:39.000 --> 00:24:42.000 1697 - And I agree with them eventually. 1696 + 00:25:37.180 --> 00:25:38.300 1697 + So we don't have a front end for it. 1698 1698 1699 1699 425 1700 - 00:24:42.000 --> 00:24:45.000 1701 - So this is what you would write to your hard drive. 1700 + 00:25:38.340 --> 00:25:41.780 1701 + Um, I'm going to challenge the, we're going to do a little VOD jam and say, Hey, at 1702 1702 1703 1703 426 1704 - 00:24:45.000 --> 00:24:46.000 1705 - Right? 1704 + 00:25:41.780 --> 00:25:44.380 1705 + proto community, here's the videos, build me a front end for it. 1706 1706 1707 1707 427 1708 - 00:24:46.000 --> 00:24:47.000 1709 - So this is the in it segment. 1708 + 00:25:44.580 --> 00:25:49.100 1709 + Given that without me asking, we got three front ends for stream place in the last 1710 1710 1711 1711 428 1712 - 00:24:47.000 --> 00:24:50.000 1713 - This is the part where you say it's 10 ADP video. 1712 + 00:25:49.100 --> 00:25:52.740 1713 + three days, I feel like in the vibe coding era, we're gonna, we're gonna get some 1714 1714 1715 1715 429 1716 - 00:24:50.000 --> 00:24:52.000 1717 - Then you have all of these. 1716 + 00:25:52.740 --> 00:25:53.380 1717 + submissions. 1718 1718 1719 1719 430 1720 - 00:24:52.000 --> 00:24:55.000 1721 - Each of these is what's called a gop segment. 1720 + 00:25:53.380 --> 00:25:57.420 1721 + If you submit one of these, uh, you're going to earn a badge next to your chat 1722 1722 1723 1723 431 1724 - 00:24:55.000 --> 00:24:59.000 1725 - So a key frame, a video followed by a bunch of other frames and then a key 1724 + 00:25:57.420 --> 00:25:58.860 1725 + name in stream place. 1726 1726 1727 1727 432 1728 - 00:24:59.000 --> 00:25:01.000 1729 - frame and then a bunch of other frames. 1728 + 00:25:59.340 --> 00:26:02.220 1729 + Um, from now until the end of time. 1730 1730 1731 1731 433 1732 - 00:25:01.000 --> 00:25:07.000 1733 - And the cool thing about this is we've totally messed up the signature now. 1732 + 00:26:03.100 --> 00:26:06.100 1733 + So, uh, yeah, that's it. 1734 1734 1735 1735 434 1736 - 00:25:07.000 --> 00:25:08.000 1737 - Right? 1736 + 00:26:06.140 --> 00:26:07.620 1737 + That's how stream place works VOD. 1738 1738 1739 1739 435 1740 - 00:25:08.000 --> 00:25:13.000 1741 - Because we, the signature is over this file with in it segment and a video 1740 + 00:26:19.220 --> 00:26:19.500 1741 + Great. 1742 1742 1743 1743 436 1744 - 00:25:13.000 --> 00:25:15.000 1745 - gop and an audio gop and then a manifest. 1744 + 00:26:21.460 --> 00:26:21.900 1745 + Awesome. 1746 1746 1747 1747 437 1748 - 00:25:15.000 --> 00:25:16.000 1749 - Right? 1748 + 00:26:27.020 --> 00:26:27.300 1749 + Yeah. 1750 1750 1751 1751 438 1752 - 00:25:16.000 --> 00:25:18.000 1753 - So this is the thing that we signed. 1752 + 00:26:29.380 --> 00:26:30.340 1753 + Yeah. 1754 1754 1755 1755 439 1756 - 00:25:18.000 --> 00:25:20.000 1757 - This doesn't look like that at all. 1756 + 00:26:30.340 --> 00:26:34.780 1757 + So the, the big alternative, um, why MP4, uh, there's a couple of reasons. 1758 1758 1759 1759 440 1760 - 00:25:20.000 --> 00:25:22.000 1761 - I've even just kind of put the manifest at the, at the end there. 1760 + 00:26:35.020 --> 00:26:39.940 1761 + Um, one because, uh, it's the most ubiquitous media format and the, that's 1762 1762 1763 1763 441 1764 - 00:25:22.000 --> 00:25:26.000 1765 - But because we have deterministic muxing tools, we can recover this. 1764 + 00:26:39.940 --> 00:26:41.420 1765 + the most highly compatible across everything. 1766 1766 1767 1767 442 1768 - 00:25:26.000 --> 00:25:29.000 1769 - We can, or we can recover the signed canonical thing. 1768 + 00:26:41.940 --> 00:26:47.860 1769 + Um, the second is, um, it gives us the, uh, the, the, the media over quick 1770 1770 1771 1771 443 1772 - 00:25:29.000 --> 00:25:30.000 1773 - Right? 1772 + 00:26:47.860 --> 00:26:50.140 1773 + stuff, um, tends to support it a lot already. 1774 1774 1775 1775 444 1776 - 00:25:30.000 --> 00:25:35.000 1777 - This format, however, is really, really useful for VOD. 1776 + 00:26:50.660 --> 00:26:54.700 1777 + Um, the, also the FM, uh, so this is like CMAF. 1778 1778 1779 1779 445 1780 - 00:25:35.000 --> 00:25:40.000 1781 - Because if you are, I'll show you why. 1780 + 00:26:54.700 --> 00:26:58.140 1781 + Back to the, this thing, this is like CMAF MP4 playback. 1782 1782 1783 1783 446 1784 - 00:25:40.000 --> 00:25:41.000 1785 - See? 1784 + 00:26:58.180 --> 00:27:02.500 1785 + Um, and the advantage here is it lets you, um, separate out the, it gives you that 1786 1786 1787 1787 447 1788 - 00:25:41.000 --> 00:25:43.000 1789 - It's like this. 1788 + 00:27:02.500 --> 00:27:05.780 1789 + lack of redundancy that I was describing where the in it segment isn't, there are 1790 1790 1791 1791 448 1792 - 00:25:43.000 --> 00:25:46.000 1793 - So this is a, a HLS playlist. 1792 + 00:27:05.780 --> 00:27:08.980 1793 + other formats that embed all of that in a data in every segment, but we don't 1794 1794 1795 1795 449 1796 - 00:25:46.000 --> 00:25:51.000 1797 - This is how you, you don't know it, but most of the time you've played video 1796 + 00:27:08.980 --> 00:27:11.820 1797 + actually want that because it's redundant for, for a long video. 1798 1798 1799 1799 450 1800 - 00:25:51.000 --> 00:25:52.000 1801 - on the internet. 1800 + 00:27:11.820 --> 00:27:13.900 1801 + So, um, yeah, those reasons. 1802 1802 1803 1803 451 1804 - 00:25:52.000 --> 00:25:54.000 1805 - You've had one of these happening in the background. 1804 + 00:27:14.900 --> 00:27:16.420 1805 + Sure. 1806 1806 1807 1807 452 1808 - 00:25:54.000 --> 00:25:58.000 1809 - And what this does is takes all of those. 1808 + 00:27:16.420 --> 00:27:21.380 1809 + Uh, the question was, uh, the, the question was, uh, the, the, the, the, the, 1810 1810 1811 1811 453 1812 - 00:25:58.000 --> 00:25:59.000 1813 - This is just the video playlist. 1812 + 00:27:22.060 --> 00:27:23.100 1813 + sure, sure, sure. 1814 1814 1815 1815 454 1816 - 00:25:59.000 --> 00:26:00.000 1817 - This just tells you how to do the video. 1816 + 00:27:23.140 --> 00:27:28.220 1817 + Uh, the question was why VP nine instead of, or why H two six four instead 1818 1818 1819 1819 455 1820 - 00:26:00.000 --> 00:26:04.000 1821 - The audio is referenced in a, in a different, in a different manifest. 1820 + 00:27:28.220 --> 00:27:31.740 1821 + of like VP nine or AV one, no reason other than maximally, maximum 1822 1822 1823 1823 456 1824 - 00:26:04.000 --> 00:26:11.000 1825 - And basically what this gives you is a, a, a byte range in an index into that 1824 + 00:27:31.740 --> 00:27:36.080 1825 + compatibility right now, we really, really want, uh, AV one in, in stream 1826 1826 1827 1827 457 1828 - 00:26:11.000 --> 00:26:12.000 1829 - file. 1828 + 00:27:36.080 --> 00:27:40.900 1829 + place, um, we fully intend to support AV one as much as we do H two six four, 1830 1830 1831 1831 458 1832 - 00:26:12.000 --> 00:26:15.000 1833 - So you can say this, this year says this is one second of video. 1832 + 00:27:40.900 --> 00:27:44.540 1833 + especially when we do stuff like, like, uh, uh, I want to replace to do a lot 1834 1834 1835 1835 459 1836 - 00:26:15.000 --> 00:26:16.000 1837 - You can find it at this index of this file. 1836 + 00:27:44.540 --> 00:27:48.020 1837 + of things that no other streaming platforms do, like for example, uh, like 1838 1838 1839 1839 460 1840 - 00:26:16.000 --> 00:26:17.000 1841 - This is one second of video. 1840 + 00:27:48.020 --> 00:27:54.100 1841 + four K 120 FPS AV one video would be SISIC, uh, uh, can't even do it. 1842 1842 1843 1843 461 1844 - 00:26:17.000 --> 00:26:19.000 1845 - You can find it at this index of this file. 1844 + 00:27:54.100 --> 00:27:55.380 1845 + I've tried to do it with H two six four. 1846 1846 1847 1847 462 1848 - 00:26:19.000 --> 00:26:22.000 1849 - And this is all, this is all you need for efficient VOD playback. 1848 + 00:27:55.380 --> 00:27:59.380 1849 + It just like doesn't know encoder can even come close to handling that. 1850 1850 1851 1851 463 1852 - 00:26:22.000 --> 00:26:26.000 1853 - If you're doing it live, there's disadvantages to doing it this way. 1852 + 00:27:59.380 --> 00:28:00.820 1853 + So, um, yeah, yeah. 1854 1854 1855 1855 464 1856 - 00:26:26.000 --> 00:26:28.000 1857 - You probably want to use media over quick and some of the other formats that we 1856 + 00:28:00.860 --> 00:28:02.980 1857 + Uh, in terms of codec support, we want to support like every 1858 1858 1859 1859 465 1860 - 00:26:28.000 --> 00:26:29.000 1861 - talked about. 1860 + 00:28:02.980 --> 00:28:04.060 1861 + codec that it makes sense to. 1862 1862 1863 1863 466 1864 - 00:26:29.000 --> 00:26:31.000 1865 - But for VOD, this is really, really good. 1864 + 00:28:04.420 --> 00:28:07.040 1865 + We just started with this because we're not quite in a world where I could 1866 1866 1867 1867 467 1868 - 00:26:31.000 --> 00:26:36.000 1869 - And we've achieved one of our design goals because all of these, it's just 1868 + 00:28:07.040 --> 00:28:08.980 1869 + probably get away with AV one only. 1870 1870 1871 1871 468 1872 - 00:26:36.000 --> 00:26:40.000 1873 - referencing different byte ranges in archive.muxal.mp4. 1872 + 00:28:09.020 --> 00:28:13.260 1873 + And we would have needed an H two six four backup anyway, in that context. 1874 1874 1875 1875 469 1876 - 00:26:40.000 --> 00:26:41.000 1877 - Right. 1876 + 00:28:13.260 --> 00:28:15.800 1877 + That's why we started with H two six four, but yeah, definitely 1878 1878 1879 1879 470 1880 - 00:26:41.000 --> 00:26:44.000 1881 - So we've, the thing that is, I've been saying on your computer, but the thing 1880 + 00:28:15.800 --> 00:28:16.700 1881 + want to support lots of codex. 1882 1882 1883 1883 471 1884 - 00:26:44.000 --> 00:26:50.000 1885 - for video, the thing that's in your at proto repository is, is just one big 1884 + 00:28:18.020 --> 00:28:18.520 1885 + Yeah. 1886 1886 1887 1887 472 1888 - 00:26:50.000 --> 00:26:51.000 1889 - MP4 file. 1890 - 1891 - 473 1892 - 00:26:51.000 --> 00:26:56.000 1893 - That's really easy to understand. 1894 - 1895 - 474 1896 - 00:26:56.000 --> 00:27:04.000 1897 - The other, the other thing we get from this is, is the Blake three Sid, the 1898 - 1899 - 475 1900 - 00:27:04.000 --> 00:27:05.000 1901 - magic of Blake three. 1902 - 1903 - 476 1904 - 00:27:05.000 --> 00:27:08.000 1905 - Why, why was it that all those video engineers were telling me that I needed 1906 - 1907 - 477 1908 - 00:27:08.000 --> 00:27:09.000 1909 - to use Blake three? 1910 - 1911 - 478 1912 - 00:27:09.000 --> 00:27:18.000 1913 - It's because this Blake three hash is a Merkle tree over this file that you see 1914 - 1915 - 479 1916 - 00:27:18.000 --> 00:27:21.000 1917 - here, which means you can request to just that part that says track one, gop 1918 - 1919 - 480 1920 - 00:27:21.000 --> 00:27:27.000 1921 - one there and and through cryptographic verification, you can be 100% confident 1922 - 1923 - 481 1924 - 00:27:27.000 --> 00:27:31.000 1925 - that that is the correct data that you've pulled out of there. 1926 - 1927 - 482 1928 - 00:27:31.000 --> 00:27:32.000 1929 - Right. 1930 - 1931 - 483 1932 - 00:27:32.000 --> 00:27:35.000 1933 - You can verify, yes, this is in fact part of this Blake three Sid, which is 1934 - 1935 - 484 1936 - 00:27:35.000 --> 00:27:40.000 1937 - really, really useful when you're doing something like a CDN because then you 1938 - 1939 - 485 1940 - 00:27:40.000 --> 00:27:44.000 1941 - can make all these, you can have be backing it with just one big file. 1942 - 1943 - 486 1944 - 00:27:44.000 --> 00:27:46.000 1945 - You can make these bite range requests. 1946 - 1947 - 487 1948 - 00:27:46.000 --> 00:27:50.000 1949 - You still get the cryptographic integrity that like, oh yes, that, that, that hash 1950 - 1951 - 488 1952 - 00:27:50.000 --> 00:27:54.000 1953 - matches what I saw in Eli's at proto repository. 1954 - 1955 - 489 1956 - 00:27:54.000 --> 00:27:57.000 1957 - So this is a really, really good format for this. 1958 - 1959 - 490 1960 - 00:27:57.000 --> 00:27:58.000 1961 - Cool. 1962 - 1963 - 491 1964 - 00:27:58.000 --> 00:28:06.000 1965 - So yes, three different formats that we, that we have here. 1966 - 1967 - 492 1968 - 00:28:06.000 --> 00:28:11.000 1969 - So the archival format, which is the big MP4 file that goes in your app proto 1970 - 1971 - 493 1972 - 00:28:11.000 --> 00:28:16.000 1973 - repository, the self certifying format, which is the part that has the CTP a 1974 - 1975 - 494 1976 - 00:28:16.000 --> 00:28:19.000 1977 - signature attached and the streaming format, which is just when you're actually 1978 - 1979 - 495 1980 - 00:28:19.000 --> 00:28:22.000 1981 - sending it out, you just send, you just send this part, right? 1982 - 1983 - 496 1984 - 00:28:22.000 --> 00:28:27.000 1985 - You stream this stuff, each, each frame of video and audio directly to use. 1986 - 1987 - 497 1988 - 00:28:27.000 --> 00:28:32.000 1989 - So for all the at proto people that didn't care about all the different 1990 - 1991 - 498 1992 - 00:28:32.000 --> 00:28:36.000 1993 - structures of the MP4 file, how do you use all of this? 1994 - 1995 - 499 1996 - 00:28:36.000 --> 00:28:39.000 1997 - We're not quite ready for it, but the very first vods available on stream 1998 - 1999 - 500 2000 - 00:28:39.000 --> 00:28:41.000 2001 - place are going to follow this format. 2002 - 2003 - 501 2004 - 00:28:41.000 --> 00:28:44.000 2005 - And it's going to be all of the talks from this conference. 2006 - 2007 - 502 2008 - 00:28:44.000 --> 00:28:48.000 2009 - They will be published to at proto repository and you'll be able to work 2010 - 2011 - 503 2012 - 00:28:48.000 --> 00:28:49.000 2013 - with them. 2014 - 2015 - 504 2016 - 00:28:49.000 --> 00:28:53.000 2017 - This is a little preview of what this looks like. 2018 - 2019 - 505 2020 - 00:28:54.000 --> 00:28:58.000 2021 - So we have a, uh, yeah. 2022 - 2023 - 506 2024 - 00:28:58.000 --> 00:29:03.000 2025 - So the man, as you might expect the, the lexicon type for this is a place.stream.video. 2026 - 2027 - 507 2028 - 00:29:03.000 --> 00:29:05.000 2029 - It's got, uh, things like creator. 2030 - 2031 - 508 2032 - 00:29:05.000 --> 00:29:09.000 2033 - Um, some of the, some of this metadata in here, this is like, I'm pretending this 2034 - 2035 - 509 2036 - 00:29:09.000 --> 00:29:10.000 2037 - is the one for this talk. 2038 - 2039 - 510 2040 - 00:29:10.000 --> 00:29:13.000 2041 - I don't have a vod for this talk because I'm still doing this talk. 2042 - 2043 - 511 2044 - 00:29:13.000 --> 00:29:14.000 2045 - So you don't know what the hash is yet. 2046 - 2047 - 512 2048 - 00:29:14.000 --> 00:29:18.000 2049 - Um, it's got, it's just, as I said, it's just a blob. 2050 - 2051 - 513 2052 - 00:29:18.000 --> 00:29:20.000 2053 - It's a video MP4 file. 2054 - 2055 - 514 2056 - 00:29:20.000 --> 00:29:23.000 2057 - Um, but it is very, very easily cashable. 2058 - 2059 - 515 2060 - 00:29:23.000 --> 00:29:26.000 2061 - Um, you've got a nanosecond duration in there. 2062 - 2063 - 516 2064 - 00:29:26.000 --> 00:29:30.000 2065 - Uh, we, the design constraints for this, I've been targeting that the maximum 2066 - 2067 - 517 2068 - 00:29:30.000 --> 00:29:33.000 2069 - length of one of these is going to be 24 hours. 2070 - 2071 - 518 2072 - 00:29:33.000 --> 00:29:37.000 2073 - Um, because, uh, at a certain point it gets ridiculous. 2074 - 2075 - 519 2076 - 00:29:37.000 --> 00:29:39.000 2077 - Yeah. 2078 - 2079 - 520 2080 - 00:29:39.000 --> 00:29:42.000 2081 - Uh, and I don't want to like overflow the nanosecond duration, but if you've got 2082 - 2083 - 521 2084 - 00:29:42.000 --> 00:29:45.000 2085 - a 24 seven live stream, that seems like a reasonable primitive that like each day 2086 - 2087 - 522 2088 - 00:29:45.000 --> 00:29:49.000 2089 - of streaming that you would stream into would become its own vod, uh, with a 2090 - 2091 - 523 2092 - 00:29:49.000 --> 00:29:50.000 2093 - 24 hour duration. 2094 - 2095 - 524 2096 - 00:29:50.000 --> 00:29:51.000 2097 - Right. 2098 - 2099 - 525 2100 - 00:29:51.000 --> 00:29:53.000 2101 - Um, and then it's got a live stream reference. 2102 - 2103 - 526 2104 - 00:29:53.000 --> 00:29:55.000 2105 - So, uh, yeah. 2106 - 2107 - 527 2108 - 00:29:55.000 --> 00:29:57.000 2109 - So, uh, all of this will be available. 2110 - 2111 - 528 2112 - 00:29:57.000 --> 00:29:58.000 2113 - Yeah. 2114 - 2115 - 529 2116 - 00:29:58.000 --> 00:30:00.000 2117 - I was hoping to have all of this available and I was like, Oh, I got an 2118 - 2119 - 530 2120 - 00:30:00.000 --> 00:30:01.000 2121 - ounce in this talk and it's going to be big. 2122 - 2123 - 531 2124 - 00:30:01.000 --> 00:30:02.000 2125 - And we're like really, really close. 2126 - 2127 - 532 2128 - 00:30:02.000 --> 00:30:05.000 2129 - But I wasn't, I didn't want to push a bunch of changes to stream place right 2130 - 2131 - 533 2132 - 00:30:05.000 --> 00:30:08.000 2133 - before we did all the live streaming and screw everything else up. 2134 - 2135 - 534 2136 - 00:30:08.000 --> 00:30:09.000 2137 - Right. 2138 - 2139 - 535 2140 - 00:30:09.000 --> 00:30:12.000 2141 - So I, I, I did try to do that. 2142 - 2143 - 536 2144 - 00:30:12.000 --> 00:30:14.000 2145 - Uh, uh, we did that. 2146 - 2147 - 537 2148 - 00:30:14.000 --> 00:30:17.000 2149 - Uh, uh, I did at about seven 10 this morning. 2150 - 2151 - 538 2152 - 00:30:17.000 --> 00:30:19.000 2153 - I'm like, all right, let's push the muscle changes. 2154 - 2155 - 539 2156 - 00:30:19.000 --> 00:30:20.000 2157 - Let's see. 2158 - 2159 - 540 2160 - 00:30:20.000 --> 00:30:24.000 2161 - And then immediately that laptop couldn't stream into stream place anymore for 2162 - 2163 - 541 2164 - 00:30:24.000 --> 00:30:25.000 2165 - whatever reason. 2166 - 2167 - 542 2168 - 00:30:25.000 --> 00:30:26.000 2169 - So I was like, Nope, Nope, back revert. 2170 - 2171 - 543 2172 - 00:30:26.000 --> 00:30:28.000 2173 - We're going to, we'll do it. 2174 - 2175 - 544 2176 - 00:30:28.000 --> 00:30:29.000 2177 - We'll do it after. 2178 - 2179 - 545 2180 - 00:30:29.000 --> 00:30:33.000 2181 - Um, so that's all by way of saying this is all very, very close. 2182 - 2183 - 546 2184 - 00:30:33.000 --> 00:30:37.000 2185 - Um, and we're hoping to give it to the community very, very soon. 2186 - 2187 - 547 2188 - 00:30:37.000 --> 00:30:41.000 2189 - Um, and, uh, yeah, and then build it with everybody, right? 2190 - 2191 - 548 2192 - 00:30:41.000 --> 00:30:42.000 2193 - So we don't have a front end for it. 2194 - 2195 - 549 2196 - 00:30:42.000 --> 00:30:45.000 2197 - Um, I'm going to challenge the, we're going to do a little VOD jam and say, Hey, 2198 - 2199 - 550 2200 - 00:30:45.000 --> 00:30:48.000 2201 - at proto community, here's the videos, build me a front end for it. 2202 - 2203 - 551 2204 - 00:30:48.000 --> 00:30:52.000 2205 - Given that without me asking, we got three front ends for stream place in the 2206 - 2207 - 552 2208 - 00:30:52.000 --> 00:30:53.000 2209 - last three days. 2210 - 2211 - 553 2212 - 00:30:53.000 --> 00:30:56.000 2213 - I feel like in the vibe coding era, we're gonna, we're gonna get some 2214 - 2215 - 554 2216 - 00:30:56.000 --> 00:30:57.000 2217 - submissions. 2218 - 2219 - 555 2220 - 00:30:57.000 --> 00:31:01.000 2221 - If you submit one of these, uh, you're going to earn a badge next to your chat 2222 - 2223 - 556 2224 - 00:31:01.000 --> 00:31:06.000 2225 - name in stream place, um, from now until the end of time. 2226 - 2227 - 557 2228 - 00:31:06.000 --> 00:31:09.000 2229 - So, uh, yeah, that's it. 2230 - 2231 - 558 2232 - 00:31:09.000 --> 00:31:11.000 2233 - That's how stream place works. 2234 - 2235 - 559 2236 - 00:31:11.000 --> 00:31:38.000 2237 - So, uh, yeah, yeah. 2238 - 2239 - 560 2240 - 00:31:38.000 --> 00:31:42.000 2241 - So the big alternative, um, why MP4, uh, there's a couple of reasons. 2242 - 2243 - 561 2244 - 00:31:42.000 --> 00:31:47.000 2245 - Um, one because, uh, it's the most ubiquitous media format and the, that's the 2246 - 2247 - 562 2248 - 00:31:47.000 --> 00:31:49.000 2249 - most highly compatible across everything. 2250 - 2251 - 563 2252 - 00:31:49.000 --> 00:31:55.000 2253 - Um, the second is, um, it gives us the, uh, the, the, the media over quick stuff. 2254 - 2255 - 564 2256 - 00:31:55.000 --> 00:31:57.000 2257 - Um, uh, tends to support it a lot already. 2258 - 2259 - 565 2260 - 00:31:57.000 --> 00:32:04.000 2261 - Um, the, also the FM, uh, so this is like CMAF back to the, this thing, this is 2262 - 2263 - 566 2264 - 00:32:04.000 --> 00:32:06.000 2265 - like CMAF MP4 playback. 2266 - 2267 - 567 2268 - 00:32:06.000 --> 00:32:10.000 2269 - Um, and the advantage here is it lets you, um, separate out the, it gives you that 2270 - 2271 - 568 2272 - 00:32:10.000 --> 00:32:14.000 2273 - lack of redundancy that I was describing where the in it segment isn't, there are 2274 - 2275 - 569 2276 - 00:32:14.000 --> 00:32:17.000 2277 - other formats that embed all of that in it data in every segment, but we don't 2278 - 2279 - 570 2280 - 00:32:17.000 --> 00:32:20.000 2281 - actually want that because it's redundant for, for a long video. 2282 - 2283 - 571 2284 - 00:32:20.000 --> 00:32:26.000 2285 - So, um, yeah, those are the reasons. 2286 - 2287 - 572 2288 - 00:32:26.000 --> 00:32:27.000 2289 - Sure, sure, sure. 2290 - 2291 - 573 2292 - 00:32:27.000 --> 00:32:32.000 2293 - Uh, the question was why VP nine instead of, or why H two six four instead of, 2294 - 2295 - 574 2296 - 00:32:32.000 --> 00:32:35.000 2297 - uh, like VP nine or AV one, no reason other than maximally compact maximum 2298 - 2299 - 575 2300 - 00:32:35.000 --> 00:32:36.000 2301 - compatibility right now. 2302 - 2303 - 576 2304 - 00:32:36.000 --> 00:32:40.000 2305 - We really, really want, uh, AV one in, in stream place. 2306 - 2307 - 577 2308 - 00:32:40.000 --> 00:32:45.000 2309 - Um, we fully intend to support AV one as much as we do H two six four, especially 2310 - 2311 - 578 2312 - 00:32:45.000 --> 00:32:48.000 2313 - when we do stuff like, like, uh, uh, I want to replace to do a lot of things 2314 - 2315 - 579 2316 - 00:32:48.000 --> 00:32:50.000 2317 - that no other streaming platforms do. 2318 - 2319 - 580 2320 - 00:32:50.000 --> 00:32:56.000 2321 - Like for example, uh, like 4k 120 FPS AV one video would be so sick. 2322 - 2323 - 581 2324 - 00:32:56.000 --> 00:32:58.000 2325 - Uh, uh, can't even do it. 2326 - 2327 - 582 2328 - 00:32:58.000 --> 00:32:59.000 2329 - I've tried to do it. 2330 - 2331 - 583 2332 - 00:32:59.000 --> 00:33:00.000 2333 - H two six four. 2334 - 2335 - 584 2336 - 00:33:00.000 --> 00:33:01.000 2337 - It just like doesn't, it did. 2338 - 2339 - 585 2340 - 00:33:01.000 --> 00:33:03.000 2341 - No encoder can even come close to handling that. 2342 - 2343 - 586 2344 - 00:33:03.000 --> 00:33:04.000 2345 - So, um, yeah, yeah. 2346 - 2347 - 587 2348 - 00:33:04.000 --> 00:33:07.000 2349 - Uh, in terms of codec support, we want to support like every codec that it makes 2350 - 2351 - 588 2352 - 00:33:07.000 --> 00:33:10.000 2353 - sense to, we just started with this because we're not quite in a world where 2354 - 2355 - 589 2356 - 00:33:10.000 --> 00:33:12.000 2357 - I could probably get away with AV one only. 2358 - 2359 - 590 2360 - 00:33:12.000 --> 00:33:17.000 2361 - And we would have needed an H two six four backup anyway in that context. 2362 - 2363 - 591 2364 - 00:33:17.000 --> 00:33:20.000 2365 - That's why we started with H two six four, but yeah, definitely want to support 2366 - 2367 - 592 2368 - 00:33:20.000 --> 00:33:22.000 2369 - lots of codecs. 2370 - 2371 - 593 2372 - 00:33:28.000 --> 00:33:30.000 1888 + 00:28:24.560 --> 00:28:24.900 2373 1889 Thank you. 2374 1890 2375 - 594 2376 - 00:33:34.000 --> 00:33:37.000 2377 - Thanks. 2378 -
+2502 -74
public/subtitles/landslide.vtt
··· 1 1 WEBVTT 2 2 3 3 1 4 - 00:00:00.000 --> 00:00:02.800 5 - many forms of machine assistance. 4 + 00:00:00.000 --> 00:00:11.100 5 + I'm just going to say that because this is the kind of conference that it is with many 6 6 7 7 2 8 - 00:00:02.800 --> 00:00:06.900 9 - And this moment is our window for bending the future 8 + 00:00:11.100 --> 00:00:16.340 9 + streams of information and in some cases multiple sources of truth, you may have seen that the 10 10 11 11 3 12 - 00:00:06.900 --> 00:00:10.120 13 - around our hopes and values that cherish knowledge 12 + 00:00:16.340 --> 00:00:18.220 13 + title of my talk is Landslide. 14 14 15 15 4 16 - 00:00:10.120 --> 00:00:12.560 17 - and communal knowing, and that orient us 16 + 00:00:18.220 --> 00:00:21.420 17 + You may also have seen the title of my talk is Hold Fast. 18 18 19 19 5 20 - 00:00:12.560 --> 00:00:16.840 21 - toward real remedies for some of our most ancient information 20 + 00:00:21.420 --> 00:00:25.660 21 + Both things are true at the same time because I gave Ted the information at different times. 22 22 23 23 6 24 - 00:00:16.840 --> 00:00:21.160 25 - troubles and pains in service of living together 24 + 00:00:25.660 --> 00:00:35.180 25 + So we're doing Landslide Hold Fast. 26 26 27 27 7 28 - 00:00:21.160 --> 00:00:24.040 29 - in peace and mutual respect. 28 + 00:00:35.180 --> 00:00:37.180 29 + One more glitch. 30 30 31 31 8 32 - 00:00:24.040 --> 00:00:26.040 33 - Thank you. 32 + 00:00:37.180 --> 00:00:38.980 33 + So hi, I'm Erin. 34 34 35 35 9 36 - 00:00:55.040 --> 00:01:02.240 37 - Truly, truly, leaning toward the wrong mic, 36 + 00:00:38.980 --> 00:00:44.440 37 + I alternate between trying to figure out what the social Internet is doing to us and trying 38 38 39 39 10 40 - 00:01:02.240 --> 00:01:04.640 41 - if you're working on this stuff, if you care about working 40 + 00:00:44.440 --> 00:00:48.900 41 + to use it to get better information to more people in more places. 42 42 43 43 11 44 - 00:01:04.640 --> 00:01:05.760 45 - on this stuff, let's talk. 44 + 00:00:48.900 --> 00:00:54.660 45 + So right now I'm doing network thinking and projects at my mini studio, wreckage salvage 46 46 47 47 12 48 - 00:01:05.760 --> 00:01:06.600 49 - That's why I'm here. 48 + 00:00:54.660 --> 00:01:00.740 49 + and also co-running a networked volunteer mutual aid information project at Unbreaking, 50 50 51 51 13 52 - 00:01:06.600 --> 00:01:10.440 53 - I gave this talk so they'd let me in the door. 52 + 00:01:00.740 --> 00:01:05.220 53 + also a project of the RAAF Foundation. 54 54 55 55 14 56 - 00:01:10.440 --> 00:01:12.360 57 - But I want to talk to people who are actually 56 + 00:01:05.220 --> 00:01:08.860 57 + We work to nail down knowledge about what our government is doing to us in the United 58 58 59 59 15 60 - 00:01:12.360 --> 00:01:13.360 61 - trying to fix this. 60 + 00:01:08.860 --> 00:01:10.740 61 + States. 62 62 63 63 16 64 - 00:01:13.360 --> 00:01:16.400 65 - Thank you. 64 + 00:01:10.740 --> 00:01:14.300 65 + Before that I co-founded the COVID tracking project at the Atlantic. 66 66 67 67 17 68 - 00:01:16.400 --> 00:01:20.160 69 - We have no time for Q&A. 68 + 00:01:14.300 --> 00:01:22.020 69 + This was before the Atlantic. 70 70 71 71 18 72 - 00:01:20.160 --> 00:01:22.120 73 - I didn't feel that service. 72 + 00:01:22.020 --> 00:01:26.260 73 + That was to help people understand what was happening in 2020 through public data. 74 74 75 75 19 76 - 00:01:22.120 --> 00:01:23.440 77 - We went a couple of minutes over. 76 + 00:01:26.260 --> 00:01:31.460 77 + Before that I was at a journalism tech community that came out of the Moz Foundation. 78 78 79 79 20 80 - 00:01:23.640 --> 00:01:24.960 81 - Let's go. 80 + 00:01:31.460 --> 00:01:35.220 81 + Before that it was all over the early web. 82 82 83 83 21 84 - 00:01:24.960 --> 00:01:28.680 85 - We are blessed with this awesome talk to kick us off, 84 + 00:01:35.220 --> 00:01:36.380 85 + So that's the nature of my work. 86 86 87 87 22 88 - 00:01:28.680 --> 00:01:31.680 89 - but we are also running a little bit late. 88 + 00:01:36.380 --> 00:01:39.740 89 + I use the tools and I try to improve the tools and then I repeat. 90 90 91 91 23 92 - 00:01:31.680 --> 00:01:35.840 93 - We will be joined here in this room by Rudy Fraser. 92 + 00:01:39.740 --> 00:01:46.420 93 + What I learned from yesterday's amazing pre-conference experience is that many of you are in much 94 94 95 95 24 96 - 00:01:35.840 --> 00:01:39.440 97 - We've got Justin Bank in the performance theater, 96 + 00:01:46.420 --> 00:01:48.340 97 + the same position, which I love. 98 98 99 99 25 100 - 00:01:39.440 --> 00:01:44.160 101 - and we've got Mosh in the classroom at the end. 100 + 00:01:48.340 --> 00:01:52.780 101 + It's like a whole room of corner cases. 102 102 103 103 26 104 - 00:01:44.160 --> 00:01:46.840 105 - Rudy, groundings with my siblings, lessons learned, 104 + 00:01:52.780 --> 00:01:57.700 105 + I want to know what the networks are doing to us and what resources that people like 106 106 107 107 27 108 - 00:01:46.840 --> 00:01:49.720 109 - building for community. 108 + 00:01:57.700 --> 00:02:04.680 109 + us have to draw from to shape our networks in ways that ground and reorient our communities 110 110 111 111 28 112 - 00:01:49.720 --> 00:01:53.120 113 - Justin Bank, the aggregation era burn journalism 112 + 00:02:04.680 --> 00:02:13.540 113 + in useful knowledge and to maybe someday live together in peace and mutual respect. 114 114 115 115 29 116 - 00:01:53.120 --> 00:01:54.920 117 - institutions to the ground. 116 + 00:02:13.540 --> 00:02:17.500 117 + Right before the end of last year I posted another extremely long blog post, which is 118 118 119 119 30 120 - 00:01:54.920 --> 00:01:58.760 121 - The federated era is emerging from those embers. 120 + 00:02:17.500 --> 00:02:22.220 121 + my jam, called Landslided Ghost Story, in which I tried to get closer to the core of 122 122 123 123 31 124 - 00:01:58.760 --> 00:02:01.520 125 - And Mosh feature product business, a framework 124 + 00:02:22.220 --> 00:02:27.340 125 + our network's role in disorienting and disintegrating us. 126 126 127 127 32 128 - 00:02:01.520 --> 00:02:04.000 129 - for sustainable app portal projects. 128 + 00:02:27.340 --> 00:02:31.220 129 + I'll talk about that one a little bit here because the new work I'm bringing builds on 130 130 131 131 33 132 - 00:02:04.000 --> 00:02:06.200 133 - So we're going to reset. 132 + 00:02:31.220 --> 00:02:32.780 133 + it. 134 134 135 135 34 136 - 00:02:06.200 --> 00:02:07.920 137 - We're going to give you about five minutes. 136 + 00:02:32.780 --> 00:02:37.700 137 + This talk, I think, and I hope is kind of a turning point for my work and what I can 138 138 139 139 35 140 - 00:02:07.920 --> 00:02:10.840 141 - But if you can pick one of those three rooms, grab a coffee, 140 + 00:02:37.700 --> 00:02:41.460 141 + bring to you because I think I finally have a good enough handle on at least parts of 142 142 143 143 36 144 - 00:02:10.840 --> 00:02:13.440 145 - and head to your next destination. 144 + 00:02:41.460 --> 00:02:46.460 145 + this to be able to offer some paths forward that aren't either unattainable or just like 146 146 147 147 37 148 - 00:02:13.440 --> 00:02:14.480 149 - Thank you for joining us. 148 + 00:02:46.460 --> 00:02:49.940 149 + disproportionately paltry. 150 + 151 + 38 152 + 00:02:49.940 --> 00:02:51.460 153 + I want to make a side note. 154 + 155 + 39 156 + 00:02:51.460 --> 00:02:56.540 157 + I take it as a given that one major underlying problem that prevents us from dealing with 158 + 159 + 40 160 + 00:02:56.540 --> 00:03:00.340 161 + many other problems is centralization and lock-in, which decentralized networks are 162 + 163 + 41 164 + 00:03:00.340 --> 00:03:01.340 165 + here to deal with. 166 + 167 + 42 168 + 00:03:01.340 --> 00:03:06.180 169 + I just want to say I think that Jay and the rest of Blue Sky's founding team have done 170 + 171 + 43 172 + 00:03:06.180 --> 00:03:11.660 173 + us all a tremendous service by, yes, making Blue Sky the app, but especially in using 174 + 175 + 44 176 + 00:03:11.660 --> 00:03:17.040 177 + all of that available momentum to get this protocol ecosystem off the ground and stable 178 + 179 + 45 180 + 00:03:17.040 --> 00:03:21.180 181 + enough to support the kind of independent development that I saw happening yesterday 182 + 183 + 46 184 + 00:03:21.180 --> 00:03:23.020 185 + and that we'll be talking about here. 186 + 187 + 47 188 + 00:03:23.020 --> 00:03:25.380 189 + I assume basically universal concordance about this. 190 + 191 + 48 192 + 00:03:25.380 --> 00:03:29.020 193 + I'm not going to spend a lot of time talking about it, but I am so grateful for the work 194 + 195 + 49 196 + 00:03:29.020 --> 00:03:30.260 197 + that the team has accomplished. 198 + 199 + 50 200 + 00:03:30.260 --> 00:03:33.180 201 + I just want to say that. 202 + 203 + 51 204 + 00:03:33.180 --> 00:03:36.420 205 + There's so much good stuff happening around the protocol, and I'm super psyched to see 206 + 207 + 52 208 + 00:03:36.420 --> 00:03:39.440 209 + the next batch of it today. 210 + 211 + 53 212 + 00:03:39.440 --> 00:03:40.440 213 + Yesterday was incredible. 214 + 215 + 54 216 + 00:03:40.440 --> 00:03:45.980 217 + The work I have been doing is for you, and I brought a lot of things, so let's get to 218 + 219 + 55 220 + 00:03:45.980 --> 00:03:47.580 221 + it. 222 + 223 + 56 224 + 00:03:47.580 --> 00:03:56.340 225 + 62 years ago yesterday, on Good Friday in 1964, a tectonic plate up under Alaska slid 226 + 227 + 57 228 + 00:03:56.340 --> 00:04:01.900 229 + under another tectonic plate and produced an extraordinarily strong and sustained earthquake 230 + 231 + 58 232 + 00:04:01.900 --> 00:04:07.100 233 + that we now know to be the second highest magnitude quake in recorded history. 234 + 235 + 59 236 + 00:04:07.100 --> 00:04:11.900 237 + It actually reshaped the field of seismology, but more immediately it caused parts of the 238 + 239 + 60 240 + 00:04:11.900 --> 00:04:17.900 241 + Alaskan coast to drop by nearly 40 feet, rise by nearly 40 feet, dropped others down below 242 + 243 + 61 244 + 00:04:17.900 --> 00:04:22.940 245 + sea level, triggered enormous tsunamis, and according to geologists, it was so big that 246 + 247 + 62 248 + 00:04:22.940 --> 00:04:26.540 249 + it rang the planet like a bell. 250 + 251 + 63 252 + 00:04:26.540 --> 00:04:32.460 253 + Alaska is not densely populated, but this is what the earthquake looked like in, this 254 + 255 + 64 256 + 00:04:32.460 --> 00:04:33.800 257 + is an anchorage. 258 + 259 + 65 260 + 00:04:33.800 --> 00:04:38.200 261 + In cities and towns, you see the kind of damage you'd expect at tore up streets and knockdown 262 + 263 + 66 264 + 00:04:38.200 --> 00:04:43.420 265 + buildings, and in Alaska, 139 people died. 266 + 267 + 67 268 + 00:04:43.420 --> 00:04:51.500 269 + It also did something exceptionally weird and horrific in the port town of Valdez. 270 + 271 + 68 272 + 00:04:51.980 --> 00:04:58.980 273 + Valdez is the northernmost year round ice free deep water port in North America and 274 + 275 + 69 276 + 00:04:58.980 --> 00:05:04.300 277 + the southern end of the Trans-Alaska oil pipeline. 278 + 279 + 70 280 + 00:05:04.300 --> 00:05:09.260 281 + My partner grew up in Valdez, so I heard about the earthquake and how weird it had been from 282 + 283 + 71 284 + 00:05:09.260 --> 00:05:14.780 285 + him, and my father-in-law worked at the Valdez Museum and had produced a video from some 286 + 287 + 72 288 + 00:05:14.780 --> 00:05:18.820 289 + of this really wild, grainy, contemporary footage of the quake, so when we went up to 290 + 291 + 73 292 + 00:05:18.820 --> 00:05:20.820 293 + visit I got to see that. 294 + 295 + 74 296 + 00:05:21.140 --> 00:05:27.580 297 + Much later, my family moved to the Cascadia subduction zone, and I became an earthquake 298 + 299 + 75 300 + 00:05:27.580 --> 00:05:30.660 301 + nerd, as one does. 302 + 303 + 76 304 + 00:05:30.660 --> 00:05:36.300 305 + I sort of just poked at this story and the records out of Valdez as part of my insomnia 306 + 307 + 77 308 + 00:05:36.300 --> 00:05:40.820 309 + rounds of upsetting things to look at in the middle of the night, but it kind of stayed 310 + 311 + 78 312 + 00:05:40.820 --> 00:05:46.140 313 + in the background until the end of last year when I discovered that the US Geological Survey 314 + 315 + 79 316 + 00:05:46.140 --> 00:05:51.700 317 + had produced a new cut of that weird film footage from the Valdez Harbor. 318 + 319 + 80 320 + 00:05:51.700 --> 00:05:59.380 321 + I'm not going to show it to you, but it is in the landslide post on my site. 322 + 323 + 81 324 + 00:05:59.380 --> 00:06:04.180 325 + The footage only existed because a supply ship, the SS China, had come into the harbor 326 + 327 + 82 328 + 00:06:04.180 --> 00:06:09.500 329 + right before the quake, and someone on the ship happened to have an 8mm camera and happened 330 + 331 + 83 332 + 00:06:09.500 --> 00:06:13.500 333 + to be filming the crew just like dorking around on deck and throwing oranges and candy to 334 + 335 + 84 336 + 00:06:13.500 --> 00:06:17.500 337 + the kids who'd come down to the docks and meet the ship. 338 + 339 + 85 340 + 00:06:17.500 --> 00:06:22.140 341 + But I'd only ever seen the footage in a form that turned out to be highly manipulated, 342 + 343 + 86 344 + 00:06:22.140 --> 00:06:28.620 345 + and the reconstructed cut from USGS revealed that the shots we always thought were of the 346 + 347 + 87 348 + 00:06:28.620 --> 00:06:36.980 349 + water of the local tsunami produced by the quake were actually of the land, which had 350 + 351 + 88 352 + 00:06:36.980 --> 00:06:44.020 353 + just turned to liquid and flowed out from under everything it was supporting. 354 + 355 + 89 356 + 00:06:44.020 --> 00:06:50.660 357 + That's what used to be the harbor, and it all just fell in the sea, and the footage 358 + 359 + 90 360 + 00:06:50.660 --> 00:06:54.340 361 + actually shows it just pouring out from under these buildings. 362 + 363 + 91 364 + 00:06:54.340 --> 00:07:00.060 365 + That re-sequence footage remains the single most upsetting piece of film I have ever seen 366 + 367 + 92 368 + 00:07:00.060 --> 00:07:05.340 369 + because the destabilization it depicts is happening at the level of basic physics, which 370 + 371 + 93 372 + 00:07:05.340 --> 00:07:08.540 373 + is gross and weird. 374 + 375 + 94 376 + 00:07:08.540 --> 00:07:12.580 377 + So here's what happened in Valdez, based on everything we know now. 378 + 379 + 95 380 + 00:07:12.580 --> 00:07:17.700 381 + The town was built on glacial moraine, which is this disorganized debris piled up by a 382 + 383 + 96 384 + 00:07:17.700 --> 00:07:23.420 385 + glacier, and down near the shoreline, that jumble of unconsolidated rock and sand went 386 + 387 + 97 388 + 00:07:23.420 --> 00:07:27.260 389 + down 600 feet before you hit bedrock. 390 + 391 + 98 392 + 00:07:27.260 --> 00:07:31.580 393 + And building on the moraine was not an obviously bad idea because it was still solid ground. 394 + 395 + 99 396 + 00:07:31.580 --> 00:07:35.340 397 + You could step on it or drive on it, and it's fine because the contact forces between 398 + 399 + 100 400 + 00:07:35.340 --> 00:07:38.220 401 + the particles would distribute the load. 402 + 403 + 101 404 + 00:07:38.220 --> 00:07:41.180 405 + But Valdez is also extremely wet. 406 + 407 + 102 408 + 00:07:41.180 --> 00:07:46.220 409 + In the winter, it's no so much people have to shovel their roofs to keep them from collapsing. 410 + 411 + 103 412 + 00:07:46.220 --> 00:07:50.620 413 + And the water table down there by the shoreline is just a few feet from the surface of the 414 + 415 + 104 416 + 00:07:50.620 --> 00:07:51.620 417 + town. 418 + 419 + 105 420 + 00:07:51.620 --> 00:07:57.740 421 + So in late March of 1964, between that just like barely subterranean water and the melt 422 + 423 + 106 424 + 00:07:57.740 --> 00:08:05.660 425 + from these exceptionally heavy snows, that loose jumbled substrate was flooded, was completely 426 + 427 + 107 428 + 00:08:05.660 --> 00:08:07.900 429 + saturated. 430 + 431 + 108 432 + 00:08:07.900 --> 00:08:13.220 433 + And it turns out that when a series of extraordinarily heavy and repeated shocks like this particular 434 + 435 + 109 436 + 00:08:13.220 --> 00:08:18.620 437 + earthquake hit a loose substrate that's also completely saturated with water, the compression 438 + 439 + 110 440 + 00:08:18.620 --> 00:08:26.060 441 + hits the water and pushes all those particles apart, and the solids just turn into liquid 442 + 443 + 111 444 + 00:08:26.060 --> 00:08:29.980 445 + almost instantly and flow away and everything falls in. 446 + 447 + 112 448 + 00:08:29.980 --> 00:08:36.580 449 + And in Valdez, the whole harbor flowed away and took out everything and everyone on it. 450 + 451 + 113 452 + 00:08:36.580 --> 00:08:43.020 453 + So this is the three-part model of how this particularly horrific thing works. 454 + 455 + 114 456 + 00:08:43.020 --> 00:08:48.420 457 + We've seen this elsewhere now, but we never had, especially we never had footage of anything 458 + 459 + 115 460 + 00:08:48.420 --> 00:08:49.420 461 + like this. 462 + 463 + 116 464 + 00:08:49.420 --> 00:08:55.700 465 + There were like some very loose records of what's called soil liquefaction. 466 + 467 + 117 468 + 00:08:55.700 --> 00:08:59.700 469 + I don't recommend that you go look for videos of soil liquefaction. 470 + 471 + 118 472 + 00:08:59.700 --> 00:09:03.780 473 + I was down this rabbit hole in December, the same time I was trying to take stock of almost 474 + 475 + 119 476 + 00:09:03.780 --> 00:09:08.060 477 + a year of work at Unbreaking where we're just kind of down slogging through the mud of our 478 + 479 + 120 480 + 00:09:08.060 --> 00:09:09.060 481 + information landscape. 482 + 483 + 121 484 + 00:09:09.060 --> 00:09:14.300 485 + And I was trying to understand like the networks piece and also the underlying like journalism 486 + 487 + 122 488 + 00:09:14.300 --> 00:09:20.260 489 + shaped stuff that's supposed to produce distributable knowledge and how our collective understanding 490 + 491 + 123 492 + 00:09:20.260 --> 00:09:24.260 493 + was faring against repeated and violent shocks. 494 + 495 + 124 496 + 00:09:24.260 --> 00:09:28.980 497 + So I wrote a lot of words about the information substrate and the saturation and flooding 498 + 499 + 125 500 + 00:09:28.980 --> 00:09:33.660 501 + of network-based overload and how those two things together produce a colossal vulnerability 502 + 503 + 126 504 + 00:09:33.660 --> 00:09:34.660 505 + to shocks. 506 + 507 + 127 508 + 00:09:34.660 --> 00:09:38.580 509 + And I'm going to lay those out super quickly here just to get them on the table so we can 510 + 511 + 128 512 + 00:09:38.580 --> 00:09:41.900 513 + move on to the good stuff. 514 + 515 + 129 516 + 00:09:41.900 --> 00:09:47.780 517 + So starting with the substrate, in the US where I'm from and in many other parts of 518 + 519 + 130 520 + 00:09:47.780 --> 00:09:52.740 521 + the world, our underlying foundational knowledge systems have taken a lot of damage. 522 + 523 + 131 524 + 00:09:52.740 --> 00:09:58.500 525 + Like the business model underlying our media continues down this decades-long death spiral. 526 + 527 + 132 528 + 00:09:58.500 --> 00:10:03.500 529 + And media consolidation which preceded the damage wrought by the internet by many decades 530 + 531 + 133 532 + 00:10:03.500 --> 00:10:09.380 533 + continues to degrade and squeeze and hollow out a lot of our most, well, formerly most 534 + 535 + 134 536 + 00:10:09.380 --> 00:10:13.620 537 + trustworthy sources of current information and basic analysis. 538 + 539 + 135 540 + 00:10:13.620 --> 00:10:15.700 541 + But it's not just journalism. 542 + 543 + 136 544 + 00:10:15.700 --> 00:10:20.220 545 + Extractive practices at every part of the knowledge production chain has dealt tremendous 546 + 547 + 137 548 + 00:10:20.220 --> 00:10:23.420 549 + damage to our whole ecosystem. 550 + 551 + 138 552 + 00:10:23.420 --> 00:10:26.900 553 + I have on my hard drive enough for like a dozen talks about what's happened to basic 554 + 555 + 139 556 + 00:10:26.900 --> 00:10:32.700 557 + research and peer review and academic presses and general presses and even like web search, 558 + 559 + 140 560 + 00:10:32.700 --> 00:10:37.740 561 + the niches that used to support independent writers and artists and some of our most recent 562 + 563 + 141 564 + 00:10:37.740 --> 00:10:42.660 565 + knowledge consolidating institutions like Stack Overflow and Wikipedia are beginning 566 + 567 + 142 568 + 00:10:42.660 --> 00:10:44.540 569 + to suffer. 570 + 571 + 143 572 + 00:10:44.540 --> 00:10:50.100 573 + And all of this hollowing out has been accompanied by an upwelling of things that we wouldn't 574 + 575 + 144 576 + 00:10:50.100 --> 00:10:56.820 577 + traditionally call news that range from genuinely vital eyewitness videos through outright and 578 + 579 + 145 580 + 00:10:56.820 --> 00:11:02.260 581 + well-funded propaganda farms to purely fact-free slop. 582 + 583 + 146 584 + 00:11:02.260 --> 00:11:09.540 585 + And all of this is enmeshed with the news organizations primarily devoted to discrediting 586 + 587 + 147 588 + 00:11:09.540 --> 00:11:14.980 589 + real reporting and presented through social platforms that in many cases deliberately 590 + 591 + 148 592 + 00:11:14.980 --> 00:11:19.780 593 + shape the subset of available information to evade responsibility for misinformation 594 + 595 + 149 596 + 00:11:19.780 --> 00:11:25.400 597 + and also to suit sort of our own worst selves desires. 598 + 599 + 150 600 + 00:11:25.400 --> 00:11:28.140 601 + So this is not great. 602 + 603 + 151 604 + 00:11:28.140 --> 00:11:34.220 605 + And then we also have just the massive proliferation of information that I feel like we've just 606 + 607 + 152 608 + 00:11:34.220 --> 00:11:38.100 609 + about lost a way to talk about maybe because we're so buried in it. 610 + 611 + 153 612 + 00:11:38.100 --> 00:11:40.020 613 + The science folks bring it up. 614 + 615 + 154 616 + 00:11:40.020 --> 00:11:44.460 617 + And that was extremely heartening to hear them acknowledging that's what they do, that 618 + 619 + 155 620 + 00:11:44.460 --> 00:11:46.020 621 + the knowledge crafting. 622 + 623 + 156 624 + 00:11:46.020 --> 00:11:52.940 625 + But this phenomenon of exponential hyperproliferation and information overload is a real one with 626 + 627 + 157 628 + 00:11:52.940 --> 00:11:58.540 629 + a large and solid body of evidence about its genuinely damaging psychological and emotional 630 + 631 + 158 632 + 00:11:58.540 --> 00:12:01.020 633 + and physical effects. 634 + 635 + 159 636 + 00:12:01.020 --> 00:12:05.940 637 + And we've been making filters and developing practices to cope with this with too much 638 + 639 + 160 640 + 00:12:05.940 --> 00:12:11.900 641 + information since we invented writing and complaining about it the whole time. 642 + 643 + 161 644 + 00:12:11.900 --> 00:12:15.900 645 + The history of information overload is amazing. 646 + 647 + 162 648 + 00:12:15.900 --> 00:12:22.060 649 + But our latest filters including web search and social media algorithms and now the LLMs 650 + 651 + 163 652 + 00:12:22.060 --> 00:12:28.300 653 + are not necessarily filtering our flood in ways that actually serve us well. 654 + 655 + 164 656 + 00:12:28.300 --> 00:12:33.860 657 + And many of us too have lost faith in some of the sort of stolid older filters because 658 + 659 + 165 660 + 00:12:33.860 --> 00:12:39.020 661 + we can see that they're not representing the reality that we find in eyewitness videos 662 + 663 + 166 664 + 00:12:39.020 --> 00:12:40.900 665 + and first person accounts. 666 + 667 + 167 668 + 00:12:40.900 --> 00:12:45.700 669 + So maybe we decide to let go of those filters too and the more filters we opt out of the 670 + 671 + 168 672 + 00:12:45.700 --> 00:12:48.900 673 + more we expose ourselves to the flood. 674 + 675 + 169 676 + 00:12:48.900 --> 00:12:54.460 677 + But at least when we do that we're getting access to more knowledge. 678 + 679 + 170 680 + 00:12:54.460 --> 00:12:59.020 681 + So this is a question social scientists have spent a lot of time and funding trying to 682 + 683 + 171 684 + 00:12:59.020 --> 00:13:00.500 685 + figure out. 686 + 687 + 172 688 + 00:13:00.500 --> 00:13:05.900 689 + And the emerging consensus is that for most people most of the time keeping up with current 690 + 691 + 173 692 + 00:13:05.900 --> 00:13:13.140 693 + events via our social feeds produces something very near to zero gains in our knowledge about 694 + 695 + 174 696 + 00:13:13.140 --> 00:13:15.340 697 + civics and politics. 698 + 699 + 175 700 + 00:13:15.340 --> 00:13:19.420 701 + We see a lot of things go by and we feel a lot of feelings about them. 702 + 703 + 176 704 + 00:13:19.420 --> 00:13:24.700 705 + But by and large we are not actually building much knowledge in our human brains. 706 + 707 + 177 708 + 00:13:24.700 --> 00:13:28.460 709 + But I feel kind of cautious about this research because it blends together a lot of different 710 + 711 + 178 712 + 00:13:28.460 --> 00:13:30.060 713 + ways to use social media. 714 + 715 + 179 716 + 00:13:30.060 --> 00:13:36.860 717 + And I think those of us in this room are probably outliers in how we use it. 718 + 719 + 180 720 + 00:13:36.860 --> 00:13:40.620 721 + In most cases like news, the researchers are just talking about a specific thing which 722 + 723 + 181 724 + 00:13:40.620 --> 00:13:48.540 725 + is links to news stories being passed around and not like mega threads of analysis or videos 726 + 727 + 182 728 + 00:13:48.540 --> 00:13:51.220 729 + by particularly gifted explainers. 730 + 731 + 183 732 + 00:13:51.220 --> 00:13:54.180 733 + But even with those caveats the numbers are not good. 734 + 735 + 184 736 + 00:13:54.180 --> 00:14:00.220 737 + There's a very recent and thorough meta analysis on whether we gain political or civic knowledge 738 + 739 + 185 740 + 00:14:00.220 --> 00:14:08.500 741 + from social media exposure that has persuasive results that on the whole we really just don't. 742 + 743 + 186 744 + 00:14:08.500 --> 00:14:11.780 745 + Which doesn't mean that outliers don't exist. 746 + 747 + 187 748 + 00:14:11.780 --> 00:14:15.700 749 + But it does mean unless we're only building for outliers we should recognize that the 750 + 751 + 188 752 + 00:14:15.700 --> 00:14:21.980 753 + combination of social media and human brains does not on average produce workable knowledge 754 + 755 + 189 756 + 00:14:21.980 --> 00:14:24.000 757 + about what's happening. 758 + 759 + 190 760 + 00:14:24.000 --> 00:14:27.520 761 + So that's bad but there's worse. 762 + 763 + 191 764 + 00:14:27.520 --> 00:14:34.200 765 + We also have pretty solid although somewhat less evidenced research that on the whole 766 + 767 + 192 768 + 00:14:34.200 --> 00:14:38.240 769 + we don't just fail to learn things from our social feeds. 770 + 771 + 193 772 + 00:14:38.240 --> 00:14:45.360 773 + We also come away from them feeling more confident in our knowledge that we don't have. 774 + 775 + 194 776 + 00:14:45.360 --> 00:14:51.080 777 + Which is also closely connected to my all time least favorite research on cognition 778 + 779 + 195 780 + 00:14:51.160 --> 00:14:55.200 781 + which is on the illusion of explanatory depth. 782 + 783 + 196 784 + 00:14:55.200 --> 00:14:58.000 785 + Who knows about the illusion of explanatory depth. 786 + 787 + 197 788 + 00:14:58.000 --> 00:14:59.520 789 + Oh great. 790 + 791 + 198 792 + 00:14:59.520 --> 00:15:01.640 793 + Okay we'll get to that later. 794 + 795 + 199 796 + 00:15:01.640 --> 00:15:08.480 797 + For now I want to underline that not knowing things we might need to know is bad but lacking 798 + 799 + 200 800 + 00:15:08.480 --> 00:15:17.080 801 + the epistemic humility to know that we might need to go learn them is probably worse. 802 + 803 + 201 804 + 00:15:17.080 --> 00:15:23.800 805 + And then there's the emotional dimension of the flood. 806 + 807 + 202 808 + 00:15:23.800 --> 00:15:28.600 809 + Which I want to talk about in strictly human terms and without laundering it through social 810 + 811 + 203 812 + 00:15:28.600 --> 00:15:35.160 813 + science which is not to pick on the highbrow moral panic about the internet folks. 814 + 815 + 204 816 + 00:15:35.160 --> 00:15:36.160 817 + Although it is. 818 + 819 + 205 820 + 00:15:36.160 --> 00:15:41.440 821 + But I think many of our dominant critical lenses on our networks and what they do to 822 + 823 + 206 824 + 00:15:41.440 --> 00:15:48.440 825 + society are essentially laundering genuine affective feelings trouble through selective 826 + 827 + 207 828 + 00:15:48.440 --> 00:15:53.160 829 + and often irresponsibly represented social science and neurological research to present 830 + 831 + 208 832 + 00:15:53.160 --> 00:15:57.440 833 + themselves as unshakably authoritative policy prescriptions. 834 + 835 + 209 836 + 00:15:57.440 --> 00:16:04.400 837 + And I took the anxious generation slide out of this talk but please note that it was there. 838 + 839 + 210 840 + 00:16:04.400 --> 00:16:08.520 841 + There are responsible ways to work with the science and I try to be really cautious when 842 + 843 + 211 844 + 00:16:08.520 --> 00:16:12.200 845 + I an epistemic trespasser do it. 846 + 847 + 212 848 + 00:16:12.200 --> 00:16:17.000 849 + But we don't even need it for conversations among ourselves because the affective stuff 850 + 851 + 213 852 + 00:16:17.000 --> 00:16:23.400 853 + is real and we experience countless ephemeral sort of news shaped bids for our attention 854 + 855 + 214 856 + 00:16:23.400 --> 00:16:28.440 857 + every day and most of us who hang out online experience them through highly emotive feeds 858 + 859 + 215 860 + 00:16:28.440 --> 00:16:32.960 861 + that lean toward volume and speed and never ending context collapse. 862 + 863 + 216 864 + 00:16:32.960 --> 00:16:36.240 865 + So for a lot of us it just feels bad. 866 + 867 + 217 868 + 00:16:36.240 --> 00:16:39.320 869 + And this is the saturating flood. 870 + 871 + 218 872 + 00:16:39.320 --> 00:16:41.420 873 + And then we get the shocks. 874 + 875 + 219 876 + 00:16:41.420 --> 00:16:46.880 877 + And in the landslide essay I focus pretty narrowly on the Trump regime's attack on the 878 + 879 + 220 880 + 00:16:46.880 --> 00:16:52.280 881 + idea of truth and on every viable model of building knowledge. 882 + 883 + 221 884 + 00:16:52.280 --> 00:16:59.220 885 + But the more important attack from the administration is that they are just doing deranged nonsensical 886 + 887 + 222 888 + 00:16:59.220 --> 00:17:03.460 889 + bullshit all the time. 890 + 891 + 223 892 + 00:17:03.460 --> 00:17:09.480 893 + Thank you. 894 + 895 + 224 896 + 00:17:09.480 --> 00:17:14.180 897 + And what that does to our ability to understand the world is still not as bad as what they 898 + 899 + 225 900 + 00:17:14.180 --> 00:17:20.960 901 + are actually doing to people and to economies and to countries and to sovereignties. 902 + 903 + 226 904 + 00:17:20.960 --> 00:17:26.740 905 + But it's still very bad because the only way out of this barring international intervention 906 + 907 + 227 908 + 00:17:26.940 --> 00:17:31.780 909 + is for Americans to pull our brains together and act. 910 + 911 + 228 912 + 00:17:31.780 --> 00:17:35.380 913 + And I don't know what your personal networks look like but a lot of people in almost every 914 + 915 + 229 916 + 00:17:35.380 --> 00:17:39.980 917 + part of mine in all my overlapping circles spent a lot of the last year in a state of 918 + 919 + 230 920 + 00:17:39.980 --> 00:17:46.940 921 + real disorientation about things like how is this not breaking the law and what is the 922 + 923 + 231 924 + 00:17:46.940 --> 00:17:49.420 925 + law even? 926 + 927 + 232 928 + 00:17:49.420 --> 00:17:53.340 929 + And this was true for almost everyone except for the folks who knew in advance that they 930 + 931 + 233 932 + 00:17:53.340 --> 00:17:57.900 933 + would be targeted and we're paying a different kind of attention. 934 + 935 + 234 936 + 00:17:57.900 --> 00:18:03.580 937 + But also unfortunately one bad regime is not the only kind of shock that we're experiencing 938 + 939 + 235 940 + 00:18:03.580 --> 00:18:05.900 941 + or will experience. 942 + 943 + 236 944 + 00:18:05.900 --> 00:18:11.200 945 + So I've spent the last few months reading more deeply in the research and also continuing 946 + 947 + 237 948 + 00:18:11.200 --> 00:18:16.860 949 + to plug away in the info minds that I'm breaking and bashing on some possibilities for building 950 + 951 + 238 952 + 00:18:16.860 --> 00:18:21.900 953 + ourselves out of this mess which is what I want to talk about next. 954 + 955 + 239 956 + 00:18:21.900 --> 00:18:27.860 957 + But first I want to briefly say why I think this work belongs here at this protocol conference 958 + 959 + 240 960 + 00:18:27.860 --> 00:18:32.820 961 + more than just about anywhere else. 962 + 963 + 241 964 + 00:18:32.820 --> 00:18:38.020 965 + When I write about the fallout of our global networks some of the points I come to echo 966 + 967 + 242 968 + 00:18:38.020 --> 00:18:43.000 969 + ones that many much fancier critics have covered but I tend to reach different conclusions 970 + 971 + 243 972 + 00:18:43.000 --> 00:18:48.740 973 + than they do because I am focused on builders and they are mostly writing toward individualistic 974 + 975 + 244 976 + 00:18:48.740 --> 00:18:51.460 977 + remedies or toward regulation. 978 + 979 + 245 980 + 00:18:51.460 --> 00:18:56.820 981 + And I have been alive for a lot of the internet so far and I have absolutely no faith in either 982 + 983 + 246 984 + 00:18:56.820 --> 00:18:59.860 985 + of those pathways at this time. 986 + 987 + 247 988 + 00:18:59.860 --> 00:19:02.420 989 + We are not going to disconnect from each other. 990 + 991 + 248 992 + 00:19:02.420 --> 00:19:04.500 993 + It's just not going to happen. 994 + 995 + 249 996 + 00:19:04.500 --> 00:19:11.860 997 + And our regulators are mostly speaking for my own country working from cartoon understandings 998 + 999 + 250 1000 + 00:19:11.860 --> 00:19:16.060 1001 + of network mechanisms and skating to where the puck was like between two and 12 years 1002 + 1003 + 251 1004 + 00:19:16.060 --> 00:19:22.820 1005 + ago which leaves us, the people in this room and people like us who hold the technological 1006 + 1007 + 252 1008 + 00:19:22.820 --> 00:19:26.940 1009 + means of production and would like to use it to do something different. 1010 + 1011 + 253 1012 + 00:19:26.940 --> 00:19:30.880 1013 + And I will be honest, like saying this kind of thing which I have been saying in a lot 1014 + 1015 + 254 1016 + 00:19:30.880 --> 00:19:35.500 1017 + of places for a long time has felt like kicking people who were already down because they 1018 + 1019 + 255 1020 + 00:19:35.500 --> 00:19:41.180 1021 + are under resourced and over-taxed open source developers or they are stuck inside corporations 1022 + 1023 + 256 1024 + 00:19:41.180 --> 00:19:46.900 1025 + with their own perverse incentives or people who have a lot of really good ideas but haven't 1026 + 1027 + 257 1028 + 00:19:46.900 --> 00:19:52.380 1029 + had the technical means to turn those into something they can show other people. 1030 + 1031 + 258 1032 + 00:19:52.380 --> 00:19:56.500 1033 + But there are two things happening right now that maybe make this moment different for 1034 + 1035 + 259 1036 + 00:19:56.500 --> 00:19:57.740 1037 + some of us. 1038 + 1039 + 260 1040 + 00:19:57.740 --> 00:20:02.780 1041 + The first is that decentralized protocols are a live force now with a bigger user base 1042 + 1043 + 261 1044 + 00:20:02.780 --> 00:20:05.260 1045 + and more attention than we have ever seen. 1046 + 1047 + 262 1048 + 00:20:05.260 --> 00:20:13.320 1049 + The atmosphere is a dev-friendly pro-experimentation zone with so much room for trying things. 1050 + 1051 + 263 1052 + 00:20:13.320 --> 00:20:18.020 1053 + The second factor is that writing code has always been difficult and time-consuming and 1054 + 1055 + 264 1056 + 00:20:18.020 --> 00:20:21.780 1057 + therefore quite expensive along one axis or another. 1058 + 1059 + 265 1060 + 00:20:21.780 --> 00:20:29.860 1061 + And that appears to be changing quite quickly which can go several ways and will. 1062 + 1063 + 266 1064 + 00:20:29.860 --> 00:20:34.180 1065 + But the models and the generators seem to be making a lot of previously high learning 1066 + 1067 + 267 1068 + 00:20:34.180 --> 00:20:40.980 1069 + curve high time commitment prototyping and experimentation vastly easier to get into. 1070 + 1071 + 268 1072 + 00:20:40.980 --> 00:20:45.220 1073 + And when I wrote this I felt like that was still sort of speculative and then we moved 1074 + 1075 + 269 1076 + 00:20:45.220 --> 00:20:48.860 1077 + closer to the conference and I was like oh it's really happening I got here and I was 1078 + 1079 + 270 1080 + 00:20:48.860 --> 00:20:52.580 1081 + like oh okay. 1082 + 1083 + 271 1084 + 00:20:52.580 --> 00:20:58.540 1085 + And this gives people who have been thinking hard about the effects of our networks a 1086 + 1087 + 272 1088 + 00:20:58.540 --> 00:21:04.700 1089 + chance to kind of rotate in and start prototyping and building and also I think gives long time 1090 + 1091 + 273 1092 + 00:21:04.700 --> 00:21:11.220 1093 + developers more time and freedom to put into stuff that's actually good for us as organisms 1094 + 1095 + 274 1096 + 00:21:11.220 --> 00:21:15.020 1097 + and communities of organisms. 1098 + 1099 + 275 1100 + 00:21:15.020 --> 00:21:22.820 1101 + Therefore I want to bring you some research threads and hopes and provocations which we 1102 + 1103 + 276 1104 + 00:21:22.860 --> 00:21:30.020 1105 + will mostly adapt from the wonderful world of kelp. 1106 + 1107 + 277 1108 + 00:21:30.020 --> 00:21:37.540 1109 + I need to turn your attention to macro algae or macro algae for the Brits in the audience. 1110 + 1111 + 278 1112 + 00:21:37.540 --> 00:21:42.980 1113 + Specifically to kelp and specifically to the subtlest and least showy parts of kelp which 1114 + 1115 + 279 1116 + 00:21:42.980 --> 00:21:46.980 1117 + are its hold fasts. 1118 + 1119 + 280 1120 + 00:21:46.980 --> 00:22:00.100 1121 + Hold fasts and thank you to my daughter June for this illustration. 1122 + 1123 + 281 1124 + 00:22:00.100 --> 00:22:04.820 1125 + Hold fasts are the structural support systems that kelp and other micro algae and also 1126 + 1127 + 282 1128 + 00:22:04.820 --> 00:22:11.140 1129 + a bunch of little sessile which is a beautiful word for non mobile sea creatures evolved 1130 + 1131 + 283 1132 + 00:22:11.140 --> 00:22:16.580 1133 + to cling on to the sea floor or even to like bigger shellfish with such strength that they 1134 + 1135 + 284 1136 + 00:22:16.580 --> 00:22:21.260 1137 + can hold on and flourish in deep water and in the roughest most turbulent intertidal 1138 + 1139 + 285 1140 + 00:22:21.260 --> 00:22:22.260 1141 + zones. 1142 + 1143 + 286 1144 + 00:22:22.260 --> 00:22:27.020 1145 + And the reason by the way that I tend to pull so heavily from the natural world and our 1146 + 1147 + 287 1148 + 00:22:27.020 --> 00:22:31.740 1149 + interactions with it is that the world has kind of figured a lot of shit out in a lot 1150 + 1151 + 288 1152 + 00:22:31.740 --> 00:22:37.180 1153 + of ways and I think leaving all of those models of complexity on the table is goofy and also 1154 + 1155 + 289 1156 + 00:22:37.180 --> 00:22:40.260 1157 + kelp is awesome. 1158 + 1159 + 290 1160 + 00:22:41.020 --> 00:22:46.780 1161 + So kelp and its hold fasts do three things that I think could be very useful for us to 1162 + 1163 + 291 1164 + 00:22:46.780 --> 00:22:47.780 1165 + think about. 1166 + 1167 + 292 1168 + 00:22:47.780 --> 00:22:54.740 1169 + They anchor entire communities into stability and they create permeable respite and sturdy 1170 + 1171 + 293 1172 + 00:22:54.740 --> 00:22:59.980 1173 + shelter for all kinds of weirdos both first up in their fronds and down at the interface 1174 + 1175 + 294 1176 + 00:22:59.980 --> 00:23:03.460 1177 + between the bedrock and the sea. 1178 + 1179 + 295 1180 + 00:23:03.460 --> 00:23:08.220 1181 + So the first thing I want to bring is the idea of anchoring networks and humans. 1182 + 1183 + 296 1184 + 00:23:08.260 --> 00:23:16.260 1185 + I think we could work toward reciprocal integration of rich sources of human knowledge. 1186 + 1187 + 297 1188 + 00:23:16.260 --> 00:23:20.820 1189 + We know that news organizations have tried to adapt to the distribution changes that 1190 + 1191 + 298 1192 + 00:23:20.820 --> 00:23:26.300 1193 + our networks have forced on them but the network's needs and affordances keep shifting so like 1194 + 1195 + 299 1196 + 00:23:26.300 --> 00:23:31.020 1197 + getting good at SEO worked for a while with constant recalibration and then AI summaries 1198 + 1199 + 300 1200 + 00:23:31.020 --> 00:23:37.200 1201 + have just cratered that experience for news orgs which is going to shut down newsrooms 1202 + 1203 + 301 1204 + 00:23:37.200 --> 00:23:39.480 1205 + and already is. 1206 + 1207 + 302 1208 + 00:23:39.480 --> 00:23:43.700 1209 + Getting integrated into social platforms worked pretty well until meta's properties started 1210 + 1211 + 303 1212 + 00:23:43.700 --> 00:23:48.240 1213 + de-prioritizing news and Twitter turned into X and started hiding links. 1214 + 1215 + 304 1216 + 00:23:48.240 --> 00:23:53.120 1217 + And I know that folks here today are psyched about getting journalists and news orgs onto 1218 + 1219 + 305 1220 + 00:23:53.120 --> 00:23:57.400 1221 + the protocol but we're going to have to make it worth their while and demonstrate that 1222 + 1223 + 306 1224 + 00:23:57.400 --> 00:24:02.520 1225 + there's a long game here that's going to be beneficial to them rather than a short period 1226 + 1227 + 307 1228 + 00:24:02.520 --> 00:24:08.720 1229 + of reciprocity followed by a shift to either extraction or exclusion. 1230 + 1231 + 308 1232 + 00:24:08.720 --> 00:24:11.940 1233 + And part of that is going to be based on whether or not people in the protocol are actually 1234 + 1235 + 309 1236 + 00:24:11.940 --> 00:24:14.620 1237 + engaging with news and knowledge. 1238 + 1239 + 310 1240 + 00:24:14.620 --> 00:24:19.840 1241 + As I suspect, although I have no data for this, is higher on blue sky and various other 1242 + 1243 + 311 1244 + 00:24:19.840 --> 00:24:25.160 1245 + skies than on other platforms. 1246 + 1247 + 312 1248 + 00:24:25.160 --> 00:24:32.080 1249 + And also we need to tell whether people in the protocol or encourage people in the protocol 1250 + 1251 + 313 1252 + 00:24:32.200 --> 00:24:37.040 1253 + are engaging with that rather than treating links and headlines like trading cards to 1254 + 1255 + 314 1256 + 00:24:37.040 --> 00:24:42.080 1257 + signal membership or confirm the truth of our already stated positions. 1258 + 1259 + 315 1260 + 00:24:42.080 --> 00:24:48.520 1261 + So this is a long way to say we should try to get people to actually read what they're 1262 + 1263 + 316 1264 + 00:24:48.520 --> 00:24:52.280 1265 + sharing. 1266 + 1267 + 317 1268 + 00:24:52.280 --> 00:24:54.960 1269 + And the current state there is not great. 1270 + 1271 + 318 1272 + 00:24:54.960 --> 00:24:58.200 1273 + Nature analysis of 35 billion Facebook posts. 1274 + 1275 + 319 1276 + 00:24:58.200 --> 00:25:04.680 1277 + I know it's Facebook but that had links showed that three quarters of the time people shared 1278 + 1279 + 320 1280 + 00:25:04.680 --> 00:25:05.680 1281 + links. 1282 + 1283 + 321 1284 + 00:25:05.680 --> 00:25:10.640 1285 + They hadn't clicked through let alone read the article they were sharing. 1286 + 1287 + 322 1288 + 00:25:10.640 --> 00:25:16.000 1289 + And the presence of sharing cues, just the existence of a cue, might you want to share 1290 + 1291 + 323 1292 + 00:25:16.000 --> 00:25:17.040 1293 + this? 1294 + 1295 + 324 1296 + 00:25:17.040 --> 00:25:23.200 1297 + Also makes people measurably worse at discerning true things from false things. 1298 + 1299 + 325 1300 + 00:25:23.200 --> 00:25:29.560 1301 + Or as the researchers put it, the social media context interferes with truth discernment. 1302 + 1303 + 326 1304 + 00:25:29.560 --> 00:25:34.960 1305 + So social media encounters as we see them on the big centralized platforms seem to push 1306 + 1307 + 327 1308 + 00:25:34.960 --> 00:25:37.440 1309 + interactions with news. 1310 + 1311 + 328 1312 + 00:25:37.440 --> 00:25:43.000 1313 + Not just from knowing things to knowing kind of about things, but from knowing about things 1314 + 1315 + 329 1316 + 00:25:43.000 --> 00:25:46.480 1317 + to signaling that we might know about them. 1318 + 1319 + 330 1320 + 00:25:46.480 --> 00:25:49.480 1321 + Which is getting really far away from the knowledge itself. 1322 + 1323 + 331 1324 + 00:25:49.480 --> 00:25:52.800 1325 + Which I mean I've been on the internet, that tracks. 1326 + 1327 + 332 1328 + 00:25:52.800 --> 00:25:58.080 1329 + If we wanted to move toward better integration and more reciprocity with knowledge collecting 1330 + 1331 + 333 1332 + 00:25:58.080 --> 00:26:05.160 1333 + institutions because if no one's clicking it's not helping them, what would we do? 1334 + 1335 + 334 1336 + 00:26:05.160 --> 00:26:12.760 1337 + So for blue sky and black sky and north sky and probably various other skies, y'all are 1338 + 1339 + 335 1340 + 00:26:12.760 --> 00:26:17.840 1341 + already ahead by not doing things that are actively hostile to knowledge. 1342 + 1343 + 336 1344 + 00:26:17.840 --> 00:26:22.600 1345 + Like hiding links and deprioritizing news and analysis. 1346 + 1347 + 337 1348 + 00:26:22.600 --> 00:26:26.880 1349 + There's probably also room to think about some remediation. 1350 + 1351 + 338 1352 + 00:26:26.880 --> 00:26:32.480 1353 + I will start here with my least favorite intervention, which is the nudge. 1354 + 1355 + 339 1356 + 00:26:32.480 --> 00:26:36.080 1357 + The nudge to read before sharing I find this highly annoying. 1358 + 1359 + 340 1360 + 00:26:36.080 --> 00:26:41.280 1361 + But I think it's interesting that it does seem to change behavior, at least in the short 1362 + 1363 + 341 1364 + 00:26:41.280 --> 00:26:42.280 1365 + term. 1366 + 1367 + 342 1368 + 00:26:42.280 --> 00:26:46.440 1369 + Twitter's comms team claimed in 2020 that when they did a little, want to read this 1370 + 1371 + 343 1372 + 00:26:46.440 --> 00:26:51.500 1373 + before retweeting it, nudge, they got a 40% boost in article opening. 1374 + 1375 + 344 1376 + 00:26:51.500 --> 00:26:53.820 1377 + We don't know what went into people's brains, but we know that happened. 1378 + 1379 + 345 1380 + 00:26:53.820 --> 00:26:55.620 1381 + That's not nothing. 1382 + 1383 + 346 1384 + 00:26:55.620 --> 00:27:00.780 1385 + And as skeptical as I am about nudges, all friction is perhaps not terrible. 1386 + 1387 + 347 1388 + 00:27:00.780 --> 00:27:06.540 1389 + There's a study from just this past winter that looked quite carefully at friction, the 1390 + 1391 + 348 1392 + 00:27:06.540 --> 00:27:13.220 1393 + nudge, and found that a very, very light touch of friction, so just a very occasional intervention, 1394 + 1395 + 349 1396 + 00:27:13.220 --> 00:27:17.620 1397 + plus a tiny quiz, really improved information quality. 1398 + 1399 + 350 1400 + 00:27:17.620 --> 00:27:24.260 1401 + Like a third, just doing the friction made people stop sharing things as much. 1402 + 1403 + 351 1404 + 00:27:24.260 --> 00:27:27.220 1405 + It didn't improve the quality of the knowledge on the network. 1406 + 1407 + 352 1408 + 00:27:27.220 --> 00:27:32.420 1409 + But the share friction plus a little bit of engaging analytical thought actually increased 1410 + 1411 + 353 1412 + 00:27:32.420 --> 00:27:37.580 1413 + the quality according to the study's measures by about a third, which is so much. 1414 + 1415 + 354 1416 + 00:27:37.580 --> 00:27:43.660 1417 + But I should say the caveat is that this study was done using a simulation. 1418 + 1419 + 355 1420 + 00:27:43.660 --> 00:27:50.940 1421 + So it's kind of like reading the headline that's like, scientists cure cancer in mice. 1422 + 1423 + 356 1424 + 00:27:50.940 --> 00:27:52.780 1425 + But even as with the mouse effect, right? 1426 + 1427 + 357 1428 + 00:27:52.780 --> 00:27:55.620 1429 + They're interesting mice. 1430 + 1431 + 358 1432 + 00:27:55.620 --> 00:28:01.260 1433 + So adding friction is never going to fully reverse the directional movement of a system 1434 + 1435 + 359 1436 + 00:28:01.260 --> 00:28:08.800 1437 + that leans toward virality and toward first-mover advantage and toward signaling versus understanding. 1438 + 1439 + 360 1440 + 00:28:08.800 --> 00:28:13.620 1441 + So what would it look like to move that problem upstream? 1442 + 1443 + 361 1444 + 00:28:13.620 --> 00:28:17.860 1445 + What would a system look like that actually centrally attended to community knowledge 1446 + 1447 + 362 1448 + 00:28:17.860 --> 00:28:19.540 1449 + and reciprocity? 1450 + 1451 + 363 1452 + 00:28:19.540 --> 00:28:24.260 1453 + What would it do when a user in such a system encountered something that appears to be, 1454 + 1455 + 364 1456 + 00:28:24.260 --> 00:28:28.840 1457 + for instance, news or analysis? 1458 + 1459 + 365 1460 + 00:28:28.840 --> 00:28:33.460 1461 + Maybe it would open an article or the video or whatever and suggest finding a good clip 1462 + 1463 + 366 1464 + 00:28:33.460 --> 00:28:37.580 1465 + or a quote to share, which could improve the quality of shared information and perhaps 1466 + 1467 + 367 1468 + 00:28:37.580 --> 00:28:40.060 1469 + get more of it into the sharer's brains. 1470 + 1471 + 368 1472 + 00:28:40.060 --> 00:28:44.420 1473 + Maybe it would automatically add sources mentioned in post that people bookmark or 1474 + 1475 + 369 1476 + 00:28:44.420 --> 00:28:50.340 1477 + a fave to a reading or watch list that they can return to to help fight the anxiety-producing 1478 + 1479 + 370 1480 + 00:28:50.340 --> 00:28:54.460 1481 + ephemerality that keeps information seekers doom-scrolling. 1482 + 1483 + 371 1484 + 00:28:54.460 --> 00:29:00.220 1485 + Maybe it could offer a tiny, even machine-generated summary and some context cues about the source 1486 + 1487 + 372 1488 + 00:29:00.220 --> 00:29:05.300 1489 + that provide enough trust signal from people with broadly strong reputations for a given 1490 + 1491 + 373 1492 + 00:29:05.300 --> 00:29:10.540 1493 + local cluster to pull attention away from worthless content farms and misinfo peddlers 1494 + 1495 + 374 1496 + 00:29:10.540 --> 00:29:14.500 1497 + and toward journalists and creators with integrity. 1498 + 1499 + 375 1500 + 00:29:14.500 --> 00:29:19.420 1501 + Or maybe, God help us, it would ask us to answer a question about the material in the 1502 + 1503 + 376 1504 + 00:29:19.420 --> 00:29:22.180 1505 + article, which I actually, I've flipped. 1506 + 1507 + 377 1508 + 00:29:22.180 --> 00:29:23.180 1509 + I'd love that. 1510 + 1511 + 378 1512 + 00:29:23.180 --> 00:29:29.180 1513 + I'm fully ready to leaderboard knowledge as a countermeasure to the current mode of leaderboarding, 1514 + 1515 + 379 1516 + 00:29:29.180 --> 00:29:30.900 1517 + the lowest common denominator. 1518 + 1519 + 380 1520 + 00:29:30.900 --> 00:29:31.900 1521 + Let's go. 1522 + 1523 + 381 1524 + 00:29:32.580 --> 00:29:36.580 1525 + The right move obviously depends on a specific project's values and goals. 1526 + 1527 + 382 1528 + 00:29:36.580 --> 00:29:41.900 1529 + I think this is the right level to consider it back in the architecture of a social internet 1530 + 1531 + 383 1532 + 00:29:41.900 --> 00:29:46.260 1533 + system rather than as aftermarket fixes. 1534 + 1535 + 384 1536 + 00:29:46.260 --> 00:29:53.020 1537 + Having seen yesterday's science track, those folks are way ahead of everyone else on this. 1538 + 1539 + 385 1540 + 00:29:53.020 --> 00:29:59.420 1541 + It's so good. 1542 + 1543 + 386 1544 + 00:29:59.420 --> 00:30:02.540 1545 + Next cool kelp fact. 1546 + 1547 + 387 1548 + 00:30:02.540 --> 00:30:08.380 1549 + Kelp makes slower, calmer zones. 1550 + 1551 + 388 1552 + 00:30:08.380 --> 00:30:15.580 1553 + For us, I think we could make slower, calmer zones that help our people keep them from 1554 + 1555 + 389 1556 + 00:30:15.580 --> 00:30:19.180 1557 + being overwhelmed by network tides. 1558 + 1559 + 390 1560 + 00:30:19.180 --> 00:30:21.940 1561 + There are two ways to look at this. 1562 + 1563 + 391 1564 + 00:30:21.940 --> 00:30:25.940 1565 + First I want to say, kelp forests are super bio-diverse. 1566 + 1567 + 392 1568 + 00:30:25.940 --> 00:30:27.740 1569 + They're a very rich community. 1570 + 1571 + 393 1572 + 00:30:27.740 --> 00:30:35.340 1573 + They're up there with coral reefs on the biodiversity and what we call productivity 1574 + 1575 + 394 1576 + 00:30:35.340 --> 00:30:36.780 1577 + as a system. 1578 + 1579 + 395 1580 + 00:30:36.780 --> 00:30:43.900 1581 + They do two things roughly that help them be such an important sheltering force. 1582 + 1583 + 396 1584 + 00:30:43.900 --> 00:30:50.260 1585 + The first is up in the water column where the kelp fronds and blades calm and slow and 1586 + 1587 + 397 1588 + 00:30:50.260 --> 00:30:55.900 1589 + deflects the very strong currents that surround kelp forests, creating calmer and less turbulent 1590 + 1591 + 398 1592 + 00:30:55.900 --> 00:30:59.140 1593 + spaces where other organisms can thrive. 1594 + 1595 + 399 1596 + 00:30:59.140 --> 00:31:02.100 1597 + The second is down in the hold fasts themselves. 1598 + 1599 + 400 1600 + 00:31:02.100 --> 00:31:07.180 1601 + The structures that wrap around and latch on to the sturdiest anchor they can are actually 1602 + 1603 + 401 1604 + 00:31:07.180 --> 00:31:10.380 1605 + the most thriving part of the community. 1606 + 1607 + 402 1608 + 00:31:10.380 --> 00:31:15.900 1609 + They shelter hundreds of mobile and sessile, invertebrate species, so they're like the 1610 + 1611 + 403 1612 + 00:31:15.900 --> 00:31:18.660 1613 + critical infrastructure for kelp busy town. 1614 + 1615 + 404 1616 + 00:31:18.660 --> 00:31:21.700 1617 + I want to take these one at a time. 1618 + 1619 + 405 1620 + 00:31:21.700 --> 00:31:26.820 1621 + First up in the water column where the tides are moving fast, but perhaps our network's 1622 + 1623 + 406 1624 + 00:31:26.820 --> 00:31:34.940 1625 + affordances could provide a little bit of cognitive and emotional traffic calming. 1626 + 1627 + 407 1628 + 00:31:34.940 --> 00:31:38.660 1629 + Something I've been watching for a long time and especially this year is that every time 1630 + 1631 + 408 1632 + 00:31:38.660 --> 00:31:43.900 1633 + something happens, whether it's someone dropping an album or a natural disaster happening or 1634 + 1635 + 409 1636 + 00:31:43.900 --> 00:31:50.660 1637 + ice shooting someone in my country, there is an instant hyper-proliferation of chatter 1638 + 1639 + 410 1640 + 00:31:50.660 --> 00:31:55.620 1641 + about it on the networks that comes online around the same time as live posting and eyewitness 1642 + 1643 + 411 1644 + 00:31:55.620 --> 00:31:58.260 1645 + video or spot analysis. 1646 + 1647 + 412 1648 + 00:31:58.260 --> 00:32:02.520 1649 + Then you get the local and specialist coverage and then you get the national and international 1650 + 1651 + 413 1652 + 00:32:02.520 --> 00:32:07.220 1653 + coverage and the next morning the think tanks wake up and get moving on it. 1654 + 1655 + 414 1656 + 00:32:07.220 --> 00:32:12.340 1657 + This is always expanding, but we don't really have a corresponding moment of synthesis or 1658 + 1659 + 415 1660 + 00:32:12.340 --> 00:32:20.620 1661 + contraction of all of that stuff into something that is intelligible to a reasonable person. 1662 + 1663 + 416 1664 + 00:32:20.700 --> 00:32:26.380 1665 + This is wild to me, but we can't just go to our networks or really anywhere, speaking 1666 + 1667 + 417 1668 + 00:32:26.380 --> 00:32:31.580 1669 + in general knowledge terms, I understand the scientists may have this better, and find 1670 + 1671 + 418 1672 + 00:32:31.580 --> 00:32:38.300 1673 + just an event node that connects all the sources of relevant information and the opinions of 1674 + 1675 + 419 1676 + 00:32:38.300 --> 00:32:41.100 1677 + people we care about in one place. 1678 + 1679 + 420 1680 + 00:32:41.100 --> 00:32:45.740 1681 + We have reporters who can do this high-speed gallop through the relevant context at the 1682 + 1683 + 421 1684 + 00:32:45.740 --> 00:32:49.300 1685 + beginning of every article they write and then the next day they wake up and they write 1686 + 1687 + 422 1688 + 00:32:49.300 --> 00:32:50.580 1689 + another article. 1690 + 1691 + 423 1692 + 00:32:50.580 --> 00:32:52.220 1693 + It's all super atomized. 1694 + 1695 + 424 1696 + 00:32:52.220 --> 00:32:54.820 1697 + There's nothing to bring it together. 1698 + 1699 + 425 1700 + 00:32:54.820 --> 00:33:00.340 1701 + If you want to build a knowledge molecule, you have to do it with your own brain or you 1702 + 1703 + 426 1704 + 00:33:00.340 --> 00:33:07.500 1705 + can glom on to someone in the creator or interpreter class, some of whom are genuinely world-class, 1706 + 1707 + 427 1708 + 00:33:07.500 --> 00:33:13.700 1709 + super gifted analysts and some of whom are basically semi-deranged street preachers and 1710 + 1711 + 428 1712 + 00:33:13.700 --> 00:33:18.020 1713 + not everyone can tell the difference all the time. 1714 + 1715 + 429 1716 + 00:33:18.140 --> 00:33:23.460 1717 + Uplifting and reciprocating our gifted interpreters is necessary and I hope we're going to hear 1718 + 1719 + 430 1720 + 00:33:23.460 --> 00:33:26.140 1721 + more about that this weekend. 1722 + 1723 + 431 1724 + 00:33:26.140 --> 00:33:31.380 1725 + But it also seems to me that we really could get the machines involved in bundling up all 1726 + 1727 + 432 1728 + 00:33:31.380 --> 00:33:36.180 1729 + of this noise into intelligible collections of material that we could actually learn through 1730 + 1731 + 433 1732 + 00:33:36.180 --> 00:33:41.100 1733 + and refer to so that it's not so insistently ephemeral and scattered. 1734 + 1735 + 434 1736 + 00:33:41.100 --> 00:33:47.180 1737 + And if this sounds like resuscitating the dream of structured data, it kind of is. 1738 + 1739 + 435 1740 + 00:33:47.180 --> 00:33:56.660 1741 + But I want to put it in service of ordinary people using tech we didn't have before and 1742 + 1743 + 436 1744 + 00:33:56.660 --> 00:34:03.020 1745 + signals from social that can make this stuff more than like a terrible index. 1746 + 1747 + 437 1748 + 00:34:03.020 --> 00:34:07.540 1749 + And it's odd to me that we have all of these recommendation algorithms working in variously 1750 + 1751 + 438 1752 + 00:34:07.540 --> 00:34:13.540 1753 + pro and antisocial ways, but as far as I can tell, we haven't effectively brought our 1754 + 1755 + 439 1756 + 00:34:13.540 --> 00:34:20.500 1757 + social tech to the work of orientation or reorientation in any structured way. 1758 + 1759 + 440 1760 + 00:34:20.500 --> 00:34:26.740 1761 + As again the science cluster is ably demonstrating, we can develop features that cluster and amplify 1762 + 1763 + 441 1764 + 00:34:26.740 --> 00:34:28.700 1765 + the knowledge people assemble. 1766 + 1767 + 442 1768 + 00:34:28.700 --> 00:34:33.340 1769 + We can do it with machine learning and human curation, probably both of them. 1770 + 1771 + 443 1772 + 00:34:33.340 --> 00:34:38.500 1773 + We could give our communities the tools to do this for their areas of interest or their 1774 + 1775 + 444 1776 + 00:34:38.500 --> 00:34:41.580 1777 + physical localities or their specializations. 1778 + 1779 + 445 1780 + 00:34:41.580 --> 00:34:48.940 1781 + And we could extend existing work on community moderation to rule certain knowledge associations 1782 + 1783 + 446 1784 + 00:34:48.940 --> 00:34:50.500 1785 + in or out. 1786 + 1787 + 447 1788 + 00:34:50.500 --> 00:34:55.400 1789 + But if we only do this work for highly motivated specialists, we're missing the chance to bring 1790 + 1791 + 448 1792 + 00:34:55.400 --> 00:34:58.460 1793 + that fire to everyone else. 1794 + 1795 + 449 1796 + 00:34:58.460 --> 00:35:02.820 1797 + And I will now embarrass my old journalism world friend Tyler Fisher and say that I think 1798 + 1799 + 450 1800 + 00:35:02.820 --> 00:35:07.100 1801 + his work with CIL is admirable and a really good start towards this. 1802 + 1803 + 451 1804 + 00:35:07.100 --> 00:35:12.140 1805 + And some things about the next area I want to talk about, which is mitigating the cognitive 1806 + 1807 + 452 1808 + 00:35:12.140 --> 00:35:21.140 1809 + and emotional effects of processing so many different emotional registers in one place. 1810 + 1811 + 453 1812 + 00:35:21.140 --> 00:35:28.540 1813 + I think we could give our embodied human selves a break if we were to find a way to split 1814 + 1815 + 454 1816 + 00:35:28.540 --> 00:35:34.260 1817 + rhetorical registers at the point of reader viewer contact. 1818 + 1819 + 455 1820 + 00:35:34.260 --> 00:35:38.500 1821 + We go online because we're bored or we're lonely or we want to see what people are talking 1822 + 1823 + 456 1824 + 00:35:38.500 --> 00:35:43.060 1825 + about either in a professional or a very unprofessional way. 1826 + 1827 + 457 1828 + 00:35:43.060 --> 00:35:49.900 1829 + But what most of us get when we come online is this amazing puree of jokes and infighting 1830 + 1831 + 458 1832 + 00:35:49.900 --> 00:35:55.920 1833 + and scary news and hustling and entertaining nonsense and dumb memes and video evidence 1834 + 1835 + 459 1836 + 00:35:55.920 --> 00:35:59.240 1837 + of war crimes. 1838 + 1839 + 460 1840 + 00:35:59.240 --> 00:36:02.800 1841 + I think this is genuinely not good for us. 1842 + 1843 + 461 1844 + 00:36:02.800 --> 00:36:07.680 1845 + There's a lot of evidence about this, but honestly, it's kind of weird. 1846 + 1847 + 462 1848 + 00:36:07.680 --> 00:36:10.040 1849 + I wanted it to be stronger. 1850 + 1851 + 463 1852 + 00:36:10.040 --> 00:36:14.320 1853 + There is a study about how rough context switching is for our ability to understand things, but 1854 + 1855 + 464 1856 + 00:36:14.320 --> 00:36:15.940 1857 + it's mostly focused on format. 1858 + 1859 + 465 1860 + 00:36:15.940 --> 00:36:22.080 1861 + So it's hard to go from video to text, which is fine, but not the same thing. 1862 + 1863 + 466 1864 + 00:36:22.080 --> 00:36:28.480 1865 + There's this really fun paper with three studies from a couple of professors of advertising 1866 + 1867 + 467 1868 + 00:36:28.480 --> 00:36:34.600 1869 + that found that scrolling Instagram for 30 seconds essentially makes us weak to ads, 1870 + 1871 + 468 1872 + 00:36:34.600 --> 00:36:39.240 1873 + but especially to ads that have high social signals. 1874 + 1875 + 469 1876 + 00:36:39.240 --> 00:36:43.880 1877 + So we're switching from a more analytical mode to heuristic processing, and if a lot 1878 + 1879 + 470 1880 + 00:36:43.880 --> 00:36:49.100 1881 + of people appear to have liked the thing, we're more likely to just buy whatever nonsense 1882 + 1883 + 471 1884 + 00:36:49.100 --> 00:36:51.000 1885 + it is. 1886 + 1887 + 472 1888 + 00:36:51.020 --> 00:36:56.160 1889 + The same paper also includes another experiment showing that people who scroll their social 1890 + 1891 + 473 1892 + 00:36:56.160 --> 00:37:01.540 1893 + feed for a very brief period also immediately got worse at math and sentence diagramming. 1894 + 1895 + 474 1896 + 00:37:01.540 --> 00:37:02.540 1897 + So that's fun. 1898 + 1899 + 475 1900 + 00:37:02.540 --> 00:37:05.160 1901 + But that's just one paper. 1902 + 1903 + 476 1904 + 00:37:05.160 --> 00:37:09.160 1905 + And there are a few others, but they're not necessarily generalizable, so I want to be 1906 + 1907 + 477 1908 + 00:37:09.160 --> 00:37:10.160 1909 + careful. 1910 + 1911 + 478 1912 + 00:37:10.160 --> 00:37:13.940 1913 + I think we do have two really helpful bodies here of indirect evidence. 1914 + 1915 + 479 1916 + 00:37:13.940 --> 00:37:20.480 1917 + One is the quite beefy body of work on transportive communication, stuff that transports us, which 1918 + 1919 + 480 1920 + 00:37:20.480 --> 00:37:26.280 1921 + is behind a bunch of the power of storytelling stuff. 1922 + 1923 + 481 1924 + 00:37:26.280 --> 00:37:32.200 1925 + But essentially things that feel transportive, including a lot of first-person testimony, 1926 + 1927 + 482 1928 + 00:37:32.200 --> 00:37:35.400 1929 + really reduce skepticism and analytical thought. 1930 + 1931 + 483 1932 + 00:37:35.400 --> 00:37:39.760 1933 + And there's a solid pool of evidence and theory there, kind of just waiting for someone to 1934 + 1935 + 484 1936 + 00:37:39.760 --> 00:37:43.800 1937 + step in and work on the effects of trying to move between the transportive and just 1938 + 1939 + 485 1940 + 00:37:43.800 --> 00:37:49.720 1941 + quotidian newsy stuff registers in rapid succession over and over again in the same 1942 + 1943 + 486 1944 + 00:37:49.720 --> 00:37:51.920 1945 + place. 1946 + 1947 + 487 1948 + 00:37:51.920 --> 00:37:57.720 1949 + But the second thing we have is, again, the evidence of our senses. 1950 + 1951 + 488 1952 + 00:37:57.720 --> 00:38:04.000 1953 + I think there are a few people having a good time in the political news zone on the social 1954 + 1955 + 489 1956 + 00:38:04.000 --> 00:38:05.600 1957 + internet. 1958 + 1959 + 490 1960 + 00:38:05.600 --> 00:38:10.840 1961 + I think there are journalism and policy people who mostly treat the networks like Brief Mean 1962 + 1963 + 491 1964 + 00:38:10.840 --> 00:38:14.880 1965 + LinkedIn, which works out well for them. 1966 + 1967 + 492 1968 + 00:38:14.880 --> 00:38:20.320 1969 + And then there are a lot of people, including people in positions of extraordinary power, 1970 + 1971 + 493 1972 + 00:38:20.320 --> 00:38:24.840 1973 + who treat the experience of modern life and the suffering of others as a spectator blood 1974 + 1975 + 494 1976 + 00:38:24.840 --> 00:38:26.040 1977 + sport. 1978 + 1979 + 495 1980 + 00:38:26.040 --> 00:38:31.140 1981 + And I do not think that that mode in particular is good or even neutral. 1982 + 1983 + 496 1984 + 00:38:31.140 --> 00:38:36.080 1985 + I think we will not fix the problems with our governance if we continue to allow it 1986 + 1987 + 497 1988 + 00:38:36.080 --> 00:38:39.920 1989 + to metastasize through our civic life. 1990 + 1991 + 498 1992 + 00:38:40.000 --> 00:38:44.540 1993 + And for the rest of us, this stuff is just exhausting and alienating, and it does things 1994 + 1995 + 499 1996 + 00:38:44.540 --> 00:38:46.640 1997 + to our brains that we don't like. 1998 + 1999 + 500 2000 + 00:38:46.640 --> 00:38:50.280 2001 + And I want to briefly bring in Joshua Myrowitz. 2002 + 2003 + 501 2004 + 00:38:50.280 --> 00:38:52.840 2005 + Do we have other Myrowitz heads in the crowd? 2006 + 2007 + 502 2008 + 00:38:52.840 --> 00:38:54.360 2009 + He wrote No Sense a Place in 1986. 2010 + 2011 + 503 2012 + 00:38:54.360 --> 00:38:58.360 2013 + Oh, my God, I'm going to write so many blog posts about Joshua Myrowitz for you. 2014 + 2015 + 504 2016 + 00:38:58.360 --> 00:39:04.680 2017 + So he's this media scholar whose ideas informed Dana Boyd and Alice Marwick's work on context 2018 + 2019 + 505 2020 + 00:39:04.680 --> 00:39:05.680 2021 + collapse. 2022 + 2023 + 506 2024 + 00:39:06.440 --> 00:39:14.480 2025 + But he was writing in the mid 80s, which makes this a little unsettling to me. 2026 + 2027 + 507 2028 + 00:39:14.480 --> 00:39:22.120 2029 + He wrote, the current merging of situations, by which he means places, doesn't give us 2030 + 2031 + 508 2032 + 00:39:22.120 --> 00:39:27.960 2033 + a sum of what we had before, but rather new synthesized behaviors that are qualitatively 2034 + 2035 + 509 2036 + 00:39:27.960 --> 00:39:29.000 2037 + different. 2038 + 2039 + 510 2040 + 00:39:29.000 --> 00:39:33.680 2041 + If we celebrate our child's wedding in an isolated situation where it is the sole experience 2042 + 2043 + 511 2044 + 00:39:33.760 --> 00:39:37.160 2045 + of the day, then our joy may be unbounded. 2046 + 2047 + 512 2048 + 00:39:37.160 --> 00:39:41.960 2049 + But when on our way to the wedding, we hear over the car radio of a devastating earthquake 2050 + 2051 + 513 2052 + 00:39:41.960 --> 00:39:46.920 2053 + or the death of a popular entertainer or the assassination of a political figure, we not 2054 + 2055 + 514 2056 + 00:39:46.920 --> 00:39:54.240 2057 + only lose our ability to rejoice fully, but also our ability to mourn deeply. 2058 + 2059 + 515 2060 + 00:39:54.240 --> 00:39:59.280 2061 + Unbounded joy and unmitigated misery cannot coexist in the same place and time. 2062 + 2063 + 516 2064 + 00:39:59.280 --> 00:40:06.320 2065 + The situations merge, the hot flush and the icy stare blend into a middle region cool. 2066 + 2067 + 517 2068 + 00:40:06.320 --> 00:40:09.680 2069 + And for Myrowitz's cool, I would substitute numb. 2070 + 2071 + 518 2072 + 00:40:11.680 --> 00:40:17.040 2073 + Now some communities in the decentralized space have tried to deal with this by asking 2074 + 2075 + 519 2076 + 00:40:17.040 --> 00:40:22.080 2077 + people to either content warn their posts based on the whole panoply of their readers' 2078 + 2079 + 520 2080 + 00:40:22.080 --> 00:40:26.400 2081 + potential sensitivities or to divide their expression into separate accounts. 2082 + 2083 + 521 2084 + 00:40:26.880 --> 00:40:30.480 2085 + And I think these people are working from good instincts, but from the wrong end of 2086 + 2087 + 522 2088 + 00:40:30.480 --> 00:40:35.800 2089 + the problem, given how alienating and anti-convivial it is to be instructed to preprocess your 2090 + 2091 + 523 2092 + 00:40:35.800 --> 00:40:39.320 2093 + emotional utterances for people you may not even be speaking to. 2094 + 2095 + 524 2096 + 00:40:39.320 --> 00:40:43.240 2097 + But I think we could make this work on the other end. 2098 + 2099 + 525 2100 + 00:40:43.240 --> 00:40:47.680 2101 + And I want to say if we do it successfully, it will be because we recognize that we cannot 2102 + 2103 + 526 2104 + 00:40:47.680 --> 00:40:54.880 2105 + rely on like civility forward sentiment analysis that for instance reads black Americans speaking 2106 + 2107 + 527 2108 + 00:40:54.880 --> 00:40:58.640 2109 + in a neutral register as aggressive. 2110 + 2111 + 528 2112 + 00:40:58.640 --> 00:41:03.400 2113 + Doing it well would involve grounding in community and doing a lot of training work which would 2114 + 2115 + 529 2116 + 00:41:03.400 --> 00:41:06.320 2117 + have to be shared across a willing group. 2118 + 2119 + 530 2120 + 00:41:06.320 --> 00:41:08.680 2121 + I don't want to undersell the difficulty. 2122 + 2123 + 531 2124 + 00:41:08.680 --> 00:41:16.000 2125 + But being able to come online and see a mourning experience that starts with like, hi, friends, 2126 + 2127 + 532 2128 + 00:41:16.000 --> 00:41:20.360 2129 + it's puppy pictures and selfies and not have the hard news come online until like after 2130 + 2131 + 533 2132 + 00:41:20.360 --> 00:41:22.720 2133 + the caffeine kicks in. 2134 + 2135 + 534 2136 + 00:41:22.800 --> 00:41:24.880 2137 + I think this would be transformative. 2138 + 2139 + 535 2140 + 00:41:24.880 --> 00:41:29.400 2141 + And like for me when I'm working, I would love to be able to filter in posts that match 2142 + 2143 + 536 2144 + 00:41:29.400 --> 00:41:36.880 2145 + the register I'm working in and hold the puppies and beefs for later. 2146 + 2147 + 537 2148 + 00:41:36.880 --> 00:41:42.680 2149 + I would like to think about this less as feed switching and more like a radio dial. 2150 + 2151 + 538 2152 + 00:41:42.680 --> 00:41:47.640 2153 + Always the people that we like, but with the option to filter different registers in and 2154 + 2155 + 539 2156 + 00:41:47.640 --> 00:41:52.440 2157 + out to suit different emotional capacities and allow for some separation. 2158 + 2159 + 540 2160 + 00:41:52.960 --> 00:41:58.040 2161 + So those are some thoughts about working on this stuff in kind of lateral ways up in the 2162 + 2163 + 541 2164 + 00:41:58.040 --> 00:42:00.240 2165 + big open world of the water column. 2166 + 2167 + 542 2168 + 00:42:00.240 --> 00:42:03.240 2169 + And now I want to talk about the other thing. 2170 + 2171 + 543 2172 + 00:42:03.240 --> 00:42:08.400 2173 + The most vibrant part of the kelp forest is in the hold fasts which act like roots but 2174 + 2175 + 544 2176 + 00:42:08.400 --> 00:42:12.160 2177 + kind of in reverse instead of pulling resources out of the soil. 2178 + 2179 + 545 2180 + 00:42:12.160 --> 00:42:17.320 2181 + They push benefits out to every living thing around them by providing a firmly anchored 2182 + 2183 + 546 2184 + 00:42:17.320 --> 00:42:24.160 2185 + structure that offers complex and variegated shelter for both the charismatic invertebrates 2186 + 2187 + 547 2188 + 00:42:24.160 --> 00:42:29.480 2189 + with all the little flowy parts and also the tiny snails and worms and all the other beloved 2190 + 2191 + 548 2192 + 00:42:29.480 --> 00:42:32.240 2193 + lobes of the kelp forest. 2194 + 2195 + 549 2196 + 00:42:32.240 --> 00:42:37.840 2197 + So one more Joshua Myrowitz quote from 1986. 2198 + 2199 + 550 2200 + 00:42:37.840 --> 00:42:42.640 2201 + For every moment of our lives there are things happening someplace that would upset us, that 2202 + 2203 + 551 2204 + 00:42:42.640 --> 00:42:46.760 2205 + would involve us, that would drain our energies and engage our feelings. 2206 + 2207 + 552 2208 + 00:42:46.760 --> 00:42:50.440 2209 + There are more things that if present in our view we would feel compelled to respond 2210 + 2211 + 553 2212 + 00:42:50.440 --> 00:42:56.560 2213 + to or do something about than could possibly fit into the same experience of a single lifetime. 2214 + 2215 + 554 2216 + 00:42:56.560 --> 00:43:01.720 2217 + Situation segregation, however, acts as a psychosocial shock absorber. 2218 + 2219 + 555 2220 + 00:43:01.720 --> 00:43:06.480 2221 + By selectively exposing ourselves to events and other people we control the flow of our 2222 + 2223 + 556 2224 + 00:43:06.480 --> 00:43:08.480 2225 + actions and emotions. 2226 + 2227 + 557 2228 + 00:43:08.480 --> 00:43:14.260 2229 + Compassion, empathy, and even ethics may be more situationally bound than we often care 2230 + 2231 + 558 2232 + 00:43:14.260 --> 00:43:15.260 2233 + to think. 2234 + 2235 + 559 2236 + 00:43:15.740 --> 00:43:18.140 2237 + I love this guy. 2238 + 2239 + 560 2240 + 00:43:18.140 --> 00:43:22.700 2241 + I feel this in the way that I participate in the online world. 2242 + 2243 + 561 2244 + 00:43:22.700 --> 00:43:27.860 2245 + I think we need space to think and feel together that isn't always fully in the current and 2246 + 2247 + 562 2248 + 00:43:27.860 --> 00:43:33.380 2249 + I feel like probably everybody here gets this. 2250 + 2251 + 563 2252 + 00:43:33.380 --> 00:43:37.500 2253 + It also produces the benefit, also I think we understand the benefit of not having to 2254 + 2255 + 564 2256 + 00:43:37.500 --> 00:43:42.980 2257 + send people off protocol into discords and group chats whenever they need to do that 2258 + 2259 + 565 2260 + 00:43:42.980 --> 00:43:44.380 2261 + work. 2262 + 2263 + 566 2264 + 00:43:44.380 --> 00:43:49.340 2265 + The spaces work that the Blue Sky team has been publishing about is going to unlock so 2266 + 2267 + 567 2268 + 00:43:49.340 --> 00:43:53.260 2269 + many affordances for pro social things that go well beyond private accounts. 2270 + 2271 + 568 2272 + 00:43:53.260 --> 00:43:57.220 2273 + I cannot tell you how excited I am about this. 2274 + 2275 + 569 2276 + 00:43:57.220 --> 00:44:02.300 2277 + I also want to make a note, I think letting people huddle up inside an anchoring structure 2278 + 2279 + 570 2280 + 00:44:02.300 --> 00:44:09.300 2281 + also undercuts both the need for and the value of mobbing as territorial defense. 2282 + 2283 + 571 2284 + 00:44:09.300 --> 00:44:13.860 2285 + I think that's something very real on the networks right now and that also came up in 2286 + 2287 + 572 2288 + 00:44:13.860 --> 00:44:15.860 2289 + the science track yesterday. 2290 + 2291 + 573 2292 + 00:44:15.860 --> 00:44:21.460 2293 + If you and your community have a cave or a building or a little sheltering trees to step 2294 + 2295 + 574 2296 + 00:44:21.460 --> 00:44:26.820 2297 + into to get out of the broad featureless plane with everyone in it filled with many other 2298 + 2299 + 575 2300 + 00:44:26.820 --> 00:44:32.060 2301 + communities some of whom will always hate you, you're not going to have to constantly 2302 + 2303 + 576 2304 + 00:44:32.060 --> 00:44:38.500 2305 + make up for your lack of shelter by continuously contesting every millimeter of cultural boundary. 2306 + 2307 + 577 2308 + 00:44:38.500 --> 00:44:40.300 2309 + You can just sidestep it. 2310 + 2311 + 578 2312 + 00:44:40.300 --> 00:44:44.900 2313 + This is so low level that I think it's honestly hard to find ways to talk about, but I think 2314 + 2315 + 579 2316 + 00:44:44.900 --> 00:44:48.060 2317 + we have to solve these problems. 2318 + 2319 + 580 2320 + 00:44:48.060 --> 00:44:55.680 2321 + I would like to suggest as a completely unqualified nonanthropologist that the entire known history 2322 + 2323 + 581 2324 + 00:44:55.680 --> 00:45:01.060 2325 + of humans coming together in groups larger than a few families has involved making buildings 2326 + 2327 + 582 2328 + 00:45:01.060 --> 00:45:05.960 2329 + of one kind or another and then elaborating those buildings fairly quickly with rooms 2330 + 2331 + 583 2332 + 00:45:05.960 --> 00:45:10.560 2333 + and divisions because our structures out in the physical world don't just shield us 2334 + 2335 + 584 2336 + 00:45:10.560 --> 00:45:11.560 2337 + from the environment. 2338 + 2339 + 585 2340 + 00:45:11.560 --> 00:45:16.680 2341 + They also give us necessary shelter from each other which probably brings the murder rate 2342 + 2343 + 586 2344 + 00:45:16.680 --> 00:45:21.120 2345 + down among other things. 2346 + 2347 + 587 2348 + 00:45:21.120 --> 00:45:26.700 2349 + I said earlier that I would revisit the illusion of explanatory depth which is essentially 2350 + 2351 + 588 2352 + 00:45:26.700 --> 00:45:32.400 2353 + a pervasive cognitive con that all our brains are running all the time by leading us to 2354 + 2355 + 589 2356 + 00:45:32.400 --> 00:45:37.120 2357 + believe that we understand things about the world that we actually do not. 2358 + 2359 + 590 2360 + 00:45:37.120 --> 00:45:42.960 2361 + We don't know that we don't know until we have to explain something or fix something 2362 + 2363 + 591 2364 + 00:45:42.960 --> 00:45:46.200 2365 + and then it's not there. 2366 + 2367 + 592 2368 + 00:45:46.200 --> 00:45:50.880 2369 + If I had an extra 10 minutes I would absolutely ask you each to turn to the person next to 2370 + 2371 + 593 2372 + 00:45:50.880 --> 00:45:56.120 2373 + you and explain how a flush toilet works. 2374 + 2375 + 594 2376 + 00:45:56.120 --> 00:45:57.640 2377 + I've worked on flush toilets. 2378 + 2379 + 595 2380 + 00:45:57.640 --> 00:45:58.640 2381 + I was so wrong. 2382 + 2383 + 596 2384 + 00:45:58.640 --> 00:46:02.300 2385 + It was very upsetting. 2386 + 2387 + 597 2388 + 00:46:02.300 --> 00:46:08.640 2389 + This is usually okay as long as we have reliable sources to refer back to but it's extremely 2390 + 2391 + 598 2392 + 00:46:08.640 --> 00:46:09.640 2393 + bad when we don't. 2394 + 2395 + 599 2396 + 00:46:09.640 --> 00:46:14.620 2397 + I read a lot about this in the landslide essay and I'll link the relevant research 2398 + 2399 + 600 2400 + 00:46:14.620 --> 00:46:19.960 2401 + but the upshot is that for people who care about knowledge we need to know that we don't 2402 + 2403 + 601 2404 + 00:46:19.960 --> 00:46:25.940 2405 + know very much in our brains actually and that our knowledge is not just embodied but 2406 + 2407 + 602 2408 + 00:46:25.940 --> 00:46:31.180 2409 + also genuinely social and networked which means that the quality of knowledge in our 2410 + 2411 + 603 2412 + 00:46:31.180 --> 00:46:37.840 2413 + networks when it goes down we all get less knowledgeable and we all get less capable 2414 + 2415 + 604 2416 + 00:46:37.840 --> 00:46:41.500 2417 + and I would argue that we all get less free. 2418 + 2419 + 605 2420 + 00:46:41.500 --> 00:46:46.820 2421 + This is why everything I'm suggesting today centres on treating ordinary people as subjects 2422 + 2423 + 606 2424 + 00:46:46.820 --> 00:46:52.380 2425 + with agency who deserve workable access to good information in reasonable environments 2426 + 2427 + 607 2428 + 00:46:52.620 --> 00:46:58.540 2429 + rather than treating them as consumers whose purpose is to be a manipulable object. 2430 + 2431 + 608 2432 + 00:46:58.540 --> 00:47:02.560 2433 + The science folks from yesterday are already demonstrating the protocol can be used to 2434 + 2435 + 609 2436 + 00:47:02.560 --> 00:47:07.740 2437 + do knowledge consolidating and brain preserving work but if we don't bring those goods to 2438 + 2439 + 610 2440 + 00:47:07.740 --> 00:47:13.660 2441 + everyone at all levels we're going to lose our democracies all of which are predicated 2442 + 2443 + 611 2444 + 00:47:13.660 --> 00:47:21.680 2445 + on the existence of at least minimally informed civic community who are subjects with agency. 2446 + 2447 + 612 2448 + 00:47:21.680 --> 00:47:24.720 2449 + So I've got one more cool kelp fact for you. 2450 + 2451 + 613 2452 + 00:47:24.720 --> 00:47:29.080 2453 + At least you'll have the kelp facts even if nothing else carries forward. 2454 + 2455 + 614 2456 + 00:47:29.080 --> 00:47:33.680 2457 + Kelp are way older than we thought until a few years ago we thought they were only 14 2458 + 2459 + 615 2460 + 00:47:33.680 --> 00:47:38.080 2461 + million years old because we found a kelp fossil and it was 14 million years old. 2462 + 2463 + 616 2464 + 00:47:38.080 --> 00:47:43.560 2465 + But then this amateur fossil collector down in Washington state cracked open some rocks 2466 + 2467 + 617 2468 + 00:47:43.560 --> 00:47:48.080 2469 + he found on the beach and found something that looked a lot like a fossilized hold fast. 2470 + 2471 + 618 2472 + 00:47:48.080 --> 00:47:54.640 2473 + So he sent it down to the ancient kelp dating nerds at UC Berkeley and the new fossils were 2474 + 2475 + 619 2476 + 00:47:54.640 --> 00:47:58.480 2477 + around 32 million years old. 2478 + 2479 + 620 2480 + 00:47:58.480 --> 00:48:04.700 2481 + And this is important because it means that the kelp evolved way before all the species 2482 + 2483 + 621 2484 + 00:48:04.700 --> 00:48:09.560 2485 + that now shelter in their fronds and their hold fasts and became a foundation species 2486 + 2487 + 622 2488 + 00:48:09.560 --> 00:48:13.800 2489 + without which all that other life would have been impossible. 2490 + 2491 + 623 2492 + 00:48:13.800 --> 00:48:18.960 2493 + But another way their presence and the affordances they offered bent the future around them in 2494 + 2495 + 624 2496 + 00:48:18.960 --> 00:48:23.320 2497 + ways that we now find beautiful and valuable and good. 2498 + 2499 + 625 2500 + 00:48:23.320 --> 00:48:28.240 2501 + To me the point of working toward knowledge anchoring and against continuous turbulence 2502 + 2503 + 626 2504 + 00:48:28.240 --> 00:48:34.360 2505 + and trouble is not just short term as a respite or a little pocket oasis for us and our friends 2506 + 2507 + 627 2508 + 00:48:34.360 --> 00:48:39.440 2509 + but toward a genuinely more workable way to think and know together. 2510 + 2511 + 628 2512 + 00:48:39.440 --> 00:48:46.240 2513 + Where together is going to include billions of humans and also many forms of machine assistance. 2514 + 2515 + 629 2516 + 00:48:46.240 --> 00:48:52.280 2517 + And this moment is our window for bending the future around our hopes and values that 2518 + 2519 + 630 2520 + 00:48:52.280 --> 00:48:57.560 2521 + cherish knowledge and communal knowing and that orient us toward real remedies for some 2522 + 2523 + 631 2524 + 00:48:57.560 --> 00:49:05.080 2525 + of our most ancient information troubles and pains in service of living together in peace 2526 + 2527 + 632 2528 + 00:49:05.080 --> 00:49:06.080 2529 + and mutual respect. 2530 + 2531 + 633 2532 + 00:49:06.080 --> 00:49:10.080 2533 + Thank you. 2534 + 2535 + 634 2536 + 00:49:37.080 --> 00:49:47.320 2537 + Truly, truly, leaning toward the wrong mic, if you're working on this stuff, if you care 2538 + 2539 + 635 2540 + 00:49:47.320 --> 00:49:49.160 2541 + about working on this stuff, let's talk. 2542 + 2543 + 636 2544 + 00:49:49.160 --> 00:49:50.160 2545 + That's why I'm here. 2546 + 2547 + 637 2548 + 00:49:50.160 --> 00:49:53.800 2549 + I gave this talk so they'd let me in the door. 2550 + 2551 + 638 2552 + 00:49:53.800 --> 00:49:56.720 2553 + But I want to talk to people who are actually trying to fix this. 2554 + 2555 + 639 2556 + 00:49:56.720 --> 00:49:58.720 2557 + Thank you. 2558 + 2559 + 640 2560 + 00:49:58.720 --> 00:49:59.720 2561 + We have no time for Q&A. 2562 + 2563 + 641 2564 + 00:49:59.720 --> 00:50:00.720 2565 + I didn't feel that. 2566 + 2567 + 642 2568 + 00:50:00.720 --> 00:50:01.720 2569 + I want a couple of minutes. 2570 + 2571 + 643 2572 + 00:50:01.720 --> 00:50:02.720 2573 + This is how these things go. 2574 + 2575 + 644 2576 + 00:50:02.720 --> 00:50:08.720 2577 + Thank you. 150 2578
+2382 -566
public/subtitles/the-phoenix-architecture.vtt
··· 1 1 WEBVTT 2 2 3 3 1 4 - 00:00:00.000 --> 00:00:02.000 5 - Thank you. 4 + 00:00:00.000 --> 00:00:01.440 5 + X architecture. 6 6 7 7 2 8 - 00:00:30.000 --> 00:00:32.000 9 - Thank you. 8 + 00:00:01.440 --> 00:00:03.880 9 + Thank you, thank you, hello. 10 10 11 11 3 12 - 00:01:00.000 --> 00:01:04.900 13 - Please. 12 + 00:00:03.880 --> 00:00:08.720 13 + This will be at protocol related, just so you know. 14 14 15 15 4 16 - 00:01:30.000 --> 00:01:34.000 17 - It's fun. 16 + 00:00:08.720 --> 00:00:10.720 17 + The description does not make it sound that way, 18 18 19 19 5 20 - 00:01:34.000 --> 00:01:38.000 21 - Good. 20 + 00:00:10.720 --> 00:00:12.160 21 + but I promise it will. 22 22 23 23 6 24 - 00:01:38.000 --> 00:01:42.000 25 - Oh good. It works. 24 + 00:00:12.160 --> 00:00:14.320 25 + For one thing, there's a leaflet link. 26 26 27 27 7 28 - 00:01:42.000 --> 00:01:46.000 29 - Perfect. We officially start in two minutes. Yeah. 28 + 00:00:14.320 --> 00:00:19.160 29 + So as Boris said, I have been writing about this for a while. 30 30 31 31 8 32 - 00:01:46.000 --> 00:01:50.000 33 - It's a good conference. 32 + 00:00:19.160 --> 00:00:21.200 33 + I've also been thinking about this topic for, 34 34 35 35 9 36 - 00:01:50.000 --> 00:01:54.000 37 - I have to leave in the morning sadly. As I expected I would. 36 + 00:00:21.200 --> 00:00:25.440 37 + and speaking and writing and practicing things around this 38 38 39 39 10 40 - 00:01:54.000 --> 00:01:58.000 41 - I feel regret. My mother-in-law is in the hot room. 40 + 00:00:25.440 --> 00:00:28.360 41 + for almost 20 years. 42 42 43 43 11 44 - 00:01:58.000 --> 00:02:02.000 45 - I'm going for surgery Monday so I have to go. Yeah. 44 + 00:00:28.360 --> 00:00:31.480 45 + So this is a, and that sounds probably pretty crazy 46 46 47 47 12 48 - 00:02:02.000 --> 00:02:06.000 49 - I have to one two. Yeah. 48 + 00:00:31.480 --> 00:00:33.760 49 + because we haven't had generative software that long, 50 50 51 51 13 52 - 00:02:06.000 --> 00:02:10.000 53 - Yeah. The other day. I haven't spoken at my conference 52 + 00:00:33.760 --> 00:00:37.200 53 + but I'm gonna talk to you about architectural patterns today. 54 54 55 55 14 56 - 00:02:10.000 --> 00:02:14.000 57 - in I don't know how many years. 56 + 00:00:37.200 --> 00:00:38.400 57 + But I wanna kinda set it up 58 58 59 59 15 60 - 00:02:14.000 --> 00:02:18.000 61 - You've done this fiddle faddle MCing business. 60 + 00:00:38.400 --> 00:00:42.320 61 + and tell you about what I was thinking. 62 62 63 63 16 64 - 00:02:18.000 --> 00:02:22.000 65 - Yeah. I've done the MC. That's not the same thing. No. It's a very 64 + 00:00:42.320 --> 00:00:46.440 65 + So probably a lot of us started thinking about vibe coding 66 66 67 67 17 68 - 00:02:22.000 --> 00:02:26.000 69 - different process. 68 + 00:00:46.440 --> 00:00:49.920 69 + before it was called vibe coding three more years ago. 70 70 71 71 18 72 - 00:02:26.000 --> 00:02:30.000 73 - I'm going to do it so much. It's different with AI. 72 + 00:00:49.920 --> 00:00:53.840 73 + And the first thought I thought back in 2023 was like, 74 74 75 75 19 76 - 00:02:30.000 --> 00:02:34.000 77 - Like this morning 76 + 00:00:53.840 --> 00:00:57.960 77 + someday people will actually allow agents to write code 78 78 79 79 20 80 - 00:02:34.000 --> 00:02:38.000 81 - I had my presentation software create a script for me which I would never read. 80 + 00:00:57.960 --> 00:00:59.360 81 + and they won't even review the code. 82 82 83 83 21 84 - 00:02:38.000 --> 00:02:42.000 85 - Then I gave it to chat GPT. I was getting ready walking around the hotel 84 + 00:00:59.360 --> 00:01:01.160 85 + That sounded crazy, you know? 86 86 87 87 22 88 - 00:02:42.000 --> 00:02:46.000 89 - room and I had a chat. I said go slide by slide and tell me 88 + 00:01:01.160 --> 00:01:03.600 89 + And then it's like, oh, next year, okay, 90 90 91 91 23 92 - 00:02:46.000 --> 00:02:50.000 93 - what's the thought and what how do I transition just to refresh myself for a minute. 92 + 00:01:03.600 --> 00:01:04.840 93 + a lot of people are gonna do this. 94 94 95 95 24 96 - 00:02:50.000 --> 00:02:54.000 97 - Amazing. 96 + 00:01:04.840 --> 00:01:07.400 97 + And now I'm thinking, of course, everyone's gonna do it. 98 98 99 99 25 100 - 00:02:55.000 --> 00:02:58.000 101 - Shall we. Alright. We're going to get started with Chad 100 + 00:01:07.400 --> 00:01:09.160 101 + Why is everyone gonna do it? 102 102 103 103 26 104 - 00:02:58.000 --> 00:03:02.000 105 - Fowler who has been writing on Bluesky for 104 + 00:01:09.160 --> 00:01:12.120 105 + Because people are lazy, right? 106 106 107 107 27 108 - 00:03:02.000 --> 00:03:06.000 109 - a while. I guess leaflet rather. About some thoughts on how 108 + 00:01:12.120 --> 00:01:15.480 109 + They are, they are lazy, agents are not lazy. 110 110 111 111 28 112 - 00:03:06.000 --> 00:03:10.000 113 - maybe software just regenerates 112 + 00:01:15.480 --> 00:01:18.080 113 + And all of us with the best intentions, 114 114 115 115 29 116 - 00:03:10.000 --> 00:03:14.000 117 - itself constantly. So over to Chad Fowler with the Phoenix architecture. 116 + 00:01:18.080 --> 00:01:21.120 117 + when we are stressed, we will do the easiest possible thing. 118 118 119 119 30 120 - 00:03:14.000 --> 00:03:18.000 121 - Thank you. Thank you. Hello. This will be 120 + 00:01:21.120 --> 00:01:25.400 121 + So I started thinking about if we know they're gonna do it, 122 122 123 123 31 124 - 00:03:18.000 --> 00:03:22.000 125 - at protocol related. Just so you know. 124 + 00:01:25.400 --> 00:01:27.320 125 + how can we make it okay? 126 126 127 127 32 128 - 00:03:22.000 --> 00:03:26.000 129 - The description does not make it sound that way but I promise it will. For one 128 + 00:01:27.320 --> 00:01:28.400 129 + And I should say it this way, 130 130 131 131 33 132 - 00:03:26.000 --> 00:03:30.000 133 - thing there's a leaflet link. So as Boris said 132 + 00:01:28.400 --> 00:01:30.320 133 + so it doesn't sound like I'm judging anyone. 134 134 135 135 34 136 - 00:03:30.000 --> 00:03:34.000 137 - I have been writing about this for a while. I've also been thinking about this 136 + 00:01:30.320 --> 00:01:32.920 137 + If I know I'm gonna do it, how can we make it okay? 138 138 139 139 35 140 - 00:03:34.000 --> 00:03:38.000 141 - topic for and speaking and writing and practicing 140 + 00:01:32.920 --> 00:01:35.520 141 + And not just for trivial vibe coded one shot apps. 142 142 143 143 36 144 - 00:03:38.000 --> 00:03:42.000 145 - things around this for almost 20 years. 144 + 00:01:35.520 --> 00:01:37.480 145 + That's a demo, that's a magic trick. 146 146 147 147 37 148 - 00:03:42.000 --> 00:03:46.000 149 - So this is a and that sounds probably pretty crazy because we haven't had 148 + 00:01:37.480 --> 00:01:39.240 149 + That doesn't matter in real life. 150 150 151 151 38 152 - 00:03:46.000 --> 00:03:50.000 153 - generative software that long but I'm going to talk to you about architectural patterns today. 152 + 00:01:39.240 --> 00:01:40.840 153 + It's fun, but it doesn't matter. 154 154 155 155 39 156 - 00:03:50.000 --> 00:03:54.000 157 - But I want to kind of set it up and 156 + 00:01:41.760 --> 00:01:45.480 157 + And so the thing that occurred to me is, 158 158 159 159 40 160 - 00:03:54.000 --> 00:03:58.000 161 - tell you about what I was thinking. So probably a lot of us started 160 + 00:01:45.480 --> 00:01:47.440 161 + and I was talking to a bunch of nerd friends, 162 162 163 163 41 164 - 00:03:58.000 --> 00:04:02.000 165 - thinking about vibe coding before it was called vibe coding three 164 + 00:01:47.440 --> 00:01:49.840 165 + you know, old people like me about, 166 166 167 167 42 168 - 00:04:02.000 --> 00:04:06.000 169 - more years ago. And the first thought I thought back in 168 + 00:01:49.840 --> 00:01:51.280 169 + if I'm looking at something like 170 170 171 171 43 172 - 00:04:06.000 --> 00:04:10.000 173 - 2023 was like someday people will actually 172 + 00:01:52.360 --> 00:01:54.400 173 + a pure function written in Haskell, 174 174 175 175 44 176 - 00:04:10.000 --> 00:04:14.000 177 - allow agents to write code and they won't even review the code. That sounded crazy. 176 + 00:01:54.400 --> 00:01:55.280 177 + this isn't Haskell, 178 178 179 179 45 180 - 00:04:14.000 --> 00:04:18.000 181 - And it's like oh next year okay a lot of people are going to do this. 180 + 00:01:55.280 --> 00:01:57.960 181 + because I didn't want you to have to try to read that. 182 182 183 183 46 184 - 00:04:18.000 --> 00:04:22.000 185 - And now I'm thinking of course everyone's going to do it. Why is everyone going to do it? 184 + 00:01:57.960 --> 00:01:59.560 185 + Pure function written in Haskell, 186 186 187 187 47 188 - 00:04:22.000 --> 00:04:26.000 189 - Because people are lazy. Right? They are. 188 + 00:01:59.560 --> 00:02:02.000 189 + so no side effects, great type system. 190 190 191 191 48 192 - 00:04:26.000 --> 00:04:30.000 193 - They are lazy. Agents are not lazy. And all of us 192 + 00:02:02.000 --> 00:02:04.880 193 + The language can ensure there are no side effects. 194 194 195 195 49 196 - 00:04:30.000 --> 00:04:34.000 197 - with the best intentions when we are stressed we will do the easiest possible thing. 196 + 00:02:04.880 --> 00:02:06.760 197 + You know what the input and the output types are, 198 198 199 199 50 200 - 00:04:34.000 --> 00:04:38.000 201 - So I started thinking about if we know they're going to 200 + 00:02:06.760 --> 00:02:08.800 201 + the names are great, et cetera. 202 202 203 203 51 204 - 00:04:38.000 --> 00:04:42.000 205 - do it how can we make it okay? And I should say it this way so it doesn't 204 + 00:02:08.800 --> 00:02:11.880 205 + I pretty much thought even three years ago, 206 206 207 207 52 208 - 00:04:42.000 --> 00:04:46.000 209 - sound like I'm judging anyone. If I know I'm going to do it how can we make it okay? 208 + 00:02:11.880 --> 00:02:15.160 209 + I can tell chat GPT in the little chat GPT program 210 210 211 211 53 212 - 00:04:46.000 --> 00:04:50.000 213 - And not just for trivial vibe coded one shot apps. That's a demo. That's a magic 212 + 00:02:15.160 --> 00:02:16.000 213 + to create that. 214 214 215 215 54 216 - 00:04:50.000 --> 00:04:54.000 217 - trick. That doesn't matter in real life. It's fun but it doesn't matter. 216 + 00:02:16.000 --> 00:02:17.280 217 + I can just copy and paste it in, 218 218 219 219 55 220 - 00:04:54.000 --> 00:04:58.000 221 - And so the thing that occurred to me 220 + 00:02:17.280 --> 00:02:19.800 221 + probably trust it, never have to verify it. 222 222 223 223 56 224 - 00:04:58.000 --> 00:05:02.000 225 - is and I was talking to a bunch of nerd friends you know old people like me about 224 + 00:02:19.800 --> 00:02:22.020 225 + We've all sort of had that intuition, 226 226 227 227 57 228 - 00:05:02.000 --> 00:05:06.000 229 - if I'm looking at something like a pure 228 + 00:02:22.020 --> 00:02:25.200 229 + that small focused things are probably okay. 230 230 231 231 58 232 - 00:05:06.000 --> 00:05:10.000 233 - function written in Haskell. This isn't Haskell because I didn't want you to have to try to read that. 232 + 00:02:26.000 --> 00:02:27.360 233 + And it's probably gonna do a good job, right? 234 234 235 235 59 236 - 00:05:10.000 --> 00:05:14.000 237 - Pure function written in Haskell. So no side effects. 236 + 00:02:27.360 --> 00:02:29.600 237 + And so I started thinking about this like, 238 238 239 239 60 240 - 00:05:14.000 --> 00:05:18.000 241 - Great type system. The language can ensure there are no side effects. 240 + 00:02:29.600 --> 00:02:33.320 241 + well, what's the difference between that and a whole system? 242 242 243 243 61 244 - 00:05:18.000 --> 00:05:22.000 245 - You know what the input and the output types are. The names are great, etc. 244 + 00:02:33.320 --> 00:02:35.880 245 + And really the whole system, it's about shapes. 246 246 247 247 62 248 - 00:05:22.000 --> 00:05:26.000 249 - I pretty much thought even three years ago I can tell 248 + 00:02:35.880 --> 00:02:37.440 249 + So I just described a bunch of things 250 250 251 251 63 252 - 00:05:26.000 --> 00:05:30.000 253 - chat GPT in the little chat GPT program to create that. I can just copy and 252 + 00:02:37.440 --> 00:02:38.960 253 + that were about shape is about size, 254 254 255 255 64 256 - 00:05:30.000 --> 00:05:34.000 257 - paste it in. Probably trust it. Never have to verify it. We've all sort of had 256 + 00:02:38.960 --> 00:02:41.600 257 + it was about like the boundaries of the function, 258 258 259 259 65 260 - 00:05:34.000 --> 00:05:38.000 261 - that intuition that small focused things are probably 260 + 00:02:41.600 --> 00:02:43.840 261 + the type system, the names, all these things. 262 262 263 263 66 264 - 00:05:38.000 --> 00:05:42.000 265 - okay. And it's probably going to do a good job. Right? And so I started thinking 264 + 00:02:44.720 --> 00:02:47.560 265 + It's easy to replace something that is that small. 266 266 267 267 67 268 - 00:05:42.000 --> 00:05:46.000 269 - about this like well what's the difference between that and a whole system? 268 + 00:02:47.560 --> 00:02:49.520 269 + It's also easy to generate something correct, 270 270 271 271 68 272 - 00:05:46.000 --> 00:05:50.000 273 - And really the whole system it's about shapes. So I just described 272 + 00:02:49.520 --> 00:02:50.640 273 + that small. 274 274 275 275 69 276 - 00:05:50.000 --> 00:05:54.000 277 - a bunch of things that were about shape. It was about size. It was about like the boundaries 276 + 00:02:50.640 --> 00:02:52.480 277 + So this led me on a whole adventure, 278 278 279 279 70 280 - 00:05:54.000 --> 00:05:58.000 281 - of the function. The type system. The names. All these things. 280 + 00:02:52.480 --> 00:02:55.880 281 + but I'm gonna go back in time a little bit to 2014. 282 282 283 283 71 284 - 00:05:58.000 --> 00:06:02.000 285 - It's easy to replace something that is that small. It's also easy to 284 + 00:02:55.880 --> 00:02:58.840 285 + Did any of you live through Heartbleed? 286 286 287 287 72 288 - 00:06:02.000 --> 00:06:06.000 289 - generate something correct that small. So this led me on a whole adventure. 288 + 00:02:58.840 --> 00:02:59.920 289 + Yeah. 290 290 291 291 73 292 - 00:06:06.000 --> 00:06:10.000 293 - But I'm going to go back in time a little bit to 2014. Did any of you 292 + 00:02:59.920 --> 00:03:01.320 293 + So if you were working at a company 294 294 295 295 74 296 - 00:06:10.000 --> 00:06:14.000 297 - live through Heartbleed? Yeah. So if you were working 296 + 00:03:01.320 --> 00:03:04.920 297 + that had any production systems when Heartbleed happened, 298 298 299 299 75 300 - 00:06:14.000 --> 00:06:18.000 301 - at a company that had any production systems when Heartbleed 300 + 00:03:04.920 --> 00:03:08.120 301 + I was at Wonderlist in Berlin at the time I was CTO. 302 302 303 303 76 304 - 00:06:18.000 --> 00:06:22.000 305 - happened, I was at Wonderlist in Berlin at the time I was CTO. I woke up 304 + 00:03:08.120 --> 00:03:10.840 305 + I woke up one morning and my colleague, 306 306 307 307 77 308 - 00:06:22.000 --> 00:06:26.000 309 - one morning and my colleague James Duncan Davidson who was the creator 308 + 00:03:10.840 --> 00:03:13.280 309 + James Duncan Davidson, who was the creator of Tomcat 310 310 311 311 78 312 - 00:06:26.000 --> 00:06:30.000 313 - of Tomcat and Ant, another old school guy, had sent me a message saying 312 + 00:03:13.280 --> 00:03:15.460 313 + and Ant, like another old school guy, 314 314 315 315 79 316 - 00:06:30.000 --> 00:06:34.000 317 - we have to turn off the entire service. That's how I woke up that morning. I was like 316 + 00:03:15.460 --> 00:03:17.040 317 + had sent me a message saying, 318 318 319 319 80 320 - 00:06:34.000 --> 00:06:38.000 321 - oh my god what did we do wrong? We didn't do anything wrong. 320 + 00:03:17.040 --> 00:03:19.000 321 + we have to turn off the entire service. 322 322 323 323 81 324 - 00:06:38.000 --> 00:06:42.000 325 - So Heartbleed was a bug in open SSL that it was just a mistake 324 + 00:03:19.000 --> 00:03:20.320 325 + That's how I woke up that morning. 326 326 327 327 82 328 - 00:06:42.000 --> 00:06:46.000 329 - that allowed leakage of private data just 328 + 00:03:20.320 --> 00:03:21.920 329 + I was like, oh my God, what is that? 330 330 331 331 83 332 - 00:06:46.000 --> 00:06:50.000 333 - to anyone on the internet that could access the service. 332 + 00:03:21.960 --> 00:03:23.160 333 + What did we do wrong? 334 334 335 335 84 336 - 00:06:50.000 --> 00:06:54.000 337 - And it was a disaster. It was such a disaster. So we had a micro 336 + 00:03:23.160 --> 00:03:24.680 337 + We didn't do anything wrong. 338 338 339 339 85 340 - 00:06:54.000 --> 00:06:58.000 341 - services architecture. And we've been doing something called immutable infrastructure 340 + 00:03:24.680 --> 00:03:27.520 341 + So Heartbleed was a bug in OpenSSL 342 342 343 343 86 344 - 00:06:58.000 --> 00:07:02.000 345 - long before that was a thing that everyone did. It was before Docker was in 344 + 00:03:27.520 --> 00:03:29.480 345 + that it was just a mistake 346 346 347 347 87 348 - 00:07:02.000 --> 00:07:06.000 349 - major circulation and usage. It was still pretty early. 348 + 00:03:29.480 --> 00:03:32.460 349 + that allowed leakage of private data 350 350 351 351 88 352 - 00:07:06.000 --> 00:07:10.000 353 - And so we had hundreds of services, which means we had hundreds of 352 + 00:03:32.460 --> 00:03:36.800 353 + just to anyone on the internet that could access the service. 354 354 355 355 89 356 - 00:07:10.000 --> 00:07:14.000 357 - computers that had a bad version of open SSL that were running in 356 + 00:03:36.800 --> 00:03:38.560 357 + And it was a disaster. 358 358 359 359 90 360 - 00:07:14.000 --> 00:07:18.000 361 - production with millions of active users. So what did we do? 360 + 00:03:38.560 --> 00:03:39.480 361 + It was such a disaster. 362 362 363 363 91 364 - 00:07:18.000 --> 00:07:22.000 365 - That's a panic situation. I remember looking at the 364 + 00:03:39.480 --> 00:03:41.800 365 + So we had a microservices architecture 366 366 367 367 92 368 - 00:07:22.000 --> 00:07:26.000 369 - AWS dashboard and all the things and just thinking what are we going to do? We were waiting for 368 + 00:03:41.800 --> 00:03:43.280 369 + and we've been doing something called 370 370 371 371 93 372 - 00:07:26.000 --> 00:07:30.000 373 - Amazon. They were not responding. They were very busy, as you might guess that day. 372 + 00:03:43.280 --> 00:03:46.000 373 + immutable infrastructure long before that was a thing 374 374 375 375 94 376 - 00:07:30.000 --> 00:07:34.000 377 - And so we said well, as soon as we have a good open SSL 376 + 00:03:46.000 --> 00:03:46.840 377 + that everyone did. 378 378 379 379 95 380 - 00:07:34.000 --> 00:07:38.000 381 - image, we're just going to replace literally every server. 380 + 00:03:46.840 --> 00:03:50.400 381 + It was before Docker was like in major circulation and usage. 382 382 383 383 96 384 - 00:07:38.000 --> 00:07:42.000 385 - Hundreds of servers. 300-ish instances at the time. 384 + 00:03:50.400 --> 00:03:51.640 385 + It was still pretty early. 386 386 387 387 97 388 - 00:07:42.000 --> 00:07:46.000 389 - How did we do it? I went to a computer. 388 + 00:03:52.640 --> 00:03:55.320 389 + And so we had hundreds of services, 390 390 391 391 98 392 - 00:07:46.000 --> 00:07:50.000 393 - I was afraid. I typed a command. And over the course of a couple of hours, they all 392 + 00:03:55.320 --> 00:03:57.400 393 + which means we had hundreds of computers 394 394 395 395 99 396 - 00:07:50.000 --> 00:07:54.000 397 - got replaced. Nothing ever went down. And it just worked. Why? 396 + 00:03:57.400 --> 00:03:59.880 397 + that had a bad version of OpenSSL 398 398 399 399 100 400 - 00:07:54.000 --> 00:07:58.000 401 - Because the system was built to be 400 + 00:03:59.880 --> 00:04:01.320 401 + that were running in production 402 402 403 403 101 404 - 00:07:58.000 --> 00:08:02.000 405 - a massive system of small components. 404 + 00:04:01.320 --> 00:04:03.840 405 + with millions of active users. 406 406 407 407 102 408 - 00:08:02.000 --> 00:08:06.000 409 - And it was always built with the idea that these components would be destroyed. 408 + 00:04:03.840 --> 00:04:04.760 409 + So what did we do? 410 410 411 411 103 412 - 00:08:06.000 --> 00:08:10.000 413 - That's the idea behind immutable infrastructure. You never change a server. 412 + 00:04:04.760 --> 00:04:06.480 413 + I mean, that's a panic situation. 414 414 415 415 104 416 - 00:08:10.000 --> 00:08:14.000 417 - You only modify the server by replacing it. So if you need to 416 + 00:04:06.480 --> 00:04:08.080 417 + I remember looking at the Amazon, 418 418 419 419 105 420 - 00:08:14.000 --> 00:08:18.000 421 - upgrade something, you throw away the old thing, you replace it with a new thing. 420 + 00:04:08.080 --> 00:04:10.880 421 + AWS dashboarded all the things and just thinking, 422 422 423 423 106 424 - 00:08:18.000 --> 00:08:22.000 425 - Kind of old hat and infrastructure now. If you're a DevOps-y kind of person, that's how you do it probably. 424 + 00:04:10.880 --> 00:04:11.860 425 + what are we gonna do? 426 426 427 427 107 428 - 00:08:22.000 --> 00:08:26.000 429 - If not, apologies to you. You should get a new job. 428 + 00:04:11.860 --> 00:04:13.280 429 + We were waiting for Amazon. 430 430 431 431 108 432 - 00:08:26.000 --> 00:08:30.000 433 - So it took us a day. It took most teams weeks 432 + 00:04:13.280 --> 00:04:14.240 433 + They were not responding. 434 434 435 435 109 436 - 00:08:30.000 --> 00:08:34.000 437 - or a week. There are still 250,000-ish servers on the 436 + 00:04:14.240 --> 00:04:17.240 437 + They were very busy, as you might guess, that day. 438 438 439 439 110 440 - 00:08:34.000 --> 00:08:38.000 441 - Internet that are suffering from this problem. Which means 250,000 440 + 00:04:17.240 --> 00:04:18.760 441 + And so we said, well, 442 442 443 443 111 444 - 00:08:38.000 --> 00:08:42.000 445 - compromised servers that you can get private data out of for whatever reason. 444 + 00:04:18.800 --> 00:04:21.280 445 + as soon as we have a good OpenSSL image, 446 446 447 447 112 448 - 00:08:42.000 --> 00:08:46.000 449 - But this problem is sort of solved, right? This is more than ten years ago. 448 + 00:04:21.280 --> 00:04:24.200 449 + we're just gonna replace literally every server, 450 450 451 451 113 452 - 00:08:46.000 --> 00:08:50.000 453 - Here's an imaginary scenario. Later on this year, 452 + 00:04:24.200 --> 00:04:29.200 453 + hundreds of servers, 300-ish instances at the time. 454 454 455 455 114 456 - 00:08:50.000 --> 00:08:54.000 457 - the Lazarus Group in North Korea infects some packages 456 + 00:04:29.200 --> 00:04:30.340 457 + How did we do it? 458 458 459 459 115 460 - 00:08:54.000 --> 00:08:58.000 461 - in NPM. Or whatever package manager. And the infection 460 + 00:04:31.240 --> 00:04:32.360 461 + I went to a computer. 462 462 463 463 116 464 - 00:08:58.000 --> 00:09:02.000 465 - goes like a virus through the network. And it starts infecting all the other 464 + 00:04:32.360 --> 00:04:33.200 465 + I was afraid. 466 466 467 467 117 468 - 00:09:02.000 --> 00:09:06.000 469 - packages. And at the end of the day, you wake up 468 + 00:04:33.200 --> 00:04:34.460 469 + I typed a command. 470 470 471 471 118 472 - 00:09:06.000 --> 00:09:10.000 473 - to the news that the entire JavaScript ecosystem is compromised. 472 + 00:04:34.460 --> 00:04:36.220 473 + And over the course of a couple of hours, 474 474 475 475 119 476 - 00:09:10.000 --> 00:09:14.000 477 - What do you do? You can't delete all the servers 476 + 00:04:36.220 --> 00:04:37.440 477 + they all got replaced. 478 478 479 479 120 480 - 00:09:14.000 --> 00:09:18.000 481 - and restart them because NPM itself is compromised. Everything is compromised. 480 + 00:04:37.440 --> 00:04:40.100 481 + Nothing ever went down and it just worked. 482 482 483 483 121 484 - 00:09:18.000 --> 00:09:22.000 485 - You can't trust anything in the ecosystem. You have to 484 + 00:04:40.100 --> 00:04:41.560 485 + Why? 486 486 487 487 122 488 - 00:09:22.000 --> 00:09:26.000 489 - actually move to a new language and a new ecosystem. So let's do that in a day. 488 + 00:04:41.560 --> 00:04:46.600 489 + Because the system was built to be a massive system 490 490 491 491 123 492 - 00:09:26.000 --> 00:09:30.000 493 - Yeah? On a complicated application. Probably not, right? 492 + 00:04:46.600 --> 00:04:49.960 493 + of small components and it was always built 494 494 495 495 124 496 - 00:09:30.000 --> 00:09:34.000 497 - But that's the idea. You would need to delete everything 496 + 00:04:49.960 --> 00:04:52.720 497 + with the idea that these components would be destroyed. 498 498 499 499 125 500 - 00:09:34.000 --> 00:09:38.000 501 - and regenerate it. It would be an absolute disaster. 500 + 00:04:52.720 --> 00:04:55.300 501 + That's the idea behind immutable infrastructure. 502 502 503 503 126 504 - 00:09:38.000 --> 00:09:42.000 505 - So this is the goal of the 504 + 00:04:55.300 --> 00:04:56.720 505 + You never change a server. 506 506 507 507 127 508 - 00:09:42.000 --> 00:09:46.000 509 - architecture that I'm putting forward here. And you probably can't read 508 + 00:04:56.720 --> 00:04:57.920 509 + You only modify, 510 510 511 511 128 512 - 00:09:46.000 --> 00:09:50.000 513 - it because it's too small. These are command lines that say Phoenix generate and 512 + 00:04:57.920 --> 00:05:00.160 513 + the only way you modify a server is by replacing it. 514 514 515 515 129 516 - 00:09:50.000 --> 00:09:54.000 517 - regenerate. And the idea is just replace all the implementations of everything that we have. 516 + 00:05:00.160 --> 00:05:01.400 517 + So if you need to upgrade something, 518 518 519 519 130 520 - 00:09:54.000 --> 00:09:58.000 521 - Say from NPM, we're going to go ahead and finally move to Rust like everybody else. 520 + 00:05:01.400 --> 00:05:02.920 521 + you throw away the old thing, 522 522 523 523 131 524 - 00:09:58.000 --> 00:10:02.000 525 - So one last story. 524 + 00:05:02.920 --> 00:05:04.380 525 + you replace it with a new thing. 526 526 527 527 132 528 - 00:10:02.000 --> 00:10:06.000 529 - Early in my career, this is over 20 years ago, 528 + 00:05:04.380 --> 00:05:06.400 529 + Kind of old hat and infrastructure now. 530 530 531 531 133 532 - 00:10:06.000 --> 00:10:10.000 533 - I was moving up the career ladder. I was at a big 532 + 00:05:06.400 --> 00:05:07.800 533 + If you're a DevOps-y kind of person, 534 534 535 535 134 536 - 00:10:10.000 --> 00:10:14.000 537 - public company. I was moving toward a CIO position in one of 536 + 00:05:07.800 --> 00:05:09.200 537 + that's how you do it probably. 538 538 539 539 135 540 - 00:10:14.000 --> 00:10:18.000 541 - the divisions of the company. And I was asked to do a new job. 540 + 00:05:09.200 --> 00:05:12.720 541 + If not, apologies to you, you should get a new job. 542 542 543 543 136 544 - 00:10:18.000 --> 00:10:22.000 545 - The new job was pretty surprising giving my career path. It was 544 + 00:05:12.720 --> 00:05:14.680 545 + So it took us a day. 546 546 547 547 137 548 - 00:10:22.000 --> 00:10:26.000 549 - to be the lone developer that took over another 548 + 00:05:14.720 --> 00:05:18.000 549 + It took most teams weeks or a week. 550 550 551 551 138 552 - 00:10:26.000 --> 00:10:30.000 553 - system from a guy who was trolling the company. So this guy 552 + 00:05:18.000 --> 00:05:21.080 553 + There are still 250,000-ish servers on the internet 554 554 555 555 139 556 - 00:10:30.000 --> 00:10:34.000 557 - had written this really complex system in C that was talking 556 + 00:05:21.080 --> 00:05:23.100 557 + that are suffering from this problem, 558 558 559 559 140 560 - 00:10:34.000 --> 00:10:38.000 561 - to the MobyTech's radio frequency network. It was managing laptops 560 + 00:05:23.100 --> 00:05:25.560 561 + which means 250,000 compromised servers 562 562 563 563 141 564 - 00:10:38.000 --> 00:10:42.000 565 - in the field for service technicians. It was basically like a bespoke message 564 + 00:05:25.560 --> 00:05:28.840 565 + that you can get private data out of for whatever reason. 566 566 567 567 142 568 - 00:10:42.000 --> 00:10:46.000 569 - queuing system. Like you'd do RabbitMQ today. He had built his own thing then. 568 + 00:05:28.840 --> 00:05:30.960 569 + Okay, but this problem is sort of solved, right? 570 570 571 571 143 572 - 00:10:46.000 --> 00:10:50.000 573 - No one knew how this thing worked. Why? Because 572 + 00:05:30.960 --> 00:05:32.800 573 + This is more than 10 years ago. 574 574 575 575 144 576 - 00:10:50.000 --> 00:10:54.000 577 - the only real artifact of the system was the code. It was a bunch of conversations 576 + 00:05:32.800 --> 00:05:35.220 577 + Here's an imaginary scenario. 578 578 579 579 145 580 - 00:10:54.000 --> 00:10:58.000 581 - that had happened in ugly conference rooms in this company over the years. 580 + 00:05:35.220 --> 00:05:39.160 581 + Later on this year, the Lazarus Group in North Korea 582 582 583 583 146 584 - 00:10:58.000 --> 00:11:02.000 585 - It was all in production. This guy was the only person who 584 + 00:05:39.160 --> 00:05:43.380 585 + infects some packages in NPM or whatever package manager. 586 586 587 587 147 588 - 00:11:02.000 --> 00:11:06.000 589 - knew how any of it worked. Really knew how it worked. But he was 588 + 00:05:44.260 --> 00:05:47.340 589 + And the infection goes like a virus through the network 590 590 591 591 148 592 - 00:11:06.000 --> 00:11:10.000 593 - basically holding us hostage as a company. So I went from 592 + 00:05:47.340 --> 00:05:50.020 593 + and it starts infecting all the other packages. 594 594 595 595 149 596 - 00:11:10.000 --> 00:11:14.000 597 - move toward CIO to go sit up all night in an office 596 + 00:05:50.020 --> 00:05:53.860 597 + And at the end of the day, you wake up to the news 598 598 599 599 150 600 - 00:11:14.000 --> 00:11:18.000 601 - in the dark like doing S-trace on server 600 + 00:05:53.860 --> 00:05:58.300 601 + that the entire JavaScript ecosystem is compromised. 602 602 603 603 151 604 - 00:11:18.000 --> 00:11:22.000 605 - processes trying to figure out what this thing does. So this can 604 + 00:05:58.300 --> 00:05:59.500 605 + What do you do? 606 606 607 607 152 608 - 00:11:22.000 --> 00:11:26.000 609 - happen today, and it could happen 20 years ago, you can be held hostage by your 608 + 00:05:59.500 --> 00:06:02.060 609 + You can't delete all the servers and restart them 610 610 611 611 153 612 - 00:11:26.000 --> 00:11:30.000 613 - code base. So I learned something very early around that 612 + 00:06:02.060 --> 00:06:03.980 613 + because NPM itself is compromised. 614 614 615 615 154 616 - 00:11:30.000 --> 00:11:34.000 617 - time in my career from a guy named Kent Beck who is the creator of 616 + 00:06:03.980 --> 00:06:04.900 617 + Everything is compromised. 618 618 619 619 155 620 - 00:11:34.000 --> 00:11:38.000 621 - Extreme Programming and a bunch of other stuff. And if you're my age in software development, he's 620 + 00:06:04.900 --> 00:06:07.060 621 + You can't trust anything in the ecosystem. 622 622 623 623 156 624 - 00:11:38.000 --> 00:11:42.000 625 - probably one of your software development heroes. If something hurts, 624 + 00:06:08.180 --> 00:06:10.140 625 + You have to actually move to a new language 626 626 627 627 157 628 - 00:11:42.000 --> 00:11:46.000 629 - do it more frequently. So with Extreme Programming, which was the precursor to Agile 628 + 00:06:10.140 --> 00:06:11.740 629 + and a new ecosystem. 630 630 631 631 158 632 - 00:11:46.000 --> 00:11:50.000 633 - which ruined everything and they never should have done the Agile thing, but Extreme Programming 632 + 00:06:11.740 --> 00:06:13.180 633 + So let's do that in a day. 634 634 635 635 159 636 - 00:11:50.000 --> 00:11:54.000 637 - was like merging is hard, you need to do continuous integration, 636 + 00:06:14.180 --> 00:06:17.860 637 + On a complicated application, probably not, right? 638 638 639 639 160 640 - 00:11:54.000 --> 00:11:58.000 641 - deployment is hard, we learned all these things, testing is hard, you should do it up front 640 + 00:06:17.860 --> 00:06:18.700 641 + But that's the idea. 642 642 643 643 161 644 - 00:11:58.000 --> 00:12:02.000 645 - so no code is written without a test, code review is hard, just do pair programming 644 + 00:06:18.700 --> 00:06:22.620 645 + You would need to delete everything and regenerate it. 646 646 647 647 162 648 - 00:12:02.000 --> 00:12:06.000 649 - constant, right? So if updating code is hard and making 648 + 00:06:22.620 --> 00:06:25.260 649 + It would be an absolute disaster. 650 650 651 651 163 652 - 00:12:06.000 --> 00:12:10.000 653 - changes to code is hard, the Kent Beck version of that would be just do it 652 + 00:06:25.260 --> 00:06:29.380 653 + So this is the goal of the architecture 654 654 655 655 164 656 - 00:12:10.000 --> 00:12:14.000 657 - constantly, like all day maybe. So how do you do that? 656 + 00:06:29.380 --> 00:06:31.620 657 + that I'm putting forward here. 658 658 659 659 165 660 - 00:12:14.000 --> 00:12:18.000 661 - That means that the code itself is not 660 + 00:06:31.620 --> 00:06:33.980 661 + And you probably can't read it because it's too small. 662 662 663 663 166 664 - 00:12:18.000 --> 00:12:22.000 665 - that important, sort of, right? If you're going to be replacing it all the time, if you're going to be throwing it away 664 + 00:06:33.980 --> 00:06:36.380 665 + These are command lines that say like Phoenix generate 666 666 667 667 167 668 - 00:12:22.000 --> 00:12:26.000 669 - and replacing it, how do you do it? And then another person who's not as smart 668 + 00:06:36.380 --> 00:06:38.260 669 + and regenerate and the idea is just like, 670 670 671 671 168 672 - 00:12:26.000 --> 00:12:30.000 673 - as Kent once said the mutability of a system is enhanced by the 672 + 00:06:38.260 --> 00:06:41.260 673 + replace all the implementations of everything that we have. 674 674 675 675 169 676 - 00:12:30.000 --> 00:12:34.000 677 - immutability of its components. I said that, but I like to quote myself 676 + 00:06:41.260 --> 00:06:43.060 677 + Say like from NPM, we're gonna go ahead 678 678 679 679 170 680 - 00:12:34.000 --> 00:12:38.000 681 - because I think it's a pretty good one. Maybe in 20 years or so, someone will say 680 + 00:06:43.260 --> 00:06:45.500 681 + and finally move to Rust like everybody else. 682 682 683 683 171 684 - 00:12:38.000 --> 00:12:42.000 685 - if it was me, you heard Chad say this and it was meaningful to you. 684 + 00:06:47.100 --> 00:06:49.100 685 + So one last story. 686 686 687 687 172 688 - 00:12:42.000 --> 00:12:46.000 689 - So the weird thing about this is, you know, we're 688 + 00:06:49.980 --> 00:06:52.540 689 + Early in my career, this is over 20 years ago, 690 690 691 691 173 692 - 00:12:46.000 --> 00:12:50.000 693 - in this weird era, how many of you are actually software developers 692 + 00:06:53.700 --> 00:06:55.980 693 + I was like moving up the career ladder. 694 694 695 695 174 696 - 00:12:50.000 --> 00:12:54.000 697 - by the way? Okay, got enough of you that some of you will feel 696 + 00:06:55.980 --> 00:06:57.220 697 + I was at a big public company. 698 698 699 699 175 700 - 00:12:54.000 --> 00:12:58.000 701 - sad about this sort of, you know, is the craft going away? 700 + 00:06:57.220 --> 00:06:59.300 701 + I was moving toward a CIO position 702 702 703 703 176 704 - 00:12:58.000 --> 00:13:02.000 705 - I've been posting a bunch of stuff on that leaflet and people get mad. Every time I post something 704 + 00:07:00.100 --> 00:07:03.220 705 + in one of the divisions of the company. 706 706 707 707 177 708 - 00:13:02.000 --> 00:13:06.000 709 - there's at least someone who is angry and like, you know, you're wrong 708 + 00:07:03.220 --> 00:07:05.380 709 + And I was asked to do a new job. 710 710 711 711 178 712 - 00:13:06.000 --> 00:13:10.000 713 - idiot, you are influenced by marketing, that was yesterday's post actually. 712 + 00:07:05.380 --> 00:07:07.980 713 + The new job was pretty surprising giving my career path. 714 714 715 715 179 716 - 00:13:10.000 --> 00:13:14.000 717 - But the craft doesn't disappear, it just moves. So, you know, 716 + 00:07:07.980 --> 00:07:11.420 717 + It was to be the lone developer 718 718 719 719 180 720 - 00:13:14.000 --> 00:13:18.000 721 - from like doing test driven development you need to be thinking about how you evaluate the code 720 + 00:07:11.420 --> 00:07:13.780 721 + that took over another system 722 722 723 723 181 724 - 00:13:18.000 --> 00:13:22.000 725 - from a business perspective and from a architectural perspective 724 + 00:07:13.780 --> 00:07:16.020 725 + from a guy who was trolling the company. 726 726 727 727 182 728 - 00:13:22.000 --> 00:13:26.000 729 - in terms of what the technical requirements are of the code. 728 + 00:07:16.020 --> 00:07:19.740 729 + So this guy had written this really complex system in C 730 730 731 731 183 732 - 00:13:26.000 --> 00:13:30.000 733 - You'll be thinking about things like what are the boundaries and what is the 732 + 00:07:19.740 --> 00:07:23.020 733 + that was talking to the MobyTek's radio frequency network. 734 734 735 735 184 736 - 00:13:30.000 --> 00:13:34.000 737 - actual architecture that can work in a system that's constantly replacing itself? 736 + 00:07:23.020 --> 00:07:25.020 737 + It was managing laptops in the field 738 738 739 739 185 740 - 00:13:34.000 --> 00:13:38.000 741 - How can that possibly work? And so I'm going to dig into that kind of stuff. 740 + 00:07:25.020 --> 00:07:26.300 741 + for service technicians. 742 742 743 743 186 744 - 00:13:39.000 --> 00:13:43.000 745 - One note here though, is there is still very much a craft 744 + 00:07:26.300 --> 00:07:29.740 745 + It was basically like a bespoke message queuing system. 746 746 747 747 187 748 - 00:13:43.000 --> 00:13:47.000 749 - or an engineering discipline or whatever sort of metaphor you want to use. Art. 748 + 00:07:29.740 --> 00:07:31.460 749 + Like you'd do RabbitMQ today. 750 750 751 751 188 752 - 00:13:47.000 --> 00:13:51.000 753 - You know, I'm a musician so maybe there's a craft or there's an art to it. 752 + 00:07:31.460 --> 00:07:33.500 753 + He had built his own thing then. 754 754 755 755 189 756 - 00:13:51.000 --> 00:13:55.000 757 - And what I'm seeing now and the fear that a lot of people have in the software 756 + 00:07:33.500 --> 00:07:35.580 757 + No one knew how this thing worked. 758 758 759 759 190 760 - 00:13:55.000 --> 00:13:59.000 761 - industry is that the senior people, 760 + 00:07:35.580 --> 00:07:36.420 761 + Why? 762 762 763 763 191 764 - 00:13:59.000 --> 00:14:03.000 765 - and senior doesn't have to mean old or even experienced, but somehow the people who have 764 + 00:07:36.420 --> 00:07:39.620 765 + Because the only real artifact of the system was the code. 766 766 767 767 192 768 - 00:14:03.000 --> 00:14:08.000 769 - gained wisdom in this field somehow, they are 768 + 00:07:39.620 --> 00:07:41.660 769 + It was a bunch of conversations that had happened 770 770 771 771 193 772 - 00:14:08.000 --> 00:14:12.000 773 - moving farther and farther away from the newbies. 772 + 00:07:41.660 --> 00:07:44.940 773 + in ugly conference rooms in this company over the years. 774 774 775 775 194 776 - 00:14:12.000 --> 00:14:17.000 777 - Because everything moves so quickly and the mistakes you make 776 + 00:07:44.940 --> 00:07:46.620 777 + It was all in production. 778 778 779 779 195 780 - 00:14:17.000 --> 00:14:21.000 781 - have such great and instant ramifications and the good choices you make 780 + 00:07:46.620 --> 00:07:50.420 781 + This guy was the only person who knew how any of it worked. 782 782 783 783 196 784 - 00:14:21.000 --> 00:14:26.000 785 - have such major ramifications that this AI thing 784 + 00:07:50.420 --> 00:07:52.100 785 + Really knew how it worked. 786 786 787 787 197 788 - 00:14:26.000 --> 00:14:30.000 789 - amplifies the effect of this experience. 788 + 00:07:52.100 --> 00:07:55.580 789 + But he was basically holding us hostage as a company. 790 790 791 791 198 792 - 00:14:31.000 --> 00:14:34.000 793 - So Phoenix Architecture, what is it? 792 + 00:07:55.580 --> 00:07:57.940 793 + So I went from move toward CIO 794 794 795 795 199 796 - 00:14:34.000 --> 00:14:38.000 797 - It's a name that I let the AI choose, honestly. 796 + 00:07:57.940 --> 00:08:02.740 797 + to go sit up all night in an office in the dark, 798 798 799 799 200 800 - 00:14:38.000 --> 00:14:42.000 801 - This is a thing I do because naming is one of the hardest things, right? 800 + 00:08:02.740 --> 00:08:05.100 801 + like doing S trace on server processes 802 802 803 803 201 804 - 00:14:42.000 --> 00:14:45.000 805 - So that's why we have LLMs. You never have to name anything again. 804 + 00:08:05.100 --> 00:08:07.740 805 + trying to figure out what this thing does. 806 806 807 807 202 808 - 00:14:45.000 --> 00:14:50.000 809 - Just make sure it's not offensive in any language if you can, but you can ask the LLM that too. 808 + 00:08:07.740 --> 00:08:09.340 809 + So this can happen today 810 810 811 811 203 812 - 00:14:50.000 --> 00:14:55.000 813 - It's an architectural idea, a bunch of architectural principles. 812 + 00:08:09.380 --> 00:08:10.980 813 + and it could happen 20 years ago. 814 814 815 815 204 816 - 00:14:55.000 --> 00:15:00.000 817 - As I said, they are extracted from my decades of thinking about this problem 816 + 00:08:10.980 --> 00:08:13.380 817 + You can be held hostage by your code base. 818 818 819 819 205 820 - 00:15:00.000 --> 00:15:04.000 821 - and trying to figure out how we can create systems that can survive. 820 + 00:08:14.820 --> 00:08:16.820 821 + So I learned something very early around that time 822 822 823 823 206 824 - 00:15:04.000 --> 00:15:09.000 825 - So if you Google for me, if anyone uses Google anymore, and put the word legacy, 824 + 00:08:16.820 --> 00:08:19.100 825 + in my career from a guy named Kent Beck 826 826 827 827 207 828 - 00:15:09.000 --> 00:15:14.000 829 - you will find me talking about this back in 2009 and some of the things I'm going to say are the same today. 828 + 00:08:19.100 --> 00:08:21.060 829 + who is the creator of Extreme Programming 830 830 831 831 208 832 - 00:15:14.000 --> 00:15:20.000 833 - Because I realized that making systems that can survive, the principles have been the same for a long time. 832 + 00:08:21.060 --> 00:08:22.300 833 + and a bunch of other stuff. 834 834 835 835 209 836 - 00:15:20.000 --> 00:15:24.000 837 - It's also a reference implementation of this architecture. 836 + 00:08:22.300 --> 00:08:24.220 837 + And if you're my age in software development, 838 838 839 839 210 840 - 00:15:24.000 --> 00:15:28.000 841 - I'm going to show you two things very briefly on the reference implementation, 840 + 00:08:24.220 --> 00:08:27.740 841 + he's probably one of your software development heroes. 842 842 843 843 211 844 - 00:15:28.000 --> 00:15:32.000 845 - and you can find it on Tangled or you can find it on the copy on GitHub. 844 + 00:08:27.740 --> 00:08:29.660 845 + If something hurts, do it more frequently. 846 846 847 847 212 848 - 00:15:32.000 --> 00:15:35.000 849 - Obviously, you're all going to use Tangled, right? 848 + 00:08:29.660 --> 00:08:31.100 849 + So with Extreme Programming, 850 850 851 851 213 852 - 00:15:35.000 --> 00:15:42.000 853 - So I'm starting to think about software, not as a thing where you go into an editor. 852 + 00:08:31.100 --> 00:08:32.740 853 + which was the precursor to Agile, 854 854 855 855 214 856 - 00:15:42.000 --> 00:15:46.000 857 - That's always been like a short version of what the AI thing would be, 856 + 00:08:32.740 --> 00:08:33.740 857 + which ruined everything, 858 858 859 859 215 860 - 00:15:46.000 --> 00:15:52.000 861 - these copilot things in an IDE that's gone already, but rather a pipeline. 860 + 00:08:33.740 --> 00:08:35.580 861 + and they never should have done the Agile thing, 862 862 863 863 216 864 - 00:15:52.000 --> 00:16:00.000 865 - So we go from specifications to something else, to something else, to something else that ends up generating code. 864 + 00:08:35.580 --> 00:08:38.980 865 + but Extreme Programming was like merging is hard. 866 866 867 867 217 868 - 00:16:00.000 --> 00:16:05.000 869 - And the something else is here. You won't be able to read this, but you can just kind of see columns here. 868 + 00:08:38.980 --> 00:08:40.700 869 + You need to do continuous integration, 870 870 871 871 218 872 - 00:16:05.000 --> 00:16:09.000 873 - Imagine you've got a bunch of markdown specifications. Those are just things where you just type stuff. 872 + 00:08:40.700 --> 00:08:41.660 873 + deployment is hard. 874 874 875 875 219 876 - 00:16:09.000 --> 00:16:16.000 877 - Maybe you're also in a chat program like FREQ. Ask me about FREQ, F-R-E-E-Q. 876 + 00:08:41.660 --> 00:08:42.820 877 + We learned all these things. 878 878 879 879 220 880 - 00:16:16.000 --> 00:16:22.000 881 - From that will be extracted clauses. So you can use LLMs for this. 880 + 00:08:42.820 --> 00:08:43.660 881 + Testing is hard. 882 882 883 883 221 884 - 00:16:22.000 --> 00:16:26.000 885 - It's not quite perfect, but my reference implementation does some hacks. 884 + 00:08:43.660 --> 00:08:44.500 885 + You should do it upfront 886 886 887 887 222 888 - 00:16:26.000 --> 00:16:30.000 889 - You extract clauses which are like different ways of saying the same thing. 888 + 00:08:44.500 --> 00:08:46.540 889 + so no code is written without a test. 890 890 891 891 223 892 - 00:16:30.000 --> 00:16:33.000 893 - You can kind of deduplicate them into those text chunks. 892 + 00:08:46.540 --> 00:08:47.580 893 + Code review is hard. 894 894 895 895 224 896 - 00:16:33.000 --> 00:16:38.000 897 - From that, you can canonicalize and deduplicate actual requirements. 896 + 00:08:47.580 --> 00:08:50.020 897 + Just do pair programming, constant, right? 898 898 899 899 225 900 - 00:16:38.000 --> 00:16:42.000 901 - From that, you can expand them into various things that you want to evaluate. 900 + 00:08:50.020 --> 00:08:52.340 901 + So if updating code is hard 902 902 903 903 226 904 - 00:16:42.000 --> 00:16:45.000 905 - They could be invariants. They could be various other constraints. 904 + 00:08:52.340 --> 00:08:54.420 905 + and making changes to code is hard, 906 906 907 907 227 908 - 00:16:45.000 --> 00:16:53.000 909 - They might even be things like this component must be fast, which turns into this component must respond within 50 milliseconds. 908 + 00:08:54.420 --> 00:08:55.820 909 + the Kent Beck version of that would be 910 910 911 911 228 912 - 00:16:53.000 --> 00:16:55.000 913 - So that becomes a constraint. 912 + 00:08:55.820 --> 00:08:59.540 913 + just do it constantly, like all day maybe. 914 914 915 915 229 916 - 00:16:55.000 --> 00:16:59.000 917 - And from there, you go into the implementation, which I'm going to talk about in a second. 916 + 00:08:59.540 --> 00:09:01.380 917 + So how do you do that? 918 918 919 919 230 920 - 00:16:59.000 --> 00:17:02.000 921 - It has two phases sort of necessarily. 920 + 00:09:01.380 --> 00:09:04.300 921 + That means that the code itself 922 922 923 923 231 924 - 00:17:02.000 --> 00:17:11.000 925 - The cool thing about this is if you create a system like this where you're actually thinking of that end piece, 924 + 00:09:04.300 --> 00:09:06.140 925 + is not that important, sort of, right? 926 926 927 927 232 928 - 00:17:11.000 --> 00:17:17.000 929 - the code as a compiled artifact, think of it as a binary, like TypeScript or whatever you're generating. 928 + 00:09:06.140 --> 00:09:07.540 929 + If you're gonna be replacing it all the time, 930 930 931 931 233 932 - 00:17:17.000 --> 00:17:19.000 933 - It's like binary code. You wouldn't edit it. 932 + 00:09:07.540 --> 00:09:08.420 933 + if you're gonna be throwing it away 934 934 935 935 234 936 - 00:17:19.000 --> 00:17:26.000 937 - It also means that you can trace the provenance from the markdown file, from a piece of text in the markdown file, 936 + 00:09:08.500 --> 00:09:10.980 937 + and replacing it, how do you do it? 938 938 939 939 235 940 - 00:17:26.000 --> 00:17:31.000 941 - through this graph of requirements all the way through to the generated thing at the end. 940 + 00:09:10.980 --> 00:09:13.140 941 + And then another person who's not as smart as Kent 942 942 943 943 236 944 - 00:17:31.000 --> 00:17:37.000 945 - So just like you were doing a C program or something where you're compiling from C to an object file to blah, blah, blah, 944 + 00:09:13.140 --> 00:09:15.380 945 + once said the mutability of a system 946 946 947 947 237 948 - 00:17:37.000 --> 00:17:40.000 949 - the TypeScript is just in that dependent path. 948 + 00:09:15.380 --> 00:09:17.980 949 + is enhanced by the immutability of its components. 950 950 951 951 238 952 - 00:17:40.000 --> 00:17:43.000 953 - So when you set up a system like this, you can do two things. 952 + 00:09:17.980 --> 00:09:20.780 953 + I said that, but I like to quote myself 954 954 955 955 239 956 - 00:17:43.000 --> 00:17:48.000 957 - One is you can regenerate just the path down to the component at the end that you want to generate. 956 + 00:09:20.780 --> 00:09:22.740 957 + because I think it's a pretty good one. 958 958 959 959 240 960 - 00:17:48.000 --> 00:17:55.000 961 - The other is if someone does do the wrong thing, so I say, and edit the code themselves as a human, 960 + 00:09:22.740 --> 00:09:24.580 961 + Maybe in 20 years or so, someone will say, 962 962 963 963 241 964 - 00:17:55.000 --> 00:17:57.000 965 - you can see where it drifts. 964 + 00:09:24.580 --> 00:09:26.660 965 + if it was me, you heard Chad say this, 966 966 967 967 242 968 - 00:17:57.000 --> 00:18:01.000 969 - And you can see, well, the drift is here and it actually affects this spec. 968 + 00:09:26.660 --> 00:09:28.220 969 + and it was meaningful to you. 970 970 971 971 243 972 - 00:18:01.000 --> 00:18:07.000 973 - And I could even like automatically analyze the code and see it's changed the spec in a certain way. 972 + 00:09:29.140 --> 00:09:32.220 973 + So the weird thing about this is, 974 974 975 975 244 976 - 00:18:07.000 --> 00:18:09.000 977 - Is that actually the spec now? Is that what you meant? 976 + 00:09:32.220 --> 00:09:35.020 977 + we're in this weird era. 978 978 979 979 245 980 - 00:18:09.000 --> 00:18:12.000 981 - And commit it as the real intent of the code. 980 + 00:09:35.020 --> 00:09:36.900 981 + How many of you are actually software developers, 982 982 983 983 246 984 - 00:18:12.000 --> 00:18:15.000 985 - Because intent is what matters more than anything else now. 984 + 00:09:36.900 --> 00:09:37.740 985 + by the way? 986 986 987 987 247 988 - 00:18:15.000 --> 00:18:18.000 989 - Intent plus architecture. 988 + 00:09:37.940 --> 00:09:39.820 989 + Got enough of you that some of you 990 990 991 991 248 992 - 00:18:18.000 --> 00:18:22.000 993 - Let me put this back in full screen. 992 + 00:09:39.820 --> 00:09:41.980 993 + will feel sad about this, sort of. 994 994 995 995 249 996 - 00:18:22.000 --> 00:18:23.000 997 - Or not. 996 + 00:09:42.980 --> 00:09:44.860 997 + Is the craft going away? 998 998 999 999 250 1000 - 00:18:23.000 --> 00:18:28.000 1001 - This is the fun of creating your own presentation software. 1000 + 00:09:44.860 --> 00:09:46.700 1001 + I've been posting a bunch of stuff on that leaflet 1002 1002 1003 1003 251 1004 - 00:18:28.000 --> 00:18:36.000 1005 - So when I was implementing this, I realized when I got to a certain point, I'm going to generate some code. 1004 + 00:09:46.700 --> 00:09:48.620 1005 + and people get mad every time I post something, 1006 1006 1007 1007 252 1008 - 00:18:36.000 --> 00:18:38.000 1009 - What the hell am I going to generate? 1008 + 00:09:48.620 --> 00:09:50.220 1009 + there's at least someone who is angry 1010 1010 1011 1011 253 1012 - 00:18:38.000 --> 00:18:40.000 1013 - Like is it a React application? 1012 + 00:09:50.220 --> 00:09:53.060 1013 + and like, you're a wrong idiot, 1014 1014 1015 1015 254 1016 - 00:18:40.000 --> 00:18:42.000 1017 - Is it a Next.js application? 1016 + 00:09:53.060 --> 00:09:54.420 1017 + you are influenced by marketing, 1018 1018 1019 1019 255 1020 - 00:18:42.000 --> 00:18:44.000 1021 - Is it a Rust thing? 1020 + 00:09:54.420 --> 00:09:56.220 1021 + that was yesterday's post, actually. 1022 1022 1023 1023 256 1024 - 00:18:44.000 --> 00:18:46.000 1025 - The answer is I don't know. 1024 + 00:09:57.620 --> 00:10:00.060 1025 + But the craft doesn't disappear, it just moves. 1026 1026 1027 1027 257 1028 - 00:18:46.000 --> 00:18:52.000 1029 - And not only do I not know, I don't want to have to, for a given application, decide those things. 1028 + 00:10:00.060 --> 00:10:02.460 1029 + So from doing test-driven development, 1030 1030 1031 1031 258 1032 - 00:18:52.000 --> 00:19:00.000 1033 - Because I want to be able to move from, let's say, JavaScript to Rust when the Lazarus group takes over NPM. 1032 + 00:10:02.460 --> 00:10:05.100 1033 + you need to be thinking about how you evaluate the code 1034 1034 1035 1035 259 1036 - 00:19:00.000 --> 00:19:04.000 1037 - They're not going to, but if they did, I want that flexibility. 1036 + 00:10:05.100 --> 00:10:06.540 1037 + from a business perspective 1038 1038 1039 1039 260 1040 - 00:19:04.000 --> 00:19:14.000 1041 - And the real life story behind that is at Wonderlist again, we launched Wonderlist 3, which was our huge rewrite that finally made the sync work and everyone was happy with it. 1040 + 00:10:06.540 --> 00:10:08.940 1041 + and from an architectural perspective 1042 1042 1043 1043 261 1044 - 00:19:14.000 --> 00:19:17.000 1045 - We launched it with Ruby on Rails as the back end. 1044 + 00:10:08.940 --> 00:10:11.900 1045 + in terms of what the technical requirements are of the code. 1046 1046 1047 1047 262 1048 - 00:19:17.000 --> 00:19:23.000 1049 - Lovely for humans, not great for compute, very expensive to run. 1048 + 00:10:12.860 --> 00:10:14.860 1049 + You'll be thinking about things like, 1050 1050 1051 1051 263 1052 - 00:19:23.000 --> 00:19:31.000 1053 - But the way we had architected this back in 2013-14 allowed us, for the same reasons that we could fix the heartbleed problem, 1052 + 00:10:14.860 --> 00:10:17.700 1053 + what are the boundaries and what is the actual architecture 1054 1054 1055 1055 264 1056 - 00:19:31.000 --> 00:19:35.000 1057 - allowed us to rewrite each service in another language within three months. 1056 + 00:10:17.700 --> 00:10:19.180 1057 + that can work in a system 1058 1058 1059 1059 265 1060 - 00:19:35.000 --> 00:19:45.000 1061 - And we went from, I'll just say we saved 70% of our compute costs by rewriting services without affecting the system. 1060 + 00:10:19.180 --> 00:10:21.140 1061 + that's constantly replacing itself? 1062 1062 1063 1063 266 1064 - 00:19:45.000 --> 00:19:48.000 1065 - Because we were just replacing the components. 1064 + 00:10:21.140 --> 00:10:22.580 1065 + How can that possibly work? 1066 1066 1067 1067 267 1068 - 00:19:48.000 --> 00:19:55.000 1069 - So in a system like this, if we're building this for agents, if we're building this for a constantly regenerating world, 1068 + 00:10:22.580 --> 00:10:24.740 1069 + And so I'm gonna dig into that kind of stuff. 1070 1070 1071 1071 268 1072 - 00:19:55.000 --> 00:20:11.000 1073 - we need to compile not to an implementation, but we need to compile to an architecture that has these properties of components with boundaries that are just like that Haskell thing I was talking about earlier that can be replaced at will because the boundaries are clear enough. 1072 + 00:10:26.340 --> 00:10:30.420 1073 + One note here though, is there is still very much a craft 1074 1074 1075 1075 269 1076 - 00:20:11.000 --> 00:20:20.000 1077 - So the idea is you have some intent. Maybe it comes from a conversation. Usually they come from conversation. Maybe documents, lots of conversations. 1076 + 00:10:30.420 --> 00:10:31.900 1077 + or an engineering discipline 1078 1078 1079 1079 270 1080 - 00:20:20.000 --> 00:20:26.000 1081 - The intent is then compiled into some decisions, not into code necessarily. 1080 + 00:10:31.900 --> 00:10:34.340 1081 + or whatever sort of metaphor you wanna use, art. 1082 1082 1083 1083 271 1084 - 00:20:26.000 --> 00:20:39.000 1085 - The decisions then generate code. And then they go through an evaluation loop where you see, well, is this code actually doing the thing that it's required to do based on the specs, including all those invariants and constraints and stuff I was talking about earlier. 1084 + 00:10:34.340 --> 00:10:36.500 1085 + I'm a musician, so maybe there's a craft 1086 1086 1087 1087 272 1088 - 00:20:39.000 --> 00:20:43.000 1089 - That could even be stuff that's coming from observability systems. 1088 + 00:10:37.340 --> 00:10:38.740 1089 + or there's an art to it. 1090 1090 1091 1091 273 1092 - 00:20:43.000 --> 00:20:51.000 1093 - So I think software development in the near future is a closed loop from production where you're actually pulling in what's happening in production. 1092 + 00:10:38.740 --> 00:10:40.580 1093 + And what I'm seeing now in the fear 1094 1094 1095 1095 274 1096 - 00:20:51.000 --> 00:20:56.000 1097 - It's informing and saying, well, this thing has now drifted from the requirements. 1096 + 00:10:40.580 --> 00:10:42.620 1097 + that a lot of people have in the software industry 1098 1098 1099 1099 275 1100 - 00:20:56.000 --> 00:21:03.000 1101 - I think we should regenerate these two components because they're not doing the thing that the business says they need to do. 1100 + 00:10:42.620 --> 00:10:46.220 1101 + is that the senior people, 1102 1102 1103 1103 276 1104 - 00:21:03.000 --> 00:21:17.000 1105 - So then you record the provenance, which means the chain of the human and human's agents and all of the different specs and everything else that led to the generation capture it forever cryptographically. 1104 + 00:10:46.220 --> 00:10:48.620 1105 + and senior doesn't have to mean old or even experienced, 1106 1106 1107 1107 277 1108 - 00:21:17.000 --> 00:21:25.000 1109 - Then you deploy it within the boundaries. Same way I talked about with Wonderless. So you're deploying these nice, tight, controlled components. 1108 + 00:10:48.620 --> 00:10:50.660 1109 + but somehow the people who have gained wisdom 1110 1110 1111 1111 278 1112 - 00:21:25.000 --> 00:21:36.000 1113 - And then I won't talk about this now, but if you read the blog, you will compact because we are creating tons and tons of garbage, those of us who are making stuff with LLMs now. 1112 + 00:10:50.660 --> 00:10:52.300 1113 + in this field somehow, 1114 1114 1115 1115 279 1116 - 00:21:36.000 --> 00:21:46.000 1117 - I accidentally created two web interfaces for my IRC network, and it took me a while to delete them because I couldn't remember which one was the right one. So there you go. 1116 + 00:10:53.460 --> 00:10:58.460 1117 + they are moving farther and farther away from the newbies 1118 1118 1119 1119 280 1120 - 00:21:47.000 --> 00:22:02.000 1121 - So I should mention what is an evaluation because this is an overloaded term now. I kind of got into it. It's all of these different things, the requirements that could be just like it must act like this, what we're used to with specs and user stories. 1120 + 00:10:59.780 --> 00:11:02.340 1121 + because everything moves so quickly 1122 1122 1123 1123 281 1124 - 00:22:02.000 --> 00:22:09.000 1125 - But it's also it shouldn't use this much memory or it has to be this fast or it has to be deployable on this thing or whatever. 1124 + 00:11:02.340 --> 00:11:05.260 1125 + and the mistakes you make have such great 1126 1126 1127 1127 282 1128 - 00:22:09.000 --> 00:22:20.000 1129 - So evaluations are the thing that are about the system and not about the code. It's not unit tests because unit tests are tied to actual implementation. So that's not the thing that you want to rely on. 1128 + 00:11:05.260 --> 00:11:06.860 1129 + and instant ramifications. 1130 1130 1131 1131 283 1132 - 00:22:20.000 --> 00:22:30.000 1133 - That's also a thing that they can generate better than we can and we should let them. So it might be has to have 100% test coverage and they always have to pass. That sort of stuff. That could be one. 1132 + 00:11:06.860 --> 00:11:11.300 1133 + And the good choices you make have such major ramifications 1134 + 1135 + 284 1136 + 00:11:11.300 --> 00:11:15.780 1137 + that this AI thing amplifies the effect of this experience. 1138 + 1139 + 285 1140 + 00:11:17.540 --> 00:11:20.980 1141 + So Phoenix architecture, what is it? 1142 + 1143 + 286 1144 + 00:11:20.980 --> 00:11:25.220 1145 + It's a name that I let the AI choose, honestly. 1146 + 1147 + 287 1148 + 00:11:25.220 --> 00:11:26.100 1149 + This is a thing I do 1150 + 1151 + 288 1152 + 00:11:26.100 --> 00:11:28.620 1153 + because naming is one of the hardest things, right? 1154 + 1155 + 289 1156 + 00:11:28.620 --> 00:11:30.260 1157 + So that's why we have LLMs. 1158 + 1159 + 290 1160 + 00:11:30.260 --> 00:11:31.820 1161 + You don't ever have to name anything again. 1162 + 1163 + 291 1164 + 00:11:31.820 --> 00:11:34.740 1165 + Just make sure it's not offensive in any language if you can, 1166 + 1167 + 292 1168 + 00:11:34.740 --> 00:11:36.460 1169 + but you can ask the LLM that too. 1170 + 1171 + 293 1172 + 00:11:37.420 --> 00:11:38.940 1173 + It's an architectural idea, 1174 + 1175 + 294 1176 + 00:11:38.940 --> 00:11:40.900 1177 + a bunch of architectural principles. 1178 + 1179 + 295 1180 + 00:11:41.820 --> 00:11:45.300 1181 + As I said, they are extracted from my decades 1182 + 1183 + 296 1184 + 00:11:45.300 --> 00:11:46.700 1185 + of thinking about this problem 1186 + 1187 + 297 1188 + 00:11:46.700 --> 00:11:49.260 1189 + and trying to figure out how we can create systems 1190 + 1191 + 298 1192 + 00:11:49.260 --> 00:11:50.380 1193 + that can survive. 1194 + 1195 + 299 1196 + 00:11:50.380 --> 00:11:53.980 1197 + So if you Google for me, if anyone uses Google anymore 1198 + 1199 + 300 1200 + 00:11:53.980 --> 00:11:55.820 1201 + and put the word legacy, 1202 + 1203 + 301 1204 + 00:11:55.820 --> 00:11:58.220 1205 + you will find me talking about this back in 2009. 1206 + 1207 + 302 1208 + 00:11:58.220 --> 00:12:00.540 1209 + And some of the things I'm gonna say are the same today 1210 + 1211 + 303 1212 + 00:12:00.540 --> 00:12:03.540 1213 + because I realized that making systems that can survive, 1214 + 1215 + 304 1216 + 00:12:03.540 --> 00:12:06.020 1217 + the principles have been the same for a long time. 1218 + 1219 + 305 1220 + 00:12:06.900 --> 00:12:10.580 1221 + It's also a reference implementation of this architecture. 1222 + 1223 + 306 1224 + 00:12:10.580 --> 00:12:13.340 1225 + And I'm gonna show you two things very briefly 1226 + 1227 + 307 1228 + 00:12:13.340 --> 00:12:15.100 1229 + on the reference implementation 1230 + 1231 + 308 1232 + 00:12:15.100 --> 00:12:16.380 1233 + and you can find it on Tangled 1234 + 1235 + 309 1236 + 00:12:16.380 --> 00:12:18.940 1237 + or you can find it on the copy on GitHub. 1238 + 1239 + 310 1240 + 00:12:18.940 --> 00:12:21.180 1241 + Obviously you're all gonna use Tangled, right? 1242 + 1243 + 311 1244 + 00:12:22.460 --> 00:12:26.260 1245 + So I'm starting to think about software, 1246 + 1247 + 312 1248 + 00:12:26.260 --> 00:12:29.300 1249 + not as a thing where you go into an editor. 1250 + 1251 + 313 1252 + 00:12:29.300 --> 00:12:31.660 1253 + That's always been like a short version 1254 + 1255 + 314 1256 + 00:12:31.660 --> 00:12:32.900 1257 + of what the AI thing would be, 1258 + 1259 + 315 1260 + 00:12:32.900 --> 00:12:36.500 1261 + these copilot things in an IDE that's gone already, 1262 + 1263 + 316 1264 + 00:12:36.500 --> 00:12:38.660 1265 + but rather a pipeline. 1266 + 1267 + 317 1268 + 00:12:38.660 --> 00:12:43.100 1269 + So we go from specifications to something else, 1270 + 1271 + 318 1272 + 00:12:43.100 --> 00:12:44.420 1273 + to something else, to something else 1274 + 1275 + 319 1276 + 00:12:44.420 --> 00:12:46.140 1277 + that ends up generating code. 1278 + 1279 + 320 1280 + 00:12:46.140 --> 00:12:48.580 1281 + And the something else is here. 1282 + 1283 + 321 1284 + 00:12:48.580 --> 00:12:49.620 1285 + You won't be able to read this, 1286 + 1287 + 322 1288 + 00:12:49.620 --> 00:12:51.620 1289 + but you can just kind of see columns here. 1290 + 1291 + 323 1292 + 00:12:51.620 --> 00:12:54.020 1293 + Imagine you've got a bunch of markdown specifications. 1294 + 1295 + 324 1296 + 00:12:54.020 --> 00:12:56.100 1297 + Those are just things where you just type stuff. 1298 + 1299 + 325 1300 + 00:12:56.100 --> 00:12:59.340 1301 + Maybe you're also in a chat program like a freak, 1302 + 1303 + 326 1304 + 00:12:59.340 --> 00:13:01.540 1305 + ask me about freak, F-R-E-E-Q. 1306 + 1307 + 327 1308 + 00:13:02.980 --> 00:13:06.580 1309 + From that will be extracted clauses. 1310 + 1311 + 328 1312 + 00:13:06.580 --> 00:13:08.540 1313 + So you can use LLMs for this. 1314 + 1315 + 329 1316 + 00:13:08.540 --> 00:13:10.140 1317 + It's not quite perfect, 1318 + 1319 + 330 1320 + 00:13:10.140 --> 00:13:13.100 1321 + but my reference implementation does some hacks. 1322 + 1323 + 331 1324 + 00:13:13.100 --> 00:13:15.540 1325 + You extract clauses which are like different ways 1326 + 1327 + 332 1328 + 00:13:15.540 --> 00:13:16.500 1329 + of saying the same thing. 1330 + 1331 + 333 1332 + 00:13:16.500 --> 00:13:19.540 1333 + You can kind of deduplicate them into those text chunks. 1334 + 1335 + 334 1336 + 00:13:19.540 --> 00:13:21.700 1337 + From that, you can canonicalize 1338 + 1339 + 335 1340 + 00:13:21.700 --> 00:13:24.780 1341 + and deduplicate actual requirements. 1342 + 1343 + 336 1344 + 00:13:24.780 --> 00:13:27.780 1345 + From that, you can expand them into various things 1346 + 1347 + 337 1348 + 00:13:27.780 --> 00:13:28.820 1349 + that you want to evaluate. 1350 + 1351 + 338 1352 + 00:13:28.820 --> 00:13:29.860 1353 + They could be invariants. 1354 + 1355 + 339 1356 + 00:13:29.860 --> 00:13:32.000 1357 + They could be various other constraints. 1358 + 1359 + 340 1360 + 00:13:32.000 --> 00:13:33.640 1361 + They might even be things like, 1362 + 1363 + 341 1364 + 00:13:33.640 --> 00:13:36.040 1365 + this component must be fast, 1366 + 1367 + 342 1368 + 00:13:36.040 --> 00:13:37.480 1369 + which turns into this component 1370 + 1371 + 343 1372 + 00:13:37.480 --> 00:13:39.520 1373 + must respond within 50 milliseconds. 1374 + 1375 + 344 1376 + 00:13:39.520 --> 00:13:41.360 1377 + So that becomes a constraint. 1378 + 1379 + 345 1380 + 00:13:41.360 --> 00:13:43.880 1381 + And from there, you go into the implementation, 1382 + 1383 + 346 1384 + 00:13:43.880 --> 00:13:45.400 1385 + which I'm gonna talk about in a second, 1386 + 1387 + 347 1388 + 00:13:45.400 --> 00:13:48.840 1389 + has two phases sort of necessarily. 1390 + 1391 + 348 1392 + 00:13:48.840 --> 00:13:51.380 1393 + The cool thing about this is, 1394 + 1395 + 349 1396 + 00:13:54.200 --> 00:13:55.600 1397 + if you create a system like this, 1398 + 1399 + 350 1400 + 00:13:55.600 --> 00:13:57.600 1401 + where you're actually thinking of that end piece, 1402 + 1403 + 351 1404 + 00:13:57.600 --> 00:14:00.000 1405 + the code as a compiled artifact, 1406 + 1407 + 352 1408 + 00:14:00.000 --> 00:14:02.000 1409 + think of it as a binary, like TypeScript 1410 + 1411 + 353 1412 + 00:14:02.000 --> 00:14:03.280 1413 + or whatever you're generating. 1414 + 1415 + 354 1416 + 00:14:03.280 --> 00:14:05.740 1417 + It's like binary code, you wouldn't edit it. 1418 + 1419 + 355 1420 + 00:14:05.740 --> 00:14:09.100 1421 + It also means that you can trace the provenance 1422 + 1423 + 356 1424 + 00:14:09.100 --> 00:14:10.480 1425 + from the markdown file, 1426 + 1427 + 357 1428 + 00:14:10.480 --> 00:14:12.560 1429 + from a piece of text in the markdown file, 1430 + 1431 + 358 1432 + 00:14:12.560 --> 00:14:14.460 1433 + through this graph of requirements, 1434 + 1435 + 359 1436 + 00:14:14.460 --> 00:14:17.320 1437 + all the way through to the generated thing at the end. 1438 + 1439 + 360 1440 + 00:14:17.320 --> 00:14:19.640 1441 + So just like you were doing a C program or something, 1442 + 1443 + 361 1444 + 00:14:19.640 --> 00:14:21.800 1445 + where you're compiling from C to an object file 1446 + 1447 + 362 1448 + 00:14:21.800 --> 00:14:23.540 1449 + to blah, blah, blah, 1450 + 1451 + 363 1452 + 00:14:23.540 --> 00:14:26.120 1453 + the TypeScript is just in that dependent path. 1454 + 1455 + 364 1456 + 00:14:26.120 --> 00:14:28.560 1457 + And so when you set up a system like this, 1458 + 1459 + 365 1460 + 00:14:28.560 --> 00:14:29.600 1461 + you can do two things. 1462 + 1463 + 366 1464 + 00:14:29.600 --> 00:14:32.220 1465 + One is you can regenerate just the path 1466 + 1467 + 367 1468 + 00:14:32.220 --> 00:14:35.220 1469 + down to the component at the end that you wanna generate. 1470 + 1471 + 368 1472 + 00:14:35.220 --> 00:14:38.340 1473 + The other is, if someone does do the wrong thing, 1474 + 1475 + 369 1476 + 00:14:38.340 --> 00:14:42.120 1477 + so I say, and edit the code themselves as a human, 1478 + 1479 + 370 1480 + 00:14:42.120 --> 00:14:43.540 1481 + you can see where it drifts. 1482 + 1483 + 371 1484 + 00:14:43.540 --> 00:14:45.680 1485 + And you can see, well, the drift is here 1486 + 1487 + 372 1488 + 00:14:45.680 --> 00:14:47.400 1489 + and it actually affects this spec. 1490 + 1491 + 373 1492 + 00:14:47.400 --> 00:14:51.360 1493 + And I could even like automatically analyze the code 1494 + 1495 + 374 1496 + 00:14:51.360 --> 00:14:54.080 1497 + and see it's changed the spec in a certain way. 1498 + 1499 + 375 1500 + 00:14:54.080 --> 00:14:55.360 1501 + Is that actually the spec now? 1502 + 1503 + 376 1504 + 00:14:55.360 --> 00:14:56.200 1505 + Is that what you meant? 1506 + 1507 + 377 1508 + 00:14:56.200 --> 00:14:58.920 1509 + And commit it as the real intent of the code. 1510 + 1511 + 378 1512 + 00:14:58.920 --> 00:15:01.560 1513 + Because intent is what matters more than anything else. 1514 + 1515 + 379 1516 + 00:15:01.560 --> 00:15:03.500 1517 + Now, intent plus architecture. 1518 + 1519 + 380 1520 + 00:15:05.680 --> 00:15:07.480 1521 + Let me put this back in full screen. 1522 + 1523 + 381 1524 + 00:15:09.240 --> 00:15:10.440 1525 + Or not. 1526 + 1527 + 382 1528 + 00:15:10.440 --> 00:15:13.680 1529 + This is the fun of creating your own presentation software. 1530 + 1531 + 383 1532 + 00:15:15.180 --> 00:15:18.700 1533 + So when I was implementing this, 1534 + 1535 + 384 1536 + 00:15:18.700 --> 00:15:21.240 1537 + I realized when I got to a certain point, 1538 + 1539 + 385 1540 + 00:15:21.240 --> 00:15:22.800 1541 + I'm gonna generate some code. 1542 + 1543 + 386 1544 + 00:15:22.800 --> 00:15:24.720 1545 + What the hell am I gonna generate? 1546 + 1547 + 387 1548 + 00:15:24.720 --> 00:15:27.140 1549 + Like, is it a React application? 1550 + 1551 + 388 1552 + 00:15:27.140 --> 00:15:29.260 1553 + Is it a Next.js application? 1554 + 1555 + 389 1556 + 00:15:29.260 --> 00:15:30.960 1557 + Is it a Rust thing? 1558 + 1559 + 390 1560 + 00:15:30.960 --> 00:15:32.900 1561 + The answer is, I don't know. 1562 + 1563 + 391 1564 + 00:15:32.900 --> 00:15:35.220 1565 + And not only do I not know, 1566 + 1567 + 392 1568 + 00:15:35.220 --> 00:15:37.500 1569 + I don't wanna have to, for a given application, 1570 + 1571 + 393 1572 + 00:15:37.500 --> 00:15:38.900 1573 + decide those things. 1574 + 1575 + 394 1576 + 00:15:38.900 --> 00:15:41.340 1577 + Because I want to be able to move from, 1578 + 1579 + 395 1580 + 00:15:41.340 --> 00:15:44.260 1581 + let's say JavaScript to Rust, 1582 + 1583 + 396 1584 + 00:15:44.260 --> 00:15:47.180 1585 + when the Lazarus group takes over NPM. 1586 + 1587 + 397 1588 + 00:15:47.180 --> 00:15:48.940 1589 + They're not going to, but if they did, 1590 + 1591 + 398 1592 + 00:15:48.940 --> 00:15:50.420 1593 + I want that flexibility. 1594 + 1595 + 399 1596 + 00:15:50.420 --> 00:15:52.580 1597 + And the real life story behind that is, 1598 + 1599 + 400 1600 + 00:15:52.580 --> 00:15:55.340 1601 + at Wonderlist again, we launched Wonderlist 3, 1602 + 1603 + 401 1604 + 00:15:55.340 --> 00:15:58.120 1605 + which was our huge rewrite that finally made the sync work 1606 + 1607 + 402 1608 + 00:15:58.120 --> 00:16:00.380 1609 + and everyone was happy with it. 1610 + 1611 + 403 1612 + 00:16:00.380 --> 00:16:04.180 1613 + We launched it with Ruby on Rails as the backend. 1614 + 1615 + 404 1616 + 00:16:04.180 --> 00:16:07.320 1617 + Lovely for humans, not great for compute, 1618 + 1619 + 405 1620 + 00:16:07.320 --> 00:16:09.540 1621 + very expensive to run. 1622 + 1623 + 406 1624 + 00:16:09.540 --> 00:16:13.620 1625 + But the way we had architected this back in 2013, 14, 1626 + 1627 + 407 1628 + 00:16:13.620 --> 00:16:15.500 1629 + allowed us, for the same reasons 1630 + 1631 + 408 1632 + 00:16:15.500 --> 00:16:17.380 1633 + that we could fix the heartbleed problem, 1634 + 1635 + 409 1636 + 00:16:17.380 --> 00:16:19.380 1637 + allowed us to rewrite each service 1638 + 1639 + 410 1640 + 00:16:19.380 --> 00:16:21.620 1641 + in another language within three months. 1642 + 1643 + 411 1644 + 00:16:21.780 --> 00:16:27.020 1645 + And we went from, I'll just say we saved 70% 1646 + 1647 + 412 1648 + 00:16:27.020 --> 00:16:29.980 1649 + of our compute costs by rewriting services 1650 + 1651 + 413 1652 + 00:16:29.980 --> 00:16:32.060 1653 + without affecting the system. 1654 + 1655 + 414 1656 + 00:16:32.060 --> 00:16:34.580 1657 + Because we were just replacing the components. 1658 + 1659 + 415 1660 + 00:16:34.580 --> 00:16:37.740 1661 + So in a system like this, if we're building this for agents, 1662 + 1663 + 416 1664 + 00:16:37.740 --> 00:16:41.660 1665 + if we're building this for a constantly regenerating world, 1666 + 1667 + 417 1668 + 00:16:41.660 --> 00:16:44.380 1669 + we need to compile not to an implementation, 1670 + 1671 + 418 1672 + 00:16:44.380 --> 00:16:46.300 1673 + but we need to compile to an architecture 1674 + 1675 + 419 1676 + 00:16:46.300 --> 00:16:49.660 1677 + that has these properties of components with boundaries 1678 + 1679 + 420 1680 + 00:16:49.700 --> 00:16:51.220 1681 + that are just like that Haskell thing 1682 + 1683 + 421 1684 + 00:16:51.220 --> 00:16:54.700 1685 + I was talking about earlier, that can be replaced at will 1686 + 1687 + 422 1688 + 00:16:54.700 --> 00:16:56.700 1689 + because the boundaries are clear enough. 1690 + 1691 + 423 1692 + 00:16:58.140 --> 00:17:00.900 1693 + So the idea is you have some intent. 1694 + 1695 + 424 1696 + 00:17:00.900 --> 00:17:02.580 1697 + Maybe it comes from a conversation. 1698 + 1699 + 425 1700 + 00:17:02.580 --> 00:17:04.180 1701 + Usually they come from a conversation. 1702 + 1703 + 426 1704 + 00:17:04.180 --> 00:17:06.820 1705 + Maybe documents, lots of conversations. 1706 + 1707 + 427 1708 + 00:17:06.820 --> 00:17:10.660 1709 + The intent is then compiled into some decisions, 1710 + 1711 + 428 1712 + 00:17:10.660 --> 00:17:12.860 1713 + not into code necessarily. 1714 + 1715 + 429 1716 + 00:17:12.860 --> 00:17:15.020 1717 + The decisions then generate code. 1718 + 1719 + 430 1720 + 00:17:15.020 --> 00:17:17.220 1721 + And then they go through an evaluation loop 1722 + 1723 + 431 1724 + 00:17:17.220 --> 00:17:19.420 1725 + where you see, well, is this code actually doing the thing 1726 + 1727 + 432 1728 + 00:17:19.740 --> 00:17:21.700 1729 + that it's required to do based on the specs, 1730 + 1731 + 433 1732 + 00:17:21.700 --> 00:17:23.900 1733 + including all those invariants and constraints 1734 + 1735 + 434 1736 + 00:17:23.900 --> 00:17:25.780 1737 + and stuff I was talking about earlier. 1738 + 1739 + 435 1740 + 00:17:25.780 --> 00:17:27.340 1741 + That could even be stuff that's coming 1742 + 1743 + 436 1744 + 00:17:27.340 --> 00:17:29.660 1745 + from observability systems. 1746 + 1747 + 437 1748 + 00:17:29.660 --> 00:17:32.740 1749 + So I think software development in the near future 1750 + 1751 + 438 1752 + 00:17:32.740 --> 00:17:35.580 1753 + is a closed loop from production, 1754 + 1755 + 439 1756 + 00:17:35.580 --> 00:17:37.260 1757 + where you're actually pulling in what's happening 1758 + 1759 + 440 1760 + 00:17:37.260 --> 00:17:39.540 1761 + in production, it's informing and saying, 1762 + 1763 + 441 1764 + 00:17:39.540 --> 00:17:43.060 1765 + well, this thing has now drifted from the requirements. 1766 + 1767 + 442 1768 + 00:17:43.060 --> 00:17:45.220 1769 + I think we should regenerate these two components 1770 + 1771 + 443 1772 + 00:17:45.220 --> 00:17:46.460 1773 + because they're not doing the thing 1774 + 1775 + 444 1776 + 00:17:46.460 --> 00:17:48.420 1777 + that the business says they need to do. 1778 + 1779 + 445 1780 + 00:17:49.820 --> 00:17:51.820 1781 + So then you record the provenance, 1782 + 1783 + 446 1784 + 00:17:51.820 --> 00:17:53.620 1785 + which means the chain of the human 1786 + 1787 + 447 1788 + 00:17:53.620 --> 00:17:57.100 1789 + or the human and human's agents 1790 + 1791 + 448 1792 + 00:17:57.100 --> 00:17:58.860 1793 + and all of the different specs 1794 + 1795 + 449 1796 + 00:17:58.860 --> 00:18:01.220 1797 + and everything else that led to the generation 1798 + 1799 + 450 1800 + 00:18:01.220 --> 00:18:03.820 1801 + capture it forever, cryptographically. 1802 + 1803 + 451 1804 + 00:18:03.820 --> 00:18:06.060 1805 + Then you deploy it within the boundaries, 1806 + 1807 + 452 1808 + 00:18:06.060 --> 00:18:07.500 1809 + same way I talked about with Wonderless. 1810 + 1811 + 453 1812 + 00:18:07.500 --> 00:18:09.260 1813 + So you're deploying these nice, 1814 + 1815 + 454 1816 + 00:18:09.260 --> 00:18:12.220 1817 + tight, controlled components. 1818 + 1819 + 455 1820 + 00:18:12.220 --> 00:18:13.900 1821 + And then I won't talk about this now, 1822 + 1823 + 456 1824 + 00:18:13.900 --> 00:18:16.500 1825 + but if you read the blog, you will compact 1826 + 1827 + 457 1828 + 00:18:16.500 --> 00:18:19.860 1829 + because we are creating tons and tons of garbage, 1830 + 1831 + 458 1832 + 00:18:19.860 --> 00:18:22.900 1833 + those of us who are making stuff with LLMs now. 1834 + 1835 + 459 1836 + 00:18:22.900 --> 00:18:25.700 1837 + I accidentally created two web interfaces 1838 + 1839 + 460 1840 + 00:18:25.700 --> 00:18:27.940 1841 + for my IRC network and it took me a while 1842 + 1843 + 461 1844 + 00:18:27.940 --> 00:18:29.380 1845 + to delete them because I couldn't remember 1846 + 1847 + 462 1848 + 00:18:29.380 --> 00:18:30.540 1849 + which one was the right one. 1850 + 1851 + 463 1852 + 00:18:30.540 --> 00:18:31.740 1853 + So there you go. 1854 + 1855 + 464 1856 + 00:18:32.980 --> 00:18:37.060 1857 + So I should mention what is an evaluation 1858 + 1859 + 465 1860 + 00:18:37.060 --> 00:18:38.860 1861 + because this is an overloaded term now. 1862 + 1863 + 466 1864 + 00:18:38.860 --> 00:18:40.380 1865 + I kind of got into it. 1866 + 1867 + 467 1868 + 00:18:40.380 --> 00:18:42.340 1869 + It's all of these different things, 1870 + 1871 + 468 1872 + 00:18:42.340 --> 00:18:44.420 1873 + the requirements that could be just like, 1874 + 1875 + 469 1876 + 00:18:44.420 --> 00:18:46.020 1877 + it must act like this. 1878 + 1879 + 470 1880 + 00:18:46.500 --> 00:18:48.580 1881 + It's not what we're used to with specs and user stories, 1882 + 1883 + 471 1884 + 00:18:48.580 --> 00:18:50.780 1885 + but it's also, it shouldn't use this much memory 1886 + 1887 + 472 1888 + 00:18:50.780 --> 00:18:54.060 1889 + or it has to be this fast or it has to be deployable 1890 + 1891 + 473 1892 + 00:18:54.060 --> 00:18:55.380 1893 + on this thing or whatever. 1894 + 1895 + 474 1896 + 00:18:55.380 --> 00:18:59.620 1897 + So evaluations are the thing that are about the system 1898 + 1899 + 475 1900 + 00:18:59.620 --> 00:19:00.740 1901 + and not about the code. 1902 + 1903 + 476 1904 + 00:19:00.740 --> 00:19:02.940 1905 + It's not unit tests because unit tests 1906 + 1907 + 477 1908 + 00:19:02.940 --> 00:19:04.580 1909 + are tied to actual implementation. 1910 + 1911 + 478 1912 + 00:19:04.580 --> 00:19:06.700 1913 + So that's not the thing that you want to rely on. 1914 + 1915 + 479 1916 + 00:19:06.700 --> 00:19:09.100 1917 + That's also a thing that they can generate 1918 + 1919 + 480 1920 + 00:19:09.100 --> 00:19:11.340 1921 + better than we can and we should let them. 1922 + 1923 + 481 1924 + 00:19:11.340 --> 00:19:14.140 1925 + So it might be, has to have 100% test coverage 1926 + 1927 + 482 1928 + 00:19:14.140 --> 00:19:16.180 1929 + and they always have to pass, that sort of stuff. 1930 + 1931 + 483 1932 + 00:19:16.180 --> 00:19:17.020 1933 + That could be one. 1934 + 1935 + 484 1936 + 00:19:19.300 --> 00:19:21.580 1937 + And then here's the sort of secret. 1938 + 1939 + 485 1940 + 00:19:21.580 --> 00:19:23.540 1941 + In the flow I showed you earlier, 1942 + 1943 + 486 1944 + 00:19:23.540 --> 00:19:27.220 1945 + where you have specs going to canonical requirements, 1946 + 1947 + 487 1948 + 00:19:27.220 --> 00:19:30.580 1949 + et cetera, et cetera, there are two things in the, 1950 + 1951 + 488 1952 + 00:19:30.580 --> 00:19:33.020 1953 + there are two like columns and implementation. 1954 + 1955 + 489 1956 + 00:19:33.020 --> 00:19:36.140 1957 + Before you get to the actual implementation, 1958 + 1959 + 490 1960 + 00:19:36.140 --> 00:19:38.260 1961 + I'm calling this implementation units 1962 + 1963 + 491 1964 + 00:19:38.260 --> 00:19:40.060 1965 + because this is actually the decisions 1966 + 1967 + 492 1968 + 00:19:40.060 --> 00:19:41.900 1969 + about what components should exist 1970 + 1971 + 493 1972 + 00:19:41.900 --> 00:19:44.140 1973 + and what their behaviors and boundaries 1974 + 1975 + 494 1976 + 00:19:44.140 --> 00:19:45.700 1977 + and interfaces need to be. 1978 + 1979 + 495 1980 + 00:19:46.620 --> 00:19:50.460 1981 + This should not be language or runtime dependent. 1982 + 1983 + 496 1984 + 00:19:50.460 --> 00:19:54.100 1985 + This is the promise of a thing that will be implemented 1986 + 1987 + 497 1988 + 00:19:54.100 --> 00:19:57.260 1989 + in some language and deployed in some runtime 1990 + 1991 + 498 1992 + 00:19:57.260 --> 00:20:00.620 1993 + that meets the requirements of the specifications. 1994 + 1995 + 499 1996 + 00:20:00.620 --> 00:20:02.940 1997 + And this is a really powerful thing 1998 + 1999 + 500 2000 + 00:20:02.940 --> 00:20:05.780 2001 + because it means you can do things like say, 2002 + 2003 + 501 2004 + 00:20:05.780 --> 00:20:07.580 2005 + well let's just do a pass this afternoon 2006 + 2007 + 502 2008 + 00:20:07.580 --> 00:20:09.780 2009 + and see if we can make this thing 50% faster. 2010 + 2011 + 503 2012 + 00:20:09.820 --> 00:20:12.420 2013 + Okay, good, Friday, deploy it. 2014 + 2015 + 504 2016 + 00:20:12.420 --> 00:20:13.900 2017 + That's where we wanna get with this stuff. 2018 + 2019 + 505 2020 + 00:20:13.900 --> 00:20:15.580 2021 + So implementation units are sort of like 2022 + 2023 + 506 2024 + 00:20:15.580 --> 00:20:19.220 2025 + the semi abstract version of the thing that you wanna test 2026 + 2027 + 507 2028 + 00:20:19.220 --> 00:20:21.620 2029 + and they're what the actual evaluations tie to. 2030 + 2031 + 508 2032 + 00:20:21.620 --> 00:20:23.340 2033 + And the implementations can have unit tests 2034 + 2035 + 509 2036 + 00:20:23.340 --> 00:20:24.500 2037 + and all the other stuff that you're used to 2038 + 2039 + 510 2040 + 00:20:24.500 --> 00:20:25.580 2041 + in your language. 2042 + 2043 + 511 2044 + 00:20:25.580 --> 00:20:28.340 2045 + But we are actually past a point now of, 2046 + 2047 + 512 2048 + 00:20:28.340 --> 00:20:31.180 2049 + I think, sorry, language advocacy. 2050 + 2051 + 513 2052 + 00:20:31.180 --> 00:20:33.180 2053 + And I say that as someone who like, 2054 + 2055 + 514 2056 + 00:20:33.180 --> 00:20:35.580 2057 + I was like, I started the Ruby nonprofit 2058 + 2059 + 515 2060 + 00:20:35.580 --> 00:20:37.100 2061 + and the Rails comp and Ruby comp 2062 + 2063 + 516 2064 + 00:20:37.100 --> 00:20:38.260 2065 + and wrote the Ruby gems thing 2066 + 2067 + 517 2068 + 00:20:38.260 --> 00:20:40.540 2069 + and spoke at Ruby conferences and wrote books about Ruby 2070 + 2071 + 518 2072 + 00:20:40.540 --> 00:20:43.780 2073 + and I was all Ruby, Ruby, Ruby 20 something years ago. 2074 + 2075 + 519 2076 + 00:20:43.780 --> 00:20:47.100 2077 + And I'm going to Ruby comp to receive an award this year 2078 + 2079 + 520 2080 + 00:20:47.100 --> 00:20:49.540 2081 + and tell them, you probably ought to not use Ruby anymore. 2082 + 2083 + 521 2084 + 00:20:49.540 --> 00:20:50.660 2085 + It's not a good idea. 2086 + 2087 + 522 2088 + 00:20:51.620 --> 00:20:53.460 2089 + Because who's Ruby for? 2090 + 2091 + 523 2092 + 00:20:53.460 --> 00:20:54.500 2093 + People. 2094 + 2095 + 524 2096 + 00:20:54.500 --> 00:20:55.620 2097 + Ruby is for people. 2098 + 2099 + 525 2100 + 00:20:56.780 --> 00:20:58.780 2101 + These programs are for machines. 2102 + 2103 + 526 2104 + 00:20:58.780 --> 00:21:01.100 2105 + And what matters now is that they're fast, correct. 2106 + 2107 + 527 2108 + 00:21:01.100 --> 00:21:02.820 2109 + You can generate them with LLMs 2110 + 2111 + 528 2112 + 00:21:02.820 --> 00:21:04.620 2113 + or whatever the technology is gonna be. 2114 + 2115 + 529 2116 + 00:21:04.620 --> 00:21:05.760 2117 + They're cheap to run. 2118 + 2119 + 530 2120 + 00:21:05.760 --> 00:21:06.740 2121 + That's what matters. 2122 + 2123 + 531 2124 + 00:21:06.740 --> 00:21:08.140 2125 + Doesn't matter what language it is anymore. 2126 + 2127 + 532 2128 + 00:21:08.960 --> 00:21:10.740 2129 + So let go of that except for your hobby time. 2130 + 2131 + 533 2132 + 00:21:10.740 --> 00:21:12.100 2133 + Write it in your hobby time. 2134 + 2135 + 534 2136 + 00:21:12.100 --> 00:21:13.380 2137 + Find fun. 2138 + 2139 + 535 2140 + 00:21:13.380 --> 00:21:15.260 2141 + Otherwise it's irresponsible. 2142 + 2143 + 536 2144 + 00:21:15.260 --> 00:21:18.220 2145 + That was a, yeah, just throwing some bombs at you here. 2146 + 2147 + 537 2148 + 00:21:18.220 --> 00:21:20.140 2149 + All right. 2150 + 2151 + 538 2152 + 00:21:20.140 --> 00:21:22.220 2153 + And so, you know, the code doesn't matter anymore. 2154 + 2155 + 539 2156 + 00:21:22.220 --> 00:21:23.260 2157 + We have to let go of that. 2158 + 2159 + 540 2160 + 00:21:23.260 --> 00:21:24.380 2161 + We have a code fetish. 2162 + 2163 + 541 2164 + 00:21:24.380 --> 00:21:26.460 2165 + I've been saying that for decades, literally, 2166 + 2167 + 542 2168 + 00:21:26.460 --> 00:21:27.900 2169 + to developers at conferences. 2170 + 2171 + 543 2172 + 00:21:27.900 --> 00:21:29.260 2173 + We have a code fetish. 2174 + 2175 + 544 2176 + 00:21:29.260 --> 00:21:30.840 2177 + It's not about the code. 2178 + 2179 + 545 2180 + 00:21:30.840 --> 00:21:33.340 2181 + Now it's about these evaluations, really, 2182 + 2183 + 546 2184 + 00:21:33.340 --> 00:21:35.340 2185 + and the fact that things need to exist. 2186 + 2187 + 547 2188 + 00:21:36.340 --> 00:21:39.260 2189 + So sort of backing up a little bit, 2190 + 2191 + 548 2192 + 00:21:39.260 --> 00:21:41.260 2193 + think about, like, I went through the whole 2194 + 2195 + 549 2196 + 00:21:41.260 --> 00:21:43.780 2197 + microservices movement, if you can call it that, 2198 + 2199 + 550 2200 + 00:21:43.780 --> 00:21:45.260 2201 + craze, hype, whatever. 2202 + 2203 + 551 2204 + 00:21:45.260 --> 00:21:47.140 2205 + And I was definitely one of them. 2206 + 2207 + 552 2208 + 00:21:47.140 --> 00:21:50.540 2209 + And I'm friends with Fred George who created that term 2210 + 2211 + 553 2212 + 00:21:50.540 --> 00:21:52.980 2213 + and probably regrets it now. 2214 + 2215 + 554 2216 + 00:21:52.980 --> 00:21:55.220 2217 + People hate microservices. 2218 + 2219 + 555 2220 + 00:21:55.220 --> 00:21:57.500 2221 + Now there's been a movement to move back to monoliths. 2222 + 2223 + 556 2224 + 00:21:57.500 --> 00:22:00.420 2225 + That's also really stupid and misguided. 2226 + 2227 + 557 2228 + 00:22:00.420 --> 00:22:02.260 2229 + The reason they hate microservices is, 2230 + 2231 + 558 2232 + 00:22:02.260 --> 00:22:04.500 2233 + like, imagine you spent six months, 2234 + 2235 + 559 2236 + 00:22:04.540 --> 00:22:06.340 2237 + like, breaking apart this monolith 2238 + 2239 + 560 2240 + 00:22:06.340 --> 00:22:08.740 2241 + into a bunch of microservices because your manager said, 2242 + 2243 + 561 2244 + 00:22:08.740 --> 00:22:10.540 2245 + we're doing microservices now. 2246 + 2247 + 562 2248 + 00:22:10.540 --> 00:22:13.220 2249 + And then you finally remove the thing and you realize, 2250 + 2251 + 563 2252 + 00:22:13.220 --> 00:22:15.220 2253 + oh, crap, there are all these dependencies 2254 + 2255 + 564 2256 + 00:22:15.220 --> 00:22:16.900 2257 + we didn't really understand that are, like, 2258 + 2259 + 565 2260 + 00:22:16.900 --> 00:22:19.820 2261 + maybe they're temporal or they're data related or whatever. 2262 + 2263 + 566 2264 + 00:22:19.820 --> 00:22:22.780 2265 + You didn't accomplish anything by doing this. 2266 + 2267 + 567 2268 + 00:22:22.780 --> 00:22:25.700 2269 + Maybe some sort of, like, production runtime improvement 2270 + 2271 + 568 2272 + 00:22:25.700 --> 00:22:28.340 2273 + of not having, you know, services get on each other's 2274 + 2275 + 569 2276 + 00:22:29.780 --> 00:22:33.100 2277 + CPU cycles and slow the whole system down or whatever. 2278 + 2279 + 570 2280 + 00:22:33.100 --> 00:22:34.260 2281 + Not good. 2282 + 2283 + 571 2284 + 00:22:35.220 --> 00:22:37.780 2285 + So this is sort of a necessary thing to think about. 2286 + 2287 + 572 2288 + 00:22:37.780 --> 00:22:39.700 2289 + Like, it's not just small, 2290 + 2291 + 573 2292 + 00:22:39.700 --> 00:22:41.980 2293 + but it's about boundaries and replaceability. 2294 + 2295 + 574 2296 + 00:22:41.980 --> 00:22:42.980 2297 + That's what matters. 2298 + 2299 + 575 2300 + 00:22:42.980 --> 00:22:46.140 2301 + And I say this as a person who did a talk called Tiny 2302 + 2303 + 576 2304 + 00:22:46.140 --> 00:22:48.220 2305 + 10 years ago at a conference thinking, 2306 + 2307 + 577 2308 + 00:22:48.220 --> 00:22:50.540 2309 + I think it's just about making things small, guys, 2310 + 2311 + 578 2312 + 00:22:50.540 --> 00:22:51.380 2313 + but it was not. 2314 + 2315 + 579 2316 + 00:22:53.140 --> 00:22:54.420 2317 + Now what I'm realizing, 2318 + 2319 + 580 2320 + 00:22:54.420 --> 00:22:57.660 2321 + and this is me also shilling my project, I must admit, 2322 + 2323 + 581 2324 + 00:22:57.660 --> 00:23:01.220 2325 + but really it's about the conversation. 2326 + 2327 + 582 2328 + 00:23:01.220 --> 00:23:03.100 2329 + So, you know, I was thinking about, like, 2330 + 2331 + 583 2332 + 00:23:03.100 --> 00:23:05.420 2333 + how do you apply all this generative AI stuff? 2334 + 2335 + 584 2336 + 00:23:05.420 --> 00:23:07.620 2337 + It's fine for one-shotting apps and, you know, 2338 + 2339 + 585 2340 + 00:23:07.620 --> 00:23:09.340 2341 + like I made this presentation with it. 2342 + 2343 + 586 2344 + 00:23:09.340 --> 00:23:10.740 2345 + I don't have a slide deck. 2346 + 2347 + 587 2348 + 00:23:10.740 --> 00:23:14.380 2349 + I just have talking to an LLM having to generate things. 2350 + 2351 + 588 2352 + 00:23:17.700 --> 00:23:21.620 2353 + What really matters though, on big systems is context. 2354 + 2355 + 589 2356 + 00:23:21.620 --> 00:23:22.740 2357 + Like, how do you get the intent? 2358 + 2359 + 590 2360 + 00:23:22.740 --> 00:23:24.780 2361 + How do you go to a 20 year old system 2362 + 2363 + 591 2364 + 00:23:24.780 --> 00:23:27.220 2365 + and find out what the intent is behind the code? 2366 + 2367 + 592 2368 + 00:23:27.220 --> 00:23:29.260 2369 + You probably do not actually, right? 2370 + 2371 + 593 2372 + 00:23:29.260 --> 00:23:30.620 2373 + Because no one captures it. 2374 + 2375 + 594 2376 + 00:23:30.620 --> 00:23:31.940 2377 + There's just no system for that. 2378 + 2379 + 595 2380 + 00:23:31.940 --> 00:23:33.060 2381 + There never has been. 2382 + 2383 + 596 2384 + 00:23:33.900 --> 00:23:35.820 2385 + Except in like really, really bureaucratic places, 2386 + 2387 + 597 2388 + 00:23:35.820 --> 00:23:38.700 2389 + but then it was malicious compliance 2390 + 2391 + 598 2392 + 00:23:38.700 --> 00:23:41.060 2393 + and you're gonna end up crap anyway. 2394 + 2395 + 599 2396 + 00:23:41.060 --> 00:23:42.900 2397 + So what if we could create an environment 2398 + 2399 + 600 2400 + 00:23:42.900 --> 00:23:45.340 2401 + where the conversation is always captured 2402 + 2403 + 601 2404 + 00:23:45.340 --> 00:23:48.460 2405 + around how the requirements were created and specified, 2406 + 2407 + 602 2408 + 00:23:48.460 --> 00:23:51.140 2409 + tied to a human in a way that is archived 2410 + 2411 + 603 2412 + 00:23:51.140 --> 00:23:53.940 2413 + and will never be lost when you move 2414 + 2415 + 604 2416 + 00:23:53.940 --> 00:23:55.880 2417 + from Slack to Teams or something. 2418 + 2419 + 605 2420 + 00:23:57.260 --> 00:23:58.900 2421 + And every commit and every piece of code 2422 + 2423 + 606 2424 + 00:23:58.900 --> 00:24:01.000 2425 + is tied to that conversation and the people that did it 2426 + 2427 + 607 2428 + 00:24:01.000 --> 00:24:02.580 2429 + so you get a sense of why. 2430 + 2431 + 608 2432 + 00:24:02.620 --> 00:24:04.500 2433 + I think this is the only responsible way 2434 + 2435 + 609 2436 + 00:24:04.500 --> 00:24:06.300 2437 + to do software development next year. 2438 + 2439 + 610 2440 + 00:24:07.340 --> 00:24:10.800 2441 + And to do that, it means you may not touch code as a human. 2442 + 2443 + 611 2444 + 00:24:10.800 --> 00:24:13.060 2445 + You can view it, like you shouldn't be able to, 2446 + 2447 + 612 2448 + 00:24:13.060 --> 00:24:14.420 2449 + you can use VI, it's okay. 2450 + 2451 + 613 2452 + 00:24:14.420 --> 00:24:15.900 2453 + If you use VI, you can change it, but you know, 2454 + 2455 + 614 2456 + 00:24:15.900 --> 00:24:19.620 2457 + like don't use the VS code and edit your code, it's wrong. 2458 + 2459 + 615 2460 + 00:24:19.620 --> 00:24:21.900 2461 + Because if you as a human do it, 2462 + 2463 + 616 2464 + 00:24:21.900 --> 00:24:23.380 2465 + you can't guarantee all this stuff. 2466 + 2467 + 617 2468 + 00:24:23.380 --> 00:24:25.020 2469 + You won't guarantee being able to capture 2470 + 2471 + 618 2472 + 00:24:25.020 --> 00:24:26.420 2473 + all this provenance. 2474 + 2475 + 619 2476 + 00:24:26.420 --> 00:24:29.040 2477 + And bots are way better at discipline than we are. 2478 + 2479 + 620 2480 + 00:24:29.200 --> 00:24:33.640 2481 + So I'm gonna go kind of fast now. 2482 + 2483 + 621 2484 + 00:24:35.680 --> 00:24:38.920 2485 + I talk about regenerating code and I talk about like systems, 2486 + 2487 + 622 2488 + 00:24:38.920 --> 00:24:42.720 2489 + like in my perfect world, a system in production 2490 + 2491 + 623 2492 + 00:24:42.720 --> 00:24:45.880 2493 + maybe doesn't have any of the same code it had last month. 2494 + 2495 + 624 2496 + 00:24:45.880 --> 00:24:48.280 2497 + And that's always true, it's just always rolling. 2498 + 2499 + 625 2500 + 00:24:48.280 --> 00:24:50.880 2501 + And probably I will think that's quaint in a year 2502 + 2503 + 626 2504 + 00:24:50.880 --> 00:24:54.240 2505 + and say, really, I meant five minutes, sorry guys, you know. 2506 + 2507 + 627 2508 + 00:24:54.240 --> 00:24:56.160 2509 + That's sort of insane though, 2510 + 2511 + 628 2512 + 00:24:56.160 --> 00:24:58.920 2513 + because just because we can change it doesn't mean we should 2514 + 2515 + 629 2516 + 00:24:59.680 --> 00:25:00.520 2517 + change it, and there are layers. 2518 + 2519 + 630 2520 + 00:25:00.520 --> 00:25:03.520 2521 + So Stewart Brand has this concept of paste layers, 2522 + 2523 + 631 2524 + 00:25:03.520 --> 00:25:06.760 2525 + which is really just about like layers of the ability 2526 + 2527 + 632 2528 + 00:25:06.760 --> 00:25:09.120 2529 + to change and where things need to move more slowly 2530 + 2531 + 633 2532 + 00:25:09.120 --> 00:25:11.000 2533 + and where they can move more quickly. 2534 + 2535 + 634 2536 + 00:25:11.000 --> 00:25:12.880 2537 + An example of a paste layer that should move slowly 2538 + 2539 + 635 2540 + 00:25:12.880 --> 00:25:15.080 2541 + is like a protocol, you know, HTTP, 2542 + 2543 + 636 2544 + 00:25:15.080 --> 00:25:18.480 2545 + let's not change that daily, but also a user interface. 2546 + 2547 + 637 2548 + 00:25:18.480 --> 00:25:20.760 2549 + You can't just have the user interface change constantly 2550 + 2551 + 638 2552 + 00:25:20.760 --> 00:25:22.760 2553 + because your users will be confused. 2554 + 2555 + 639 2556 + 00:25:22.760 --> 00:25:24.640 2557 + And I think Paul might have mentioned that earlier 2558 + 2559 + 640 2560 + 00:25:24.640 --> 00:25:25.640 2561 + in their presentation. 2562 + 2563 + 641 2564 + 00:25:26.640 --> 00:25:30.120 2565 + The other thing that we need to worry about is hidden state. 2566 + 2567 + 642 2568 + 00:25:30.120 --> 00:25:35.120 2569 + And I sort of got to that with the deletion test idea 2570 + 2571 + 643 2572 + 00:25:35.720 --> 00:25:38.040 2573 + of doing this big microservices thing, 2574 + 2575 + 644 2576 + 00:25:38.040 --> 00:25:41.120 2577 + and then you replace the monolith with microservices 2578 + 2579 + 645 2580 + 00:25:41.120 --> 00:25:42.880 2581 + and nothing works. 2582 + 2583 + 646 2584 + 00:25:42.880 --> 00:25:44.520 2585 + There's a bunch of that in the world. 2586 + 2587 + 647 2588 + 00:25:44.520 --> 00:25:48.520 2589 + And so to do an architecture like this, 2590 + 2591 + 648 2592 + 00:25:48.520 --> 00:25:50.640 2593 + and this is gonna be different for every application, 2594 + 2595 + 649 2596 + 00:25:50.640 --> 00:25:52.760 2597 + this is a very serious thing you need to be thinking hard 2598 + 2599 + 650 2600 + 00:25:52.760 --> 00:25:55.360 2601 + about service boundaries, data boundaries, et cetera, 2602 + 2603 + 651 2604 + 00:25:55.400 --> 00:25:57.600 2605 + even temporal coupling. 2606 + 2607 + 652 2608 + 00:25:59.000 --> 00:26:01.520 2609 + The end sort of goal here, 2610 + 2611 + 653 2612 + 00:26:01.520 --> 00:26:04.080 2613 + and really something that's always been true, 2614 + 2615 + 654 2616 + 00:26:04.080 --> 00:26:06.600 2617 + is if we're on a team together, 2618 + 2619 + 655 2620 + 00:26:06.600 --> 00:26:08.460 2621 + what we are building is not the code, 2622 + 2623 + 656 2624 + 00:26:08.460 --> 00:26:09.980 2625 + we're building a system, 2626 + 2627 + 657 2628 + 00:26:09.980 --> 00:26:13.560 2629 + and the code is not only not the asset, it is a liability. 2630 + 2631 + 658 2632 + 00:26:13.560 --> 00:26:17.040 2633 + It always is, because every line of code you ever wrote 2634 + 2635 + 659 2636 + 00:26:17.040 --> 00:26:20.400 2637 + is legacy code, the moment you wrote it, right? 2638 + 2639 + 660 2640 + 00:26:20.400 --> 00:26:23.400 2641 + Legacy code is bad, we all know that, right? 2642 + 2643 + 661 2644 + 00:26:23.400 --> 00:26:25.000 2645 + So the system is the asset, 2646 + 2647 + 662 2648 + 00:26:25.520 --> 00:26:26.760 2649 + code is a liability. 2650 + 2651 + 663 2652 + 00:26:26.760 --> 00:26:30.560 2653 + So if you think about all this stuff I was just saying, 2654 + 2655 + 664 2656 + 00:26:30.560 --> 00:26:33.160 2657 + you think about anything in your current systems, 2658 + 2659 + 665 2660 + 00:26:33.160 --> 00:26:37.140 2661 + like pick one component, could you replace it tomorrow? 2662 + 2663 + 666 2664 + 00:26:37.140 --> 00:26:39.840 2665 + Could you just have Claude redo it? 2666 + 2667 + 667 2668 + 00:26:39.840 --> 00:26:42.440 2669 + If not, you probably have a refactoring job, 2670 + 2671 + 668 2672 + 00:26:42.440 --> 00:26:45.040 2673 + a system-wide refactoring job ahead of you. 2674 + 2675 + 669 2676 + 00:26:45.040 --> 00:26:47.200 2677 + And I will assert you already have 2678 + 2679 + 670 2680 + 00:26:47.200 --> 00:26:48.560 2681 + that refactoring job ahead of you, 2682 + 2683 + 671 2684 + 00:26:48.560 --> 00:26:49.640 2685 + you just didn't know it yet 2686 + 2687 + 672 2688 + 00:26:49.640 --> 00:26:52.060 2689 + because things are moving a thousand times faster 2690 + 2691 + 673 2692 + 00:26:52.060 --> 00:26:54.080 2693 + than they used to, or maybe faster than that, 2694 + 2695 + 674 2696 + 00:26:54.120 --> 00:26:56.520 2697 + I don't know what the right number it is. 2698 + 2699 + 675 2700 + 00:26:56.520 --> 00:27:00.520 2701 + So the point is AI didn't actually create this problem. 2702 + 2703 + 676 2704 + 00:27:00.520 --> 00:27:03.120 2705 + And I think that's true of a lot of stuff we're seeing now, 2706 + 2707 + 677 2708 + 00:27:03.120 --> 00:27:05.220 2709 + both in terms of the problems we see from AI 2710 + 2711 + 678 2712 + 00:27:05.220 --> 00:27:06.960 2713 + and the solutions. 2714 + 2715 + 679 2716 + 00:27:06.960 --> 00:27:08.560 2717 + It's like a real pattern I'm seeing. 2718 + 2719 + 680 2720 + 00:27:08.560 --> 00:27:12.800 2721 + I'm also a VC, sorry, I heard some shade to VCs 2722 + 2723 + 681 2724 + 00:27:12.800 --> 00:27:15.760 2725 + on the last talk, and I agree with it, honestly. 2726 + 2727 + 682 2728 + 00:27:15.760 --> 00:27:17.580 2729 + I'm a VC who's also a programmer. 2730 + 2731 + 683 2732 + 00:27:17.580 --> 00:27:18.880 2733 + I talk to a lot of people, 2734 + 2735 + 684 2736 + 00:27:18.880 --> 00:27:20.280 2737 + and a lot of things happening now 2738 + 2739 + 685 2740 + 00:27:20.280 --> 00:27:22.200 2741 + that I think are really powerful are like, 2742 + 2743 + 686 2744 + 00:27:22.200 --> 00:27:24.880 2745 + AI is creating a problem because things move so fast, 2746 + 2747 + 687 2748 + 00:27:24.880 --> 00:27:27.440 2749 + so much content's getting created, et cetera, et cetera, 2750 + 2751 + 688 2752 + 00:27:27.440 --> 00:27:29.880 2753 + so we're gonna use AI to fix the problem. 2754 + 2755 + 689 2756 + 00:27:29.880 --> 00:27:32.120 2757 + And that's kind of where I am right now. 2758 + 2759 + 690 2760 + 00:27:32.120 --> 00:27:33.840 2761 + But it's the same thing we always had, 2762 + 2763 + 691 2764 + 00:27:33.840 --> 00:27:35.880 2765 + it's just going a thousand miles per hour. 2766 + 2767 + 692 2768 + 00:27:37.640 --> 00:27:40.080 2769 + So all the stuff I was talking about, 2770 + 2771 + 693 2772 + 00:27:40.080 --> 00:27:41.640 2773 + how do we make it more concrete? 2774 + 2775 + 694 2776 + 00:27:42.960 --> 00:27:45.480 2777 + Well, I told you I have a reference implementation 2778 + 2779 + 695 2780 + 00:27:45.480 --> 00:27:48.460 2781 + of the Phoenix architecture, I linked it earlier. 2782 + 2783 + 696 2784 + 00:27:48.460 --> 00:27:51.160 2785 + But I also told you the conversation is the commit. 2786 + 2787 + 697 2788 + 00:27:51.160 --> 00:27:52.160 2789 + And the things I was saying, 2790 + 2791 + 698 2792 + 00:27:52.160 --> 00:27:53.520 2793 + I hope they were registering like, 2794 + 2795 + 699 2796 + 00:27:53.520 --> 00:27:56.160 2797 + well, I can't use Slack as my system of record, 2798 + 2799 + 700 2800 + 00:27:56.160 --> 00:27:59.080 2801 + or I can't use Teams or whatever, or Discord, right? 2802 + 2803 + 701 2804 + 00:27:59.080 --> 00:28:02.600 2805 + I need something with durability that I can host myself, 2806 + 2807 + 702 2808 + 00:28:02.600 --> 00:28:04.280 2809 + that I can trust that no one else can read 2810 + 2811 + 703 2812 + 00:28:04.280 --> 00:28:05.640 2813 + unless I want them to. 2814 + 2815 + 704 2816 + 00:28:06.520 --> 00:28:09.000 2817 + I want cryptographic identities. 2818 + 2819 + 705 2820 + 00:28:09.000 --> 00:28:10.400 2821 + I want provenance that way. 2822 + 2823 + 706 2824 + 00:28:10.400 --> 00:28:13.720 2825 + I want my agents to be spawned by me and my key, 2826 + 2827 + 707 2828 + 00:28:13.720 --> 00:28:15.040 2829 + and I want them to have keys, 2830 + 2831 + 708 2832 + 00:28:15.040 --> 00:28:18.440 2833 + and I want us to maybe even have reputation and durability. 2834 + 2835 + 709 2836 + 00:28:18.440 --> 00:28:20.960 2837 + And so I decided I would just build something 2838 + 2839 + 710 2840 + 00:28:21.080 --> 00:28:22.000 2841 + that does this. 2842 + 2843 + 711 2844 + 00:28:22.000 --> 00:28:23.680 2845 + It started as a hack one day, 2846 + 2847 + 712 2848 + 00:28:23.680 --> 00:28:25.640 2849 + and here's where it's an app protocol thing. 2850 + 2851 + 713 2852 + 00:28:25.640 --> 00:28:29.320 2853 + I was like, what if we could sign into IRC, 2854 + 2855 + 714 2856 + 00:28:29.320 --> 00:28:30.160 2857 + if you know what that is, 2858 + 2859 + 715 2860 + 00:28:30.160 --> 00:28:32.840 2861 + internet relay chat for the young people, 2862 + 2863 + 716 2864 + 00:28:33.880 --> 00:28:35.960 2865 + with your blue sky handle? 2866 + 2867 + 717 2868 + 00:28:35.960 --> 00:28:38.920 2869 + And it just kind of got out of control. 2870 + 2871 + 718 2872 + 00:28:38.920 --> 00:28:42.640 2873 + So now what I'm building is a substrate 2874 + 2875 + 719 2876 + 00:28:42.640 --> 00:28:45.460 2877 + with all of these properties, agent provenance, 2878 + 2879 + 720 2880 + 00:28:45.460 --> 00:28:47.860 2881 + et cetera, et cetera, there's a lot to it. 2882 + 2883 + 721 2884 + 00:28:48.860 --> 00:28:51.660 2885 + But the end goal is the substrate 2886 + 2887 + 722 2888 + 00:28:51.660 --> 00:28:55.220 2889 + for agent driven development with Phoenix. 2890 + 2891 + 723 2892 + 00:28:55.220 --> 00:29:00.220 2893 + And so please join freak.at, please contribute stuff, 2894 + 2895 + 724 2896 + 00:29:00.420 --> 00:29:02.260 2897 + tell me what's stupid, what's not great. 2898 + 2899 + 725 2900 + 00:29:02.260 --> 00:29:06.860 2901 + It kind of looks like there's iOS, Android, Windows, web, 2902 + 2903 + 726 2904 + 00:29:06.860 --> 00:29:11.860 2905 + 2e, Rust SDK, bot SDK, great docs, it's ready for you, 2906 + 2907 + 727 2908 + 00:29:12.900 --> 00:29:14.540 2909 + but I have not launched it. 2910 + 2911 + 728 2912 + 00:29:14.540 --> 00:29:16.220 2913 + And don't tell anyone about it, 2914 + 2915 + 729 2916 + 00:29:16.300 --> 00:29:19.660 2917 + but please join because it's just for nerds right now. 2918 + 2919 + 730 2920 + 00:29:19.660 --> 00:29:22.100 2921 + But I think this is how things are gonna work in the future. 2922 + 2923 + 731 2924 + 00:29:22.100 --> 00:29:24.120 2925 + And I guess I'm out of time. 2926 + 2927 + 732 2928 + 00:29:24.120 --> 00:29:26.260 2929 + So thank you very much for your attention. 2930 + 2931 + 733 2932 + 00:29:26.260 --> 00:29:29.600 2933 + ! 2934 + 2935 + 734 2936 + 00:29:30.560 --> 00:29:31.860 2937 + Thank you very much, Chad. 2938 + 2939 + 735 2940 + 00:29:33.340 --> 00:29:35.820 2941 + Accidentally, an encrypted IRC client 2942 + 2943 + 736 2944 + 00:29:35.820 --> 00:29:37.740 2945 + with at-portal accounts. 2946 + 2947 + 737 2948 + 00:29:37.740 --> 00:29:39.280 2949 + Amazing, thank you very much. 1134 2950
+486
scripts/data/place-stream-video-record-cids.json
··· 1 + { 2 + "version": 1, 3 + "updatedAt": "2026-04-03T23:30:05.207Z", 4 + "records": { 5 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi56pnvulh2o": { 6 + "cid": "bafyreifub2hrf2khwzhy5sf5oo2eokr7cofybhpdwcgnbgtc444br3ngjm", 7 + "slug": "did-lexicon-enterprise-data-problem", 8 + "durationNs": 1830207116666 9 + }, 10 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5ag3scgk2k": { 11 + "cid": "bafyreifmwhoagtuie7mjyf3ky672uejoslts2ipz3jaeo3yiausbzpqeay", 12 + "slug": "building-future-of-ai-on-atproto", 13 + "durationNs": 1851243216666 14 + }, 15 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5c65iee42h": { 16 + "cid": "bafyreibelb3jvtlmhursbgndcdpn22j75k5bpkhkxrmrb4xcecwau7lm4u", 17 + "slug": "custom-feeds-landscape", 18 + "durationNs": 1854245233333 19 + }, 20 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5hy457fu2r": { 21 + "cid": "bafyreie5o6d6uhvwqjwqygonq76he3c7zz33hceqyoqh622psb43se6glu", 22 + "slug": "building-cirrus", 23 + "durationNs": 2235930983333 24 + }, 25 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5k3brfax2b": { 26 + "cid": "bafyreifphohl37wsdxkj6utfte2ylnl72uc5ycppj4swq57ty7eijdjgde", 27 + "slug": "rethinking-the-client", 28 + "durationNs": 1271224200000 29 + }, 30 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5lb763vn2j": { 31 + "cid": "bafyreiexdrycqrjskurhk6znkw22f53xsa77obwabzrvpkrp53sfrpgk3e", 32 + "slug": "account-logic-tee", 33 + "durationNs": 2013541283333 34 + }, 35 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5q4ey4232y": { 36 + "cid": "bafyreih2jhwv7iuar3asxa2ha5kbfp3tlb6j4y46ln34js6ov7qxro6w4a", 37 + "slug": "stop-hallucinating-the-protocol", 38 + "durationNs": 1000739966666 39 + }, 40 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5r2rp7a62e": { 41 + "cid": "bafyreib6bgnif6hkfbske4jkqex43ng5v2g7bubohdvj57xaoyg5zsntoa", 42 + "slug": "decentralized-is-bluesky", 43 + "durationNs": 607076783333 44 + }, 45 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5rnhjugb2h": { 46 + "cid": "bafyreic444qjtykgf65nj46wqxgf5zzbt6jd7o4cuvhhtsthuvxru6mgce", 47 + "slug": "e2ee-dms", 48 + "durationNs": 543952183333 49 + }, 50 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5s5mqmgj2r": { 51 + "cid": "bafyreihftporturdy73rmavalnicavsotda7c3freoxr5q33x7mymhb64q", 52 + "slug": "pollen-toolkit", 53 + "durationNs": 727272033333 54 + }, 55 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5stzyxji2e": { 56 + "cid": "bafyreicewuaatuo53ekzmwgrtlmghzrtjyf6huy2ngmazig7mqgctktvhe", 57 + "slug": "how-streamplace-works-vods", 58 + "durationNs": 1714000000000 59 + }, 60 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5uqr2spg2l": { 61 + "cid": "bafyreiahdfgo7cwb6mwt5tab4j4bi2e4qre44stnnd57dqfq6u36syolmq", 62 + "slug": "hypercerts-on-atproto", 63 + "durationNs": 1863269933333 64 + }, 65 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7kaogqjs22": { 66 + "cid": "bafyreiconjgsa4njtsnf6wb4fnoc3xm2hwrx4glchihnulczdhhon2juuu", 67 + "slug": "npmx-modern-browser-for-npm", 68 + "durationNs": 2132729266666 69 + }, 70 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7mb4jbag23": { 71 + "cid": "bafyreigl6c5yfqger5xzqd2ljwtnyd6xest6xnqqnipnvtvwzejb6axwxu", 72 + "slug": "tangled-the-lewis-end", 73 + "durationNs": 2298460916666 74 + }, 75 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7ofq7ob72a": { 76 + "cid": "bafyreic7zwwkmrwexwifm63snbqkyj66mweodryznradtlogv75xcdb7di", 77 + "slug": "one-year-of-graze", 78 + "durationNs": 1178187283333 79 + }, 80 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7tqadgv22d": { 81 + "cid": "bafyreierptkgl2gbph4j3rphkleiq2se3h4m43qwnpxcy2cqmnlctzkg5m", 82 + "slug": "social-components", 83 + "durationNs": 6532790000000 84 + }, 85 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7ztge2sf2h": { 86 + "cid": "bafyreibig53xjzelsacagkmpte5h4bya5rixn5hztg6s3dz6pnwoalzmwi", 87 + "slug": "designing-for-social-web", 88 + "durationNs": 2217244900000 89 + }, 90 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia3vqrg4r23": { 91 + "cid": "bafyreig4ckmab3a2lhlkrn42qduut37m6bme4hsyz2kpnlpw4n3a6h3hea", 92 + "slug": "data-sovereignty-for-games", 93 + "durationNs": 1665000000000 94 + }, 95 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia5khdija2h": { 96 + "cid": "bafyreierfgqregw6vkayr24sp4l5k22s7eid2ngyflkou54ymyko6av474", 97 + "slug": "protocol-governance-hard-decentralization", 98 + "durationNs": 1668175266666 99 + }, 100 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia74qg3622a": { 101 + "cid": "bafyreiesnh45wjrpjgyxjgsl63vxg6eiiekqgzdcmyy6kvwngsqlb6b2ba", 102 + "slug": "building-bridgy-not-walls", 103 + "durationNs": 3111972250000 104 + }, 105 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miac22soys22": { 106 + "cid": "bafyreihy4ercixns4g6iu5b3xh2p76vnrokyluyv7lgpdkdmnvgjl2tmeu", 107 + "slug": "affordances-of-the-atmosphere", 108 + "durationNs": 587841300000 109 + }, 110 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miaef2b4mh2h": { 111 + "cid": "bafyreifrrqroht3uajao4uvt7er4ytwq745mwlx4v2fdhpxzr2m2mm4kgq", 112 + "slug": "rewilding-internet-atproto", 113 + "durationNs": 1451877933333 114 + }, 115 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7ldfbjwe26": { 116 + "cid": "bafyreiafz2nanw4uuommn35ekicpssywzkydxkfy5eu3zoft3pdbt4y62a", 117 + "slug": "how-and-why-news-on-atprotocol", 118 + "durationNs": 3011280566666 119 + }, 120 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7pxl6xkz22": { 121 + "cid": "bafyreiagkous6kivb7cio5wq4znsjnpp2httov2v6d3m436bmyapzk5osm", 122 + "slug": "bluenotes-community-notes", 123 + "durationNs": 1885840033333 124 + }, 125 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7rpxijg725": { 126 + "cid": "bafyreicy5ockpgo7aoj2leuiaibhr5zffnnmqacjm7wcvclmq6wxmcssei", 127 + "slug": "community-privacy-decentralized-network", 128 + "durationNs": 1646886266666 129 + }, 130 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7zxhekcu2d": { 131 + "cid": "bafyreibf4ryl2pehijopxmsghy7unwq2rezceqdxr4zm6stexkz2kv2pfa", 132 + "slug": "building-decentralized-ai", 133 + "durationNs": 1991758183333 134 + }, 135 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia5mbp4tf22": { 136 + "cid": "bafyreiddwurnzlg4lyw3dnxitfgoavmf4bauih3gbo7crxrajiizt7o2ee", 137 + "slug": "from-toilets-to-moths", 138 + "durationNs": 1854244566666 139 + }, 140 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia7dt6fnp2m": { 141 + "cid": "bafyreigvfdgoirfbk2umj2pjin7egcmzbsdazc4xemyokla23vlnnizk44", 142 + "slug": "bookhive-design-philosophy", 143 + "durationNs": 2190837116666 144 + }, 145 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miabfvrtei26": { 146 + "cid": "bafyreifgrejxlq3wmu3r36vlzzfd3oanpmw3uvp3ish3nch5wmo7cpjhay", 147 + "slug": "abstracting-the-appview", 148 + "durationNs": 721267333333 149 + }, 150 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miacmwnd2z2z": { 151 + "cid": "bafyreiezewncvjwhxh7n6rsfbpmgtl4ug4fu66ysenamizhjo3unrgfloe", 152 + "slug": "jacquard-magic-rust", 153 + "durationNs": 1781732216666 154 + }, 155 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miaec7exqi25": { 156 + "cid": "bafyreidynb73krrvb26mxrmlij5a7w34lfbdczziogqwpjpkl2kyouympe", 157 + "slug": "artist-dreaming-atmosphere", 158 + "durationNs": 1683428100000 159 + }, 160 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2jdevvu626": { 161 + "cid": "bafyreigha4ri55oinytskrasi5ffpyomm7q7cs6645b7y2xjwzxaeu4nqu", 162 + "slug": "keynote-towards-modular-open-science", 163 + "durationNs": 9111135350000 164 + }, 165 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2rtfj5ec2m": { 166 + "cid": "bafyreigoznksbpdxffv5e2v6bvgjx746wrrrgerob7syyb6336wlj6n3k4", 167 + "slug": "can-decentralists-cooperate-rethinking-commons-and-collective-action-in-the-age-of-platforms-and-ai", 168 + "durationNs": 136882966666 169 + }, 170 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2ryxrnin2a": { 171 + "cid": "bafyreic2zojwbnncb74llukfyhnysqvqkoknf472ruwdobzo7vyqfsm2d4", 172 + "slug": "reproducible-citation-aware-automated-paper-reviews", 173 + "durationNs": 727076366666 174 + }, 175 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2u6pl6ah2z": { 176 + "cid": "bafyreiadelegoblyohjz5ddbc6tkkqtjtjdhgviltpjsnnkp3qcgjbix54", 177 + "slug": "skysquare-is-context-as-a-service", 178 + "durationNs": 96183450000 179 + }, 180 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2son7re62m": { 181 + "cid": "bafyreig6zdi47witczohzib5i46zxximhn72va6jiepucs5r6yawvmhgza", 182 + "slug": "building-collective-intelligence-to-reduce-division-at-viewsift", 183 + "durationNs": 691398866666 184 + }, 185 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2tdpailb2m": { 186 + "cid": "bafyreig5z6kkj73dlufhnnqzpdf3utrokhcvz5zswn7w4fr32cxxmsaswm", 187 + "slug": "making-wisdom-together", 188 + "durationNs": 51112233333 189 + }, 190 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi2wu5u5rs2i": { 191 + "cid": "bafyreigioj2wisndn4jls74svaa3tvopfnkoqn2acnsdrxgni6hophjuqq", 192 + "slug": "the-astrosky-ecosystem-an-independent-online-home-for-astronomy", 193 + "durationNs": 5508387083333 194 + }, 195 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi33ycoo5d2a": { 196 + "cid": "bafyreihf7f45vpz23pswd3fpm7bj4jxzlwmwzr4nuc7j6lbg5v7xdwxw6m", 197 + "slug": "future-of-science-social-media", 198 + "durationNs": 784373283333 199 + }, 200 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi34ps3oym2i": { 201 + "cid": "bafyreieurbzkxnndpsbeiad6peegjjmt343dgwbjzsycalqyigx6rvtotq", 202 + "slug": "crowdsourced-research-synthesis-on-atproto-envisioning-an-inclusive-future", 203 + "durationNs": 673188766666 204 + }, 205 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi35eplsua23": { 206 + "cid": "bafyreiaz3wnwlm5jp3gcthg4dgv6knj4pp55me7bq47zggar3i3dbammsi", 207 + "slug": "studying-social-media-through-the-atmosphere", 208 + "durationNs": 1272839200000 209 + }, 210 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi36lcxgce2b": { 211 + "cid": "bafyreibu2ck2h5z4xbeq2bvpamrc2se3qurzy4oiayfek6jvvndeed7pc4", 212 + "slug": "narrative-strands-and-memetic-lineages-in-community-social-data-using-community-archive", 213 + "durationNs": 920973916666 214 + }, 215 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi37ha3edb23": { 216 + "cid": "bafyreief7qpgxd7yzphezlxst7jilkz4plvhgfqqngqd5v62tbjss6pjnq", 217 + "slug": "how-de-centralized-is-bluesky-really", 218 + "durationNs": 1394848433333 219 + }, 220 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi54jqrm372z": { 221 + "cid": "bafyreiaqszvlmz3u5hc2ltk7jmemivcmpkopithgms6c6uuxdxv3wubjna", 222 + "slug": "landslide", 223 + "durationNs": 3008000000000 224 + }, 225 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi54lyc5ts25": { 226 + "cid": "bafyreihxp3ygnnn7d62xs72frrtxobmydlymza4domwzz4ywinrjvaq5ky", 227 + "slug": "the-aggregation-era-burned-journalism-institutions-to-the-ground-the-federated-era-is-emerging-from-those-embers", 228 + "durationNs": 2144920900000 229 + }, 230 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi54nec66s2w": { 231 + "cid": "bafyreig4rgzhioyx256v2t2kwmargpgxuqaan2wrvi3w45ddm4j3xszqiq", 232 + "slug": "feature-product-business-a-framework-for-sustainable-atproto-projects", 233 + "durationNs": 2199845166666 234 + }, 235 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi54oonum62b": { 236 + "cid": "bafyreiedwf5pqgd5p4wb7ndnpor656vapfpwkscgcuudfenshjwzkgs5oq", 237 + "slug": "groundings-with-my-siblings-lessons-learned-building-for-community", 238 + "durationNs": 2019117566666 239 + }, 240 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi56m3hnrq2z": { 241 + "cid": "bafyreigcrt7m744ns7zdrrbzbbgrziuxugzuvyvygmbklghupvsrxdp2jy", 242 + "slug": "the-economics-of-sovereign-media-a-roadmap-for-at-protocol", 243 + "durationNs": 1761589450000 244 + }, 245 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi56n6j2g22d": { 246 + "cid": "bafyreifpkap4duv5qwp6ay37y26t3htgxza7tejyvqddlzti2cmzfuab5u", 247 + "slug": "who-owns-the-group-chat-building-collaborative-spaces-on-atproto", 248 + "durationNs": 1521554866666 249 + }, 250 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5a2y3tej2z": { 251 + "cid": "bafyreifx2l6kzexwh32y6luq7nvohtcmifb3bvkzemneebtjrgwwiyc5ta", 252 + "slug": "this-isn-t-over-until-we-all-listen-to-kpop", 253 + "durationNs": 1318712266666 254 + }, 255 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5aarspma27": { 256 + "cid": "bafyreiddi7zixgepzbg3vasoj7lm7xmae5fl7f3cfpstjezf63hebcoy7m", 257 + "slug": "creators-first-video-and-media-as-the-foundation-of-a-thriving-creator-economy-on-atproto", 258 + "durationNs": 1857789233333 259 + }, 260 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5bya72ub2d": { 261 + "cid": "bafyreidql5knzmxubwkrpicwdh4o4esckkuxhdmm5jh5lx4h4ulylxruam", 262 + "slug": "a-discussion-with-news-creators", 263 + "durationNs": 2029130700000 264 + }, 265 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5bcpyqg32a": { 266 + "cid": "bafyreia66msuluij4vkdchwt4xth6peuc5a6ubhymababbkik2ds3yqw4i", 267 + "slug": "beyond-bluesky-community-infrastructure", 268 + "durationNs": 1587263566666 269 + }, 270 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5hza73vs2z": { 271 + "cid": "bafyreia3av5kkddv3ptkcga77x3bkdg4cqlhk73s375hrxdj2aae5eipxi", 272 + "slug": "sattestations", 273 + "durationNs": 869930266666 274 + }, 275 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5hx4v6cr26": { 276 + "cid": "bafyreidwi4d7yxdkviwmrgpxxmgupqsjutdxjpljy535dodatyywk7hztm", 277 + "slug": "advocating-for-digital-sovereignty-european-experiences-and-global-lessons", 278 + "durationNs": 1945239650000 279 + }, 280 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5itmi65s2z": { 281 + "cid": "bafyreiexramwyhollpqcsqcnnabahdh5eqk6ks7i5x4dqfust5md5egzx4", 282 + "slug": "feeds-are-the-new-websites", 283 + "durationNs": 816027283333 284 + }, 285 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5jmsg6kn2m": { 286 + "cid": "bafyreidviq3tnso6ywahywfnsisxwh6vkxx47dunkiaf4zghx25luufavy", 287 + "slug": "consent-before-cryptography", 288 + "durationNs": 1794372266666 289 + }, 290 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5jrjmk6y2n": { 291 + "cid": "bafyreicaku6lgoz2q3mpspyjpy5oz62bhr3onizus23d3vb75htabpf5um", 292 + "slug": "open-social-tech-and-geopolitical-risk", 293 + "durationNs": 1716487600000 294 + }, 295 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5lexqbqf2z": { 296 + "cid": "bafyreigsvpbcmgvwbwwqbpjzoea7mrtqrheb77kkfgagyvckbchugp4pq4", 297 + "slug": "building-public-interest-infrastructure-on-atproto", 298 + "durationNs": 1616842450000 299 + }, 300 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5ldvd46r2i": { 301 + "cid": "bafyreigivkxexry6krj6g7elywih4yqmqcm5siphntzd7tv4jbxvojjvg4", 302 + "slug": "from-protocol-to-product-how-expo-powers-the-next-wave-of-at-proto-applications", 303 + "durationNs": 2216209916666 304 + }, 305 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5mvmovsn2i": { 306 + "cid": "bafyreifyj4vq42expvzgdfdktqg2shmywmsmi3y5x3k6ssxto3vhpmj5vy", 307 + "slug": "2026-atmosphere-report", 308 + "durationNs": 3410980733333 309 + }, 310 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5q3oibtu2i": { 311 + "cid": "bafyreiaxdu6w75bzrizb5ihb7mq7b6fvtpu2yl3ofqnhde5ipjyc6knwpa", 312 + "slug": "why-gander-social", 313 + "durationNs": 1003760300000 314 + }, 315 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5q57diht27": { 316 + "cid": "bafyreifgsghjz56afr7fhcypbafywlgqxzy7hvsyw67igio5gkbb4n5iki", 317 + "slug": "semble-rediscovering-the-magic-of-trails", 318 + "durationNs": 906014266666 319 + }, 320 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5qzkwfe42z": { 321 + "cid": "bafyreidpgjqzxausbno2inhcrprzzdtpgxof5wdear4i376b6mrmdszr5e", 322 + "slug": "who-where-why-what-about-w-social", 323 + "durationNs": 586024716666 324 + }, 325 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5qywid6z25": { 326 + "cid": "bafyreieatweglxvqiapcvp6lt7kmwfgpevq7czg3paynmh7ggfcehnxf74", 327 + "slug": "what-350-000-users-taught-me-about-growing-on-open-social", 328 + "durationNs": 640023633333 329 + }, 330 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5rl4r4a725": { 331 + "cid": "bafyreict4ch3wibdj4mvvusdjlnk2s6l6d7hffedxk5wjwkmy6fgwibc5e", 332 + "slug": "bridging-social-graphs-how-sky-follower-bridge-helps-people-move-to-bluesky", 333 + "durationNs": 580019683333 334 + }, 335 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5rm4y7ts2b": { 336 + "cid": "bafyreidqau7ycyig3whnitjyhfsfdqcmeq3ygt2hybabbwvzltpvewlclu", 337 + "slug": "the-future-of-open-source-is-social", 338 + "durationNs": 474044633333 339 + }, 340 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5s2x6tkd2d": { 341 + "cid": "bafyreihlr5c4pn6jfnj34w54uavue2fgx2glqdhkb3ttk7ifwt3mno6yfa", 342 + "slug": "burning-down-data-walls-in-the-us-fire-service-and-beyond", 343 + "durationNs": 675947600000 344 + }, 345 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5s4foj7h2a": { 346 + "cid": "bafyreifkpf5dcstlp5egmsgaoljblsjctyqfistqpp3qcqsw6fep7udtd4", 347 + "slug": "oaklog-building-a-community-calendar-in-the-oakland-bay-area", 348 + "durationNs": 555979900000 349 + }, 350 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5sn7zmfy23": { 351 + "cid": "bafyreigiimx5qui7fvuphrssemf364azzw6pdnpw3uptm5hh5jzrsoifli", 352 + "slug": "a-free-press-needs-free-protocols", 353 + "durationNs": 2145763233333 354 + }, 355 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5spj6izy2a": { 356 + "cid": "bafyreighqyhh5dkd6fymhj5ij5c7k3ydi2e43d2q53cxerhehrlz4g7w3q", 357 + "slug": "the-phoenix-architecture", 358 + "durationNs": 1778000000000 359 + }, 360 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5unzkbat27": { 361 + "cid": "bafyreifhgr2yl4mcjxfxxt3kjyl23mgiljmmeblenfolvfx4jdzoyye66m", 362 + "slug": "journalism-must-create-its-own-algorithms", 363 + "durationNs": 2244939033333 364 + }, 365 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5unhqisv22": { 366 + "cid": "bafyreiggeahiicdqjcmh4hljqai7tla76uylpq22borkwklhh4eej5fnka", 367 + "slug": "this-title-left-intentionally-blank", 368 + "durationNs": 2152505916666 369 + }, 370 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi5wqocga62h": { 371 + "cid": "bafyreigode4edpq5q4ajk5tmgnx7wnjvc5jcnhwa4yuc2qik7xbgms7cxy", 372 + "slug": "day-3-closing-remarks", 373 + "durationNs": 856376616666 374 + }, 375 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7jhwzagl2n": { 376 + "cid": "bafyreif6tdxc7hyj5zciffuvu4bm7bunscodkc5mwqzxa4ueif2mkpr7wy", 377 + "slug": "opening-remarks-day-4", 378 + "durationNs": 822003266666 379 + }, 380 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7lapdbjc2t": { 381 + "cid": "bafyreiem3tfohar3d2ur4hdprhekvlij3vwzhfvboamkucx3j2tqh4a2mq", 382 + "slug": "roomy-and-community-organizing-for-system-change", 383 + "durationNs": 3513160550000 384 + }, 385 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7ok5zmuk2k": { 386 + "cid": "bafyreiawgs7wc4lde6m3maytmvtzyxou5wfgnanmyughcc6s6le5fcpvmu", 387 + "slug": "how-to-have-more-non-english-speaking-users", 388 + "durationNs": 1722021616666 389 + }, 390 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7o5amqqx2d": { 391 + "cid": "bafyreibfgfrfigvcc63bfni376rcbckdr7z6hssj5skitssgexmk72rmqe", 392 + "slug": "bringing-self-sovereign-identities-to-the-masses-via-atproto-and-how-to-maximize-coherence-between-upcoming-did-plc-forks", 393 + "durationNs": 1959442700000 394 + }, 395 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7pjfdkhv2b": { 396 + "cid": "bafyreieir5o6etjdpa3iwzldcorlmln2mqxjluiq7x4llrueex6pke63lu", 397 + "slug": "waiting-for-the-future-to-load", 398 + "durationNs": 2561466883333 399 + }, 400 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7q5mjlbe2c": { 401 + "cid": "bafyreidzzikssu3of32zl7n53547nrhopwayggf2w4zcvaobbetsed55ie", 402 + "slug": "blousques-case-study-on-the-challenges-in-translating-bluesky-s-ui", 403 + "durationNs": 2241920700000 404 + }, 405 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7rvqdpj722": { 406 + "cid": "bafyreidyz7tw4wkuhtn6siumjg3y7exfpl6min5uyf5gv56y7qgbizwv3y", 407 + "slug": "a-fireside-chat-on-resonant-computing-why-we-wrote-the-manifesto-and-where-we-go-from-here", 408 + "durationNs": 1944355233333 409 + }, 410 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7tcodsqu2t": { 411 + "cid": "bafyreibunl3dwk3sveacc7yt5h7qdt577bv6owqjkvr7qekc376iy7rgbq", 412 + "slug": "creating-a-safer-web-blacksky-s-moderation-tool", 413 + "durationNs": 7350903583333 414 + }, 415 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mi7tbwgymp25": { 416 + "cid": "bafyreie7u4pypp4gszmaumetlmx7qog7syayih4tml4s3l6zh4wi5ksnea", 417 + "slug": "compete-or-kill-cooperate-and-succeed", 418 + "durationNs": 7165602733333 419 + }, 420 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia26ffz2j2c": { 421 + "cid": "bafyreid4qbyqfluxg7zqozabfogcprnauyvpmdro3oupmreqzol7d655zu", 422 + "slug": "two-years-of-skywatch-lessons-learned-for-community-moderation", 423 + "durationNs": 1854261550000 424 + }, 425 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia3vm5oyd2u": { 426 + "cid": "bafyreif44mqbf7apnn4v6x5nlqtgkkhwtn4hnilcfxokxa2apb7bh6jmru", 427 + "slug": "coop-open-source-trust-and-safety-infrastructure-for-all", 428 + "durationNs": 1950417000000 429 + }, 430 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia3svkvjw22": { 431 + "cid": "bafyreigr77b3o7vtuic6l3bkiaw22ufgvxsyfovo2wi4vy6fuu7pstr5ra", 432 + "slug": "furryli-st-building-communities-without-landlords-from-the-protocol-up", 433 + "durationNs": 1916032516666 434 + }, 435 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia5q5vu4q2h": { 436 + "cid": "bafyreiey4fnvwn7jvep6xicv76deadbkl6sowbzzytjlmaz7qvaa2utzse", 437 + "slug": "webtiles-showcase", 438 + "durationNs": 1902339450000 439 + }, 440 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3mia7iun75l2x": { 441 + "cid": "bafyreihejeqj42xbtcrfpuxwz4ouzljdu3v6mhmq7c7ybukyij45k6dgue", 442 + "slug": "keywords-vs-embeddings", 443 + "durationNs": 2079654266666 444 + }, 445 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miabh2g67c2c": { 446 + "cid": "bafyreibrggcmefyyxloaxfcasfeguaxyftujvjaecqjdam7axgxh7vkeie", 447 + "slug": "scaling-the-atmosphere", 448 + "durationNs": 718261983333 449 + }, 450 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miacmdq4sm2a": { 451 + "cid": "bafyreib3t5jei3jdsexmxqb66ho6o5acuek2xlhauxwjdu3qw6iqe4ctge", 452 + "slug": "how-to-use-bluesky-to-easily-and-securely-preview-a-software-product-to-users", 453 + "durationNs": 678053266666 454 + }, 455 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miac5ez6a22r": { 456 + "cid": "bafyreia44uwnrll3v2prxuphvo5entvq7aqwhz5vndo7tdsv5y2okon2ie", 457 + "slug": "skylimit-a-curating-web-client-with-fine-grained-controls-to-mimic-the-newspaper-experience", 458 + "durationNs": 564988950000 459 + }, 460 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miac3urhgt23": { 461 + "cid": "bafyreid5mrx45wn7id6r4ogyg4xk7o737bvwse3abn36c32mj3wflxa42q", 462 + "slug": "using-graphql-to-build-with-atproto", 463 + "durationNs": 540157166666 464 + }, 465 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miadb23fme2a": { 466 + "cid": "bafyreihxnlmwsybuaygebxeclka5yxh5snv2rlynlsw53knvizpyrm2wla", 467 + "slug": "wherever-you-get-your-podcasts-interoperability-in-the-atmosphere", 468 + "durationNs": 1192065966666 469 + }, 470 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miacona6fc2e": { 471 + "cid": "bafyreigr4m65jlpkh2zkkqqabyc6ohac5dr6flgpag7ub5blk24gt2v2x4", 472 + "slug": "at-transparency-logs-accountable-record-collections", 473 + "durationNs": 679175483333 474 + }, 475 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miadd43al32c": { 476 + "cid": "bafyreiguxaud2su4qnygvrak7roe7g5l3yzaah34vmi3j5qn4cyn4sadce", 477 + "slug": "matadata-publishing-scientific-data-straight-to-at", 478 + "durationNs": 619088850000 479 + }, 480 + "at://did:plc:rbvrr34edl5ddpuwcubjiost/place.stream.video/3miadvkvhfv2h": { 481 + "cid": "bafyreihe5252dxkkcho6ssjeucka6w3b6kigakrggtupqwrydfzsym5noq", 482 + "slug": "did-plc-war-games", 483 + "durationNs": 2247941716666 484 + } 485 + } 486 + }
+834
scripts/regen-video-subtitles-if-record-changed.mjs
··· 1 + /** 2 + * Compares place.stream.video record CIDs on the PDS to a local snapshot and 3 + * regenerates VTT subtitles for sessions whose records changed. 4 + * 5 + * Usage: 6 + * pnpm regen:video-subtitles-if-record-changed 7 + * pnpm regen:video-subtitles-if-record-changed --init 8 + * pnpm regen:video-subtitles-if-record-changed --dry-run 9 + * pnpm regen:video-subtitles-if-record-changed --status 10 + * pnpm regen:video-subtitles-if-record-changed --status --remote 11 + */ 12 + 13 + import { spawn } from "node:child_process"; 14 + import { access, mkdir, readFile, writeFile } from "node:fs/promises"; 15 + import path from "node:path"; 16 + import process from "node:process"; 17 + import { fileURLToPath } from "node:url"; 18 + 19 + import { sessions } from "../src/data/conference.ts"; 20 + import { 21 + getVideoSubtitlePath, 22 + parseWebVtt, 23 + } from "../src/lib/video-subtitles.ts"; 24 + 25 + const SNAPSHOT_VERSION = 1; 26 + const SNAPSHOT_BASENAME = "place-stream-video-record-cids.json"; 27 + const CONCURRENT_FETCHES = 8; 28 + /** 29 + * Max seconds between `place.stream.video` record duration (full video length) and the last 30 + * VTT cue end time. Subtitles usually stop at the last speech, well before the file ends, so 31 + * this must be large; we only flag gross mismatches (wrong VTT file, very out-of-date transcode). 32 + */ 33 + const VTT_VS_RECORD_DURATION_TOLERANCE_SEC = 100; 34 + 35 + function getProjectRoot() { 36 + const __dirname = path.dirname(fileURLToPath(import.meta.url)); 37 + return path.resolve(__dirname, ".."); 38 + } 39 + 40 + function getSnapshotPath(rootDir) { 41 + return path.join(rootDir, "scripts", "data", SNAPSHOT_BASENAME); 42 + } 43 + 44 + function parseArgs(argv) { 45 + const args = { dryRun: false, init: false, remote: false, status: false }; 46 + 47 + for (const argument of argv) { 48 + if (argument === "--dry-run") { 49 + args.dryRun = true; 50 + continue; 51 + } 52 + if (argument === "--init") { 53 + args.init = true; 54 + continue; 55 + } 56 + if (argument === "--remote") { 57 + args.remote = true; 58 + continue; 59 + } 60 + if (argument === "--status") { 61 + args.status = true; 62 + continue; 63 + } 64 + if (argument === "--help") { 65 + printUsage(); 66 + process.exit(0); 67 + } 68 + throw new Error(`Unknown argument: ${argument}`); 69 + } 70 + 71 + return args; 72 + } 73 + 74 + function printUsage() { 75 + process.stdout 76 + .write(`Regenerate video subtitles when place.stream.video records change. 77 + 78 + Compares each session to ${SNAPSHOT_BASENAME} and to the live place.stream.video record: 79 + if the record CID differs, the VTT is missing, or the last cue end time in the VTT 80 + differs from the record duration by more than ${VTT_VS_RECORD_DURATION_TOLERANCE_SEC}s, it runs 81 + generate-video-subtitles.mjs --slug <slug> --force for that session. 82 + 83 + Usage: 84 + pnpm regen:video-subtitles-if-record-changed 85 + pnpm regen:video-subtitles-if-record-changed --init 86 + pnpm regen:video-subtitles-if-record-changed --dry-run 87 + pnpm regen:video-subtitles-if-record-changed --status 88 + pnpm regen:video-subtitles-if-record-changed --status --remote 89 + 90 + Options: 91 + --init Fetch current CIDs and write the snapshot only (establish baseline). 92 + --dry-run Print which sessions would regenerate; do not run ffmpeg or update the snapshot. 93 + --status List what needs attention: missing VTT files, snapshot gaps, and (with --remote) 94 + AT records whose CID differs from the snapshot. No generation, no snapshot writes. 95 + --remote With --status: query the PDS for current CIDs (otherwise status is local-only). 96 + --help 97 + `); 98 + } 99 + 100 + /** @param {string} uri */ 101 + function parseAtUri(uri) { 102 + const match = /^at:\/\/([^/]+)\/([^/]+)\/([^/]+)$/u.exec(uri); 103 + if (!match) { 104 + throw new Error(`Invalid at URI: ${uri}`); 105 + } 106 + 107 + return { repo: match[1], collection: match[2], rkey: match[3] }; 108 + } 109 + 110 + /** @type {Map<string, string>} */ 111 + const pdsByDid = new Map(); 112 + 113 + /** @param {string} did */ 114 + async function getPdsEndpoint(did) { 115 + const cached = pdsByDid.get(did); 116 + if (cached) { 117 + return cached; 118 + } 119 + 120 + const response = await fetch( 121 + `https://plc.directory/${encodeURIComponent(did)}`, 122 + ); 123 + 124 + if (!response.ok) { 125 + throw new Error(`PLC lookup failed for ${did}: HTTP ${response.status}`); 126 + } 127 + 128 + /** @type {{ service?: Array<{ type?: string; serviceEndpoint?: string }> }} */ 129 + const doc = await response.json(); 130 + const pds = doc.service?.find( 131 + (service) => service.type === "AtprotoPersonalDataServer", 132 + )?.serviceEndpoint; 133 + 134 + if (!pds || typeof pds !== "string") { 135 + throw new Error(`No Atproto PDS endpoint in DID document for ${did}`); 136 + } 137 + 138 + const normalized = pds.endsWith("/") ? pds.slice(0, -1) : pds; 139 + pdsByDid.set(did, normalized); 140 + return normalized; 141 + } 142 + 143 + /** 144 + * @param {string} pdsBase 145 + * @param {string} repo 146 + * @param {string} collection 147 + * @param {string} rkey 148 + */ 149 + /** 150 + * @param {string} pdsBase 151 + * @param {string} repo 152 + * @param {string} collection 153 + * @param {string} rkey 154 + * @returns {Promise<{ cid: string; value: Record<string, unknown> }>} 155 + */ 156 + async function getRecord(pdsBase, repo, collection, rkey) { 157 + const url = new URL("/xrpc/com.atproto.repo.getRecord", `${pdsBase}/`); 158 + url.searchParams.set("repo", repo); 159 + url.searchParams.set("collection", collection); 160 + url.searchParams.set("rkey", rkey); 161 + 162 + const response = await fetch(url); 163 + 164 + if (!response.ok) { 165 + const text = await response.text(); 166 + throw new Error( 167 + `getRecord failed HTTP ${response.status} for ${repo} ${collection} ${rkey}: ${text.slice(0, 200)}`, 168 + ); 169 + } 170 + 171 + /** @type {{ cid?: string; value?: Record<string, unknown> }} */ 172 + const body = await response.json(); 173 + 174 + if (!body.cid || typeof body.cid !== "string") { 175 + throw new Error(`getRecord response missing cid for ${repo} ${rkey}`); 176 + } 177 + 178 + if (!body.value || typeof body.value !== "object") { 179 + throw new Error(`getRecord response missing value for ${repo} ${rkey}`); 180 + } 181 + 182 + return { cid: body.cid, value: body.value }; 183 + } 184 + 185 + /** 186 + * @param {string} recordUri 187 + * @returns {Promise<{ cid: string; value: Record<string, unknown> }>} 188 + */ 189 + async function fetchRecordForRecordUri(recordUri) { 190 + const { repo, collection, rkey } = parseAtUri(recordUri); 191 + const pds = await getPdsEndpoint(repo); 192 + return getRecord(pds, repo, collection, rkey); 193 + } 194 + 195 + /** 196 + * place.stream.video stores duration in nanoseconds. 197 + * @param {Record<string, unknown>} value 198 + */ 199 + function getRecordDurationSeconds(value) { 200 + const duration = value.duration; 201 + if (typeof duration !== "number" || !Number.isFinite(duration)) { 202 + return null; 203 + } 204 + 205 + return duration / 1e9; 206 + } 207 + 208 + /** 209 + * @param {string} vttPath 210 + * @returns {Promise<number | null>} Max end time in seconds, or null if unreadable/empty. 211 + */ 212 + async function getVttMaxEndSeconds(vttPath) { 213 + try { 214 + const raw = await readFile(vttPath, "utf8"); 215 + const cues = parseWebVtt(raw); 216 + 217 + if (cues.length === 0) { 218 + return null; 219 + } 220 + 221 + return Math.max(...cues.map((cue) => cue.end)); 222 + } catch { 223 + return null; 224 + } 225 + } 226 + 227 + /** 228 + * @param {{ slug: string; recordUri: string }} session 229 + * @param {{ cid: string; value: Record<string, unknown> }} record 230 + * @param {{ cid?: string; durationNs?: number } | undefined} snapshotEntry 231 + * @param {string} rootDir 232 + * @returns {Promise<string[]>} Human-readable stale reasons (non-empty ⇒ should regen). 233 + */ 234 + async function collectStaleReasons(session, record, snapshotEntry, rootDir) { 235 + const reasons = []; 236 + const prevCid = snapshotEntry?.cid; 237 + 238 + if (prevCid !== record.cid) { 239 + reasons.push("record CID differs from snapshot"); 240 + } 241 + 242 + const vttPath = getSubtitlePathOnDisk(rootDir, session.slug); 243 + const vttExists = await pathExists(vttPath); 244 + const recordDurSec = getRecordDurationSeconds(record.value); 245 + 246 + if (!vttExists) { 247 + reasons.push("missing VTT file"); 248 + } else if (recordDurSec !== null) { 249 + const vttMax = await getVttMaxEndSeconds(vttPath); 250 + 251 + if (vttMax === null) { 252 + reasons.push("VTT missing cues or unreadable"); 253 + } else if ( 254 + Math.abs(recordDurSec - vttMax) > VTT_VS_RECORD_DURATION_TOLERANCE_SEC 255 + ) { 256 + reasons.push( 257 + `VTT last cue ends at ${vttMax.toFixed(1)}s but record duration is ${recordDurSec.toFixed(1)}s (>${VTT_VS_RECORD_DURATION_TOLERANCE_SEC}s apart)`, 258 + ); 259 + } 260 + } 261 + 262 + return reasons; 263 + } 264 + 265 + /** 266 + * @param {Record<string, unknown>} value 267 + * @returns {number | undefined} 268 + */ 269 + function getDurationNsFromValue(value) { 270 + const duration = value.duration; 271 + if (typeof duration !== "number" || !Number.isFinite(duration)) { 272 + return undefined; 273 + } 274 + 275 + return duration; 276 + } 277 + 278 + /** 279 + * @template T 280 + * @param {T[]} items 281 + * @param {number} concurrency 282 + * @param {(item: T) => Promise<void>} fn 283 + */ 284 + async function poolMap(items, concurrency, fn) { 285 + let index = 0; 286 + 287 + async function worker() { 288 + while (index < items.length) { 289 + const current = index; 290 + index += 1; 291 + await fn(items[current]); 292 + } 293 + } 294 + 295 + const workers = Array.from( 296 + { length: Math.min(concurrency, items.length) }, 297 + () => worker(), 298 + ); 299 + await Promise.all(workers); 300 + } 301 + 302 + /** 303 + * @param {string} rootDir 304 + * @param {string} slug 305 + */ 306 + /** @param {string} rootDir @param {string} slug */ 307 + function getSubtitlePathOnDisk(rootDir, slug) { 308 + const publicPath = getVideoSubtitlePath(slug); 309 + return path.join(rootDir, "public", publicPath.replace(/^\//u, "")); 310 + } 311 + 312 + /** @param {string} filePath */ 313 + async function pathExists(filePath) { 314 + try { 315 + await access(filePath); 316 + return true; 317 + } catch { 318 + return false; 319 + } 320 + } 321 + 322 + /** 323 + * @param {string} rootDir 324 + * @param {{ remote: boolean }} options 325 + */ 326 + async function runStatusReport(rootDir, options) { 327 + const snapshotPath = getSnapshotPath(rootDir); 328 + const recorded = sessions.filter((session) => session.recordUri); 329 + 330 + /** @type {Record<string, { cid: string; slug: string; durationNs?: number }>} */ 331 + let previousRecords = {}; 332 + 333 + try { 334 + const raw = await readFile(snapshotPath, "utf8"); 335 + const parsed = JSON.parse(raw); 336 + 337 + if (parsed?.version === SNAPSHOT_VERSION && parsed.records) { 338 + previousRecords = parsed.records; 339 + } 340 + } catch (error) { 341 + if (/** @type {NodeJS.ErrnoException} */ (error).code !== "ENOENT") { 342 + throw error; 343 + } 344 + } 345 + 346 + const hasSnapshot = Object.keys(previousRecords).length > 0; 347 + 348 + /** @type {string[]} */ 349 + const missingVtt = []; 350 + /** @type {string[]} */ 351 + const notInSnapshot = []; 352 + 353 + for (const session of recorded) { 354 + const uri = session.recordUri; 355 + const vttPath = getSubtitlePathOnDisk(rootDir, session.slug); 356 + 357 + if (!(await pathExists(vttPath))) { 358 + missingVtt.push(session.slug); 359 + } 360 + 361 + if (hasSnapshot && !previousRecords[uri]) { 362 + notInSnapshot.push(session.slug); 363 + } 364 + } 365 + 366 + /** @type {Array<{ slug: string; reasons: string[] }>} */ 367 + const localDurationMismatch = []; 368 + 369 + for (const session of recorded) { 370 + const uri = session.recordUri; 371 + const durationNs = previousRecords[uri]?.durationNs; 372 + 373 + if (typeof durationNs !== "number" || !Number.isFinite(durationNs)) { 374 + continue; 375 + } 376 + 377 + const recordDurSec = durationNs / 1e9; 378 + const vttPath = getSubtitlePathOnDisk(rootDir, session.slug); 379 + 380 + if (!(await pathExists(vttPath))) { 381 + continue; 382 + } 383 + 384 + const vttMax = await getVttMaxEndSeconds(vttPath); 385 + 386 + if (vttMax === null) { 387 + localDurationMismatch.push({ 388 + slug: session.slug, 389 + reasons: [ 390 + "VTT unreadable or has no cues (compare to snapshot duration)", 391 + ], 392 + }); 393 + continue; 394 + } 395 + 396 + if ( 397 + Math.abs(recordDurSec - vttMax) > VTT_VS_RECORD_DURATION_TOLERANCE_SEC 398 + ) { 399 + localDurationMismatch.push({ 400 + slug: session.slug, 401 + reasons: [ 402 + `VTT ends ~${vttMax.toFixed(1)}s but snapshot record duration is ~${recordDurSec.toFixed(1)}s (>${VTT_VS_RECORD_DURATION_TOLERANCE_SEC}s apart; run --init if snapshot is old)`, 403 + ], 404 + }); 405 + } 406 + } 407 + 408 + /** @type {Array<{ slug: string; reasons: string[] }>} */ 409 + const remoteStale = []; 410 + 411 + if (options.remote) { 412 + const errors = []; 413 + 414 + await poolMap(recorded, CONCURRENT_FETCHES, async (session) => { 415 + const uri = session.recordUri; 416 + 417 + try { 418 + const record = await fetchRecordForRecordUri(uri); 419 + const reasons = await collectStaleReasons( 420 + session, 421 + record, 422 + previousRecords[uri], 423 + rootDir, 424 + ); 425 + 426 + if (reasons.length > 0) { 427 + remoteStale.push({ slug: session.slug, reasons }); 428 + } 429 + } catch (error) { 430 + errors.push({ 431 + slug: session.slug, 432 + message: error instanceof Error ? error.message : String(error), 433 + }); 434 + } 435 + }); 436 + 437 + if (errors.length > 0) { 438 + for (const { slug, message } of errors) { 439 + process.stderr.write(`Fetch failed (${slug}): ${message}\n`); 440 + } 441 + 442 + throw new Error(`${errors.length} getRecord request(s) failed.`); 443 + } 444 + } 445 + 446 + const problemSlugs = new Set(); 447 + 448 + for (const slug of missingVtt) { 449 + problemSlugs.add(slug); 450 + } 451 + 452 + for (const slug of notInSnapshot) { 453 + problemSlugs.add(slug); 454 + } 455 + 456 + if (options.remote) { 457 + for (const entry of remoteStale) { 458 + problemSlugs.add(entry.slug); 459 + } 460 + } else { 461 + for (const entry of localDurationMismatch) { 462 + problemSlugs.add(entry.slug); 463 + } 464 + } 465 + 466 + const needsWork = problemSlugs.size > 0; 467 + 468 + process.stdout.write( 469 + `Subtitle status (${recorded.length} recorded sessions in conference data)\n\n`, 470 + ); 471 + 472 + if (missingVtt.length === 0) { 473 + process.stdout.write("Missing VTT files: none\n"); 474 + } else { 475 + process.stdout.write( 476 + `Missing VTT files (${missingVtt.length}) — run generate:video-subtitles for these slugs:\n`, 477 + ); 478 + 479 + for (const slug of missingVtt.sort()) { 480 + process.stdout.write(` - ${slug}\n`); 481 + } 482 + } 483 + 484 + process.stdout.write("\n"); 485 + 486 + if (!hasSnapshot) { 487 + process.stdout.write( 488 + `Snapshot: none at ${path.relative(rootDir, snapshotPath)} — run with --init once, then commit.\n`, 489 + ); 490 + } else if (notInSnapshot.length === 0) { 491 + process.stdout.write( 492 + `Snapshot: all ${recorded.length} record URIs are present.\n`, 493 + ); 494 + } else { 495 + process.stdout.write( 496 + `Snapshot gaps (${notInSnapshot.length}) — new record URIs not in snapshot (run --init or regen after merge):\n`, 497 + ); 498 + 499 + for (const slug of notInSnapshot.sort()) { 500 + process.stdout.write(` - ${slug}\n`); 501 + } 502 + } 503 + 504 + process.stdout.write("\n"); 505 + 506 + if (!options.remote) { 507 + if (localDurationMismatch.length === 0) { 508 + process.stdout.write( 509 + `VTT vs record duration (local, uses durationNs in snapshot): no mismatches${hasSnapshot ? "" : " (no snapshot)"}.\n`, 510 + ); 511 + } else { 512 + process.stdout.write( 513 + `VTT vs record duration (${localDurationMismatch.length}) — subtitles may be out of date vs last --init:\n`, 514 + ); 515 + 516 + for (const entry of localDurationMismatch) { 517 + process.stdout.write(` - ${entry.slug}\n`); 518 + 519 + for (const reason of entry.reasons) { 520 + process.stdout.write(` ${reason}\n`); 521 + } 522 + } 523 + 524 + process.stdout.write( 525 + "\nRun --status --remote to re-check against live PDS data, or pnpm regen:video-subtitles-if-record-changed to fix.\n", 526 + ); 527 + } 528 + 529 + process.stdout.write( 530 + "\nPDS check: not run. Use --status --remote to compare live records + VTT vs snapshot + duration.\n", 531 + ); 532 + } else if (remoteStale.length === 0) { 533 + process.stdout.write( 534 + "Live PDS + VTT: nothing stale (CIDs, missing files, and VTT end time vs record duration all OK).\n", 535 + ); 536 + } else { 537 + process.stdout.write( 538 + `Live PDS + VTT (${remoteStale.length}) — run pnpm regen:video-subtitles-if-record-changed (no --status) to regenerate:\n`, 539 + ); 540 + 541 + for (const entry of remoteStale) { 542 + process.stdout.write(` - ${entry.slug}\n`); 543 + 544 + for (const reason of entry.reasons) { 545 + process.stdout.write(` ${reason}\n`); 546 + } 547 + } 548 + } 549 + 550 + process.stdout.write("\n"); 551 + 552 + if (!needsWork && options.remote) { 553 + process.stdout.write("Nothing to update.\n"); 554 + } else if (!needsWork && !options.remote) { 555 + process.stdout.write( 556 + "Nothing obvious locally. If videos were updated on the PDS, use --status --remote.\n", 557 + ); 558 + } else { 559 + process.stdout.write( 560 + "Summary: fix missing VTTs, run --init if the snapshot is behind, then run regen without --status.\n", 561 + ); 562 + } 563 + 564 + if (needsWork) { 565 + process.exitCode = 1; 566 + } 567 + } 568 + 569 + function runGenerateSubtitles(rootDir, slug) { 570 + return new Promise((resolve, reject) => { 571 + const child = spawn( 572 + process.execPath, 573 + [ 574 + "--experimental-strip-types", 575 + path.join(rootDir, "scripts", "generate-video-subtitles.mjs"), 576 + "--slug", 577 + slug, 578 + "--force", 579 + ], 580 + { 581 + cwd: rootDir, 582 + stdio: "inherit", 583 + }, 584 + ); 585 + 586 + child.on("error", reject); 587 + child.on("close", (code) => { 588 + if (code === 0) { 589 + resolve(); 590 + return; 591 + } 592 + 593 + reject(new Error(`generate-video-subtitles exited with code ${code}`)); 594 + }); 595 + }); 596 + } 597 + 598 + async function main() { 599 + const rootDir = getProjectRoot(); 600 + const args = parseArgs(process.argv.slice(2)); 601 + 602 + if (args.status && args.init) { 603 + throw new Error("Use either --status or --init, not both."); 604 + } 605 + 606 + if (args.remote && !args.status) { 607 + throw new Error("--remote is only valid with --status."); 608 + } 609 + 610 + if (args.status) { 611 + await runStatusReport(rootDir, { remote: args.remote }); 612 + return; 613 + } 614 + 615 + const snapshotPath = getSnapshotPath(rootDir); 616 + 617 + const recorded = sessions.filter((session) => session.recordUri); 618 + 619 + if (recorded.length === 0) { 620 + throw new Error("No sessions with recordUri in conference data."); 621 + } 622 + 623 + /** @type {Record<string, { cid: string; slug: string; durationNs?: number }>} */ 624 + let previousRecords = {}; 625 + 626 + try { 627 + const raw = await readFile(snapshotPath, "utf8"); 628 + const parsed = JSON.parse(raw); 629 + 630 + if (parsed?.version === SNAPSHOT_VERSION && parsed.records) { 631 + previousRecords = parsed.records; 632 + } 633 + } catch (error) { 634 + if (/** @type {NodeJS.ErrnoException} */ (error).code !== "ENOENT") { 635 + throw error; 636 + } 637 + } 638 + 639 + /** @type {Record<string, { cid: string; value: Record<string, unknown> }>} */ 640 + const fetchedByUri = {}; 641 + /** @type {Map<string, string>} */ 642 + const slugByUri = new Map( 643 + recorded.map((session) => [session.recordUri, session.slug]), 644 + ); 645 + 646 + const errors = []; 647 + 648 + await poolMap(recorded, CONCURRENT_FETCHES, async (session) => { 649 + const uri = session.recordUri; 650 + 651 + try { 652 + fetchedByUri[uri] = await fetchRecordForRecordUri(uri); 653 + } catch (error) { 654 + errors.push({ 655 + slug: session.slug, 656 + message: error instanceof Error ? error.message : String(error), 657 + }); 658 + } 659 + }); 660 + 661 + if (errors.length > 0) { 662 + for (const { slug, message } of errors) { 663 + process.stderr.write(`Fetch failed (${slug}): ${message}\n`); 664 + } 665 + 666 + throw new Error(`${errors.length} getRecord request(s) failed.`); 667 + } 668 + 669 + /** @type {Array<{ slug: string; recordUri: string; previous: string | undefined; current: string; reasons: string[] }>} */ 670 + const changed = []; 671 + 672 + for (const session of recorded) { 673 + const uri = session.recordUri; 674 + const record = fetchedByUri[uri]; 675 + const reasons = await collectStaleReasons( 676 + session, 677 + record, 678 + previousRecords[uri], 679 + rootDir, 680 + ); 681 + 682 + if (reasons.length > 0) { 683 + changed.push({ 684 + slug: session.slug, 685 + recordUri: uri, 686 + previous: previousRecords[uri]?.cid, 687 + current: record.cid, 688 + reasons, 689 + }); 690 + } 691 + } 692 + 693 + if (args.init) { 694 + await mkdir(path.dirname(snapshotPath), { recursive: true }); 695 + await writeFile( 696 + snapshotPath, 697 + `${JSON.stringify( 698 + { 699 + version: SNAPSHOT_VERSION, 700 + updatedAt: new Date().toISOString(), 701 + records: Object.fromEntries( 702 + recorded.map((session) => { 703 + const uri = session.recordUri; 704 + const record = fetchedByUri[uri]; 705 + const durationNs = getDurationNsFromValue(record.value); 706 + 707 + return [ 708 + uri, 709 + { 710 + cid: record.cid, 711 + slug: session.slug, 712 + ...(durationNs !== undefined ? { durationNs } : {}), 713 + }, 714 + ]; 715 + }), 716 + ), 717 + }, 718 + null, 719 + 2, 720 + )}\n`, 721 + ); 722 + 723 + process.stdout.write( 724 + `Wrote baseline snapshot (${recorded.length} records): ${path.relative(rootDir, snapshotPath)}\n`, 725 + ); 726 + return; 727 + } 728 + 729 + if (changed.length === 0) { 730 + process.stdout.write( 731 + "No subtitle work needed: snapshot CID matches PDS, VTT files exist, and VTT length matches record duration.\n", 732 + ); 733 + process.stdout.write( 734 + "Tip: pnpm regen:video-subtitles-if-record-changed --status\n", 735 + ); 736 + return; 737 + } 738 + 739 + process.stdout.write( 740 + `${changed.length} session(s) need subtitle regeneration:\n`, 741 + ); 742 + 743 + for (const entry of changed) { 744 + process.stdout.write( 745 + ` - ${entry.slug}\n CID ${entry.previous ?? "(no prior snapshot)"} → ${entry.current}\n`, 746 + ); 747 + 748 + for (const reason of entry.reasons) { 749 + process.stdout.write(` · ${reason}\n`); 750 + } 751 + } 752 + 753 + if (args.dryRun) { 754 + process.stdout.write("\nDry run: no subtitles generated.\n"); 755 + return; 756 + } 757 + 758 + if (Object.keys(previousRecords).length === 0) { 759 + throw new Error( 760 + `No snapshot at ${path.relative(rootDir, snapshotPath)}. Run with --init first to create a baseline, then run again after records change.`, 761 + ); 762 + } 763 + 764 + const failures = []; 765 + 766 + for (const entry of changed) { 767 + process.stdout.write(`\nRegenerating subtitles for ${entry.slug}...\n`); 768 + 769 + try { 770 + await runGenerateSubtitles(rootDir, entry.slug); 771 + } catch (error) { 772 + failures.push({ 773 + slug: entry.slug, 774 + message: error instanceof Error ? error.message : String(error), 775 + }); 776 + } 777 + } 778 + 779 + /** @type {Record<string, { cid: string; slug: string; durationNs?: number }>} */ 780 + const nextRecords = { ...previousRecords }; 781 + 782 + for (const session of recorded) { 783 + const uri = session.recordUri; 784 + const failed = failures.some((failure) => failure.slug === session.slug); 785 + const wasChanged = changed.some((c) => c.recordUri === uri); 786 + const record = fetchedByUri[uri]; 787 + const durationNs = getDurationNsFromValue(record.value); 788 + 789 + if (wasChanged && failed) { 790 + continue; 791 + } 792 + 793 + nextRecords[uri] = { 794 + cid: record.cid, 795 + slug: slugByUri.get(uri) ?? session.slug, 796 + ...(durationNs !== undefined ? { durationNs } : {}), 797 + }; 798 + } 799 + 800 + await mkdir(path.dirname(snapshotPath), { recursive: true }); 801 + await writeFile( 802 + snapshotPath, 803 + `${JSON.stringify( 804 + { 805 + version: SNAPSHOT_VERSION, 806 + updatedAt: new Date().toISOString(), 807 + records: nextRecords, 808 + }, 809 + null, 810 + 2, 811 + )}\n`, 812 + ); 813 + 814 + process.stdout.write( 815 + `\nUpdated snapshot: ${path.relative(rootDir, snapshotPath)}\n`, 816 + ); 817 + 818 + if (failures.length > 0) { 819 + process.stderr.write( 820 + "\nSome regenerations failed (snapshot kept prior CIDs for those):\n", 821 + ); 822 + 823 + for (const failure of failures) { 824 + process.stderr.write(` - ${failure.slug}: ${failure.message}\n`); 825 + } 826 + 827 + process.exitCode = 1; 828 + } 829 + } 830 + 831 + main().catch((error) => { 832 + console.error(error); 833 + process.exitCode = 1; 834 + });