Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

rework sosoft proposal: whitepaper template focused on dialogue & feedback

Rewrote the SO SOFT Cycle 2 proposal from "4 scores to test" to "platform
submitted for dialogue." Body text now uses Georgia serif (whitepaper style),
titles/headings use YWFT Processing + Berkeley Mono from the AC repo.
Added colored @jeffrey handle, technical stack appendix (B), and full
sitemap appendix (C). Removed forced page breaks in favor of natural
content flow with break-after: avoid on headings.

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

+878 -299
+2 -1
sosoft/generate-pdf.mjs
··· 13 13 14 14 const browser = await puppeteer.launch({ 15 15 headless: true, 16 + executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || "/usr/sbin/chromium-browser", 16 17 args: ["--no-sandbox", "--disable-setuid-sandbox"], 17 18 }); 18 19 ··· 23 24 path: outputPath, 24 25 format: "Letter", 25 26 printBackground: true, 26 - margin: { top: "0.9in", bottom: "0.9in", left: "1in", right: "1in" }, 27 + margin: { top: "0.65in", bottom: "0.65in", left: "0.75in", right: "0.75in" }, 27 28 }); 28 29 29 30 await browser.close();
+788 -159
sosoft/proposal.html
··· 3 3 <head> 4 4 <meta charset="UTF-8"> 5 5 <style> 6 - @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,400;0,600;1,400&family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,600;1,400&display=swap'); 6 + /* === AC FONTS === */ 7 + @font-face { 8 + font-family: 'YWFTProcessing-Regular'; 9 + src: url('../system/public/type/webfonts/ywft-processing-regular.woff2') format('woff2'), 10 + url('../system/public/type/webfonts/ywft-processing-regular.woff') format('woff'); 11 + font-weight: normal; font-style: normal; font-display: swap; 12 + } 13 + @font-face { 14 + font-family: 'YWFTProcessing-Bold'; 15 + src: url('../system/public/type/webfonts/ywft-processing-bold.woff2') format('woff2'), 16 + url('../system/public/type/webfonts/ywft-processing-bold.woff') format('woff'); 17 + font-weight: normal; font-style: normal; font-display: swap; 18 + } 19 + @font-face { 20 + font-family: 'YWFTProcessing-Light'; 21 + src: url('../system/public/type/webfonts/ywft-processing-light.woff2') format('woff2'), 22 + url('../system/public/type/webfonts/ywft-processing-light.woff') format('woff'); 23 + font-weight: normal; font-style: normal; font-display: swap; 24 + } 25 + @font-face { 26 + font-family: 'Berkeley Mono Variable'; 27 + src: url('../system/public/type/webfonts/BerkeleyMonoVariable-Regular.woff2') format('woff2'), 28 + url('../system/public/type/webfonts/BerkeleyMonoVariable-Regular.woff') format('woff'); 29 + font-weight: normal; font-style: normal; 30 + } 31 + @font-face { 32 + font-family: 'Berkeley Mono Variable'; 33 + src: url('../system/public/type/webfonts/BerkeleyMonoVariable-Italic.woff2') format('woff2'), 34 + url('../system/public/type/webfonts/BerkeleyMonoVariable-Italic.woff') format('woff'); 35 + font-weight: normal; font-style: italic; 36 + } 7 37 8 38 * { margin: 0; padding: 0; box-sizing: border-box; } 9 39 10 - @page { 11 - size: letter; 12 - margin: 1in 1.2in; 13 - } 40 + @page { size: letter; margin: 0.65in 0.75in; } 14 41 42 + /* === BASE: clean whitepaper prose === */ 15 43 body { 16 - font-family: 'IBM Plex Sans', sans-serif; 17 - font-size: 11pt; 18 - line-height: 1.6; 19 - color: #111; 44 + font-family: Georgia, 'Times New Roman', serif; 45 + font-size: 10pt; 46 + line-height: 1.65; 47 + color: #1a1a1a; 20 48 } 21 49 22 - .header { 23 - margin-bottom: 2.5em; 50 + /* === AC-BRANDED ELEMENTS === */ 51 + 52 + .title-block { 53 + text-align: center; 54 + margin-bottom: 1.6em; 55 + padding-bottom: 1em; 56 + border-bottom: 2.5px solid rgb(64, 56, 74); 24 57 } 25 58 26 - .header h1 { 27 - font-family: 'IBM Plex Mono', monospace; 28 - font-size: 22pt; 29 - font-weight: 600; 59 + .title-block h1 { 60 + font-family: 'YWFTProcessing-Bold', monospace; 61 + font-size: 26pt; 30 62 letter-spacing: -0.02em; 31 - line-height: 1.2; 63 + line-height: 1.1; 32 64 margin-bottom: 0.15em; 65 + color: rgb(64, 56, 74); 33 66 } 34 67 35 - .header .subtitle { 68 + .title-block .subtitle { 69 + font-family: 'YWFTProcessing-Light', monospace; 36 70 font-size: 12pt; 37 - font-weight: 300; 38 - color: #555; 39 - margin-bottom: 1.2em; 71 + color: rgb(180, 72, 135); 72 + margin-bottom: 0.5em; 40 73 } 41 74 42 - .header .meta { 43 - font-size: 9.5pt; 75 + .title-block .meta { 76 + font-size: 9pt; 44 77 color: #777; 45 - line-height: 1.7; 78 + line-height: 1.8; 79 + } 80 + 81 + .title-block .meta a { 82 + font-family: 'Berkeley Mono Variable', monospace; 83 + font-size: 8.5pt; 84 + color: rgb(120, 80, 180); 85 + text-decoration: none; 86 + } 87 + 88 + /* @handle coloring — each char gets an AC-palette color */ 89 + .handle { font-family: 'Berkeley Mono Variable', monospace; font-weight: bold; white-space: nowrap; } 90 + .handle .c1 { color: rgb(205, 92, 155); } 91 + .handle .c2 { color: rgb(92, 205, 155); } 92 + .handle .c3 { color: rgb(155, 120, 205); } 93 + .handle .c4 { color: rgb(205, 155, 92); } 94 + .handle .c5 { color: rgb(92, 155, 205); } 95 + .handle .c6 { color: rgb(205, 92, 92); } 96 + .handle .c7 { color: rgb(155, 205, 92); } 97 + .handle .c8 { color: rgb(92, 120, 205); } 98 + 99 + /* === TWO-COLUMN LAYOUT === */ 100 + 101 + .columns { 102 + column-count: 2; 103 + column-gap: 1.8em; 104 + column-rule: 1px solid #e0e0e0; 46 105 } 47 106 48 107 h2 { 49 - font-family: 'IBM Plex Mono', monospace; 50 - font-size: 11pt; 51 - font-weight: 600; 52 - margin-top: 2em; 53 - margin-bottom: 0.5em; 108 + font-family: 'YWFTProcessing-Bold', monospace; 109 + font-size: 9pt; 110 + margin-top: 1.3em; 111 + margin-bottom: 0.3em; 54 112 text-transform: uppercase; 55 113 letter-spacing: 0.06em; 114 + color: rgb(180, 72, 135); 115 + break-after: avoid; 56 116 } 57 117 118 + h2:first-child { margin-top: 0; } 119 + 58 120 p { 59 - margin-bottom: 0.75em; 121 + margin-bottom: 0.6em; 122 + text-align: justify; 123 + hyphens: auto; 60 124 } 61 125 62 - ul { 63 - margin: 0.4em 0 0.9em 1.2em; 64 - } 65 - 66 - li { 67 - margin-bottom: 0.2em; 68 - } 126 + ul { margin: 0.3em 0 0.65em 1.1em; } 127 + li { margin-bottom: 0.15em; } 128 + li strong { color: rgb(64, 56, 74); } 69 129 70 130 code { 71 - font-family: 'IBM Plex Mono', monospace; 72 - font-size: 9.5pt; 73 - background: #f0f0f0; 74 - padding: 0.1em 0.3em; 131 + font-family: 'Berkeley Mono Variable', monospace; 132 + font-size: 8.5pt; 133 + background: rgba(120, 80, 180, 0.07); 134 + padding: 0.08em 0.25em; 75 135 border-radius: 2px; 136 + color: rgb(100, 60, 160); 76 137 } 77 138 78 - .links { 79 - font-size: 9.5pt; 80 - color: #666; 81 - margin-top: 1.5em; 82 - line-height: 1.8; 139 + em { font-style: italic; } 140 + 141 + /* === SECTION DIVIDERS === */ 142 + .section-divider { 143 + border: none; 144 + border-top: 2px solid rgb(64, 56, 74); 145 + margin: 1.2em 0 0.8em; 83 146 } 84 147 85 - .links a { 86 - color: #333; 87 - text-decoration: none; 88 - font-family: 'IBM Plex Mono', monospace; 89 - font-size: 9pt; 90 - } 148 + /* === APPENDIX SHARED === */ 91 149 92 - hr { 93 - border: none; 94 - border-top: 1px solid #ddd; 95 - margin: 1.5em 0; 150 + .appendix-title { 151 + font-family: 'YWFTProcessing-Bold', monospace; 152 + font-size: 11pt; 153 + text-align: center; 154 + margin-bottom: 0.15em; 155 + text-transform: uppercase; 156 + letter-spacing: 0.06em; 157 + color: rgb(64, 56, 74); 158 + break-after: avoid; 96 159 } 97 160 98 - .diagram-section { 99 - page-break-before: always; 100 - padding-top: 0.5em; 161 + .appendix-subtitle { 162 + font-family: 'YWFTProcessing-Light', monospace; 163 + font-size: 9pt; 164 + text-align: center; 165 + color: #999; 166 + margin-bottom: 1em; 167 + break-after: avoid; 101 168 } 102 169 103 - .diagram-section h2 { 104 - margin-top: 0; 170 + .appendix-header { 171 + break-after: avoid; 172 + break-inside: avoid; 105 173 } 174 + 175 + /* === STAT GRID === */ 106 176 107 177 .stat-grid { 108 178 display: grid; 109 179 grid-template-columns: 1fr 1fr 1fr; 110 - gap: 0.6em; 111 - margin: 0.8em 0; 180 + gap: 0.45em; 181 + margin: 0.6em 0; 182 + break-inside: avoid; 112 183 } 113 184 114 185 .stat-box { 115 - background: #f7f7f7; 116 - border: 1px solid #e0e0e0; 117 - padding: 0.5em 0.7em; 186 + background: linear-gradient(135deg, rgba(180, 72, 135, 0.05) 0%, rgba(120, 80, 180, 0.05) 100%); 187 + border: 1.5px solid rgba(180, 72, 135, 0.18); 188 + border-radius: 4px; 189 + padding: 0.5em 0.4em; 118 190 text-align: center; 119 191 } 120 192 121 193 .stat-box .num { 122 - font-family: 'IBM Plex Mono', monospace; 123 - font-size: 18pt; 124 - font-weight: 600; 125 - color: #111; 194 + font-family: 'YWFTProcessing-Bold', monospace; 195 + font-size: 19pt; 196 + color: rgb(180, 72, 135); 126 197 line-height: 1.2; 127 198 } 128 199 129 200 .stat-box .label { 130 - font-size: 8pt; 201 + font-family: 'Berkeley Mono Variable', monospace; 202 + font-size: 7pt; 131 203 text-transform: uppercase; 132 204 letter-spacing: 0.08em; 133 - color: #888; 134 - margin-top: 0.15em; 205 + color: rgb(120, 80, 180); 206 + margin-top: 0.1em; 135 207 } 136 208 137 - .doc-sample { 138 - background: #fafafa; 139 - border: 1px solid #e0e0e0; 140 - padding: 0.5em 0.7em; 209 + .makers { 210 + font-size: 8.5pt; 211 + color: #666; 141 212 margin: 0.5em 0; 142 - font-family: 'IBM Plex Mono', monospace; 213 + text-align: center; 214 + } 215 + .makers strong { color: rgb(180, 72, 135); font-family: 'Berkeley Mono Variable', monospace; font-size: 8pt; } 216 + 217 + /* === DIAGRAMS === */ 218 + 219 + .diagram-box { 220 + background: rgba(244, 235, 250, 0.5); 221 + border: 1.5px solid rgba(120, 80, 180, 0.18); 222 + border-radius: 5px; 223 + padding: 0.6em 0.8em; 224 + margin: 0.6em 0; 225 + break-inside: avoid; 226 + } 227 + 228 + .diagram-label { 229 + font-family: 'YWFTProcessing-Bold', monospace; 230 + font-size: 7pt; 231 + color: rgb(120, 80, 180); 232 + text-transform: uppercase; 233 + letter-spacing: 0.08em; 234 + margin-bottom: 0.25em; 235 + break-after: avoid; 236 + } 237 + 238 + .flow { 239 + font-family: 'Berkeley Mono Variable', monospace; 143 240 font-size: 8pt; 144 - line-height: 1.5; 241 + line-height: 2; 242 + text-align: center; 243 + color: #333; 244 + } 245 + 246 + .flow .arrow { color: rgba(180, 72, 135, 0.5); } 247 + .flow .node { 248 + font-family: 'YWFTProcessing-Bold', monospace; 249 + color: rgb(180, 72, 135); 250 + background: rgba(180, 72, 135, 0.1); 251 + padding: 0.15em 0.4em; 252 + border-radius: 3px; 253 + } 254 + .flow .note { 255 + font-family: 'Berkeley Mono Variable', monospace; 256 + color: rgb(120, 80, 180); font-size: 7pt; 257 + } 258 + 259 + /* === DOC SAMPLES === */ 260 + 261 + .doc-sample { 262 + background: #fff; 263 + border-left: 3px solid rgb(180, 72, 135); 264 + padding: 0.3em 0.5em; 265 + margin: 0.35em 0; 266 + font-family: 'Berkeley Mono Variable', monospace; 267 + font-size: 7pt; 268 + line-height: 1.45; 145 269 color: #444; 146 270 white-space: pre-wrap; 271 + } 272 + .doc-sample strong { color: rgb(120, 80, 180); } 273 + 274 + .appendix-cols { 275 + column-count: 2; 276 + column-gap: 1.6em; 277 + margin-top: 0.4em; 278 + } 279 + .doc-samples { break-inside: avoid; } 280 + 281 + /* === TECH STACK === */ 282 + 283 + .stack-grid { 284 + display: grid; 285 + grid-template-columns: 1fr 1fr; 286 + gap: 0.5em; 287 + margin: 0.5em 0; 147 288 } 148 289 149 - .doc-label { 150 - font-family: 'IBM Plex Mono', monospace; 151 - font-size: 8pt; 152 - color: #999; 290 + .stack-card { 291 + background: rgba(244, 235, 250, 0.4); 292 + border: 1.5px solid rgba(120, 80, 180, 0.13); 293 + border-radius: 4px; 294 + padding: 0.45em 0.6em; 295 + break-inside: avoid; 296 + } 297 + 298 + .stack-card-title { 299 + font-family: 'YWFTProcessing-Bold', monospace; 300 + font-size: 7.5pt; 301 + color: rgb(180, 72, 135); 302 + text-transform: uppercase; 303 + letter-spacing: 0.06em; 304 + margin-bottom: 0.2em; 305 + } 306 + 307 + .stack-card ul { 308 + font-family: 'Berkeley Mono Variable', monospace; 309 + font-size: 7.5pt; 310 + margin: 0 0 0 0.8em; 311 + color: #444; 312 + line-height: 1.5; 313 + } 314 + .stack-card li { margin-bottom: 0.05em; } 315 + 316 + .tool-row { 317 + display: flex; 318 + gap: 0.4em; 319 + flex-wrap: wrap; 320 + margin: 0.4em 0; 321 + } 322 + 323 + .tool-chip { 324 + font-family: 'Berkeley Mono Variable', monospace; 325 + font-size: 7pt; 326 + background: rgba(180, 72, 135, 0.08); 327 + color: rgb(140, 50, 110); 328 + padding: 0.2em 0.5em; 329 + border-radius: 3px; 330 + border: 1px solid rgba(180, 72, 135, 0.13); 331 + } 332 + .tool-chip.green { 333 + background: rgba(92, 205, 155, 0.1); 334 + color: rgb(30, 120, 80); 335 + border-color: rgba(92, 205, 155, 0.2); 336 + } 337 + .tool-chip.purple { 338 + background: rgba(120, 80, 180, 0.08); 339 + color: rgb(90, 50, 150); 340 + border-color: rgba(120, 80, 180, 0.15); 341 + } 342 + .tool-chip.blue { 343 + background: rgba(60, 120, 200, 0.08); 344 + color: rgb(40, 90, 170); 345 + border-color: rgba(60, 120, 200, 0.15); 346 + } 347 + 348 + .source-box { 349 + background: #faf8fc; 350 + border: 1.5px solid rgba(120, 80, 180, 0.13); 351 + border-radius: 5px; 352 + padding: 0.5em 0.7em; 353 + margin: 0.5em 0; 354 + font-family: 'Berkeley Mono Variable', monospace; 355 + font-size: 7pt; 356 + line-height: 1.5; 357 + color: #555; 358 + break-inside: avoid; 359 + } 360 + .source-box strong { 361 + color: rgb(120, 80, 180); 362 + font-family: 'YWFTProcessing-Bold', monospace; 363 + font-size: 7.5pt; 364 + } 365 + 366 + /* === SITEMAP === */ 367 + 368 + .sitemap-section { 369 + break-inside: avoid; 370 + margin-bottom: 0.5em; 371 + } 372 + 373 + .sitemap-header { 374 + font-family: 'YWFTProcessing-Bold', monospace; 375 + font-size: 7.5pt; 376 + color: rgb(180, 72, 135); 153 377 text-transform: uppercase; 154 - letter-spacing: 0.08em; 155 - margin-top: 0.7em; 378 + letter-spacing: 0.06em; 156 379 margin-bottom: 0.15em; 380 + padding-bottom: 0.1em; 381 + border-bottom: 1px solid rgba(180, 72, 135, 0.18); 382 + break-after: avoid; 157 383 } 158 384 159 - .doc-label:first-child { margin-top: 0; } 385 + .sitemap-routes { 386 + font-family: 'Berkeley Mono Variable', monospace; 387 + font-size: 6.5pt; 388 + color: #555; 389 + line-height: 1.4; 390 + display: flex; 391 + flex-wrap: wrap; 392 + gap: 0.15em 0.6em; 393 + } 160 394 161 - .flow { 162 - font-family: 'IBM Plex Mono', monospace; 163 - font-size: 9pt; 164 - line-height: 2; 165 - margin: 0.6em 0; 395 + .sitemap-route::before { content: "/"; color: rgba(120, 80, 180, 0.35); } 396 + 397 + .sitemap-cols { column-count: 2; column-gap: 1.6em; } 398 + 399 + .domain-grid { 400 + display: grid; 401 + grid-template-columns: 1fr 1fr 1fr; 402 + gap: 0.35em; 403 + margin: 0.4em 0; 404 + } 405 + 406 + .domain-card { 407 + background: rgba(244, 235, 250, 0.4); 408 + border: 1.5px solid rgba(120, 80, 180, 0.13); 409 + border-radius: 4px; 410 + padding: 0.35em 0.5em; 166 411 text-align: center; 167 - color: #333; 168 412 } 169 413 170 - .flow .arrow { color: #999; } 171 - .flow .node { font-weight: 600; } 172 - .flow .note { color: #888; font-size: 8pt; font-weight: normal; } 414 + .domain-name { 415 + font-family: 'YWFTProcessing-Bold', monospace; 416 + font-size: 7.5pt; 417 + color: rgb(120, 80, 180); 418 + } 419 + 420 + .domain-desc { 421 + font-family: 'Berkeley Mono Variable', monospace; 422 + font-size: 6.5pt; 423 + color: #999; 424 + margin-top: 0.1em; 425 + } 426 + 427 + /* === FOOTER === */ 428 + .page-footer { 429 + font-family: 'Berkeley Mono Variable', monospace; 430 + font-size: 7pt; 431 + color: #bbb; 432 + text-align: center; 433 + margin-top: 1.5em; 434 + padding-top: 0.5em; 435 + border-top: 1px solid #eee; 436 + } 173 437 </style> 174 438 </head> 175 439 <body> 176 440 177 - <div class="header"> 178 - <h1>Aesthetic Computer as Social Instrument</h1> 179 - <div class="subtitle">Score for Social Software &mdash; Cycle 2 Proposal</div> 441 + <!-- ============ PAGE 1: PROPOSAL ============ --> 442 + 443 + <div class="title-block"> 444 + <h1>Aesthetic Computer: Open Development</h1> 445 + <div class="subtitle">A Platform Submitted for Dialogue</div> 180 446 <div class="meta"> 181 - Jeffrey Scudder &ensp;/&ensp; @jeffrey<br> 182 - DESMA 596/199 &ensp;&middot;&ensp; March 2026 447 + Jeffrey Scudder &ensp;/&ensp; 448 + <span class="handle"><span class="c1">@</span><span class="c2">j</span><span class="c3">e</span><span class="c4">f</span><span class="c5">f</span><span class="c6">r</span><span class="c7">e</span><span class="c8">y</span></span><br> 449 + Score for Social Software &mdash; Cycle 2 &ensp;&middot;&ensp; DESMA 596/199 &ensp;&middot;&ensp; March 2026<br> 450 + <a href="https://aesthetic.computer">aesthetic.computer</a> &ensp;&middot;&ensp; 451 + <a href="https://github.com/whistlegraph/aesthetic-computer">github</a> &ensp;&middot;&ensp; 452 + <a href="https://nopaint.art">nopaint.art</a> 183 453 </div> 184 454 </div> 185 455 456 + <div class="columns"> 457 + 186 458 <h2>The Score</h2> 187 459 188 460 <p> 189 - I want to use this cycle to develop the social choreography of Aesthetic Computer (AC) &mdash; the open-source creative computing platform I've been building since 2021. AC is a mobile-first runtime and social network where users write, publish, and share small interactive programs called <em>pieces</em>. It already has the technical infrastructure for social software: real-time chat, @handles with custom colors, ephemeral status updates (moods), a pixel painting gallery, a built-in Lisp dialect (KidLisp) for generative art, multiplayer WebSocket sessions, and user profiles that track creative output. 461 + I'm submitting Aesthetic Computer (AC)&thinsp;&mdash;&thinsp;the open-source creative computing platform I've been building since 2021&thinsp;&mdash;&thinsp;as a social software project in active development. I'm not proposing to build a new thing for this cycle. I'm bringing the thing I'm already building into the room for dialogue, feedback, and critical exchange as I continue to develop it alongside its community. 462 + </p> 463 + 464 + <p> 465 + AC is a mobile-first runtime and social network where users write, publish, and share small interactive programs called <em>pieces</em>. It has real-time chat, @handles with per-character color customization, ephemeral status updates (moods mirrored to Bluesky via ATProto), a pixel painting system, a built-in Lisp dialect (KidLisp), multiplayer WebSocket sessions, and user profiles that track creative output. The codebase is open source with 4+ years of continuous development. 190 466 </p> 191 467 192 468 <p> 193 - What I haven't had the chance to develop is the <em>social composition</em> &mdash; deliberate structures for how people use this system together. The platform has 351 built-in pieces and ~2,800 registered handles, but the social dynamics are still largely emergent. I'd like to design and test specific social scores: structured rituals like a daily painting circle, weekly piece exchanges where members fork and remix each other's published programs, collaborative KidLisp jams, and constraint-based chat performances. I want to see what happens when a committed group performs these scores together over 10 weeks. 469 + The score is simple: I develop AC in the open over 10 weeks, sharing what I'm working on, what decisions I'm facing, and what the community is doing on the platform. The cohort engages as users and as critics&thinsp;&mdash;&thinsp;trying the tools, reading the design choices, and giving me feedback I can't get from inside the project. 194 470 </p> 195 471 472 + <h2>What I'm Looking For</h2> 473 + 196 474 <p> 197 - Concretely, I'd build new AC pieces during the cycle &mdash; a cohort dashboard, multiplayer collaborative tools, and score templates that define social rules as playable software. I'd also write a "Write a Score" guide that documents how to compose social structures on the platform, parallel to AC's existing "Write a Piece" programming guide. 475 + I've been deep inside AC's architecture for years. I know how the systems work. What I lack is outside perspective on the social design&thinsp;&mdash;&thinsp;the questions I can't answer alone: 198 476 </p> 199 477 200 - <h2>Audience</h2> 478 + <ul> 479 + <li>What feels inviting and what feels opaque when you first encounter the platform?</li> 480 + <li>Which social features sustain participation vs. which are technically impressive but socially inert?</li> 481 + <li>How does the "instrument" metaphor land for people who aren't already invested in it?</li> 482 + <li>What would you want to do on AC that you currently can't?</li> 483 + <li>Where does the design accidentally exclude the people it claims to welcome?</li> 484 + </ul> 201 485 202 486 <p> 203 - The immediate audience is this cohort. The scores I want to test need real people showing up regularly &mdash; you can't evaluate social software alone. Longer term, anything built during the cycle would be live on the public platform for AC's existing community, and the documentation would be reusable for other educators running creative computing workshops. 487 + These questions require sustained dialogue, not a single usability test. A cohort of practitioners thinking about social software from different angles is the right context for this kind of exchange. 204 488 </p> 205 489 490 + <h2>What the Cohort Gets</h2> 491 + 492 + <ul> 493 + <li><strong>A live codebase</strong>&thinsp;&mdash;&thinsp;open source, documented, actively changing week to week</li> 494 + <li><strong>The dev process</strong>&thinsp;&mdash;&thinsp;I work with Claude Code, Cursor, and VS Code, and maintain a living <code>SCORE.md</code>; the process is as legible as the product</li> 495 + <li><strong>Platform accounts</strong>&thinsp;&mdash;&thinsp;everyone gets an @handle, can paint, chat, set moods, write KidLisp, publish pieces</li> 496 + <li><strong>Real community data</strong>&thinsp;&mdash;&thinsp;2,800 handles, 18k chat messages, 4,400 paintings, 16k KidLisp programs; the social patterns are there to observe</li> 497 + </ul> 498 + 206 499 <h2>Why This Cycle</h2> 207 500 208 501 <p> 209 - AC's <code>SCORE.md</code> already uses the metaphor of a musical score to organize the project &mdash; the platform's interface is designed to function like an instrument where users discover memorizable paths, build literacy through play, and eventually improvise. Casey's framing of "scores for social software" maps directly onto this. I've been building the instrument; this cycle is a chance to compose for it with peers who are thinking about similar questions from different angles. 502 + Casey's framing of "scores for social software" maps directly onto how I already think about AC. The platform's <code>SCORE.md</code> literally uses the metaphor of a musical score to organize the project. The interface is designed to work like an instrument&thinsp;&mdash;&thinsp;users discover memorizable paths, build literacy through play, and eventually improvise. But I've been composing alone. This cycle is a chance to compose in conversation. 210 503 </p> 211 504 212 505 <p> 213 - I also want the critical feedback. I've been deep in the technical architecture for years and need outside eyes on the social design &mdash; what feels inviting, what's confusing, what rituals actually sustain participation. A flat cohort of practitioners working on their own social software projects is the right context for that kind of dialogue. 506 + I'm at a specific inflection point. The technical infrastructure is mature. The question now is about social design: how do the features I've built actually shape the way people relate to each other and to creative computing? That's best answered through dialogue with people thinking critically about social software, not through more engineering. 214 507 </p> 215 508 216 509 <h2>Practice</h2> 217 510 218 511 <p> 219 - I'm an artist, educator, and software developer. I build software as a medium for art and education. Before AC, I created No Paint (2020), a pixel art tool whose community of non-technical users taught me how people learn computing through social participation in software they love. AC extends that into a full platform: anyone can write, publish, and share interactive programs at a URL. The codebase is open source and has been in continuous development for 4+ years. 512 + I'm an artist, educator, and software developer. Before AC, I created No Paint (2020), a pixel art tool whose community of non-technical users taught me how people learn computing through social participation in software they love. AC extends that into a full platform: anyone can write, publish, and share interactive programs at a URL. 220 513 </p> 221 514 222 515 <p> 223 - I teach creative computing and have used AC as infrastructure in courses and workshops. 516 + I teach creative computing and have used AC as infrastructure in courses and workshops. My interest in social software comes from watching people learn computation through social participation&thinsp;&mdash;&thinsp;first in No Paint, now in AC. I'm bringing this not as a finished project but as an ongoing practice I want to develop through critical exchange. 224 517 </p> 225 518 226 - <div class="links"> 227 - <a href="https://aesthetic.computer">aesthetic.computer</a> &ensp;&middot;&ensp; 228 - <a href="https://github.com/whistlegraph/aesthetic-computer">github</a> &ensp;&middot;&ensp; 229 - <a href="https://nopaint.art">nopaint.art</a> &ensp;&middot;&ensp; 230 - <a href="https://news.ycombinator.com/item?id=41526754">notepat on hn</a> 231 519 </div> 232 520 233 - <!-- NETWORK REPORT CARD --> 234 - <div class="diagram-section"> 521 + <!-- ============ APPENDIX A: NETWORK DATA ============ --> 235 522 236 - <h2>Appendix: The Network</h2> 523 + <hr class="section-divider"> 237 524 238 - <p style="font-size: 9.5pt; color: #666; margin-bottom: 0.8em;"> 239 - Live data from AC's MongoDB cluster as of March 2, 2026. This is the material a score composes over. 240 - </p> 525 + <div class="appendix-header"> 526 + <div class="appendix-title">Appendix A: The Network</div> 527 + <div class="appendix-subtitle">Live data from AC's MongoDB cluster &mdash; March 2, 2026</div> 528 + </div> 241 529 242 530 <div class="stat-grid"> 243 531 <div class="stat-box"><div class="num">2,798</div><div class="label">@handles</div></div> ··· 251 539 <div class="stat-box"><div class="num">93,122</div><div class="label">boot events</div></div> 252 540 </div> 253 541 254 - <p style="font-size: 9pt; color: #666; margin: 0.3em 0 0;"> 255 - <strong style="color:#444;">Who makes things:</strong> 256 - 1,067 users have painted &middot; 257 - 997 have posted moods &middot; 258 - 59 have written KidLisp &middot; 542 + <p class="makers"> 543 + <strong>Who makes things:</strong> 544 + 1,067 have painted &ensp;&middot;&ensp; 545 + 997 have posted moods &ensp;&middot;&ensp; 546 + 59 have written KidLisp &ensp;&middot;&ensp; 259 547 19 have published pieces 260 548 </p> 261 549 262 - <div class="doc-label">The instrument loop</div> 263 - <div class="flow"> 264 - <span class="node">prompt</span> 265 - <span class="arrow">&ensp;&rarr;&ensp;</span> 266 - type a piece name 267 - <span class="arrow">&ensp;&rarr;&ensp;</span> 268 - <span class="node">enter</span> 269 - <span class="arrow">&ensp;&rarr;&ensp;</span> 270 - play the piece 271 - <span class="arrow">&ensp;&rarr;&ensp;</span> 272 - <span class="node">esc</span> 273 - <span class="arrow">&ensp;&rarr;&ensp;</span> 274 - back to prompt 550 + <div class="appendix-cols"> 551 + 552 + <div class="diagram-box"> 553 + <div class="diagram-label">The Instrument Loop</div> 554 + <div class="flow"> 555 + <span class="node">prompt</span> 556 + <span class="arrow">&ensp;&rarr;&ensp;</span> 557 + type a piece name 558 + <span class="arrow">&ensp;&rarr;&ensp;</span> 559 + <span class="node">enter</span> 560 + <span class="arrow">&ensp;&rarr;&ensp;</span> 561 + play the piece 562 + <span class="arrow">&ensp;&rarr;&ensp;</span> 563 + <span class="node">esc</span> 564 + <span class="arrow">&ensp;&rarr;&ensp;</span> 565 + back to prompt 566 + </div> 567 + </div> 568 + 569 + <div class="diagram-box"> 570 + <div class="diagram-label">User Data Flow</div> 571 + <div class="flow"> 572 + <span class="node">@handle</span> 573 + <span class="arrow">&ensp;&rarr;&ensp;</span> 574 + paint / chat / mood / kid / publish 575 + <span class="arrow">&ensp;&rarr;&ensp;</span> 576 + <span class="node">MongoDB</span> 577 + <span class="arrow">&ensp;&rarr;&ensp;</span> 578 + profile 579 + <span class="arrow">&ensp;&rarr;&ensp;</span> 580 + <span class="node">public URL</span> 581 + <br> 582 + <span class="note">moods &rarr; Bluesky via ATProto &ensp;&middot;&ensp; paintings &rarr; DO Spaces CDN</span> 583 + </div> 584 + </div> 585 + 586 + <div class="doc-samples"> 587 + <div class="diagram-label">Sample Documents (live)</div> 588 + <div class="doc-sample"><strong>mood</strong> { mood: "studying astronomy", when: "2026-03-02T12:32:49Z", atproto: { rkey: "3mg3b6jcj4k2x" } }</div> 589 + <div class="doc-sample"><strong>painting</strong> { code: "gfl", slug: "2026.03.02.14.14.39", when: "2026-03-02T13:14:48Z" }</div> 590 + <div class="doc-sample"><strong>kidlisp</strong> { code: "27z", source: "fade:red-blue-black-blue-red\nscroll (* 100 amp)", hits: 1 }</div> 591 + <div class="doc-sample"><strong>chat</strong> { text: "y'all gonna piss me off", when: "2026-03-02T05:26:25Z", font: "font_1" }</div> 592 + <div class="doc-sample"><strong>piece</strong> { code: "zod", slug: "zod", name: "3d-cube", extension: ".mjs", hits: 1 }</div> 593 + </div> 594 + 595 + </div> 596 + 597 + <!-- ============ APPENDIX B: TECHNICAL STACK ============ --> 598 + 599 + <hr class="section-divider"> 600 + 601 + <div class="appendix-header"> 602 + <div class="appendix-title">Appendix B: Technical Stack</div> 603 + <div class="appendix-subtitle">Open source &mdash; github.com/whistlegraph/aesthetic-computer</div> 604 + </div> 605 + 606 + <div class="stack-grid"> 607 + 608 + <div class="stack-card"> 609 + <div class="stack-card-title">Frontend Runtime</div> 610 + <ul> 611 + <li>ES Modules (.mjs) &mdash; no build step for pieces</li> 612 + <li>Canvas 2D + WebGL2 rendering</li> 613 + <li>WebSocket hot-reload module loader</li> 614 + <li>Service worker for offline caching</li> 615 + <li>351 built-in pieces (333 JS + 18 KidLisp)</li> 616 + </ul> 617 + </div> 618 + 619 + <div class="stack-card"> 620 + <div class="stack-card-title">System Server (Netlify)</div> 621 + <ul> 622 + <li>~85 serverless API endpoints</li> 623 + <li>Edge functions for media + routing</li> 624 + <li>Auth0 + Firebase authentication</li> 625 + <li>Stripe + PayPal payments</li> 626 + <li>Auto-deploys on push to main</li> 627 + </ul> 628 + </div> 629 + 630 + <div class="stack-card"> 631 + <div class="stack-card-title">Session Server</div> 632 + <ul> 633 + <li>Fastify + Geckos.io (WebSocket)</li> 634 + <li>Jamsocket ephemeral containers</li> 635 + <li>Real-time chat, multiplayer, rooms</li> 636 + <li>Redis state synchronization</li> 637 + <li>DigitalOcean droplet + pm2</li> 638 + </ul> 639 + </div> 640 + 641 + <div class="stack-card"> 642 + <div class="stack-card-title">Oven Service</div> 643 + <ul> 644 + <li>Express.js + FFmpeg</li> 645 + <li>Tape recordings &rarr; MP4 video</li> 646 + <li>Screenshot &amp; OG image generation</li> 647 + <li>Caddy reverse proxy (auto HTTPS)</li> 648 + <li>DigitalOcean droplet</li> 649 + </ul> 650 + </div> 651 + 652 + <div class="stack-card"> 653 + <div class="stack-card-title">Workers (Cloudflare)</div> 654 + <ul> 655 + <li>Feed server (Hono + TypeScript)</li> 656 + <li>Grab worker (Browser Rendering API)</li> 657 + <li>KV storage for playlists &amp; channels</li> 658 + <li>Durable Objects for state</li> 659 + </ul> 660 + </div> 661 + 662 + <div class="stack-card"> 663 + <div class="stack-card-title">Data</div> 664 + <ul> 665 + <li>MongoDB Atlas &mdash; all user content</li> 666 + <li>Redis &mdash; session cache</li> 667 + <li>DigitalOcean Spaces (S3 CDN) &mdash; media</li> 668 + <li>Cloudflare KV &mdash; feed data</li> 669 + <li>ATProto PDS &mdash; Bluesky bridge</li> 670 + </ul> 671 + </div> 672 + 673 + </div> 674 + 675 + <div class="diagram-label" style="margin-top: 0.5em;">KidLisp &mdash; Built-in Language</div> 676 + <div class="source-box"> 677 + <strong>118 built-in functions</strong> across 12 categories: math, color, shape, transform, animation, text, noise, input, logic, list, meta, system. Minimal Lisp dialect for generative art. No external libraries. Programs stored in MongoDB, shareable by 3-character code. Evaluator: <strong>lib/kidlisp.mjs</strong> (~2,400 lines). 678 + </div> 679 + 680 + <div class="diagram-label" style="margin-top: 0.5em;">Development Tools</div> 681 + <div class="tool-row"> 682 + <span class="tool-chip">Claude Code (Opus)</span> 683 + <span class="tool-chip">Cursor</span> 684 + <span class="tool-chip">VS Code</span> 685 + <span class="tool-chip purple">Node.js</span> 686 + <span class="tool-chip purple">esbuild</span> 687 + <span class="tool-chip purple">Puppeteer</span> 688 + <span class="tool-chip green">Jasmine</span> 689 + <span class="tool-chip green">Vitest</span> 690 + <span class="tool-chip green">Lighthouse</span> 691 + <span class="tool-chip blue">Netlify CLI</span> 692 + <span class="tool-chip blue">Wrangler</span> 693 + <span class="tool-chip blue">Docker</span> 694 + <span class="tool-chip blue">pm2</span> 695 + <span class="tool-chip blue">Caddy</span> 696 + <span class="tool-chip blue">systemd</span> 697 + </div> 698 + 699 + <div class="diagram-label" style="margin-top: 0.5em;">Source Code</div> 700 + <div class="source-box"> 701 + <strong>Repository:</strong> github.com/whistlegraph/aesthetic-computer &ensp;&middot;&ensp; Open source, continuously developed since 2021<br> 702 + <strong>Core files:</strong> boot.mjs (entry) &rarr; bios.mjs (runtime) &rarr; disk.mjs (API, ~572KB) &rarr; disks/*.mjs (pieces)<br> 703 + <strong>Languages:</strong> JavaScript (ES Modules), TypeScript (workers), KidLisp (generative art), HTML/CSS<br> 704 + <strong>Project score:</strong> SCORE.md &mdash; a living musical score metaphor that organizes all development work<br> 705 + <strong>Maintenance:</strong> AestheticAnts (AA) &mdash; colony of AI agents for automated codebase care 706 + </div> 707 + 708 + <!-- ============ APPENDIX C: SITEMAP ============ --> 709 + 710 + <hr class="section-divider"> 711 + 712 + <div class="appendix-header"> 713 + <div class="appendix-title">Appendix C: Sitemap</div> 714 + <div class="appendix-subtitle">22 domains &ensp;&middot;&ensp; ~355 disk routes &ensp;&middot;&ensp; ~85 API endpoints &ensp;&middot;&ensp; ~120 redirects</div> 715 + </div> 716 + 717 + <div class="domain-grid"> 718 + <div class="domain-card"><div class="domain-name">aesthetic.computer</div><div class="domain-desc">primary platform</div></div> 719 + <div class="domain-card"><div class="domain-name">kidlisp.com</div><div class="domain-desc">lisp editor</div></div> 720 + <div class="domain-card"><div class="domain-name">notepat.com</div><div class="domain-desc">music sequencer</div></div> 721 + <div class="domain-card"><div class="domain-name">sotce.net</div><div class="domain-desc">art portal</div></div> 722 + <div class="domain-card"><div class="domain-name">botce.ac</div><div class="domain-desc">bot interface</div></div> 723 + <div class="domain-card"><div class="domain-name">wipppps.world</div><div class="domain-desc">whistlegraph</div></div> 724 + <div class="domain-card"><div class="domain-name">news.*</div><div class="domain-desc">newsletter</div></div> 725 + <div class="domain-card"><div class="domain-name">give.*</div><div class="domain-desc">donations</div></div> 726 + <div class="domain-card"><div class="domain-name">shop.*</div><div class="domain-desc">physical goods</div></div> 727 + <div class="domain-card"><div class="domain-name">help.*</div><div class="domain-desc">AI assistant</div></div> 728 + <div class="domain-card"><div class="domain-name">feed.*</div><div class="domain-desc">DP1 feed</div></div> 729 + <div class="domain-card"><div class="domain-name">grab.*</div><div class="domain-desc">screenshots</div></div> 275 730 </div> 276 731 277 - <div class="doc-label">How user data flows</div> 278 - <div class="flow"> 279 - <span class="node">@handle</span> 280 - <span class="arrow">&ensp;&rarr;&ensp;</span> 281 - paint / chat / mood / kid / publish 282 - <span class="arrow">&ensp;&rarr;&ensp;</span> 283 - <span class="node">MongoDB</span> 284 - <span class="arrow">&ensp;&rarr;&ensp;</span> 285 - profile scorecard 286 - <span class="arrow">&ensp;&rarr;&ensp;</span> 287 - <span class="node">public URL</span> 288 - <br> 289 - <span class="note">moods also mirror to Bluesky via ATProto &ensp;&middot;&ensp; paintings stored on DigitalOcean Spaces CDN</span> 732 + <div class="sitemap-cols"> 733 + 734 + <div class="sitemap-section"> 735 + <div class="sitemap-header">Creative Tools / Drawing &ensp;(44)</div> 736 + <div class="sitemap-routes"> 737 + <span class="sitemap-route">paint</span> 738 + <span class="sitemap-route">nopaint</span> 739 + <span class="sitemap-route">line</span> 740 + <span class="sitemap-route">pline</span> 741 + <span class="sitemap-route">shape</span> 742 + <span class="sitemap-route">oval</span> 743 + <span class="sitemap-route">rect</span> 744 + <span class="sitemap-route">fill</span> 745 + <span class="sitemap-route">spray</span> 746 + <span class="sitemap-route">smear</span> 747 + <span class="sitemap-route">marker</span> 748 + <span class="sitemap-route">crayon</span> 749 + <span class="sitemap-route">sparkle-brush</span> 750 + <span class="sitemap-route">multipen</span> 751 + <span class="sitemap-route">doodle</span> 752 + <span class="sitemap-route">wand</span> 753 + <span class="sitemap-route">brush</span> 754 + <span class="sitemap-route">crop</span> 755 + <span class="sitemap-route">stamp</span> 756 + <span class="sitemap-route">blur</span> 757 + <span class="sitemap-route">snap</span> 758 + <span class="sitemap-route">paste</span> 759 + <span class="sitemap-route">make</span> 760 + <span class="sitemap-route">painting</span> 761 + <span class="sitemap-route">handprint</span> 762 + <span class="sitemap-route">nail</span> 763 + <span class="sitemap-route">colors</span> 764 + <span class="sitemap-route">selfie</span> 765 + <span class="sitemap-route">camera</span> 766 + <span class="sitemap-route">cards</span> 767 + </div> 290 768 </div> 291 769 292 - <div class="doc-label">Sample documents from MongoDB (live)</div> 770 + <div class="sitemap-section"> 771 + <div class="sitemap-header">Music / Audio &ensp;(24)</div> 772 + <div class="sitemap-routes"> 773 + <span class="sitemap-route">notepat</span> 774 + <span class="sitemap-route">beat</span> 775 + <span class="sitemap-route">tone</span> 776 + <span class="sitemap-route">chord</span> 777 + <span class="sitemap-route">melody</span> 778 + <span class="sitemap-route">song</span> 779 + <span class="sitemap-route">sing</span> 780 + <span class="sitemap-route">bleep</span> 781 + <span class="sitemap-route">say</span> 782 + <span class="sitemap-route">whistle</span> 783 + <span class="sitemap-route">metronome</span> 784 + <span class="sitemap-route">microphone</span> 785 + <span class="sitemap-route">uke</span> 786 + <span class="sitemap-route">pedal</span> 787 + <span class="sitemap-route">amp</span> 788 + <span class="sitemap-route">sfx</span> 789 + <span class="sitemap-route">r8dio</span> 790 + <span class="sitemap-route">squaresong</span> 791 + <span class="sitemap-route">rattle</span> 792 + <span class="sitemap-route">visualizer</span> 793 + <span class="sitemap-route">tracker</span> 794 + <span class="sitemap-route">3x3</span> 795 + </div> 796 + </div> 293 797 294 - <div class="doc-sample"><strong>mood</strong> { mood: "studying astronomy", when: "2026-03-02T12:32:49Z", atproto: { rkey: "3mg3b6jcj4k2x" } }</div> 798 + <div class="sitemap-section"> 799 + <div class="sitemap-header">Games / Interactive &ensp;(25)</div> 800 + <div class="sitemap-routes"> 801 + <span class="sitemap-route">game</span> 802 + <span class="sitemap-route">1v1</span> 803 + <span class="sitemap-route">brick-breaker</span> 804 + <span class="sitemap-route">flap</span> 805 + <span class="sitemap-route">fly</span> 806 + <span class="sitemap-route">hop</span> 807 + <span class="sitemap-route">scawy-snake</span> 808 + <span class="sitemap-route">run&amp;gun</span> 809 + <span class="sitemap-route">gostop</span> 810 + <span class="sitemap-route">staka</span> 811 + <span class="sitemap-route">pond</span> 812 + <span class="sitemap-route">balls</span> 813 + <span class="sitemap-route">bubble</span> 814 + <span class="sitemap-route">rain</span> 815 + <span class="sitemap-route">sno</span> 816 + <span class="sitemap-route">starfield</span> 817 + <span class="sitemap-route">metaballs</span> 818 + <span class="sitemap-route">ant</span> 819 + <span class="sitemap-route">field</span> 820 + <span class="sitemap-route">toss</span> 821 + </div> 822 + </div> 295 823 296 - <div class="doc-sample"><strong>painting</strong> { code: "gfl", slug: "2026.03.02.14.14.39", when: "2026-03-02T13:14:48Z", atproto: { rkey: "3mg3djpo6ck2x" } }</div> 824 + <div class="sitemap-section"> 825 + <div class="sitemap-header">KidLisp / Programming &ensp;(15)</div> 826 + <div class="sitemap-routes"> 827 + <span class="sitemap-route">kidlisp</span> 828 + <span class="sitemap-route">keep</span> 829 + <span class="sitemap-route">kept</span> 830 + <span class="sitemap-route">learn</span> 831 + <span class="sitemap-route">lang</span> 832 + <span class="sitemap-route">decode</span> 833 + <span class="sitemap-route">encode</span> 834 + <span class="sitemap-route">prompt</span> 835 + <span class="sitemap-route">chat</span> 836 + <span class="sitemap-route">docgen</span> 837 + <span class="sitemap-route">docs/*</span> 838 + </div> 839 + </div> 297 840 298 - <div class="doc-sample"><strong>kidlisp</strong> { code: "27z", source: "fade:red-blue-black-blue-red\nscroll (* 100 amp)", hits: 1, when: "2026-03-01" }</div> 841 + <div class="sitemap-section"> 842 + <div class="sitemap-header">Social / Community &ensp;(8)</div> 843 + <div class="sitemap-routes"> 844 + <span class="sitemap-route">mood</span> 845 + <span class="sitemap-route">moods</span> 846 + <span class="sitemap-route">share</span> 847 + <span class="sitemap-route">sign</span> 848 + <span class="sitemap-route">signature</span> 849 + <span class="sitemap-route">mail</span> 850 + <span class="sitemap-route">list</span> 851 + <span class="sitemap-route">insta</span> 852 + </div> 853 + </div> 299 854 300 - <div class="doc-sample"><strong>chat</strong> { text: "y'all gonna piss me off", when: "2026-03-02T05:26:25Z", font: "font_1" }</div> 855 + <div class="sitemap-section"> 856 + <div class="sitemap-header">People / Characters &ensp;(16)</div> 857 + <div class="sitemap-routes"> 858 + <span class="sitemap-route">mom</span> 859 + <span class="sitemap-route">dad</span> 860 + <span class="sitemap-route">brother</span> 861 + <span class="sitemap-route">sister</span> 862 + <span class="sitemap-route">husband</span> 863 + <span class="sitemap-route">wife</span> 864 + <span class="sitemap-route">boyfriend</span> 865 + <span class="sitemap-route">girlfriend</span> 866 + <span class="sitemap-route">kid</span> 867 + <span class="sitemap-route">angel</span> 868 + <span class="sitemap-route">robo</span> 869 + <span class="sitemap-route">sage</span> 870 + <span class="sitemap-route">tobby</span> 871 + <span class="sitemap-route">valbear</span> 872 + <span class="sitemap-route">gargoyle</span> 873 + <span class="sitemap-route">dolls</span> 874 + </div> 875 + </div> 301 876 302 - <div class="doc-sample"><strong>piece</strong> { code: "zod", slug: "zod", name: "3d-cube", extension: ".mjs", hits: 1, when: "2026-02-12" }</div> 877 + <div class="sitemap-section"> 878 + <div class="sitemap-header">Whistlegraph &ensp;(8)</div> 879 + <div class="sitemap-routes"> 880 + <span class="sitemap-route">whistlegraph</span> 881 + <span class="sitemap-route">wg</span> 882 + <span class="sitemap-route">wgr</span> 883 + <span class="sitemap-route">m2w2</span> 884 + <span class="sitemap-route">wipppps</span> 885 + <span class="sitemap-route">neo-wipppps</span> 886 + <span class="sitemap-route">merry-fade</span> 887 + </div> 888 + </div> 303 889 304 - <p style="font-size: 9pt; color: #666; margin-top: 1em;"> 305 - Every document ties back to an authenticated user. Every user has a profile that counts their contributions. The question for this cycle: what social structures &mdash; what <em>scores</em> &mdash; can make these numbers move together instead of in isolation? 306 - </p> 890 + <div class="sitemap-section"> 891 + <div class="sitemap-header">Media / TV &ensp;(7)</div> 892 + <div class="sitemap-routes"> 893 + <span class="sitemap-route">tv</span> 894 + <span class="sitemap-route">tapes</span> 895 + <span class="sitemap-route">screen</span> 896 + <span class="sitemap-route">screenshots</span> 897 + <span class="sitemap-route">replay</span> 898 + <span class="sitemap-route">video</span> 899 + </div> 900 + </div> 901 + 902 + <div class="sitemap-section"> 903 + <div class="sitemap-header">UCLA Course &ensp;(13)</div> 904 + <div class="sitemap-routes"> 905 + <span class="sitemap-route">ucla-1</span> 906 + <span class="sitemap-route">ucla-2</span> 907 + <span class="sitemap-route">ucla-3</span> 908 + <span class="sitemap-route">ucla-4</span> 909 + <span class="sitemap-route">ucla-5</span> 910 + <span class="sitemap-route">ucla-6</span> 911 + <span class="sitemap-route">ucla-7</span> 912 + + keyboard, box, turtle, balls, dial, jump variants 913 + </div> 914 + </div> 915 + 916 + <div class="sitemap-section"> 917 + <div class="sitemap-header">Single-Letter &amp; Numeric &ensp;(47)</div> 918 + <div class="sitemap-routes"> 919 + <span class="sitemap-route">$</span> 920 + <span class="sitemap-route">0&ndash;9</span> 921 + <span class="sitemap-route">a&ndash;z</span> 922 + </div> 923 + </div> 924 + 925 + <div class="sitemap-section"> 926 + <div class="sitemap-header">Dynamic Patterns</div> 927 + <div class="sitemap-routes" style="flex-direction: column;"> 928 + <span style="font-family: 'Berkeley Mono Variable', monospace; font-size: 7pt; color: rgb(120, 80, 180);">/@:handle &rarr; user profile &ensp;&middot;&ensp; /@:handle/:piece &rarr; user piece &ensp;&middot;&ensp; /preview/* &rarr; OG images &ensp;&middot;&ensp; /session/* &rarr; multiplayer rooms</span> 929 + </div> 930 + </div> 307 931 932 + </div> 933 + 934 + <div class="page-footer"> 935 + Aesthetic Computer Whitepaper &ensp;&middot;&ensp; March 2026 &ensp;&middot;&ensp; 936 + <span class="handle"><span class="c1">@</span><span class="c2">j</span><span class="c3">e</span><span class="c4">f</span><span class="c5">f</span><span class="c6">r</span><span class="c7">e</span><span class="c8">y</span></span> 308 937 </div> 309 938 310 939 </body>
sosoft/proposal.pdf

This is a binary file and will not be displayed.

+88 -139
sosoft/report.md
··· 1 - # SO SOFT — Social Software Cycle Proposal 1 + # Aesthetic Computer: Open Development 2 2 3 - ## Proposal for DESMA 596/199: Score for Social Software 4 - ### Jeffrey Scudder / @jeffrey / Aesthetic Computer 3 + ## A Platform Submitted for Dialogue 4 + ### Score for Social Software — Cycle 2 Proposal 5 + ### Jeffrey Scudder / @jeffrey / DESMA 596/199 / March 2026 5 6 6 7 --- 7 8 8 - ## 1. The Score 9 + ## The Score 9 10 10 - **Title:** *Aesthetic Computer as Social Instrument* 11 + I'm submitting Aesthetic Computer (AC) — the open-source creative computing 12 + platform I've been building since 2021 — as a social software project in active 13 + development. I'm not proposing to build a new thing for this cycle. I'm bringing 14 + the thing I'm already building into the room for dialogue, feedback, and critical 15 + exchange as I develop it alongside its community. 11 16 12 - **Core idea:** Develop Aesthetic Computer's existing social infrastructure into a 13 - legible, playable *score* — a set of rules, rituals, and interfaces that a small 14 - community performs together over the 10-week cycle. 17 + AC is a mobile-first runtime and social network where users write, publish, and 18 + share small interactive programs called *pieces*. It has real-time chat, @handles 19 + with custom colors, ephemeral status updates (moods mirrored to Bluesky via 20 + ATProto), a pixel painting system, a built-in Lisp dialect (KidLisp), multiplayer 21 + WebSocket sessions, and user profiles that track creative output. The codebase is 22 + open source with 4+ years of continuous development. 15 23 16 - AC already has the bones of social software built into its runtime: 24 + The score: I develop AC in the open over 10 weeks, sharing what I'm working on, 25 + what decisions I'm facing, and what the community is doing. The cohort engages as 26 + users and as critics — trying the tools, reading the design choices, and giving 27 + me feedback I can't get from inside the project. 17 28 18 - - **@handles** — unique identity with per-character color customization 19 - - **chat** — real-time group messaging with hearts/reactions 20 - - **moods** — ephemeral status updates (mirrored to Bluesky via ATProto) 21 - - **paintings** — collaborative pixel art gallery tied to user profiles 22 - - **KidLisp** — a minimal Lisp dialect anyone can use to publish generative art 23 - - **pieces** — URL-addressable programs anyone can write and publish at `@handle/piece-name` 24 - - **multiplayer sessions** — WebSocket rooms that any piece can use for real-time collaboration 25 - - **profiles** — live scorecards showing each user's creative output across all media types 29 + ## What I'm Looking For 26 30 27 - What's missing is not technology — it's *choreography*. The platform has 351 28 - built-in pieces, ~2800 registered handles, and 16k+ chat messages, but the 29 - social dynamics are still largely emergent and undirected. The cycle offers a 30 - chance to compose deliberate social scores *on top of* the existing runtime. 31 + - What feels inviting and what feels opaque when you first encounter the platform? 32 + - Which social features sustain participation vs. which are technically impressive 33 + but socially inert? 34 + - How does the "instrument" metaphor land for people who aren't already invested? 35 + - What would you want to do on AC that you currently can't? 36 + - Where does the design accidentally exclude the people it claims to welcome? 31 37 32 - ### Proposed Scores to Develop 38 + ## What the Cohort Gets 33 39 34 - **Score A: "Daily Painting Circle"** 35 - A structured daily practice where cycle members each create and publish one 36 - painting per day using AC's pixel tools (`new`, `rect`, `line`, `smear`, `fill`, 37 - `shape`). Paintings are published via `done` and visible on each member's 38 - profile. The group reviews the day's paintings together in weekly meetings. 39 - This is a simple, repeatable ritual that teaches the platform's creative tools 40 - through committed practice. 40 + - **A live codebase** — open source, documented, changing week to week 41 + - **The dev process** — I work with Claude Code, Cursor, VS Code, and maintain a 42 + living SCORE.md; the process is as legible as the product 43 + - **Platform accounts** — everyone gets an @handle, can paint, chat, set moods, 44 + write KidLisp, publish pieces 45 + - **Real community data** — 2,800 handles, 18k chat messages, 4,400 paintings, 46 + 16k KidLisp programs 41 47 42 - **Score B: "Piece Exchange"** 43 - Each member writes and publishes one AC piece (a small interactive program) per 44 - week, shared at their `@handle/piece-name`. The group plays each other's pieces 45 - and discusses them. Members can fork each other's work via `source @handle/piece` 46 - and publish remixes. This teaches the programming API through peer learning and 47 - creates a growing library of social artifacts. 48 + ## Why This Cycle 48 49 49 - **Score C: "KidLisp Jam"** 50 - Weekly sessions where members collectively write KidLisp programs — AC's 51 - built-in Lisp dialect for generative art. KidLisp has 118 built-in functions 52 - and programs can be stored and shared instantly. The constraint of a minimal 53 - language (no external libraries, immediate visual output) creates a level 54 - playing field between experienced programmers and beginners. 50 + Casey's framing of "scores for social software" maps directly onto how I think 51 + about AC. The platform's SCORE.md uses the metaphor of a musical score to 52 + organize the project. The interface is designed like an instrument — users 53 + discover memorizable paths, build literacy through play, and eventually 54 + improvise. But I've been composing alone. This cycle is a chance to compose in 55 + conversation. 55 56 56 - **Score D: "Chat as Performance"** 57 - Using AC's real-time chat as a performance medium. Structured chat sessions with 58 - rules — e.g., "only respond with piece names," "conversation through shared 59 - paintings," "one word per message." The chat system supports custom fonts, 60 - handle colors, and hearts, making it already suited to expressive constraint-based 61 - communication. 57 + The technical infrastructure is mature. The question now is about social design: 58 + how do the features I've built actually shape the way people relate to each other 59 + and to creative computing? That's best answered through dialogue with people 60 + thinking critically about social software. 62 61 63 - ### What I Would Build During the Cycle 62 + ## Practice 64 63 65 - 1. **A `sosoft` piece** — a dedicated AC piece (`aesthetic.computer/sosoft`) that 66 - serves as the cohort's home base: a dashboard showing all members' recent 67 - activity, paintings, published pieces, and moods in one view. 64 + I'm an artist, educator, and software developer. Before AC, I created No Paint 65 + (2020), a pixel art tool whose community taught me how people learn computing 66 + through social participation. AC extends that into a full platform: anyone can 67 + write, publish, and share interactive programs at a URL. I teach creative 68 + computing and have used AC as infrastructure in courses and workshops. I'm 69 + bringing this not as a finished project but as an ongoing practice I want to 70 + develop through critical exchange. 68 71 69 - 2. **Score templates** — simple markdown + code templates that define the rules 70 - for each social score, publishable as AC pieces themselves. 71 - 72 - 3. **Multiplayer scoring pieces** — new pieces that use AC's session server for 73 - real-time collaborative drawing, KidLisp editing, or structured turn-taking. 74 - 75 - 4. **Documentation** — a "Write a Score" guide parallel to AC's existing 76 - "Write a Piece" guide, teaching others to compose their own social software 77 - scores on the platform. 72 + **Links:** 73 + - Aesthetic Computer: https://aesthetic.computer 74 + - GitHub: https://github.com/whistlegraph/aesthetic-computer 75 + - No Paint: https://nopaint.art 76 + - Notepat on HN: https://news.ycombinator.com/item?id=41526754 78 77 79 78 --- 80 79 81 - ## 2. Intended Users / Audience / Community 80 + ## Appendix A: The Network (March 2, 2026) 82 81 83 - **Primary:** The cycle's own members (MFA and BA students in DESMA 596/199). 84 - The scores are designed to be performed by a small group (5–12 people) who 85 - commit to regular participation. 82 + | Metric | Count | 83 + |--------|-------| 84 + | @handles | 2,798 | 85 + | Chat messages | 18,016 | 86 + | Paintings | 4,392 | 87 + | Moods | 2,900 | 88 + | KidLisp programs | 16,174 | 89 + | Published pieces | 265 | 90 + | Clocks | 333 | 91 + | Tapes | 102 | 92 + | Boot events | 93,122 | 86 93 87 - **Secondary:** AC's existing community (~2800 registered handles). Anything 88 - built during the cycle would be immediately live on the public platform. 89 - Existing AC users could discover and join the scores organically. 94 + **Who makes things:** 1,067 have painted · 997 have posted moods · 95 + 59 have written KidLisp · 19 have published pieces 90 96 91 - **Tertiary:** Creative computing educators and students elsewhere. The "Write a 92 - Score" documentation would be a reusable framework for anyone running a creative 93 - computing workshop or class using AC as infrastructure. 97 + ## Appendix B: Technical Stack 94 98 95 - --- 99 + - **Frontend:** ES Modules, Canvas 2D + WebGL2, WebSocket hot-reload, 351 pieces 100 + - **System Server:** Netlify (~85 API endpoints, edge functions, Auth0, Stripe) 101 + - **Session Server:** Fastify + Geckos.io, Jamsocket containers, Redis 102 + - **Oven Service:** Express.js + FFmpeg, tape → MP4, screenshots 103 + - **Workers:** Cloudflare (feed, grab, KV, Durable Objects) 104 + - **Data:** MongoDB Atlas, Redis, DigitalOcean Spaces (S3 CDN), ATProto PDS 105 + - **Language:** KidLisp — 118 built-in functions, 12 categories 106 + - **Dev Tools:** Claude Code, Cursor, VS Code, esbuild, Jasmine, Vitest, Docker 96 107 97 - ## 3. Why This Cycle 108 + ## Appendix C: Sitemap 98 109 99 - Aesthetic Computer has been in development since 2021, growing from No Paint 100 - (2020, discussed on Hacker News) into a full runtime with 351 pieces, a Lisp 101 - dialect, multiplayer, chat, and a handle system. The technical infrastructure 102 - is mature. What it needs now is *social composition* — deliberate experiments 103 - in how people use this system together. 110 + 22 domains · ~355 disk routes · ~85 API endpoints · ~120 redirects 104 111 105 - Casey's framing of "scores for social software" maps directly onto how I already 106 - think about AC. The SCORE.md file in the repository literally uses the metaphor 107 - of a musical score to organize the project. AC's interface is designed to 108 - function like a musical instrument — users discover memorizable paths, build 109 - literacy through play, and eventually improvise and compose. 112 + ## PDF Generation 110 113 111 - This cycle offers: 112 - 113 - - **A committed cohort** to test social features that need real human 114 - participation to evaluate (you can't A/B test a conversation) 115 - - **Critical feedback** from Casey and peers on the social design, not just the 116 - technical architecture 117 - - **A structured timeframe** (10 weeks) that creates urgency and rhythm — 118 - exactly what a score needs to be performed 119 - - **Cross-pollination** with other participants' social software projects, 120 - creating a richer discourse than working in isolation 121 - 122 - I'm also interested in this cycle as a way to develop AC's role as 123 - *educational infrastructure* — something I can bring to my own teaching practice 124 - and share with other educators. 125 - 126 - --- 127 - 128 - ## 4. Practice Description 129 - 130 - I'm Jeffrey Scudder (@jeffrey), an artist, educator, and software developer. 131 - I direct Aesthetic Computer (https://aesthetic.computer), an open-source 132 - creative computing platform and social network. 133 - 134 - My practice centers on building software as a medium for art and education. 135 - Before AC, I created No Paint (nopaint.art, 2020), a pixel art tool that was 136 - discussed on Hacker News and used by a community of non-technical artists who 137 - learned computing through contributing to the software they loved. 138 - 139 - AC extends this into a full platform: a mobile-first runtime where anyone can 140 - write, publish, and share interactive programs. It includes KidLisp (a Lisp 141 - dialect for generative art), real-time multiplayer, a chat system, and a social 142 - handle system. The codebase is open source with ~78 API endpoints and has been 143 - in continuous development for 4+ years. 144 - 145 - I teach creative computing and have used AC as infrastructure in courses and 146 - workshops. My interest in "social software" comes directly from watching 147 - non-technical users learn computation through social participation in software 148 - communities — first in No Paint, now in AC. 149 - 150 - **Links:** 151 - - Aesthetic Computer: https://aesthetic.computer 152 - - GitHub: https://github.com/whistlegraph/aesthetic-computer 153 - - No Paint: https://nopaint.art 154 - - Notepat on HN: https://news.ycombinator.com/item?id=41526754 155 - 156 - --- 157 - 158 - ## Technical Stack for PDF Generation 159 - 160 - - **Content source:** This report.md 161 - - **PDF generation:** Puppeteer (already in project dependencies) rendering a 162 - styled HTML template to PDF 163 - - **Script:** `sosoft/generate-pdf.mjs` — converts the HTML to a print-quality 164 - PDF with proper typography 165 - - **Output:** `sosoft/proposal.pdf` 166 - 167 - To generate: `node sosoft/generate-pdf.mjs` 114 + - **Source:** sosoft/proposal.html 115 + - **Script:** `node sosoft/generate-pdf.mjs` 116 + - **Output:** sosoft/proposal.pdf